Version 0.8.0

=============
Just before creating the external config file
This commit is contained in:
2006-07-04 01:45:39 +00:00
parent 8a641a6e1e
commit a0ee66638d
7 changed files with 241 additions and 28 deletions

View File

@ -68,11 +68,11 @@ public class Board {
/** /**
* Importance of real mobility in position evaluation (ie. how many moves can one make compared to the other) * Importance of real mobility in position evaluation (ie. how many moves can one make compared to the other)
*/ */
public static final int REAL_MOBILITY_VALUE = 1000; //10; public static final int REAL_MOBILITY_VALUE = 40; //10;
/** /**
* Importance of relative mobility (mobility of other pieces that may not be able to play because of a compulsory move) * Importance of relative mobility (mobility of other pieces that may not be able to play because of a compulsory move)
*/ */
public static final int RELATIVE_MOBILITY_VALUE = 1000; //5; public static final int RELATIVE_MOBILITY_VALUE = 40; //5;
//with less than that many pawns on one side, the computer will enter endgame mode //with less than that many pawns on one side, the computer will enter endgame mode
public static final int ENDGAME_PAWNS = 3; public static final int ENDGAME_PAWNS = 3;
@ -81,14 +81,22 @@ public class Board {
public static final int ENDGAME_PIECES = 8; public static final int ENDGAME_PIECES = 8;
public static final int[] SQUARE_WEIGHT = { public static final int[] SQUARE_WEIGHT = {
-20, -10, -10, -10, -10, -10, -10, -20, /* -20, -10, -10, -10, -10, -10, -10, -20,
-10, 0, 3, 5, 5, 3, 0, -10, -10, 0, 3, 5, 5, 3, 0, -10,
-10, 2, 15, 15, 15, 15, 2, -10, -10, 2, 15, 15, 15, 15, 2, -10,
-10, 7, 15, 25, 25, 15, 7, -10, -10, 7, 15, 25, 25, 15, 7, -10,
-10, 7, 15, 25, 25, 15, 7, -10, -10, 7, 15, 25, 25, 15, 7, -10,
-10, 2, 15, 15, 15, 15, 2, -10, -10, 2, 15, 15, 15, 15, 2, -10,
-10, 0, 3, 5, 5, 3, 0, -10, -10, 0, 3, 5, 5, 3, 0, -10,
-20, -10, -10, -10, -10, -10, -10, -20 -20, -10, -10, -10, -10, -10, -10, -20*/
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10
}; };
@ -621,7 +629,7 @@ public class Board {
//this is a very very basic evaluation function that will be changed. //this is a very very basic evaluation function that will be changed.
//boardValue = numberOfBlackPieces - numberOfWhitePieces; //boardValue = numberOfBlackPieces - numberOfWhitePieces;
boardValue = 0; boardValue = 0;
if((numberOfPieces[Piece.BLACK_PAWN] <= ENDGAME_PAWNS) || (numberOfPieces[Piece.WHITE_PAWN] <= ENDGAME_PAWNS) /*if((numberOfPieces[Piece.BLACK_PAWN] <= ENDGAME_PAWNS) || (numberOfPieces[Piece.WHITE_PAWN] <= ENDGAME_PAWNS)
|| (numberOfPieces[Piece.BLACK_PIECES] <= ENDGAME_PIECES) || (numberOfPieces[Piece.WHITE_PIECES] <= ENDGAME_PIECES) ) { || (numberOfPieces[Piece.BLACK_PIECES] <= ENDGAME_PIECES) || (numberOfPieces[Piece.WHITE_PIECES] <= ENDGAME_PIECES) ) {
//System.out.println("Playing endgame"); //System.out.println("Playing endgame");
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) { for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
@ -629,17 +637,18 @@ public class Board {
} }
} else { } else {
//System.out.println("Playing midgame"); //System.out.println("Playing midgame");
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) { /*for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
//boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i]; boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i];
for(int squareNb = 0; squareNb<NB_OF_SQUARES; squareNb++) { }*/
Piece pieceOnSquare = getPiece(new Square(squareNb)); for(int squareNb = 0; squareNb<NB_OF_SQUARES; squareNb++) {
if(pieceOnSquare.getPieceNumber()!=Piece.NONE) { Piece pieceOnSquare = getPiece(new Square(squareNb));
boardValue += SQUARE_WEIGHT[squareNb]*Piece.PIECE_VALUE_MIDDLEGAME[pieceOnSquare.getColor()]; if(pieceOnSquare.getPieceNumber()!=Piece.NONE) {
} //System.out.println(SQUARE_WEIGHT[squareNb]);
boardValue += SQUARE_WEIGHT[squareNb]*Piece.PIECE_VALUE_MIDDLEGAME[pieceOnSquare.getPieceNumber()];
} }
} }
boardValue += ((mobility(Piece.WHITE)-mobility(Piece.BLACK))); //boardValue += ((mobility(Piece.WHITE)-mobility(Piece.BLACK)));
} //}
} }
} }
if (!Rules.isThereALegalMovesForPlayer(this)) { if (!Rules.isThereALegalMovesForPlayer(this)) {

View File

@ -157,6 +157,13 @@ public class ComputerPlayer {
"\t"+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds "\t"+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\t"+nodesSearched+"\t"+bestScore.getPrincipalVariation()); "\t"+nodesSearched+"\t"+bestScore.getPrincipalVariation());
} }
if((bitboard.getCurrentPlayer()==Piece.BLACK
&& bestScore.getBranchValue()==Board.BLACK_WINS)
|| (bitboard.getCurrentPlayer()==Piece.WHITE
&& bestScore.getBranchValue()==Board.WHITE_WINS)) {
break; //no need to continue iterative deepening.
}
} }
if(SuicideChess.playInACSII()) { if(SuicideChess.playInACSII()) {
@ -249,6 +256,11 @@ public class ComputerPlayer {
"\t"+nodesSearched+"\t"+bestVariationSoFar); "\t"+nodesSearched+"\t"+bestVariationSoFar);
} }
//System.out.println("*** Clear "); //System.out.println("*** Clear ");
if(bestScoreSoFar==Board.BLACK_WINS) { //found a win, no need to go further
if(SuicideChess.playInACSII()) System.out.println("Found a win !");
bestMoves.add(allLegalMoves.get(i));
return new ReturnWrapper(beta,bestScoreSoFar,bestVariationSoFar);
}
} }
} }
if(currentDepth==0) { if(currentDepth==0) {
@ -294,6 +306,11 @@ public class ComputerPlayer {
"\t"+((int)((new Date()).getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds "\t"+((int)((new Date()).getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\t"+nodesSearched+"\t"+bestVariationSoFar); "\t"+nodesSearched+"\t"+bestVariationSoFar);
} }
if(bestScoreSoFar==Board.WHITE_WINS) { //found a win, no need to go further
if(SuicideChess.playInACSII()) System.out.println("Found a win !");
bestMoves.add(allLegalMoves.get(i));
return new ReturnWrapper(alpha,bestScoreSoFar,bestVariationSoFar);
}
//System.out.println("*** Clear "); //System.out.println("*** Clear ");
} }
} }

View File

@ -0,0 +1,150 @@
package suicideChess;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
* This class is used to read configuration settings for the AI
*
* @author Jean-Baptiste H&eacute;tier
* @version $LastChangedRevision$, $LastChangedDate$
*
*/
public class ConfigFile {
private static int[] pieceValuesMiddle;
private static int[] pieceValuesEnd;
private static int[] squareWeightMiddle;
private static int[] squareWeightEnd;
private static int primaryMobilityValueMiddle;
private static int primaryMobilityValueEnd;
private static int secondaryMobilityValueMiddle;
private static int secondaryMobilityValueEnd;
private static int endGamePawns;
private static int endGamePieces;
/**
* The pieces value in the middlegame
*/
public static int[] getPieceValuesMiddle() {
return pieceValuesMiddle;
}
/**
* The pieces value in the end
*/
public static int[] getPieceValuesEnd() {
return pieceValuesEnd;
}
/**
* The weight of each square in the middle game
*/
public static int[] getSquareWeightMiddle() {
return squareWeightMiddle;
}
/**
* The weight of each square in the endgame
*/
public static int[] getSquareWeightEnd() {
return squareWeightEnd;
}
/**
* The primary mobility value (nb of possible legal moves) in the midgame
*/
public static int getPrimaryMobilityValueMiddle() {
return primaryMobilityValueMiddle;
}
/**
* The primary mobility value (nb of possible legal moves) in the endgame
*/
public static int getPrimaryMobilityValueEnd() {
return primaryMobilityValueEnd;
}
/**
* The secondary mobility value (nb of possible but not legal moves) in the midgame
*/
public static int getSecondaryMobilityValueMiddle() {
return secondaryMobilityValueMiddle;
}
/**
* The secondary mobility value (nb of possible but not legal moves)
*/
public static int getScondaryMobilityValueEnd() {
return secondaryMobilityValueEnd;
}
/**
* Number of pawns on the opposite side before entering endgame
*/
public static int getEndGamePawns() {
return endGamePawns;
}
/**
* Number of pieces on the opposite site before entering endgame
*/
public static int getEndGamePieces() {
return endGamePieces;
}
public static void load(String file) {
//declared here only to make visible to finally clause
BufferedReader problemReader = null;
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.");
}
static {
pieceValuesMiddle[Piece.WHITE_KING]=-100; //500
pieceValuesMiddle[Piece.WHITE_QUEEN]=-100; //900
pieceValuesMiddle[Piece.WHITE_ROOK]=-100; //350
pieceValuesMiddle[Piece.WHITE_KNIGHT]=-100; //300
pieceValuesMiddle[Piece.WHITE_BISHOP]= -100; //started with -100, -400, -200
pieceValuesMiddle[Piece.WHITE_PAWN]= -100; //started with 100
pieceValuesMiddle[Piece.BLACK_KING]=-pieceValuesMiddle[Piece.WHITE_KING];
pieceValuesMiddle[Piece.BLACK_QUEEN]=-pieceValuesMiddle[Piece.WHITE_QUEEN];
pieceValuesMiddle[Piece.BLACK_ROOK]=-pieceValuesMiddle[Piece.WHITE_ROOK];
pieceValuesMiddle[Piece.BLACK_KNIGHT]=-pieceValuesMiddle[Piece.WHITE_KNIGHT];
pieceValuesMiddle[Piece.BLACK_BISHOP]=-pieceValuesMiddle[Piece.WHITE_BISHOP];
pieceValuesMiddle[Piece.BLACK_PAWN]=-pieceValuesMiddle[Piece.WHITE_PAWN];
pieceValuesEnd[Piece.WHITE_KING]=-400;
pieceValuesEnd[Piece.WHITE_QUEEN]=-400;
pieceValuesEnd[Piece.WHITE_ROOK]=-100;
pieceValuesEnd[Piece.WHITE_KNIGHT]=-700;
pieceValuesEnd[Piece.WHITE_BISHOP]=-400;
pieceValuesEnd[Piece.WHITE_PAWN]=-900;
pieceValuesEnd[Piece.BLACK_KING]=-pieceValuesEnd[Piece.WHITE_KING];
pieceValuesEnd[Piece.BLACK_QUEEN]=-pieceValuesEnd[Piece.WHITE_QUEEN];
pieceValuesEnd[Piece.BLACK_ROOK]=-pieceValuesEnd[Piece.WHITE_ROOK];
pieceValuesEnd[Piece.BLACK_KNIGHT]=-pieceValuesEnd[Piece.WHITE_KNIGHT];
pieceValuesEnd[Piece.BLACK_BISHOP]=-pieceValuesEnd[Piece.WHITE_BISHOP];
pieceValuesEnd[Piece.BLACK_PAWN]=-pieceValuesEnd[Piece.WHITE_PAWN];
}
}

View File

@ -87,7 +87,7 @@ public class OpeningBook {
*/ */
public static void played(Move move) { public static void played(Move move) {
for (int i=0; i<validMoves.length; i++) { for (int i=0; i<validMoves.length; i++) {
if(validMoves[i] && (book.get(i).length>=nbOfMovesThatHaveBeenPlayed)) { if(validMoves[i] && (book.get(i).length>nbOfMovesThatHaveBeenPlayed)) {
if (!(book.get(i)[nbOfMovesThatHaveBeenPlayed].equals(move.toString()))) { if (!(book.get(i)[nbOfMovesThatHaveBeenPlayed].equals(move.toString()))) {
validMoves[i]=false; //this branch is not valid anymore validMoves[i]=false; //this branch is not valid anymore
} }
@ -107,7 +107,7 @@ public class OpeningBook {
for(int j=nbOfMovesThatHaveBeenPlayed; j<book.get(i).length; j++) { for(int j=nbOfMovesThatHaveBeenPlayed; j<book.get(i).length; j++) {
formatVariation += book.get(i)[j]+" "; formatVariation += book.get(i)[j]+" ";
} }
System.out.println(1+"\t"+0+"\t"+0+"\t"+validMoves.length+"\t"+formatVariation+" [Book Move]"); System.out.println(" "+1+"\t"+0+"\t"+0+"\t"+validMoves.length+"\t"+formatVariation+" [Book Move]");
} }
} }
} }
@ -118,7 +118,6 @@ public class OpeningBook {
Random generator = new Random(); Random generator = new Random();
Move chosenMove = possibleMoves.get(generator.nextInt(possibleMoves.size())); Move chosenMove = possibleMoves.get(generator.nextInt(possibleMoves.size()));
played(chosenMove);
return chosenMove; return chosenMove;
} }

View File

@ -101,12 +101,12 @@ public class Piece {
PIECE_VALUE_ENDGAME[BLACK_KNIGHT]=-PIECE_VALUE_ENDGAME[WHITE_KNIGHT]; PIECE_VALUE_ENDGAME[BLACK_KNIGHT]=-PIECE_VALUE_ENDGAME[WHITE_KNIGHT];
PIECE_VALUE_ENDGAME[BLACK_BISHOP]=-PIECE_VALUE_ENDGAME[WHITE_BISHOP]; PIECE_VALUE_ENDGAME[BLACK_BISHOP]=-PIECE_VALUE_ENDGAME[WHITE_BISHOP];
PIECE_VALUE_ENDGAME[BLACK_PAWN]=-PIECE_VALUE_ENDGAME[WHITE_PAWN]; */ PIECE_VALUE_ENDGAME[BLACK_PAWN]=-PIECE_VALUE_ENDGAME[WHITE_PAWN]; */
PIECE_VALUE_MIDDLEGAME[WHITE_KING]=100; PIECE_VALUE_MIDDLEGAME[WHITE_KING]=-100;
PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]=100; PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]=-100;
PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]=100; PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]=-100;
PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]=100; PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]=-100;
PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]= 100; //started with -100, -400, -200 PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]= -100; //started with -100, -400, -200
PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]= 100; //started with 100 PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]= -100; //started with 100
PIECE_VALUE_MIDDLEGAME[BLACK_KING]=-PIECE_VALUE_MIDDLEGAME[WHITE_KING]; PIECE_VALUE_MIDDLEGAME[BLACK_KING]=-PIECE_VALUE_MIDDLEGAME[WHITE_KING];
PIECE_VALUE_MIDDLEGAME[BLACK_QUEEN]=-PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]; PIECE_VALUE_MIDDLEGAME[BLACK_QUEEN]=-PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN];
PIECE_VALUE_MIDDLEGAME[BLACK_ROOK]=-PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]; PIECE_VALUE_MIDDLEGAME[BLACK_ROOK]=-PIECE_VALUE_MIDDLEGAME[WHITE_ROOK];

