132 lines
4.7 KiB
Java
132 lines
4.7 KiB
Java
package suicideChess;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileReader;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Random;
|
|
|
|
import suicideChess.Move.NotAValidMoveException;
|
|
import suicideChess.Square.NotAValidSquare;
|
|
|
|
/**
|
|
* This class is used to play the first few moves of a game
|
|
*
|
|
* @author Jean-Baptiste Hétier
|
|
* @version $LastChangedRevision$, $LastChangedDate$
|
|
*
|
|
*/
|
|
public class OpeningBook {
|
|
|
|
@SuppressWarnings("serial")
|
|
public static class NoOpeningMovesLeft extends Exception {
|
|
NoOpeningMovesLeft(String s) { super(s); };
|
|
}
|
|
|
|
//This array will hold all book variants.
|
|
private static ArrayList<String[]> book; //each arrayList is an array of one possible opening moves (index 0 is the first move).
|
|
static void load() { openingBookLoad("openbook"); reset();} //initialise with file 'problems' if found in current directory
|
|
|
|
/**
|
|
* This function is used to load an openingbook file
|
|
* @param file
|
|
*/
|
|
public static void openingBookLoad(String file) {
|
|
//declared here only to make visible to finally clause
|
|
BufferedReader problemReader = null;
|
|
book = new ArrayList<String[]>();
|
|
try {
|
|
problemReader = new BufferedReader(new FileReader(file));
|
|
String line = null; //not declared within while loop
|
|
while ((line = problemReader.readLine()) != null) {
|
|
if (!line.startsWith("#")) { //ignore lines starting with # (comments)
|
|
book.add(line.split("\\s")); //each space defines a new move
|
|
}
|
|
}
|
|
}
|
|
catch (FileNotFoundException e) {
|
|
System.out.println("File '"+file+"' not found. Opening book won't be available.");
|
|
}
|
|
catch (IOException e){
|
|
System.out.println("Error reading file '"+file+"'.");
|
|
}
|
|
finally {
|
|
try {
|
|
if (problemReader!= null) {
|
|
problemReader.close();
|
|
}
|
|
}
|
|
catch (IOException ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
System.out.println(book.size()+" opening variants loaded.");
|
|
}
|
|
|
|
// this variable is the currentBook
|
|
private static boolean[] validMoves;
|
|
|
|
/**
|
|
* This function should be called everytime a game is reset
|
|
*/
|
|
public static void reset() {
|
|
validMoves = new boolean[book.size()];
|
|
for (int i=0; i<validMoves.length; i++)
|
|
validMoves[i]=true; //all moves are valid
|
|
nbOfMovesThatHaveBeenPlayed = 0;
|
|
}
|
|
|
|
//used to access the correct index in the list of moves
|
|
private static int nbOfMovesThatHaveBeenPlayed = 0;
|
|
|
|
|
|
/**
|
|
* everytime a move is played by the opposite player, the computer should be notified
|
|
* using this function. He will update the list of moves that can be played
|
|
*/
|
|
public static void played(Move move) {
|
|
for (int i=0; i<validMoves.length; i++) {
|
|
if(validMoves[i] && (book.get(i).length>nbOfMovesThatHaveBeenPlayed)) {
|
|
if (!(book.get(i)[nbOfMovesThatHaveBeenPlayed].equals(move.toString()))) {
|
|
validMoves[i]=false; //this branch is not valid anymore
|
|
}
|
|
}
|
|
}
|
|
nbOfMovesThatHaveBeenPlayed++;
|
|
}
|
|
|
|
/**
|
|
* Returns a move from the book if available, given a bitboard.
|
|
* @param bitboard
|
|
* @return
|
|
* @throws NotAValidMoveException
|
|
* @throws NotAValidSquare
|
|
* @throws NoOpeningMovesLeft
|
|
*/
|
|
public static Move getMove(Board bitboard) throws NotAValidMoveException, NotAValidSquare, NoOpeningMovesLeft {
|
|
ArrayList<Move> possibleMoves = new ArrayList<Move>();
|
|
for (int i=0; i<validMoves.length; i++) {
|
|
if(validMoves[i] && (book.get(i).length>nbOfMovesThatHaveBeenPlayed)) {
|
|
possibleMoves.add(new Move(book.get(i)[nbOfMovesThatHaveBeenPlayed],bitboard));
|
|
if (SuicideChess.postThinkingOutput()) {
|
|
String formatVariation = "";
|
|
for(int j=nbOfMovesThatHaveBeenPlayed; j<book.get(i).length; j++) {
|
|
formatVariation += book.get(i)[j]+" ";
|
|
}
|
|
System.out.println(" "+1+"\t"+0+"\t"+0+"\t"+validMoves.length+"\t"+formatVariation+" [Book Move]");
|
|
}
|
|
}
|
|
}
|
|
//select one of the possible moves randomly
|
|
if(possibleMoves.size()==0) {
|
|
throw new NoOpeningMovesLeft("No moves left in opening book.");
|
|
}
|
|
|
|
Random generator = new Random();
|
|
Move chosenMove = possibleMoves.get(generator.nextInt(possibleMoves.size()));
|
|
return chosenMove;
|
|
}
|
|
|
|
}
|