/*
* Created on Jun 6, 2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package stage2;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import stage1.HandRecordClusterId;
import _game.Card;
import _io.ReadBinaryClusterIdStream;
import _io.WriteBinaryClusterIDTableStream;
import _misc.ByteArrayWrapper;
import _misc.Combinations;
import _misc.Constants;
import _misc.Helper;
/**
* @author Adam
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class DoTransitionPDTStep1 {
private static final String ROOT_INPUT_DIR = Constants.DATA_FILE_REPOSITORY +
"stage2" + Constants.dirSep;
private static final String ROOT_OUTPUT_DIR = Constants.DATA_FILE_REPOSITORY +
"stage2" + Constants.dirSep;
private static final int MAX_SIMULT_FILES_OPEN = 1;
public static void main(String[] args) throws IOException {
double tTotal = System.currentTimeMillis();
int numBoardCards1 = Integer.parseInt(args[0]);
int stopAtNumBoardCards1 = Integer.parseInt(args[1]);
if(numBoardCards1 > stopAtNumBoardCards1) {
throw new RuntimeException();
}
int numBoardCards2 = Helper.getNextBoardCardCount(numBoardCards1, false);
while (numBoardCards1 <= stopAtNumBoardCards1) {
double tBoardCards = System.currentTimeMillis();
System.out.println("");
System.out.println("---------");
System.out.println("TPDT Step 1'ing " + numBoardCards1 + "->" + numBoardCards2 + " boardcards");
System.out.println("---------");
boolean isFiveBcs = (numBoardCards2 == 5 ? true : false);
byte[] holeCards;
int numIterations = Constants.choose(Card.NUM_CARDS, 2);
int iterationCounter = 0;
while((holeCards = getNextTask(numBoardCards1)) != null) {
double tIteration = System.currentTimeMillis();
System.out.println("Executing on hole cards: " + Helper.byteArrayToString(holeCards) + "...");
// ------------------------------------------------------------
// load up our two input files -- (x) bc's and (x+1) bc's
// ------------------------------------------------------------
String inputPath1 = getInputFileName(numBoardCards1, holeCards);
String inputPath2 = getInputFileName(numBoardCards2, holeCards);
ReadBinaryClusterIdStream in1 =
new ReadBinaryClusterIdStream(inputPath1, numBoardCards1, Helper.getBufferSize(MAX_SIMULT_FILES_OPEN));
ReadBinaryClusterIdStream in2 =
new ReadBinaryClusterIdStream(inputPath2, numBoardCards2, Helper.getBufferSize(MAX_SIMULT_FILES_OPEN));
// ------------------------------------------------------------
// load up output file
// ------------------------------------------------------------
String outputPath = getOutputFileName(numBoardCards1, holeCards);
Helper.prepFilePath(outputPath);
WriteBinaryClusterIDTableStream out =
new WriteBinaryClusterIDTableStream(
outputPath, numBoardCards1, numBoardCards2, holeCards,
in1.getNumClusters(), in2.getNumClusters(),
Helper.getBufferSize(MAX_SIMULT_FILES_OPEN));
// ------------------------------------------------------------
// read input for numBoardCards2 into array for random access
// ------------------------------------------------------------
byte[][][][][] newClusterIds = new byte[Card.NUM_CARDS+1]
[Card.NUM_CARDS+1]
[Card.NUM_CARDS+1]
[Card.NUM_CARDS+1]
[Card.NUM_CARDS+1];
HandRecordClusterId hr2;
double arrayPopulateTimer = System.currentTimeMillis();
int numEntriesToPopulate = Constants.choose(Card.NUM_CARDS-2, numBoardCards2);
int modVal = (int)Math.floor(numEntriesToPopulate/100);
if(isFiveBcs) {
int counter = 0;
int percent = 0;
while((hr2 = in2.readRecord()) != null) {
byte[] boardCards2Copy = hr2.boardCards;
newClusterIds[boardCards2Copy[0]]
[boardCards2Copy[1]]
[boardCards2Copy[2]]
[boardCards2Copy[3]]
[boardCards2Copy[4]] = hr2.clusterId;
if(++counter % modVal == 0) {
// System.out.println(" " + (percent++) + "% done populating array");
}
}
} else {
while((hr2 = in2.readRecord()) != null) {
byte[] boardCards2Copy = new byte[5];
for(int i = 0; i < numBoardCards2; i++) {
boardCards2Copy[i] = hr2.boardCards[i];
}
for(int i = numBoardCards2; i < 5; i++) {
boardCards2Copy[i] = Card.NUM_CARDS;
}
newClusterIds[boardCards2Copy[0]]
[boardCards2Copy[1]]
[boardCards2Copy[2]]
[boardCards2Copy[3]]
[boardCards2Copy[4]] = hr2.clusterId;
}
}
// System.out.println(" load array: " +
// (System.currentTimeMillis() - arrayPopulateTimer));
// ------------------------------------------------------------
// create output
// ------------------------------------------------------------
// for each (50 choose numBoardCards1) ...
// print clusterId for numBoardCards1
// loop through all possible (50 choose numBoardCards2) boardcards,
// merge each one with our holecards to get the candidates for the
// next card-turn. For each of those, look up the cluster ID for
// these holecards and print that out
HandRecordClusterId hr1;
// each output sequence (for each boardCard config) will now:
// 1) be the same length
// 2) be in the same order, given the boardcards
// output cluster ID will only be Byte.MAX_VALUE if the newly delt
// card is one of the ones in these holecards.
while((hr1 = in1.readRecord()) != null) {
// first print the master clusterId for numBoardCards1
out.putClusterId(hr1.clusterId);
Combinations nextHandAddCards = new Combinations(
Helper.getRemainingCards(hr1.boardCards),
(numBoardCards2 - numBoardCards1)); //hot spot?
byte[] addCards;
while(nextHandAddCards.hasMoreElements()) {
addCards = nextHandAddCards.nextElement();
boolean legalGivenHCs = true;
for(int i = 0; i < addCards.length; i++) {
if(addCards[i] == holeCards[0] ||
addCards[i] == holeCards[1]) {
legalGivenHCs = false;
break;
}
}
if(legalGivenHCs) {
byte[] newHand = Helper.mergeOrderedByteArrays(
hr1.boardCards, addCards);
byte newClusterId = -1;
if(isFiveBcs) {
newClusterId = newClusterIds[newHand[0]]
[newHand[1]]
[newHand[2]]
[newHand[3]]
[newHand[4]];
} else {
byte[] newBcs = new byte[5];
for(int i = 0; i < numBoardCards2; i++) {
newBcs[i] = newHand[i];
}
for(int i = numBoardCards2; i < 5; i++) {
newBcs[i] = Card.NUM_CARDS;
}
newClusterId = newClusterIds[newBcs[0]]
[newBcs[1]]
[newBcs[2]]
[newBcs[3]]
[newBcs[4]];
}
out.putClusterId(newClusterId);
} else {
out.putClusterId(Byte.MAX_VALUE); // place holder!
}
}
}
out.close();
deleteLock(numBoardCards1, holeCards);
System.out.println(" Iteration " + ((int) Math.floor(100*((double) ++iterationCounter/numIterations))) + "% done in time: " + (System.currentTimeMillis() - tIteration));
}
System.out.println("numBoardCards " + numBoardCards1 + "->" + numBoardCards2 + " completed in time: " + (System.currentTimeMillis() - tBoardCards));
switch(numBoardCards1) {
case 0 : numBoardCards1=3; numBoardCards2=4; break;
case 3 : numBoardCards1=4; numBoardCards2=5; break;
case 4 : numBoardCards1=Integer.MAX_VALUE; numBoardCards2=Integer.MAX_VALUE; break;
default : throw new RuntimeException(); }
}
System.out.println("All TPDT Step1'ing completed in time: " + (System.currentTimeMillis() - tTotal));
}
private static byte[] getNextTask(int numBoardCards1) throws IOException {
Combinations combo = new Combinations(Card.ALLCARDSINDEX, 2);
byte[] holeCards;
while(combo.hasMoreElements()) {
holeCards = combo.nextElement();
// disqualified if it's already been done
if(new File(getOutputFileName(numBoardCards1, holeCards)).exists()) {
continue;
}
// disqualified if it's currently being done...otherwise lock it
// (check for lock, and lock, atomically)
File lock = new File(getInputFileName(numBoardCards1, holeCards) + ".lock");
if(lock.createNewFile()) {
// we got a lock!
return holeCards;
}
}
// we couldn't find any tasks
return null;
}
private static void deleteLock(int numBoardCards1, byte[] holeCards) {
File lock = new File(getInputFileName(numBoardCards1, holeCards) + ".lock");
if(!lock.exists()) {
throw new RuntimeException();
}
lock.delete();
}
private static String getInputFileName(int numBoardCards, byte[] holeCards) {
return ROOT_INPUT_DIR + "clustering_step2_" + numBoardCards+ "" + Constants.dirSep
+ new Integer(holeCards[0]).toString() + "_"
+ new Integer(holeCards[1]).toString();
}
private static String getOutputFileName(int numBoardCards1, byte[] holeCards) {
return ROOT_OUTPUT_DIR + "transitions_step1_"
+ numBoardCards1 + "" + Constants.dirSep
+ new Integer(holeCards[0]).toString() + "_"
+ new Integer(holeCards[1]).toString();
}
}