Yeah, the current project is chess. I've decided on this. Because it's fun, and it'll be a good AI exercise for me down the road. Also up to now I've made a number of attempts at a blog update only to realize I'd have like a thousand updates on everything cool that I figure out. So instead, weekly updates!
A week ago, on the whim of not really having anything to do at work while my code ran (apparently analyzing sixteen gigs of genomic data takes a while), I decided to make a chess clone in C++ because I know that language best. That day I'd made the board minus the border, which was cool, and had some cool text that showed up. Altogether, nothing too fancy.
Over the week I've finished the board, added the internal representation of the board, created the Player structure, methods to: get the current location of every piece; show the board; reset the board; randomize the board (this was mostly for testing the "show" and "reset" methods, but is kinda cool nonetheless); output the text representation for the board to standard output; and an "initialize" method that doesn't actually do much. The current image set for my chess clone is actually just letters for the moment, but that'll change in polishing. Unless I'm really as lazy as I think I can be sometimes.
So, this is intended to be more than a journal of my progress. I'd also like to get pieces of my code on here so either 1) people can learn from it; or 2) I can learn from other people looking at it and telling me I'm stupid. Both totally valid. Without further delay, let's take a look at what I've been doing, starting with the internal representation of the board!
Nothing special. You might be wondering "but why are you using ints? They don't mean anything to a chess program!" This is true, at least in a vacuum; but I really like enums.
This basically assigns each piece type a numeric value, for those of you unfamiliar with enum (it 'enum'erates over a number of identifiers! who'da thunk that programming can make sense?). Now, the reason I have two sets of piece identifiers is for the two different players, because otherwise you have to integrate display functions with board state retrieval and it's a bit of a mess. Speaking of board state retrieval...
A wild Player class has appeared! It has the Piece struct you haven't seen yet as a fundamental part of its definition, but we'll get to that next. This is basically just a nice way to keep all the player data in one place. The mostly omitted constructor basically just makes a bunch of new Piece objects, and depending on the color of this particular player (we're abstracting race into a true-false distinction, because we can) puts them in the right places. It's really verbose because I can't think of a better way to do it without passing it off to some other function, which doesn't really make sense since it only happens once. I don't think it needs a destructor yet, since games don't actually happen, let alone finish, so yeah. Now to the Pieces!
This is pretty simple. Probably a little redundant overall, but whatevs. The last thing of interest, I think, is the thing that determines the current location of every piece based on each player's list of pieces:
Again, it's pretty simple, but it worked the first time I compiled with it so I'm kinda proud of it because I'm normally really bad with iterators. I also really liked how the Piece and Player structures made this so trivial, made me feel good about my design choices. I'm sure that'll change soon.
So, if you have anything to add, ask about, or comment on, let me know in the comments!
A week ago, on the whim of not really having anything to do at work while my code ran (apparently analyzing sixteen gigs of genomic data takes a while), I decided to make a chess clone in C++ because I know that language best. That day I'd made the board minus the border, which was cool, and had some cool text that showed up. Altogether, nothing too fancy.
Over the week I've finished the board, added the internal representation of the board, created the Player structure, methods to: get the current location of every piece; show the board; reset the board; randomize the board (this was mostly for testing the "show" and "reset" methods, but is kinda cool nonetheless); output the text representation for the board to standard output; and an "initialize" method that doesn't actually do much. The current image set for my chess clone is actually just letters for the moment, but that'll change in polishing. Unless I'm really as lazy as I think I can be sometimes.
So, this is intended to be more than a journal of my progress. I'd also like to get pieces of my code on here so either 1) people can learn from it; or 2) I can learn from other people looking at it and telling me I'm stupid. Both totally valid. Without further delay, let's take a look at what I've been doing, starting with the internal representation of the board!
int board[8][8] = {{0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0}, };Nothing special. You might be wondering "but why are you using ints? They don't mean anything to a chess program!" This is true, at least in a vacuum; but I really like enums.
enum Pieces { PAWN, KING, QUEEN, ROOK, BISHOP, KNIGHT, BPAWN, BKING, BQUEEN, BROOK, BBISHOP, BKNIGHT, EMPTY};This basically assigns each piece type a numeric value, for those of you unfamiliar with enum (it 'enum'erates over a number of identifiers! who'da thunk that programming can make sense?). Now, the reason I have two sets of piece identifiers is for the two different players, because otherwise you have to integrate display functions with board state retrieval and it's a bit of a mess. Speaking of board state retrieval...
class Player { private: bool color; //true = white, false = black vector pieces; public: Player(bool isWhite) { color = isWhite; //code omitted for brevity } vector getPieceList() { return this->pieces; }};A wild Player class has appeared! It has the Piece struct you haven't seen yet as a fundamental part of its definition, but we'll get to that next. This is basically just a nice way to keep all the player data in one place. The mostly omitted constructor basically just makes a bunch of new Piece objects, and depending on the color of this particular player (we're abstracting race into a true-false distinction, because we can) puts them in the right places. It's really verbose because I can't think of a better way to do it without passing it off to some other function, which doesn't really make sense since it only happens once. I don't think it needs a destructor yet, since games don't actually happen, let alone finish, so yeah. Now to the Pieces!
struct Piece { Pieces type; int x, y; //the position on the board Piece(Pieces _type) { type = _type; } void setPos(int _x, int _y) { x = _x; y = _y; }};This is pretty simple. Probably a little redundant overall, but whatevs. The last thing of interest, I think, is the thing that determines the current location of every piece based on each player's list of pieces:
void getCurrentBoardState() { vector w_piece = w.getPieceList(); vector b_piece = b.getPieceList(); for (vector::iterator it = w_piece.begin(); it < w_piece.end(); it++) { int tempx = it->x, tempy = it->y; board[tempx][tempy] = it->type; } for (vector::iterator it = b_piece.begin(); it < b_piece.end(); it++) { int tempx = it->x, tempy = it->y; board[tempx][tempy] = it->type + 6; }}Again, it's pretty simple, but it worked the first time I compiled with it so I'm kinda proud of it because I'm normally really bad with iterators. I also really liked how the Piece and Player structures made this so trivial, made me feel good about my design choices. I'm sure that'll change soon.
So, if you have anything to add, ask about, or comment on, let me know in the comments!

No comments:
Post a Comment