Browse Source

Version 0.8.0

=============
Just before creating the external config file
master
djib 16 years ago
parent
commit
a0ee66638d
  1. 37
      src/suicideChess/Board.java
  2. 17
      src/suicideChess/ComputerPlayer.java
  3. 150
      src/suicideChess/ConfigFile.java
  4. 5
      src/suicideChess/OpeningBook.java
  5. 12
      src/suicideChess/Piece.java
  6. 28
      src/suicideChess/SuicideChess.java
  7. 20
      src/suicideChess/XBoardProtocol.java

37
src/suicideChess/Board.java

@ -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)
*/
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)
*/
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
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[] 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, 2, 15, 15, 15, 15, 2, -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, 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.
//boardValue = numberOfBlackPieces - numberOfWhitePieces;
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) ) {
//System.out.println("Playing endgame");
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
@ -629,17 +637,18 @@ public class Board {
}
} else {
//System.out.println("Playing midgame");
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
//boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i];
for(int squareNb = 0; squareNb<NB_OF_SQUARES; squareNb++) {
Piece pieceOnSquare = getPiece(new Square(squareNb));
if(pieceOnSquare.getPieceNumber()!=Piece.NONE) {
boardValue += SQUARE_WEIGHT[squareNb]*Piece.PIECE_VALUE_MIDDLEGAME[pieceOnSquare.getColor()];
}
/*for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i];
}*/
for(int squareNb = 0; squareNb<NB_OF_SQUARES; squareNb++) {
Piece pieceOnSquare = getPiece(new Square(squareNb));
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)) {

17
src/suicideChess/ComputerPlayer.java

@ -157,6 +157,13 @@ public class ComputerPlayer {
"\t"+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\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()) {
@ -249,6 +256,11 @@ public class ComputerPlayer {
"\t"+nodesSearched+"\t"+bestVariationSoFar);
}
//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) {
@ -294,6 +306,11 @@ public class ComputerPlayer {
"\t"+((int)((new Date()).getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\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 ");
}
}

150
src/suicideChess/ConfigFile.java

@ -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];
}
}

5
src/suicideChess/OpeningBook.java

@ -87,7 +87,7 @@ public class OpeningBook {
*/
public static void played(Move move) {
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()))) {
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++) {
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();
Move chosenMove = possibleMoves.get(generator.nextInt(possibleMoves.size()));
played(chosenMove);
return chosenMove;
}

12
src/suicideChess/Piece.java

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

28
src/suicideChess/SuicideChess.java

@ -37,12 +37,12 @@ public class SuicideChess {
/**
* 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.
*/
private static boolean asciiGame = false;
private static boolean asciiGame = true;
/**
* 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("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();
@ -165,6 +164,10 @@ public class SuicideChess {
Board bitboard = new Board();
addPlayedPosition(bitboard);
bitboard.display();
System.out.println();
displayPlayer(bitboard);
boolean computerPlaying = true; //the computer does not play in foce mode.
boolean playing = true;
@ -182,6 +185,7 @@ public class SuicideChess {
} else if ((whatMove.length()>=12)&&(whatMove.substring(8,12).equals("load"))) {
SuicideProblems.suicideProblemsLoad(whatMove.substring(13));
} else {
openingPhase=false;
try {
int problemNb = Integer.parseInt(whatMove.substring(8));
bitboard=new Board(SuicideProblems.getProblemNumber(problemNb));
@ -204,6 +208,11 @@ public class SuicideChess {
switch (xBoardCommand) {
case XBoardProtocol.XBOARD:
asciiGame=false;
break;
case XBoardProtocol.ACCEPTED:
break;
case XBoardProtocol.VARIANT_SUICIDE:
break;
case XBoardProtocol.PROTOVER:
XBoardProtocol.initialise();
@ -238,7 +247,6 @@ public class SuicideChess {
System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard));
break;
case XBoardProtocol.FORCE:
openingPhase=false; //don't know what will happen next
computerPlaying = false;
break;
case XBoardProtocol.PING:
@ -273,6 +281,17 @@ public class SuicideChess {
System.out.println("Not a valid depth: "+ whatMove.substring(3));
}
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:
if (acceptedUsermove) {
System.out.println("Error (unknown command): "+whatMove);
@ -365,6 +384,7 @@ public class SuicideChess {
if(openingPhase) {
try {
computerMove = OpeningBook.getMove(bitboard);
OpeningBook.played(computerMove);
} catch (NoOpeningMovesLeft e) {
openingPhase = false;
computerMove = ComputerPlayer.doAlphaBetaMove(bitboard);

20
src/suicideChess/XBoardProtocol.java

@ -87,9 +87,21 @@ public class XBoardProtocol {
*/
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;
/**
* 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
*/
@ -166,6 +178,12 @@ public class XBoardProtocol {
return SETBOARD;
} else if (command.startsWith("sd")) {
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;

Loading…
Cancel
Save