Hey guys,
Please can someone have a look at this code and let me know whether I am on the right track with the "check_somefigure_move"s and the "check_black/white_promotion"s please?
And also any other help you can give would be greatly appreciated!
Thanks!
P.S. I know the code is not the best implementation, but its a template I have to follow :(
Code:
class Moves {
private final Board B;
private boolean regular;
public Moves(final Board b) { B = b; regular = regular_position(); }
public boolean get_regular_position() { return regular; }
public void set_regular_position(final boolean new_reg) {
regular = new_reg;
}
// checking whether B represents a "normal" position or not;
// if not, then only simple checks regarding move-correctness should
// be performed, only checking the direct characteristics of the figure
// moved;
// checks whether there is exactly one king of each colour, there are
// no more figures than promotions allow, and there are no pawns on the
// first or last rank;
public boolean regular_position() {
int[] counts = new int[256];
for (char file = 'a'; file <= 'h'; ++file)
for (char rank = '1'; rank <= '8'; ++rank)
++counts[(int) B.get(file,rank)];
if (counts[Board.white_king] != 1 || counts[Board.black_king] != 1)
return false;
if (counts[Board.white_pawn] > 8 || counts[Board.black_pawn] > 8)
return false;
int count_w_promotions = 0;
count_w_promotions += Math.max(counts[Board.white_queen]-1,0);
count_w_promotions += Math.max(counts[Board.white_rook]-2,0);
count_w_promotions += Math.max(counts[Board.white_bishop]-2,0);
count_w_promotions += Math.max(counts[Board.white_knight]-2,0);
if (count_w_promotions > 8 - counts[Board.white_pawn]) return false;
int count_b_promotions = 0;
count_b_promotions += Math.max(counts[Board.black_queen]-1,0);
count_b_promotions += Math.max(counts[Board.black_rook]-2,0);
count_b_promotions += Math.max(counts[Board.black_bishop]-2,0);
count_b_promotions += Math.max(counts[Board.black_knight]-2,0);
if (count_b_promotions > 8 - counts[Board.black_pawn]) return false;
for (char file = 'a'; file <= 'h'; ++file) {
final char fig1 = B.get(file,'1');
if (fig1 == Board.white_pawn || fig1 == Board.black_pawn) return false;
final char fig8 = B.get(file,'8');
if (fig8 == Board.white_pawn || fig8 == Board.black_pawn) return false;
}
return true;
}
public boolean check_normal_white_move(final char file0, final char rank0,
final char file1, final char rank1) {
if (! Board.is_valid_white_figure(B.get(file0,rank0))) return false;
if (! B.is_empty(file1,rank1) && ! Board.is_valid_black_figure(B.get(file1,rank1)))
return false;
if (B.get_active_colour() != 'w') return false;
if (! check_move_simple(file0,rank0,file1,rank1)) return false;
if (! regular) return true;
final Board test_board = new Board(B);
test_board.normal_white_move_0(file0,rank0,file1,rank1);
final Moves test_move = new Moves(test_board);
final char[] king_pos = test_move.white_king_position();
assert(king_pos.length == 2);
return test_move.black_not_attacking(king_pos[0],king_pos[1]);
}
public boolean check_normal_black_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED THE CHECK NORMAL BLACK MOVE BASED ON THE CHECK NORMAL WHITE MOVE
if (! Board.is_valid_black_figure(B.get(file0,rank0))) return false;
if (! B.is_empty(file1,rank1) && ! Board.is_valid_white_figure(B.get(file1,rank1)))
return false;
if (B.get_active_colour() != 'b') return false;
if (! check_move_simple(file0,rank0,file1,rank1)) return false;
if (! regular) return true;
final Board test_board = new Board(B);
test_board.normal_black_move_0(file0,rank0,file1,rank1);
final Moves test_move = new Moves(test_board);
final char[] king_pos = test_move.black_king_position();
assert(king_pos.length == 2);
return test_move.white_not_attacking(king_pos[0],king_pos[1]);
}
// for checking a normal move by just applying the move-rules
private boolean check_move_simple(final char file0, final char rank0,
final char file1, final char rank1) {
final char fig = B.get(file0,rank0);
if (fig == Board.white_king || fig == Board.black_king)
return check_king_move(file0,rank0,file1,rank1);
if (fig == Board.white_queen || fig == Board.black_queen)
return check_queen_move(file0,rank0,file1,rank1);
if (fig == Board.white_rook || fig == Board.black_rook)
return check_rook_move(file0,rank0,file1,rank1);
if (fig == Board.white_bishop || fig == Board.black_bishop)
return check_bishop_move(file0,rank0,file1,rank1);
if (fig == Board.white_knight || fig == Board.black_knight)
return check_knight_move(file0,rank0,file1,rank1);
if (fig == Board.white_pawn)
return check_white_pawn_move(file0,rank0,file1,rank1);
else
return check_black_pawn_move(file0,rank0,file1,rank1);
}
private boolean check_king_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED KING MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
return fileChange <= 1 && fileChange >= -1
&& rankChange <= 1 && rankChange >= -1;
}
private boolean check_queen_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED QUEEN MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
return fileChange <=8 && fileChange >= -8
&& rankChange <= 8 && rankChange >= -8;
}
private boolean check_rook_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED ROOK MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
return fileChange <=8 || fileChange >= -8
|| rankChange <= 8 || rankChange >= -8;
}
private boolean check_bishop_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED BISHOP MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
return fileChange <= 8 && rankChange <= 8
|| fileChange <= 8 && rankChange >= -8
|| fileChange >= -8 && rankChange >= -8
|| fileChange >= -8 && rankChange <= 8;
}
private boolean check_knight_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED KNIGHT MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
/* IS THIS THE CORRECT WAY?
* return fileChange <= 1 && rankChange <= 2
|| fileChange <= 1 && rankChange >= -2
|| fileChange <= 2 && rankChange <= 1
|| fileChange <= 2 && rankChange >= -1
|| fileChange >= -1 && rankChange <= 2
|| fileChange >= -1 && rankChange >= -2
|| fileChange >= -2 && rankChange <= 1
|| fileChange >= -2 && rankChange >= -1;*/
// OR IS THIS?
return fileChange <= 1 || fileChange >= -1 || fileChange <= 2 || fileChange >= -2
&& rankChange <= 1 || rankChange >= - 1 || rankChange <= 2 || rankChange >= -2;
}
private boolean check_white_pawn_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED PAWN MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
return fileChange == 0
&& rankChange <= 1;
}
private boolean check_black_pawn_move(final char file0, final char rank0,
final char file1, final char rank1) {
// ADDED PAWN MOVE
int fileChange = file0 - file1;
int rankChange = rank0 - rank1;
return fileChange == 0
&& rankChange >= -1;
}
public boolean check_white_kingside_castling() {
// only demonstration code:
final char c = B.get_white_castling();
if (c == '-' || c == 'q') return false;
if (B.get_active_colour() == 'b') return false;
if (B.get('e','1') != 'K') return false;
if (! black_not_attacking('e','1')) return false;
if (! free_white('f','1')) return false;
// XXX
return true;
}
public boolean check_white_queenside_castling() {
// only demonstration code:
final char c = B.get_white_castling();
if (c == '-' || c == 'k') return false;
if (B.get_active_colour() == 'b') return false;
// ADDED BASED ON KINGSIDE CASTLING
if (B.get('e','1') != 'Q') return false;
if (! black_not_attacking('e','1')) return false;
if (! free_white('f','1')) return false;
// XXX
return true;
}
public boolean check_black_kingside_castling() {
// only demonstration code:
final char c = B.get_black_castling();
if (c == '-' || c == 'q') return false;
if (B.get_active_colour() == 'w') return false;
// ADDED BASED ON CHECK WHITE
if (B.get('e','8') != 'K') return false;
if (! black_not_attacking('e','8')) return false;
if (! free_white('f','8')) return false;
// XXX
return true;
}
public boolean check_black_queenside_castling() {
// only demonstration code:
final char c = B.get_black_castling();
if (c == '-' || c == 'k') return false;
if (B.get_active_colour() == 'w') return false;
// ADDED BASED ON KINGSIDE CASTLING
if (B.get('e','8') != 'Q') return false;
if (! black_not_attacking('e','8')) return false;
if (! free_white('f','8')) return false;
// XXX
return true;
}
public boolean check_white_promotion(final char pawn_file, final char figure) {
// XXX
// ADDED CHECKING FOR CORRECT FIGURE AND POSITION - ALTHOUGH IT SEEMS AS THOUGH
// PAWN_FILE SHOULD BE PAWN_RANK, AS IT IS THE REACHING OF THE END RANK THAT
// CAUSES PROMOTION OF A PAWN, NOT FILE
if (figure == P && pawn_file == 8) {
return true;
}
else return false;
}
public boolean check_black_promotion(final char pawn_file, final char figure) {
// XXX
// ADDED CHECKING FOR CORRECT FIGURE AND POSITION
if (figure == p && pawn_file == 1) {
return true;
}
else return false;
}
// checks whether black doesn't attack the field:
public boolean black_not_attacking(final char file, final char rank) {
// XXX
return true;
}
public boolean free_white(final char file, final char rank) {
// XXX
return black_not_attacking(file,rank) && B.is_empty(file,rank);
}
// checks whether white doesn't attack the field:
public boolean white_not_attacking(final char file, final char rank) {
// XXX
return true;
}
public boolean free_black(final char file, final char rank) {
// XXX
return white_not_attacking(file,rank) && B.is_empty(file,rank);
}
public char[] white_king_position() {
for (char file = 'a'; file <= 'h'; ++file)
for (char rank = '1'; rank <= '8'; ++rank)
if (B.get(file,rank) == Board.white_king) {
char[] result = new char[2];
result[0] = file; result[1] = rank;
return result;
}
return new char[0];
}
public char[] black_king_position() {
for (char file = 'a'; file <= 'h'; ++file)
for (char rank = '1'; rank <= '8'; ++rank)
if (B.get(file,rank) == Board.black_king) {
char[] result = new char[2];
result[0] = file; result[1] = rank;
return result;
}
return new char[0];
}
public static void main(final String[] args) {
// checking regular_position
{
Moves m = new Moves(new Board());
assert(m.regular_position());
m = new Moves(new Board("8/8/8/8/8/8/8/8 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("KK6/8/8/8/8/8/8/8 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("kk6/8/8/8/8/8/8/8 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/8/8/8/8/8/8/8 w - - 0 1"));
assert(m.regular_position());
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/8 w - - 0 1"));
assert(m.regular_position());
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/n7 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/N7 w - - 0 1"));
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/b7 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/B7 w - - 0 1"));
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/r7 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/R7 w - - 0 1"));
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/q7 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/qqqqqqqq/QQQQQQQQ/Q7/q7/rrbbnn2/RRBBNN2/Q7 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kkp5/8/8/8/8/8/8/8 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("KkP5/8/8/8/8/8/8/8 w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/8/8/8/8/8/8/7p w - - 0 1"));
assert(!m.regular_position());
m = new Moves(new Board("Kk6/8/8/8/8/8/8/7P w - - 0 1"));
assert(!m.regular_position());
}
// checking check_white/black_king/queenside_castling
{
Moves m = new Moves(new Board("4k2r/8/8/8/8/8/8/4K2R w Kk - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("4k2r/8/8/8/8/8/8/4K2R b Kk - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("4k2r/4pppp/8/8/8/8/4PPPP/4K2R w KQkq - 0 1"));
assert(m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("4k2r/4pppp/8/8/8/8/4PPPP/4K2R b KQkq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("r3k3/8/8/8/8/8/8/R3K3 w Qq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("r3k3/8/8/8/8/8/8/R3K3 b Qq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("r3k3/p7/8/8/8/8/8/R3K3 w Qq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("r3k3/p7/8/8/8/8/8/R3K3 b Qq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(m.check_black_queenside_castling());
m = new Moves(new Board("r3k3/p7/8/8/8/n7/8/R3K3 w Qq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
m = new Moves(new Board("r3k3/p7/B7/8/8/8/8/R3K3 b Qq - 0 1"));
assert(!m.check_white_kingside_castling());
assert(!m.check_black_kingside_castling());
assert(!m.check_white_queenside_castling());
assert(!m.check_black_queenside_castling());
// XXX
}
}
}