X-Git-Url: https://git.ucc.asn.au/?p=progcomp2013.git;a=blobdiff_plain;f=agents%2Fc%2B%2B%2Fqchess.cpp;h=f908756ffaed72c56f75ae8ec7b32f2fdd43cf86;hp=fbca35262f0231db6139ea308305feb681f8ad85;hb=7518ec8d771e731d6ffbbe00b275b7e3c4b23301;hpb=8571bc0c18f4a42bd1c8f34a5a36bcd9678b3f14 diff --git a/agents/c++/qchess.cpp b/agents/c++/qchess.cpp index fbca352..f908756 100644 --- a/agents/c++/qchess.cpp +++ b/agents/c++/qchess.cpp @@ -9,24 +9,27 @@ using namespace std; + /** * @constructor * @param new_x, new_y - Position of piece * @param new_colour - Colour of piece * @param type1, type2 - Types of piece - * @param index - Index for initial type of piece + * @param new_type_index - Index for initial type of piece + * @param new_piece_index - Index for piece in a vector */ -Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece::Type & type1, const Piece::Type & type2, int index) - : x(new_x), y(new_y), colour(new_colour), type_index(index), types(), current_type() +Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece::Type & type1, const Piece::Type & type2, + int new_type_index, int new_piece_index) + : x(new_x), y(new_y), colour(new_colour), type_index(new_type_index), types(), current_type(), piece_index(new_piece_index) { types[0] = type1; types[1] = type2; - if (index < 0 || index >= 2) + if (type_index < 0 || type_index >= 2) { current_type = Piece::UNKNOWN; } else { - current_type = types[index]; + current_type = types[type_index]; } } @@ -34,7 +37,7 @@ Piece::Piece(int new_x, int new_y, const Piece::Colour & new_colour, const Piece * @constructor * @param cpy - Piece to copy construct from */ -Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_index(cpy.type_index) +Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_index(cpy.type_index), piece_index(cpy.piece_index) { types[0] = cpy.types[0]; types[1] = cpy.types[1]; @@ -44,7 +47,9 @@ Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_i * @constructor * @param choose_types - Indicates whether Board should setup the 2nd types of pieces; default false */ -Board::Board(bool choose_types) +Board::Board(bool choose_types) + : white(), black(), white_unknown(), black_unknown(), white_nUnknown(0), black_nUnknown(0), + white_king(NULL), black_king(NULL), parent(NULL) { // initialise all the Squares @@ -69,6 +74,14 @@ Board::Board(bool choose_types) freq[Piece::QUEEN] = 1; freq[Piece::PAWN] = 8; + if (!choose_types) + { + white_unknown = freq; + black_unknown = freq; + white_nUnknown = 15; + black_nUnknown = 15; + } + // for white and black... for (int i = 0; i < 2; ++i) { @@ -80,26 +93,25 @@ Board::Board(bool choose_types) int y = (i == 0) ? 1 : BOARD_HEIGHT-2; for (int x = 0; x < BOARD_WIDTH; ++x) { - Piece * p = new Piece(x, y, colours[i], Piece::PAWN, Piece::UNKNOWN); - v.push_back(p); + Piece::AddPiece(v, x, y, colours[i], Piece::PAWN, Piece::UNKNOWN); } // add other pieces y = (i == 0) ? 0 : BOARD_HEIGHT-1; - v.push_back(new Piece(0, y, colours[i], Piece::ROOK, Piece::UNKNOWN)); - v.push_back(new Piece(BOARD_WIDTH-1, y, colours[i], Piece::ROOK, Piece::UNKNOWN)); - v.push_back(new Piece(1, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN)); - v.push_back(new Piece(BOARD_WIDTH-2, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN)); - v.push_back(new Piece(2, y, colours[i], Piece::BISHOP, Piece::UNKNOWN)); - v.push_back(new Piece(BOARD_WIDTH-3, y, colours[i], Piece::BISHOP, Piece::UNKNOWN)); - v.push_back(new Piece(3, y, colours[i], Piece::QUEEN, Piece::UNKNOWN)); - - Piece * k = new Piece(4, y, colours[i], Piece::KING, Piece::KING, 1); + Piece::AddPiece(v, 0, y, colours[i], Piece::ROOK, Piece::UNKNOWN); + Piece::AddPiece(v, BOARD_WIDTH-1, y, colours[i], Piece::ROOK, Piece::UNKNOWN); + Piece::AddPiece(v, 1, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN); + Piece::AddPiece(v, BOARD_WIDTH-2, y, colours[i], Piece::KNIGHT, Piece::UNKNOWN); + Piece::AddPiece(v, 2, y, colours[i], Piece::BISHOP, Piece::UNKNOWN); + Piece::AddPiece(v, BOARD_WIDTH-3, y, colours[i], Piece::BISHOP, Piece::UNKNOWN); + Piece::AddPiece(v, 3, y, colours[i], Piece::QUEEN, Piece::UNKNOWN); + + Piece * k = Piece::AddPiece(v, 4, y, colours[i], Piece::KING, Piece::KING, 1); if (i == 0) white_king = k; else black_king = k; - v.push_back(k); + // add to board and choose second types if required map f(freq); @@ -133,10 +145,12 @@ Board::Board(bool choose_types) /** * @constructor - * @param cpy - Board to copy construct from; each Piece in the copy will be *copied* - * The Piece's in the copied Board may be altered without affecting the original + * @param cpy - Board to clone */ -Board::Board(const Board & cpy) +Board::Board(Board & cpy) +: white(cpy.white), black(cpy.black), white_unknown(cpy.white_unknown), black_unknown(cpy.black_unknown), + white_nUnknown(cpy.white_nUnknown), black_nUnknown(cpy.black_nUnknown), + white_king(cpy.white_king), black_king(cpy.black_king), parent(&cpy) { for (int x = 0; x < BOARD_WIDTH; ++x) { @@ -144,12 +158,7 @@ Board::Board(const Board & cpy) { grid[x][y].x = x; grid[x][y].y = y; - - if (cpy.grid[x][y].piece != NULL) - { - grid[x][y].piece = new Piece(*(cpy.grid[x][y].piece)); - pieces(grid[x][y].piece->colour).push_back(grid[x][y].piece); - } + grid[x][y].piece = cpy.grid[x][y].piece; } } } @@ -176,17 +185,43 @@ Board::~Board() * @purpose Update Piece that has been selected * @param x, y - Position of Piece to update * @param index - 0 or 1 - State the Piece "collapsed" into - * @param type - Type of the Piece + * @param type - Type of the Piece as a string */ void Board::Update_select(int x, int y, int index, const string & type) { - cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << type << "\n"; + Board::Update_select(x, y, index, Piece::str2type(type)); +} + +/** + * @funct Update_select + * @purpose Update Piece that has been selected + * @param x, y - Position of Piece to update + * @param index - 0 or 1 - State the Piece "collapsed" into + * @param t - Type of the Piece + */ +void Board::Update_select(int x, int y, int index, const Piece::Type & t) +{ + cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << t << "\n"; Square & s = grid[x][y]; + + Clone_copy(s); + assert(s.piece != NULL); assert(index >= 0 && index < 2); s.piece->type_index = index; - s.piece->types[index] = Piece::str2type(type); - s.piece->current_type = s.piece->types[index]; + + if (s.piece->types[index] == Piece::UNKNOWN) + { + map & m = unknown_types(s.piece->colour); + int n = (m[t]--); + if (n < 0) + throw Exception("Board::Update_select", "Too many pieces of type %s found", Piece::type2str(t)); + + nUnknown(s.piece->colour)--; + + } + s.piece->types[index] = t; + s.piece->current_type = t; } /** @@ -201,6 +236,12 @@ void Board::Update_move(int x1, int y1, int x2, int y2) { Square & s1 = grid[x1][y1]; Square & s2 = grid[x2][y2]; + + Clone_copy(s1); + + + + if (s2.piece != NULL) { vector & p = pieces(s2.piece->colour); @@ -214,6 +255,11 @@ void Board::Update_move(int x1, int y1, int x2, int y2) } ++i; } + while (i != p.end()) + { + (*i)->piece_index -= 1; + ++i; + } Piece * k = king(s2.piece->colour); if (k == s2.piece) { @@ -222,8 +268,10 @@ void Board::Update_move(int x1, int y1, int x2, int y2) else black_king = NULL; } - - delete s2.piece; + if ((IsClone() && s2.piece == parent->grid[x2][y2].piece) == false) + { + delete s2.piece; + } } s1.piece->x = s2.x; @@ -375,6 +423,36 @@ Piece::Type Piece::str2type(const string & str) return Piece::UNKNOWN; } +/** + * @funct type2str + * @purpose Convert Piece::Type to string + * @param t - The Types + * @returns a const char* + */ +const char * Piece::type2str(const Piece::Type & t) +{ + switch (t) + { + case PAWN: + return "pawn"; + case BISHOP: + return "bishop"; + case KNIGHT: + return "knight"; + case ROOK: + return "rook"; + case QUEEN: + return "queen"; + case UNKNOWN: + return "unknown"; + case KING: + return "king"; + default: + throw Exception("Piece::type2str", "Unknown type %d", (int)t); + return ""; + } +} + /** * @funct str2colour * @purpose Convert string to Piece::Colour @@ -392,4 +470,34 @@ Piece::Colour Piece::str2colour(const string & str) return Piece::BLACK; // should never get here } +/** + * @funct AddPiece + * @purpose Creates a new Piece and adds it to a vector + * @param v - The vector + * @params - All remaining parameters passed to Piece::Piece + * @returns Pointer to the new Piece + */ +Piece * Piece::AddPiece(vector & v, int x, int y, const Piece::Colour & colour, const Piece::Type & t1, const Piece::Type & t2, + int type_index) +{ + Piece * p = new Piece(x,y,colour,t1, t2,type_index, v.size()); + v.push_back(p); + return p; +} +/** + * @funct Clone_copy + * @purpose If necessary, copy the piece in the square + * @param s - The square + */ +void Board::Clone_copy(Square & s) +{ + if (s.piece == NULL || !IsClone()) return; + if (parent->grid[s.x][s.y].piece == s.piece) + { + s.piece = new Piece(*(s.piece)); + vector & v = pieces(s.piece->colour); + v[s.piece->piece_index] = s.piece; + } + +} \ No newline at end of file