Browse Source

Version 6.9

===========
Now detects draw (50 moves only)
Displays time to find move
Can read a library of problems from a file
Each problem can be selected independently or all can be
  played in succession and then the result is displayed.
master
djib 16 years ago
parent
commit
1b500b4421
  1. 70
      src/suicideChess/Board.java
  2. 23
      src/suicideChess/ComputerPlayer.java
  3. 5
      src/suicideChess/Rules.java
  4. 339
      src/suicideChess/SuicideChess.java
  5. 89
      src/suicideChess/SuicideProblems.java

70
src/suicideChess/Board.java

@ -1,5 +1,6 @@
package suicideChess;
import suicideChess.Square.NotAValidSquare;
/**
@ -32,8 +33,11 @@ public class Board {
private static final int NB_OF_BITBOARDS = 14;
//with less than that many pawns on one side, the computer will enter endgame mode
public static final int ENDGAME = 3;
public static final int ENDGAME_PAWNS = 3;
//with less than that many pieces on one side, the computer will enter endgame mode
public static final int ENDGAME_PIECES = 6;
@SuppressWarnings("serial")
public class NoPieceOnSquare extends Exception {
NoPieceOnSquare(String s) { super(s); };
@ -61,9 +65,12 @@ public class Board {
* Value representing the minimum value possible for the evaluation function
*/
public static final int MIN_VALUE = BLACK_WINS-1;
/**
* Value representing the value of a draw position
*/
public static final int DRAW_BOARD = 0;
/*======*
* DATA *
*======*/
@ -94,6 +101,11 @@ public class Board {
private int boardValue = 0; //evaluation of the board value
private int currentPlayer; //color of the current player.
//starts at 1 and increment after each of black's move
private int fullmoveNumber;
//this variable holds the number of Moves since last capture or last pawn move
private int halfmoveClock;
/*=============*
* CONSTRUCTOR *
@ -108,6 +120,9 @@ public class Board {
//the following line makes sure that enPassantSquare is defined at some point.
enPassantSquare = new Square("a1");
fullmoveNumber = 1;
halfmoveClock = 0;
numberOfPieces = new int[Piece.MAX_PIECE_NUMBER+1];
for (int i=0; i<=Piece.MAX_PIECE_NUMBER; i++) {
numberOfPieces[i]=0;
@ -163,6 +178,9 @@ public class Board {
this.numberOfPieces[i] = bitboard.numberOfPieces[i];
}
this.fullmoveNumber = bitboard.fullmoveNumber;
this.halfmoveClock = bitboard.halfmoveClock;
this.boardValue = bitboard.boardValue;
this.bitBoards = new long[NB_OF_BITBOARDS];
for (int i=0; i<NB_OF_BITBOARDS; i++) {
@ -214,9 +232,16 @@ public class Board {
enPassant = false;
enPassantSquare = new Square("a1"); //otherwise it is null
}
try {
fullmoveNumber = Integer.parseInt(result[12]);
halfmoveClock = Integer.parseInt(result[11]);
} catch (NumberFormatException e) {
System.out.println("Error (impossible to parse clock): "+command);
fullmoveNumber = 1;
halfmoveClock = 0;
}
numberOfPieces = new int[Piece.MAX_PIECE_NUMBER];
numberOfPieces = new int[Piece.MAX_PIECE_NUMBER+1];
for(int split=0; split < 8; split++) {
int offset=0;
@ -262,12 +287,14 @@ public class Board {
*/
public void doMove(Move move) throws NoPieceOnSquare, NotAValidSquare {
if (move.isCaptureMove()) {
halfmoveClock++;
if (move.isCaptureMove()) {
if (move.isEnPassant()) {
removePiece(move.getEnPassantSquare(), move.getCapturedPiece());
} else {
removePiece(move.toSquare(), move.getCapturedPiece());
}
halfmoveClock=0; //reinitialise halfmoveClock since there has been a capture
}
removePiece(move.fromSquare(), move.getMovingPiece());
if (move.isPromotionMove()) {
@ -275,6 +302,9 @@ public class Board {
} else {
addPiece(move.toSquare(), move.getMovingPiece());
}
if(move.getMovingPiece().getPieceNumber()==Piece.PAWN) {
halfmoveClock = 0; //a pawn has been moved
}
this.enPassant=false;
if (move.enablesEnPassant()) {
@ -287,11 +317,12 @@ public class Board {
//if (SuicideChess.ASCII_GAME)
// System.out.println("Black: ");
} else {
fullmoveNumber++; //black has just played
currentPlayer=Piece.WHITE;
//if (SuicideChess.ASCII_GAME)
// System.out.println("White: ");
}
evaluateNewBoardValue(move);
}
@ -396,6 +427,24 @@ public class Board {
return boardValue;
}
/**
* This function tells if the board is in a draw status
*/
public boolean isADraw() {
if(halfmoveClock>=Rules.NUMBER_OF_MOVES_BEFORE_DRAW) {
return true;
}
return false;
}
/**
* Used to get the halfmoveClock.
* @return the number of halfmoves since the last capture or pawn movement
*/
public int getHalfmoveClock() {
return halfmoveClock;
}
/**
* This function returns the current player color
* @return Integer
@ -543,13 +592,14 @@ 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) || (numberOfPieces[Piece.WHITE_PAWN] <= ENDGAME)) {
System.out.println("Playing endgame");
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++) {
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_ENDGAME[i];
}
} else {
System.out.println("Playing midgame");
//System.out.println("Playing midgame");
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i];
}

23
src/suicideChess/ComputerPlayer.java

@ -1,6 +1,7 @@
package suicideChess;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import suicideChess.Board.NoPieceOnSquare;
@ -138,9 +139,11 @@ public class ComputerPlayer {
public static Move doAlphaBetaMove(Board bitboard) throws NotAValidSquare, NoPieceOnSquare {
bestMove = null;
nodesSearched = 0;
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1);
Date thinkingBeginingTime = new Date();
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1);
Date thinkingEndTime = new Date();
//select one of the best moves randomly
Random generator = new Random();
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
@ -149,7 +152,9 @@ public class ComputerPlayer {
System.out.println("Found "+bestMoves.size()+" good moves.");
if (SuicideChess.postThinkingOutput()) {
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore.getAlphaBeta()*100+" 0 "+nodesSearched+" "+bestMove);
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore.getAlphaBeta()*100+
" "+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
" "+nodesSearched+" "+bestMove);
}
return bestMove;
@ -172,6 +177,10 @@ public class ComputerPlayer {
};
private static ReturnWrapper AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare {
nodesSearched++;
if(bitboard.isADraw()) {
return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD);
}
if (currentDepth >= SuicideChess.PLY_DEPTH) {
//System.out.println("'-> Evaluate: "+bitboard.getBoardValue());
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue());
@ -202,7 +211,7 @@ public class ComputerPlayer {
//System.out.println("Analysing "+currentDepth+":"+allLegalMoves.get(i));
ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,alpha,beta);
ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,Board.MIN_VALUE,beta);
currentScore = returnValue.getBranchValue();
currentAlphaBeta = returnValue.getAlphaBeta();
@ -229,7 +238,7 @@ public class ComputerPlayer {
}
if(beta<alpha) {
//System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
//if(currentDepth!=SuicideChess.PLY_DEPTH-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
return new ReturnWrapper(alpha,bestScoreSoFar); //pruning
}
}
@ -242,7 +251,7 @@ public class ComputerPlayer {
//System.out.println("Analysing "+currentDepth+":"+allLegalMoves.get(i));
ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,alpha,beta);
ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,alpha,Board.MAX_VALUE);
currentScore = returnValue.getBranchValue();
currentAlphaBeta = returnValue.getAlphaBeta();
@ -269,7 +278,7 @@ public class ComputerPlayer {
}
if(alpha>beta) {
//System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
//if(currentDepth!=SuicideChess.PLY_DEPTH-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
return new ReturnWrapper(beta,bestScoreSoFar); //pruning
}
}

5
src/suicideChess/Rules.java

@ -12,6 +12,11 @@ import suicideChess.Square.NotAValidSquare;
*/
public class Rules {
/**
* Number of moves without a piece being capture or a pawn being moved before the game becomes a draw
*/
public static int NUMBER_OF_MOVES_BEFORE_DRAW=50;
private static ArrayList<Move> legalMovesNonCapture;
private static ArrayList<Move> legalMovesCapture;

339
src/suicideChess/SuicideChess.java

@ -5,8 +5,11 @@ import java.io.InputStreamReader;
import java.util.ArrayList;
import suicideChess.Board.NoPieceOnSquare;
import suicideChess.Board.UnableToParseFENStringException;
import suicideChess.Move.NotAValidMoveException;
import suicideChess.Square.NotAValidSquare;
import suicideChess.SuicideProblems.NoSuchSuicideProblem;
/**
* Main file (the game in itself)
@ -33,7 +36,7 @@ public class SuicideChess {
/**
* The name to be displayed
*/
public static final String NAME = "djib's SuShi v0.5.5";
public static final String NAME = "djib's SuShi v0.6.9";
/**
* Displays informations in the console.
@ -51,13 +54,16 @@ public class SuicideChess {
* @return True or False
*/
private static boolean testWinningPosition (Board bitboard) {
private static boolean testAndDisplayIfWinningOrDrawPosition (Board bitboard) {
if (bitboard.getBoardValue()==Board.BLACK_WINS) {
System.out.println("0-1 {Black mates}");
return true;
} else if (bitboard.getBoardValue()==Board.WHITE_WINS) {
System.out.println("1-0 {White mates}");
return true;
} else if (bitboard.isADraw()) {
System.out.println("1/2-1/2 {Draw}");
return true;
}
return false;
}
@ -134,164 +140,184 @@ public class SuicideChess {
try {
String whatMove= moveInput.readLine();
boolean playedALegalMove = false;
int xBoardCommand = XBoardProtocol.getCommand(whatMove);
switch (xBoardCommand) {
case XBoardProtocol.XBOARD:
break;
case XBoardProtocol.PROTOVER:
XBoardProtocol.initialise();
break;
case XBoardProtocol.NOT_ACCEPTED_SUICIDE:
System.out.println("tellusererror \"This game only plays suicide chess.\"");
playing=false;
break;
case XBoardProtocol.ACCEPTED_USERMOVE:
acceptedUsermove=true;
break;
case XBoardProtocol.NOPROTOVER:
System.out.println("tellusererror \"You must use an engine with XBoard protocol 2 or higher.\"");
playing=false;
break;
case XBoardProtocol.QUIT:
System.out.println("Goodbye!");
playing=false;
break;
case XBoardProtocol.NEW:
//System.out.println("variant suicide");
break;
case XBoardProtocol.HINT:
System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard));
break;
case XBoardProtocol.FORCE:
computerPlaying = false;
break;
case XBoardProtocol.PING:
System.out.println("pong "+whatMove.substring(5));
break;
case XBoardProtocol.REMOVE:
removePlayedPosition();
//no break here
case XBoardProtocol.UNDO:
bitboard=new Board(removePlayedPosition());
if (ASCII_GAME) {
bitboard.display();
}
break;
case XBoardProtocol.POST:
post=true;
break;
case XBoardProtocol.NOPOST:
post=false;
break;
case XBoardProtocol.SETBOARD:
bitboard=new Board(whatMove.substring(9));
if(ASCII_GAME)
bitboard.display();
break;
case XBoardProtocol.UNKNOWN:
if (acceptedUsermove) {
System.out.println("Error (unknown command): "+whatMove);
break;
}
//if XBoard did not accept usermove command we try and interpret every unknown command
//as a move.
case XBoardProtocol.MOVE:
Move theMove;
if (acceptedUsermove) {
theMove = new Move(whatMove.substring(9), bitboard);
if (whatMove.startsWith("problem")) { //special case for problems
if(whatMove.length()==7) {
System.out.println("There are "+SuicideProblems.numberOfProblems()+" problems.");
} else if (whatMove.substring(8).equals("auto")) {
autoProblem();
} else if ((whatMove.length()>=12)&&(whatMove.substring(8,12).equals("load"))) {
SuicideProblems.suicideProblemsLoad(whatMove.substring(13));
} else {
theMove = new Move(whatMove, bitboard);
try {
int problemNb = Integer.parseInt(whatMove.substring(8));
bitboard=new Board(SuicideProblems.getProblemNumber(problemNb));
if(ASCII_GAME)
bitboard.display();
} catch (NumberFormatException e) {
System.out.println("Not a valid number: "+ whatMove.substring(8));
}
}
} else {
int xBoardCommand = XBoardProtocol.getCommand(whatMove);
if (testWinningPosition(bitboard)) {
//if board was set in an illegal position
System.out.println("Illegal move: "+theMove.toString());
switch (xBoardCommand) {
case XBoardProtocol.XBOARD:
break;
}
boolean needToCapture = false;
int foundMoveIndex = -1;
if(theMove.getMovingPiece().getColor() == bitboard.getCurrentPlayer()) {
Rules.legalMovesForPlayer(bitboard);
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
if (allLegalMoves.size()==0) {
allLegalMoves = Rules.getLegalMovesNonCapture();
case XBoardProtocol.PROTOVER:
XBoardProtocol.initialise();
break;
case XBoardProtocol.NOT_ACCEPTED_SUICIDE:
System.out.println("tellusererror \"This game only plays suicide chess.\"");
playing=false;
break;
case XBoardProtocol.ACCEPTED_USERMOVE:
acceptedUsermove=true;
break;
case XBoardProtocol.NOPROTOVER:
System.out.println("tellusererror \"You must use an engine with XBoard protocol 2 or higher.\"");
playing=false;
break;
case XBoardProtocol.QUIT:
System.out.println("Goodbye!");
playing=false;
break;
case XBoardProtocol.NEW:
//System.out.println("variant suicide");
break;
case XBoardProtocol.HINT:
System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard));
break;
case XBoardProtocol.FORCE:
computerPlaying = false;
break;
case XBoardProtocol.PING:
System.out.println("pong "+whatMove.substring(5));
break;
case XBoardProtocol.REMOVE:
removePlayedPosition();
//no break here
case XBoardProtocol.UNDO:
bitboard=new Board(removePlayedPosition());
if (ASCII_GAME) {
bitboard.display();
}
break;
case XBoardProtocol.POST:
post=true;
break;
case XBoardProtocol.NOPOST:
post=false;
break;
case XBoardProtocol.SETBOARD:
bitboard=new Board(whatMove.substring(9));
if(ASCII_GAME)
bitboard.display();
break;
case XBoardProtocol.UNKNOWN:
if (acceptedUsermove) {
System.out.println("Error (unknown command): "+whatMove);
break;
}
//if XBoard did not accept usermove command we try and interpret every unknown command
//as a move.
case XBoardProtocol.MOVE:
Move theMove;
if (acceptedUsermove) {
theMove = new Move(whatMove.substring(9), bitboard);
} else {
needToCapture = true;
theMove = new Move(whatMove, bitboard);
}
for (int moveIndex = 0; moveIndex < allLegalMoves.size(); moveIndex++) {
if (allLegalMoves.get(moveIndex).isSimpleEqual(theMove)) {
if(theMove.isPromotionMove()&&
theMove.getPromotionPiece().getPieceNumber()!=allLegalMoves.get(moveIndex).getPromotionPiece().getPieceNumber()) {
continue;
if (testAndDisplayIfWinningOrDrawPosition(bitboard)) {
//if board was set in an illegal position
System.out.println("Illegal move: "+theMove.toString());
break;
}
boolean needToCapture = false;
int foundMoveIndex = -1;
if(theMove.getMovingPiece().getColor() == bitboard.getCurrentPlayer()) {
Rules.legalMovesForPlayer(bitboard);
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
if (allLegalMoves.size()==0) {
allLegalMoves = Rules.getLegalMovesNonCapture();
} else {
needToCapture = true;
}
for (int moveIndex = 0; moveIndex < allLegalMoves.size(); moveIndex++) {
if (allLegalMoves.get(moveIndex).isSimpleEqual(theMove)) {
if(theMove.isPromotionMove()&&
theMove.getPromotionPiece().getPieceNumber()!=allLegalMoves.get(moveIndex).getPromotionPiece().getPieceNumber()) {
continue;
}
foundMoveIndex=moveIndex;
break;
}
foundMoveIndex=moveIndex;
break;
}
}
if (foundMoveIndex == -1) {
if (needToCapture) {
if (ASCII_GAME)
System.out.println("Capturing is mandatory.");
if (foundMoveIndex == -1) {
if (needToCapture) {
if (ASCII_GAME)
System.out.println("Capturing is mandatory.");
}
System.out.println("Illegal move: "+theMove.toString());
} else {
bitboard.doMove(allLegalMoves.get(foundMoveIndex));
addPlayedPosition(bitboard);
if (ASCII_GAME) {
allLegalMoves.get(foundMoveIndex).display();
System.out.println("Board value: "+bitboard.getBoardValue());
bitboard.display();
}
playedALegalMove=true;
}
System.out.println("Illegal move: "+theMove.toString());
} else {
bitboard.doMove(allLegalMoves.get(foundMoveIndex));
addPlayedPosition(bitboard);
if (ASCII_GAME)
System.out.println("Please play a piece of the right color.");
System.out.println("Illegal move: "+theMove.toString());
}
if (testAndDisplayIfWinningOrDrawPosition(bitboard)) {
computerPlaying=false;
}
if (!playedALegalMove) {
break;
}
//No break statement here on purpose.
case XBoardProtocol.GO:
//this is not really nice but it avoids having to write twice the code
//I check if I did really receive a XBoardProtocol.GO or it I just got there
//because there is no break statement.
if (xBoardCommand==XBoardProtocol.GO)
computerPlaying = true;
if (testAndDisplayIfWinningOrDrawPosition(bitboard)) {
//in case an illegal position have been sent
computerPlaying=false;
break;
}
if (computerPlaying) {
Move computerMove = ComputerPlayer.doAlphaBetaMove(bitboard);
bitboard.doMove(computerMove);
addPlayedPosition(bitboard);
XBoardProtocol.doMove(computerMove);
if (ASCII_GAME) {
allLegalMoves.get(foundMoveIndex).display();
computerMove.display();
System.out.println("Board value: "+bitboard.getBoardValue());
bitboard.display();
}
playedALegalMove=true;
}
if (testAndDisplayIfWinningOrDrawPosition(bitboard)) {
computerPlaying=false;
}
} else {
if (ASCII_GAME)
System.out.println("Please play a piece of the right color.");
System.out.println("Illegal move: "+theMove.toString());
}
if (testWinningPosition(bitboard)) {
computerPlaying=false;
}
if (!playedALegalMove) {
break;
}
//No break statement here on purpose.
case XBoardProtocol.GO:
//this is not really nice but it avoids having to write twice the code
//I check if I did really receive a XBoardProtocol.GO or it I just got there
//because there is no break statement.
if (xBoardCommand==XBoardProtocol.GO)
computerPlaying = true;
if (testWinningPosition(bitboard)) {
//in case an illegal position have been sent
computerPlaying=false;
break;
}
if (computerPlaying) {
Move computerMove = ComputerPlayer.doAlphaBetaMove(bitboard);
bitboard.doMove(computerMove);
addPlayedPosition(bitboard);
XBoardProtocol.doMove(computerMove);
if (ASCII_GAME) {
computerMove.display();
System.out.println("Board value: "+bitboard.getBoardValue());
bitboard.display();
}
}
if (testWinningPosition(bitboard)) {
computerPlaying=false;
}
break;
}
// if (whatMove.startsWith("hint")) {
@ -330,10 +356,39 @@ public class SuicideChess {
} catch (NotAValidSquare err) {
System.out.println(err);
continue;
} catch (NoSuchSuicideProblem err) {
System.out.println(err);
continue;
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
//lets the computer try every problem and stop on error.
//in the end it says what games where lost by white.
private static void autoProblem() throws NotAValidSquare, UnableToParseFENStringException, NoPieceOnSquare, NoSuchSuicideProblem {
Board bitboard;
boolean[] result=new boolean[SuicideProblems.numberOfProblems()];
for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) {
System.out.println("\n\nProblem "+i);
bitboard=new Board(SuicideProblems.getProblemNumber(i));
while(!testAndDisplayIfWinningOrDrawPosition(bitboard)) {
Move computerMove = ComputerPlayer.doAlphaBetaMove(bitboard);
bitboard.doMove(computerMove);
}
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
result[i-1]=false;
} else {
result[i-1]=true;
}
}
System.out.println("\n\nLost following games:\n========begin========");
for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) {
if (!result[i-1])
System.out.println("Problem "+i+" lost !");
}
System.out.println("=========end=========");
}
}

89
src/suicideChess/SuicideProblems.java

@ -0,0 +1,89 @@
package suicideChess;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class SuicideProblems {
/**
* This class is used to load problems from a file
*
* @author Jean-Baptiste H&eacute;tier
* @version $LastChangedRevision$, $LastChangedDate$
*
*/
@SuppressWarnings("serial")
public static class NoSuchSuicideProblem extends Exception {
NoSuchSuicideProblem(String s) { super(s); };
}
//This array can hold setup for different problems.
private static String[] suicideProblems;
static { suicideProblemsLoad("problems"); } //initialise with file 'problems' if found in current directory
/**
* How many problems are loaded
*/
public static int numberOfProblems() {
if (suicideProblems[0].equals("")) {
return 0;
} else {
return suicideProblems.length;
}
}
/**
* Return FEN notation string for given problem number
* @param problemNb
* @throws NoSuchSuicideProblem
*/
public static String getProblemNumber(int problemNb) throws NoSuchSuicideProblem {
if ((problemNb > numberOfProblems())||(problemNb<1)) {
throw new NoSuchSuicideProblem("*** Invalid Entry: "+problemNb+" ***");
}
return suicideProblems[problemNb-1];
}
/**
* This function is used to load other problem files
* @param file
*/
public static void suicideProblemsLoad(String file) {
StringBuffer problemBuffer = new StringBuffer();
//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)
problemBuffer.append(line);
problemBuffer.append("\n"); //I will then use this symbol to break the buffer in an array
}
}
}
catch (FileNotFoundException e) {
System.out.println("File '"+file+"' not found. Problems 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();
}
}
suicideProblems = problemBuffer.toString().split("\n");
System.out.println(numberOfProblems()+" loaded");
}
}
Loading…
Cancel
Save