dimanche 1 juin 2014

Pieces pop up in my chess program


Vote count:

-1




I have some trouble with my chess program. It's a start. I don't aim to build a "good" chess engine. And the issue isn't how to improve it. Could you help me to find what is wrong please. I have got piece that pop up from nowhere while running. And I assume the problem coming from the copy functions of my classes and is relevant to memory. I searched for an awkward "=" standing instead of an "==" in an if() but there's none.


There is 3 classes : SQPIECE which encloses the informations about a square occupation, BOARD that contains a table SQPIECE [8][8], and BITBOARD designed to contains any information I want to represent as bool[8][8],


and 1 class called COORD in order to make easier the handling of board coordinates. There's no dynamic allocation or pointer handling in this program, because last time I used them it put a mess for debugging problems. And because of the gaps in my knowledge of C++. I seek to get around gaps when I can. Thanks for helping. Have fun!



#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;

#define BLACK 0
#define WHITE 1
#define ROOK 3
#define KNIGHT 5
#define QUEEN 2
#define PAWN 6
#define BISHOP 4
#define KING 1
#define EMPTY 0
#define SQUARE 0

#define ABSO(x)( ((int)(x) < 0) ? -(int)(x) :(int)(x) )
//functions for console display
char convert_file(int f){
switch(f){
case 0 : return 'a'; case 1 : return 'b'; case 2 : return 'c';
case 3 : return 'd'; case 4 : return 'e'; case 5 : return 'f';
case 6 : return 'g'; case 7 : return 'h'; default : return '?';
}
}
int convert_file(char f){
switch(f){
case 'A' : return 0; case 'a' : return 0; case 'B' : return 1;
case 'b' : return 1; case 'C' : return 2; case 'c' : return 2;
case 'D' : return 3; case 'd' : return 3; case 'E' : return 4;
case 'e' : return 4; case 'F' : return 5; case 'f' : return 5;
case 'G' : return 6; case 'g' : return 6; case 'H' : return 7;
case 'h' : return 7; default : return 9;
}
}
int convert_rank(char r){return (int(r)-48-1);}
char convert_rank(int r){return char(r+48+1);}
//*************************************************************************************
//there is nothing wrong with this class, a bit too much overloaded maybe but convenient sometimes
class COORD
{
public :
int fl; //file
int rk; //rank

void copy(const COORD & coord){fl = coord.fl; rk = coord.rk;}
void copy(const COORD * coord){fl = coord->fl; rk = coord->rk;}
bool set(const int pfile, const int prank){ fl = pfile; rk = prank; }
bool set(const char ch[3]){ fl = convert_file(ch[0]); rk = convert_rank(ch[1]); }
bool set(const char pfile, const char prank){ fl = convert_file(pfile); rk = convert_rank(prank); }

//constructors
COORD():fl(0),rk(0) {}
COORD(const COORD & coord){copy(coord);}
COORD(const COORD * coord){copy(coord);}
COORD(const int pfile, const int prank){set(pfile, prank);}
COORD(const char pfile, const char prank){set(pfile, prank);}
COORD(const char ch[3]){set(ch);}

inline bool on_board(){if(fl >= 0 && fl < 8 && rk >= 0 && rk < 8) return true; else return false;}

inline bool add(const int pfile, const int prank){ fl += pfile; rk += prank;}
inline bool add(const COORD & coord){fl += coord.fl; rk += coord.rk;}
inline bool sub(const int pfile, const int prank){fl -= pfile; rk -= prank;}
inline bool sub(const COORD & coord){rk -= coord.rk; fl -= coord.fl;}
COORD & operator = (const COORD & coord){ copy(coord); return *this;}
COORD & operator -= (const COORD & coord){ sub(coord); return *this;}
COORD & operator += (const COORD & coord){ add(coord); return *this;}
COORD operator - (const COORD & coord){ return COORD(fl-coord.fl, rk-coord.rk);}
COORD operator + (const COORD & coord){ return COORD(fl+coord.fl, rk+coord.rk);}
bool operator == (const COORD & coord){
if(fl == coord.fl && rk == coord.rk ) return true;
else return false;
}
bool operator != (const COORD & coord)
{
if(fl != coord.fl && rk != coord.rk) return true;
else return false;
}
// friend ostream & operator << (ostream & out, COORD & coord);
};