View File

@ -37,12 +37,12 @@ public class SuicideChess {
/** /**
* The name to be displayed * The name to be displayed
*/ */
public static final String NAME = "djib's SuShi v0.7.9"; public static final String NAME = "djib's SuShi v0.8.0";
/** /**
* Displays informations in the console. * Displays informations in the console.
*/ */
private static boolean asciiGame = false; private static boolean asciiGame = true;
/** /**
* Should the game be played in acsii * Should the game be played in acsii
@ -153,7 +153,6 @@ public class SuicideChess {
System.out.println("Welcome to SuicideChess "+SuicideChess.NAME+"!\n"); System.out.println("Welcome to SuicideChess "+SuicideChess.NAME+"!\n");
System.out.println("Type 'asciiplay' to be able to play in a terminal.");
System.out.println("If you want a graphical interface, you can use XBoard, WinBoard or any compatible program."); System.out.println("If you want a graphical interface, you can use XBoard, WinBoard or any compatible program.");
System.out.println(); System.out.println();
@ -165,6 +164,10 @@ public class SuicideChess {
Board bitboard = new Board(); Board bitboard = new Board();
addPlayedPosition(bitboard); addPlayedPosition(bitboard);
bitboard.display();
System.out.println();
displayPlayer(bitboard);
boolean computerPlaying = true; //the computer does not play in foce mode. boolean computerPlaying = true; //the computer does not play in foce mode.
boolean playing = true; boolean playing = true;
@ -182,6 +185,7 @@ public class SuicideChess {
} else if ((whatMove.length()>=12)&&(whatMove.substring(8,12).equals("load"))) { } else if ((whatMove.length()>=12)&&(whatMove.substring(8,12).equals("load"))) {
SuicideProblems.suicideProblemsLoad(whatMove.substring(13)); SuicideProblems.suicideProblemsLoad(whatMove.substring(13));
} else { } else {
openingPhase=false;
try { try {
int problemNb = Integer.parseInt(whatMove.substring(8)); int problemNb = Integer.parseInt(whatMove.substring(8));
bitboard=new Board(SuicideProblems.getProblemNumber(problemNb)); bitboard=new Board(SuicideProblems.getProblemNumber(problemNb));
@ -204,6 +208,11 @@ public class SuicideChess {
switch (xBoardCommand) { switch (xBoardCommand) {
case XBoardProtocol.XBOARD: case XBoardProtocol.XBOARD:
asciiGame=false;
break;
case XBoardProtocol.ACCEPTED:
break;
case XBoardProtocol.VARIANT_SUICIDE:
break; break;
case XBoardProtocol.PROTOVER: case XBoardProtocol.PROTOVER:
XBoardProtocol.initialise(); XBoardProtocol.initialise();
@ -238,7 +247,6 @@ public class SuicideChess {
System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard)); System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard));
break; break;
case XBoardProtocol.FORCE: case XBoardProtocol.FORCE:
openingPhase=false; //don't know what will happen next
computerPlaying = false; computerPlaying = false;
break; break;
case XBoardProtocol.PING: case XBoardProtocol.PING:
@ -273,6 +281,17 @@ public class SuicideChess {
System.out.println("Not a valid depth: "+ whatMove.substring(3)); System.out.println("Not a valid depth: "+ whatMove.substring(3));
} }
break; break;
case XBoardProtocol.BOOK:
//display book moves
boolean temp = postThinkingOutput;
postThinkingOutput=true;
try {
OpeningBook.getMove(bitboard);
} catch (NoOpeningMovesLeft e) {
openingPhase = false;
}
postThinkingOutput=temp;
break;
case XBoardProtocol.UNKNOWN: case XBoardProtocol.UNKNOWN:
if (acceptedUsermove) { if (acceptedUsermove) {
System.out.println("Error (unknown command): "+whatMove); System.out.println("Error (unknown command): "+whatMove);
@ -365,6 +384,7 @@ public class SuicideChess {
if(openingPhase) { if(openingPhase) {
try { try {
computerMove = OpeningBook.getMove(bitboard); computerMove = OpeningBook.getMove(bitboard);
OpeningBook.played(computerMove);
} catch (NoOpeningMovesLeft e) { } catch (NoOpeningMovesLeft e) {
openingPhase = false; openingPhase = false;
computerMove = ComputerPlayer.doAlphaBetaMove(bitboard); computerMove = ComputerPlayer.doAlphaBetaMove(bitboard);

View File

@ -87,9 +87,21 @@ public class XBoardProtocol {
*/ */
public static final int SETBOARD = 17; public static final int SETBOARD = 17;
/** /**
* XBoard send a signal to limit ply depth * XBoard sends a signal to limit ply depth
*/ */
public static final int SETPLY = 18; public static final int SETPLY = 18;
/**
* XBoard sends an accepted signal
*/
public static final int ACCEPTED = 19;
/**
* XBoard sends an 'variant suicide' signal
*/
public static final int VARIANT_SUICIDE = 20;
/**
* XBoard sends a book request
*/
public static final int BOOK = 21;
/** /**
* Unknown command * Unknown command
*/ */
@ -166,6 +178,12 @@ public class XBoardProtocol {
return SETBOARD; return SETBOARD;
} else if (command.startsWith("sd")) { } else if (command.startsWith("sd")) {
return SETPLY; return SETPLY;
} else if (command.startsWith("accepted")) {
return ACCEPTED;
} else if (command.equals("variant suicide")) {
return VARIANT_SUICIDE;
} else if (command.equals("bk")) {
return BOOK;
} }
return UNKNOWN; return UNKNOWN;