Code: Select all
square[32] = BPAWN; // square no. 32 now contains a black pawn
Code: Select all
// board.h
#include <string>
#include <string.h>
#ifndef BOARD_INC
#define BOARD_INC
#include "func.h"
#include "names.h"
const unsigned short BLANK = 0, WPAWN = 1, WKNIGHT = 2, WBISHOP = 3, WROOK = 4, WQUEEN = 5, WKING = 6 ;
const unsigned short BPAWN = 7, BKNIGHT = 8, BBISHOP = 9, BROOK = 10, BQUEEN = 11, BKING = 12 ;
const unsigned short WHITE = 1, BLACK = 2;
class Board {
public:
unsigned short WP[64], WQ[64], WK[64], WN[64], WB[64], WR[64];
unsigned short BP[64], BQ[64], BK[64], BN[64], BB[64], BR[64];
unsigned short allBoard[64], W_Pieces[64], B_Pieces[64];
unsigned short WCCOO, WCCOOO, BCCOO, BCCOOO; //WCCOO = White Can Castle O-O (King side)
//BCCOOO = Black Can Castle O-O-O (Queen side)
//...etc...
unsigned short colorToMove;
unsigned short epSq; //enPassant square no.
unsigned int hmslcopm; //hmslcopm = Half-Moves Since Last Capture Or Pawn Move
unsigned int moveNum; //The current move number in game
void setFEN(const char fen[]);
void setPieces(const unsigned short state[]);
void displayBoard();
void doMove(const unsigned short &fromSq, const unsigned short &toSq);
void parseMove(const char move[]);
};
#endif
Code: Select all
// board.cpp
#include <iostream>
#include <cstdlib> //for atio()
#include "board.h"
#include "func.h"
#include "names.h"
//Some test positions for fen parser:
//rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
//r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 3
//r1bqk1nr/ppppbppp/2n5/4p3/4P3/5N2/PPPPBPPP/RNBQK2R w KQkq - 0 4
//rnbqkbnr/ppp3pp/8/2Pppp2/4P3/8/PP1P1PPP/RNBQKBNR w KQkq D5 0 4
void Board::setFEN(const char fen[]) {
//fill up all arrays with 0:
for(register short foo = 0; foo < 64; ++foo) {
Board::allBoard[foo] = 0;
Board::BB[foo] = 0;
Board::BK[foo] = 0;
Board::BN[foo] = 0;
Board::BP[foo] = 0;
Board::BQ[foo] = 0;
Board::BR[foo] = 0;
Board::B_Pieces[foo] = 0;
Board::WB[foo] = 0;
Board::WK[foo] = 0;
Board::WN[foo] = 0;
Board::WP[foo] = 0;
Board::WQ[foo] = 0;
Board::WR[foo] = 0;
Board::W_Pieces[foo] = 0;
}
unsigned short task = 1, sq; //task = 1 =(in human language) read first part of the fen string
short rank, file;
unsigned short result[64];
//Initialize all the elements of array result to BLANK
for(short foo = 0; foo < 64; ++foo)
result[foo] = BLANK;
short j = 0;
register short i = 0;
while((j <= 64) && (fen[i] != ' ')) {
//Thanks to Thomas Petzke for the next two lines of code
file = 1 + (j % 8);
rank = 8 - (j / 8);
sq = toSquare(file, rank);
switch(fen[i]) {
case 'p':
result[j] = BPAWN;
break;
case 'n':
result[j] = BKNIGHT;
break;
case 'b':
result[j] = BBISHOP;
break;
case 'r':
result[j] = BROOK;
break;
case 'q':
result[j] = BQUEEN;
break;
case 'k':
result[j] = BKING;
break;
case 'P':
result[j] = WPAWN;
break;
case 'N':
result[j] = WKNIGHT;
break;
case 'B':
result[j] = WBISHOP;
break;
case 'R':
result[j] = WROOK;
break;
case 'Q':
result[j] = WQUEEN;
break;
case 'K':
result[j] = WKING;
break;
case '/':
--j;
break;
case '1':
break;
case '2':
++j;
break;
case '3':
j += 2;
break;
case '4':
j += 3;
break;
case '5':
j += 4;
break;
case '6':
j += 5;
break;
case '7':
j += 6;
break;
case '8':
j += 7;
break;
}
++j;
++i; //Just to get some extra lines of code :)
}
setPieces(result);
//to avoid fen parse errors, increment i until it doesn't point to ' ' or blank space
for(short foo = i; fen[foo] == ' '; ++foo)
++i;
Board::colorToMove = (fen[i] == 'b') ? BLACK : WHITE; //so that default is white
//to avoid fen parse errors, increment i until it doesn't point to ' ' or blank space.
for(short foo = i; fen[foo] == ' '; ++foo)
++i;
//Set up castling:
for(short foo = i; fen[foo] != EOF; ++foo) { //search through all the rest of fen
Board::colorToMove = (fen[foo] == 'b') ? BLACK : WHITE; //so that default is white
if(fen[foo] == 'K')
WCCOO = 1;
if(fen[foo] == 'Q')
WCCOOO = 1;
if(fen[foo] == 'k')
BCCOO = 1;
if(fen[foo] == 'q')
BCCOOO = 1;
}
//increment i till it gets out of blank chars
for(short foo = i; fen[foo] != ' '; ++foo)
++i;
//i should now point to a blank char, and i+1 would point to the castling part.
//So, increment i till it again points to blank char ' '
for(short foo = i; fen[foo] == ' '; ++foo)
++i;
//to avoid fen parse errors, increment i until it doesn't point to ' ' or blank space.
for(short foo = i; fen[foo] != ' '; ++foo)
++i;
//increment i till it points to a non blank char ' '
for(short foo = i; fen[foo] == ' '; ++foo)
++i;
//Now we are in the enPassant Part:
if((fen[i] >= 'a') && (fen[i] <= 'h')) { //if file numbers are given in small letters
file = fen[i++] - 96;
rank = fen[i] - 48;
Board::epSq = toSquare(file, rank);
}
else if((fen[i] >= 'A') && (fen[i] <= 'H')) {
file = fen[i++] - 64;
rank = fen[i] - 48;
Board::epSq = toSquare(file, rank);
}
++i;
//to avoid fen parse errors, increment i till it points to a non blank char ' '
for(short foo = i; fen[foo] == ' '; ++foo)
++i;
Board::hmslcopm = atoi(&fen[i]);
//increment i to get out of non blank chars or ' '
for(short foo = i; fen[foo] != ' '; ++foo)
++i;
//Now, to avoid fen parse errors, increment i till it points to a non blank char ' '
for(short foo = i; fen[foo] == ' '; ++foo)
++i;
Board::moveNum = atoi(&fen[i]);
}
void Board::setPieces(const unsigned short state[]) {
//set pieces in separate arrays for every piece
for(short i = 0; i < 64; ++i) {
if(state[i] == BLANK) { //Blank square
continue; //Do nothing
}
else if(state[i] == WPAWN) {
Board::WP[i] = WPAWN;
}
else if(state[i] == WKNIGHT) {
Board::WN[i] = WKNIGHT;
}
else if(state[i] == WBISHOP) {
Board::WB[i] = WBISHOP;
}
else if(state[i] == WROOK) {
Board::WR[i] = WROOK;
}
else if(state[i] == WQUEEN) {
Board::WQ[i] = WKING;
}
else if(state[i] == WKING) {
Board::WK[i] = WKING;
}
else if(state[i] == BPAWN) {
Board::BP[i] = BPAWN;
}
else if(state[i] == BKNIGHT) {
Board::BN[i] = BKNIGHT;
}
else if(state[i] == BBISHOP) {
Board::BB[i] = BBISHOP;
}
else if(state[i] == BROOK) {
Board::BR[i] = BROOK;
}
else if(state[i] == BQUEEN) {
Board::BQ[i] = BQUEEN;
}
else if(state[i] == BKING) {
Board::BK[i] = BKING;
}
//Copy state to allBoard:
for (short n = 0; i < 64; i++) {
Board::allBoard[i] = state[i];
}
//fill up W_Pieces and B_Pieces with White and Black pieces
for(short m = 0; m < 64; m++) {
if(state[m] < BPAWN) { //if state[m] denotes a white piece.
//If you don't get me, pay attention on '<' sign. Think, think think!
W_Pieces[m] = state[m];
}
else {
B_Pieces[m] = state[m];
}
}
}
}
void Board::displayBoard() {
std::cout << "*******************************";
for(short j = 0; j < 64; ++j) {
if(!(j % 8)) std::cout << "\n";
std::cout << "| " << piece2char(Board::allBoard[j]) << " ";
}
std::cout << "\n";
std::cout << "*******************************" << std::endl;
}
inline char piece2char(const short piece) {
if(piece == BLANK) {
return ' ';
}
else if(piece == WPAWN) {
return 'P';
}
else if(piece == WKNIGHT) {
return 'N';
}
else if(piece == WBISHOP) {
return 'B';
}
else if(piece == WROOK) {
return 'R';
}
else if(piece == WQUEEN) {
return 'Q';
}
else if(piece == WKING) {
return 'K';
}
else if(piece == BPAWN) {
return 'p';
}
else if(piece == BKNIGHT) {
return 'n';
}
else if(piece == BBISHOP) {
return 'b';
}
else if(piece == BROOK) {
return 'r';
}
else if(piece == BQUEEN) {
return 'q';
}
else if(piece == BKING) {
return 'k';
}
else return '!';
}
void Board::parseMove(const char move[]) {
unsigned short file, rank, toFile, toRank;
switch(move[0]) {
case 'a':
file = 1;
break;
case 'b':
file = 2;
break;
case 'c':
file = 3;
break;
case 'd':
file = 4;
break;
case 'e':
file = 5;
break;
case 'f':
file = 6;
break;
case 'g':
file = 7;
break;
case 'h':
file = 8;
break;
}
rank = atoi(&move[1]);
switch(move[2]) {
case 'a':
toFile = 1;
break;
case 'b':
toFile = 2;
break;
case 'c':
toFile = 3;
break;
case 'd':
toFile = 4;
break;
case 'e':
toFile = 5;
break;
case 'f':
toFile = 6;
break;
case 'g':
toFile = 7;
break;
case 'h':
toFile = 8;
break;
}
toRank = atoi(&move[3]);
unsigned short fromSq = toSquare(file, rank);
unsigned short toSq = toSquare(toFile, toRank);
Board::doMove(fromSq, toSq);
}
inline void Board::doMove(const unsigned short &fromSq, const unsigned short &toSq) {
short fsq = sq2comp(fromSq), tsq = sq2comp(toSq);
Board::allBoard[tsq] = Board::allBoard[fsq];
Board::allBoard[fsq] = BLANK;
setPieces(Board::allBoard);
}
My questions:
1) Provide at least one code sample from my code where you use bitboards to access individual pieces like I do in a array.
2) Is my code 'creepy' or difficult to understand?
3) Is my code fast?
4) Give me some advice to improve this code, if you have...
Thanks in advance.[/code]