class BITBOARD
{
public :
bool bit[8][8];
void init(){ for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) bit[i][j] = false;}
void copy(const BITBOARD & bitb)
{
for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) bit[i][j] = bitb.bit[i][j];
}
void copy(const BITBOARD * bitb)
{
for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) bit[i][j] = bitb->bit[i][j];
}
BITBOARD(){init();}
BITBOARD(const BITBOARD & bitb) {copy(bitb);}
BITBOARD(const BITBOARD * bitb) {copy(bitb);}
~BITBOARD(){};
BITBOARD & operator = (const BITBOARD & bitb){ copy(bitb); return *this;}
BITBOARD & operator = (const BITBOARD * bitb){ copy(bitb); return *this;}
BITBOARD & operator & (const BITBOARD & bitb)
{
for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) bit[i][j] = (bit[i][j] & bitb.bit[i][j]);
return *this;
}
};

class SQPIECE //either a piece or an empty square
{
public :

bool color;
bool moved;
int type;
void init(){color = 0; moved = 0; type = 0;}
void copy(const SQPIECE & piece){
type = piece.type;
color = piece.color;
moved = piece.moved;}
void copy(const SQPIECE * piece){
type = piece->type;
color = piece->color;
moved = piece->moved;}
SQPIECE(){init();}
SQPIECE(const SQPIECE & piece){copy(piece);}
~SQPIECE(){};
SQPIECE & operator = (const SQPIECE & piece){ copy(piece); return *this;}
SQPIECE & operator = (const SQPIECE * piece){ copy(piece); return *this;}
};

class BOARD
{
public :
SQPIECE sq[8][8]; //the board
COORD black_king; //to spare time from searching to test incheck
COORD white_king;
bool turn;

void clear(){ for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) sq[i][j].init(); black_king.set(0,0); white_king.set(0,0); turn = WHITE;}
void copy(const BOARD & pboard){
for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) sq[i][j] = pboard.sq[i][j];
black_king = pboard.black_king;
white_king = pboard.white_king;
turn = pboard.turn;}
void copy(const BOARD * pboard){
for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) sq[i][j] = pboard->sq[i][j];
black_king = pboard->black_king;
white_king = pboard->white_king;
turn = pboard->turn;}
BOARD(){clear();}
BOARD(const BOARD & board) {copy(board);}
BOARD(const BOARD * board) {copy(board);}
~BOARD(){};
BOARD & operator = (const BOARD & board){ copy(board); return *this;}
BOARD & operator = (const BOARD * board){ copy(board); return *this;}

inline void place(COORD coord, bool color, int type, bool moved);
inline void takeoff(COORD coord);
bool move(COORD orig, COORD dest);
void refreshkingposition();

BITBOARD bishop_ctrl(const int fl, const int rk);
BITBOARD search_piece(const bool color,const int type);
};

inline void BOARD::place(COORD coord, bool color, int type, bool moved)
{
sq[coord.fl][coord.rk].type = type;
sq[coord.fl][coord.rk].color = color;
sq[coord.fl][coord.rk].moved = moved;
}
inline void BOARD::takeoff(COORD coord)
{
sq[coord.fl][coord.rk].type = 0;
sq[coord.fl][coord.rk].color = 0;
sq[coord.fl][coord.rk].moved = 0;
}

bool BOARD::move(COORD orig, COORD dest)
{
if(orig.on_board() && dest.on_board()){
sq[dest.fl][dest.rk] = sq[orig.fl][orig.rk];
takeoff(orig);
sq[dest.fl][dest.rk].moved = true;
turn = ! sq[dest.fl][dest.rk].color;
return true;
}
return false;
}

void BOARD::refreshkingposition(){
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
if(sq[i][j].type==KING){
if(sq[i][j].color==BLACK) black_king.set(i,j);
if(sq[i][j].color==WHITE) white_king.set(i,j);
}
}
}
}

//return a bitboard with bishop moves simulated from square [fl][rk] given as parameters
BITBOARD BOARD::bishop_ctrl(const int fl, const int rk){
BITBOARD bitb;
for(int i = fl+1, j = rk+1; i < 8, j < 8; i++, j++){
bitb.bit[i][j] = true;
if(sq[i][j].type != EMPTY) break;
}
for(int i = fl+1, j = rk-1; i < 8, j >= 0; i++, j--){
bitb.bit[i][j] = true;
if(sq[i][j].type != EMPTY) break;
}
for(int i = fl-1, j = rk-1; i >= 0, j >= 0; i--, j--){
bitb.bit[i][j] = true;
if(sq[i][j].type != EMPTY) break;
}
for(int i = fl-1, j = rk+1; i >= 0, j < 8; i--, j++){
bitb.bit[i][j] = true;
if(sq[i][j].type != EMPTY) break;
}
return bitb;
}
BITBOARD BOARD::search_piece(const bool color, const int type){
BITBOARD bitb;
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
if(sq[i][j].type==type && sq[i][j].color==color) bitb.bit[i][j] = true;
}
}
return bitb;
}

/******************************************************************************************/
//interface functions :
void showcoord(const COORD & coord){ cout << convert_file(coord.fl) << convert_rank(coord.rk);}
void showcoord(const int fl, const int rk){ cout << convert_file(fl) << convert_rank(rk);}

void display_board(const BOARD & board){
cout << "\n";
for(int j = 7; j >= 0; j--){
switch(j){
case 7 : cout << "8 "; break;
case 6 : cout << "7 "; break;
case 5 : cout << "6 "; break;
case 4 : cout << "5 "; break;
case 3 : cout << "4 "; break;
case 2 : cout << "3 "; break;
case 1 : cout << "2 "; break;
case 0 : cout << "1 "; break;
}
for(int i = 0; i < 8; i++){
if(board.sq[i][j].type == EMPTY){
cout << ".. "; continue;
}

switch(board.sq[i][j].type){
case QUEEN : cout << "Q"; break;
case KING : cout << "K"; break;
case BISHOP : cout << "B"; break;
case KNIGHT : cout << "N"; break;
case PAWN : cout << "+"; break;
case ROOK : cout << "R"; break;
default : cout << "?"; break;
}
if(board.sq[i][j].color == WHITE) cout << "w";
if(board.sq[i][j].color == BLACK) cout << "b";
cout << " ";
}
cout << "\n\n";
}
cout << " " << "A B C D E F G H" << "\n\n";
}

void display_bitboard(const BITBOARD & bitb){
cout << "\n";
for(int j = 7; j >= 0; j--){
switch(j){
case 7 : cout << "8 "; break;
case 6 : cout << "7 "; break;
case 5 : cout << "6 "; break;
case 4 : cout << "5 "; break;
case 3 : cout << "4 "; break;
case 2 : cout << "3 "; break;
case 1 : cout << "2 "; break;
case 0 : cout << "1 "; break;
}
for(int i = 0; i < 8; i++){
if(bitb.bit[i][j] == false){
cout << ".. "; continue;
}
else{
showcoord(i,j);
}
cout << " ";
}
cout << "\n\n";
}
cout << " " << "A B C D E F G H" << "\n\n";
}

int main()
{
BOARD board;
board.place("a1", WHITE, ROOK, 0);
board.place("b1", WHITE, KNIGHT, 0);
board.place("c1", WHITE, BISHOP, 0);
board.place("d1", WHITE, QUEEN, 0);
board.place("e1", WHITE, KING, 0);
board.place("f1", WHITE, BISHOP, 0);
board.place("g1", WHITE, KNIGHT, 0);
board.place("h1", WHITE, ROOK, 0);
board.place("a8", BLACK, ROOK, 0);
board.place("b8", BLACK, KNIGHT, 0);
board.place("c8", BLACK, BISHOP, 0);
board.place("d8", BLACK, QUEEN, 0);
board.place("e8", BLACK, KING, 0);
board.place("f8", BLACK, BISHOP, 0);
board.place("g8", BLACK, KNIGHT, 0);
board.place("h8", BLACK, ROOK, 0);

board.refreshkingposition();
display_board(board);

//here the purpose is to display the bishop moves from black's king position(s) just to test the functions
BITBOARD blackkingboard = board.search_piece(BLACK,KING);

//for each position of the black king (supposed to be only one)
for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) if(blackkingboard.bit[i][j] == true)
{
cout << "black king position:" << endl;
display_bitboard(blackkingboard);
BITBOARD bishopmov = board.bishop_ctrl(i,j); //we give the coordinates of the king to apply the bishop move pattern
cout << "bishop pattern from king pos:" << endl;
display_bitboard(bishopmov);
}
//and what isn't expected is that their is another black king popping upon "h3" in the BITBOARD blackkingboard, I assume the problem comes from constructors or copy function
system("PAUSE");
return 0;
}




asked 1 min ago






Aucun commentaire:

Enregistrer un commentaire