void IterableChess::pushPawnMoves(int posy, int posx, ChessColor player, std::vector<ChessMove>& moves) const { int begins_from_y; // Where it begins int direction; // 1 for forward, -1 for backward if (player == B) { begins_from_y = 6; direction = -1; } else { begins_from_y = 1; direction = 1; } if (posy == begins_from_y) { insert_move_if_empty(posy, posx, posy+2*direction, posx, moves, m_state); } if (posy + 1*direction < CHESS_DIMENTION_Y) { insert_move_if_empty(posy, posx, posy+1*direction, posx, moves, m_state); // check the possibility of eating if (posx < CHESS_DIMENTION_X-1) { if (m_state[posy+1*direction][posx+1].color == OtherColor(player) && m_state[posy+1*direction][posx+1].type != EMPTY) { moves.push_back(ChessMove(posy, posx, posy+1*direction, posx+1)); } } if (posx >= 1) { if (m_state[posy+1*direction][posx-1].color == OtherColor(player) && m_state[posy+1*direction][posx-1].type != EMPTY) { moves.push_back(ChessMove(posy, posx, posy+1*direction, posx-1)); } } } }
void IterableChess::pushQueenMoves(int posy, int posx, ChessColor player, std::vector<ChessMove>& moves) const { std::vector< std::pair<int, int> > dirs; dirs.push_back(std::pair<int, int>(1, 1)); dirs.push_back(std::pair<int, int>(1, -1)); dirs.push_back(std::pair<int, int>(-1, 1));dirs.push_back(std::pair<int, int>(-1, -1)); dirs.push_back(std::pair<int, int>(1, 0)); dirs.push_back(std::pair<int, int>(-1, 0)); dirs.push_back(std::pair<int, int>(0, 1)); dirs.push_back(std::pair<int, int>(0, -1)); std::vector< std::pair<int, int> >::iterator iter = dirs.begin();; for (; iter != dirs.end(); iter++) { int desty = posy+iter->first, destx = posx+iter->second; while (destx < CHESS_DIMENTION_X && destx >= 0 && desty < CHESS_DIMENTION_Y && desty >= 0 && m_state[desty][destx].type == EMPTY) { moves.push_back(ChessMove(posy, posx, desty, destx)); desty+=iter->first; destx+=iter->second; } if (destx < CHESS_DIMENTION_X && destx >= 0 && desty < CHESS_DIMENTION_Y && desty >= 0 && m_state[desty][destx].type != EMPTY && m_state[desty][destx].color == OtherColor(player)) { moves.push_back(ChessMove(posy, posx, desty, destx)); } } }
void ChessGameStateTest::test_capture() { m_state->move(ChessMove(Point(4, 6), Point(4, 4))); // e4 m_state->move(ChessMove(Point(3, 1), Point(3, 3))); // d5 m_state->move(ChessMove(Point(4, 4), Point(3, 3))); // exd5 CPPUNIT_ASSERT(m_state->board().get(Point(3, 3)) == ChessPiece(ChessPiece::WHITE, ChessPiece::PAWN)); }
void ChessGameStateTest::test_en_passant() { m_state->move(ChessMove(Point(4, 6), Point(4, 4))); // e4 m_state->move(ChessMove(Point(7, 1), Point(7, 2))); // h6 m_state->move(ChessMove(Point(4, 4), Point(4, 3))); // e5 ChessMove d5(Point(3, 1), Point(3, 3)); d5.setType(ChessMove::EN_PASSANT_TRIGGER); m_state->move(d5); CPPUNIT_ASSERT(m_state->enPassant() == Point(3, 2)); ChessMove exd6(Point(4, 3), Point(3, 2)); exd6.setType(ChessMove::EN_PASSANT_CAPTURE); m_state->move(exd6); CPPUNIT_ASSERT(m_state->board().get(Point(3, 3)) == ChessPiece()); }
/** * push the move to the vector only if the the target checker is empty. */ static void insert_move_if_empty(int from_y, int from_x, int to_y, int to_x, std::vector<ChessMove> &moves, const ChessPart state[8][8]) { if (state[to_y][to_x].type == EMPTY) { ChessMove m = ChessMove(from_y, from_x, to_y, to_x); moves.push_back(m); } }
void ChessLegalityTest::test_en_passant() { m_state->move(ChessMove(Point(4, 6), Point(4, 4))); m_state->move(ChessMove(Point(7, 1), Point(7, 2))); m_state->move(ChessMove(Point(4, 4), Point(4, 3))); ChessMove d5(Point(3, 1), Point(3, 3)); CPPUNIT_ASSERT(m_legality_check->legal(d5)); CPPUNIT_ASSERT(d5.enPassantTrigger() == Point(3, 2)); m_state->move(d5); ChessMove exd6(Point(4, 3), Point(3, 2)); CPPUNIT_ASSERT(m_legality_check->legal(exd6)); CPPUNIT_ASSERT(exd6.captureSquare() == Point(3, 3)); m_state->move(ChessMove(Point(7, 6), Point(7, 5))); m_state->move(ChessMove(Point(7, 2), Point(7, 3))); ChessMove tmp(Point(4, 3), Point(3, 2)); CPPUNIT_ASSERT(!m_legality_check->pseudolegal(tmp)); }
/** * Insert the move if the destination exists on board, empty, * or filled with other color. */ static void insert_move_if_empty_exst_other(int fromy, int fromx, int toy, int tox, ChessColor player, std::vector<ChessMove> &moves, const ChessPart state[8][8]) { if ( (toy < CHESS_DIMENTION_Y && toy >= 0 && tox < CHESS_DIMENTION_X && tox >= 0) && (state[toy][tox].type == EMPTY || state[toy][tox].color == OtherColor(player)) ) { moves.push_back(ChessMove(fromy, fromx, toy, tox)); } }
ChessMove ChessMove::fromString(const std::string& str) { if(str.length()<4) { return ChessMove(); } PieceType promotion = ptNone; if(str.length()>4) { ChessPiece p = ChessPiece::fromChar(str[4]); switch(p.type()) { case ptQueen: case ptRook: case ptBishop: case ptKnight: promotion = p.type(); break; } } CoordPair cpair = CoordPair::fromString(str.substr(0, 4)); if(cpair==CoordPair()) return ChessMove(); return ChessMove(cpair, promotion); }
//--------------------------------------------------------------------------- //Parse in the format: //a2 a4 //a2xb3 //Na1 a8 //Pc1xd5 const bool ChessGame::ParseMove( const std::string& s, ChessMove& move) const { if (s.empty()==true) return false; //Obtain chesstypes from the only upper case character at the first index //If there is no upper case, it is a pawn if (s=="o-o" || s=="O-O" || s == "0-0") { const int y = (this->GetWhoseTurn() == white ? 0 : 7); move = ChessMove(king,4,y,false,6,y); return true; } if (s=="o-o-o" || s=="O-O-O" || s == "0-0-0") { const int y = (this->GetWhoseTurn() == white ? 0 : 7); move = ChessMove(king,4,y,false,2,y); return true; } switch(s[0]) { case 'N': move.type = knight; break; case 'B': move.type = bishop; break; case 'R': move.type = rook ; break; case 'Q': move.type = queen ; break; case 'K': move.type = king ; break; default: move.type = pawn; } const int minSize = (move.type == pawn ? 5 : 6); if (static_cast<int>(s.size()) < minSize) return false; if (move.type == pawn) { if (s[2]==' ') move.capture = false; else if (s[2]=='x') move.capture = true; else return false; } else { if (s[3]==' ') move.capture = false; else if (s[3]=='x') move.capture = true; else return false; } const std::string from = (move.type == pawn ? s.substr(0,2) : s.substr(1,2) ); const std::string to = (move.type == pawn ? s.substr(3,2) : s.substr(4,2) ); switch(from[0]) { case 'a': move.x1 = 0; break; case 'b': move.x1 = 1; break; case 'c': move.x1 = 2; break; case 'd': move.x1 = 3; break; case 'e': move.x1 = 4; break; case 'f': move.x1 = 5; break; case 'g': move.x1 = 6; break; case 'h': move.x1 = 7; break; default: return false; } switch(from[1]) { case '1': move.y1 = 0; break; case '2': move.y1 = 1; break; case '3': move.y1 = 2; break; case '4': move.y1 = 3; break; case '5': move.y1 = 4; break; case '6': move.y1 = 5; break; case '7': move.y1 = 6; break; case '8': move.y1 = 7; break; default: return false; } switch(to[0]) { case 'a': move.x2 = 0; break; case 'b': move.x2 = 1; break; case 'c': move.x2 = 2; break; case 'd': move.x2 = 3; break; case 'e': move.x2 = 4; break; case 'f': move.x2 = 5; break; case 'g': move.x2 = 6; break; case 'h': move.x2 = 7; break; default: return false; } switch(to[1]) { case '1': move.y2 = 0; break; case '2': move.y2 = 1; break; case '3': move.y2 = 2; break; case '4': move.y2 = 3; break; case '5': move.y2 = 4; break; case '6': move.y2 = 5; break; case '7': move.y2 = 6; break; case '8': move.y2 = 7; break; default: return false; } //if it contains exactly one 'x' it is a capture return true; }
void ChessGameStateTest::test_simple_move() { m_state->move(ChessMove(Point(4, 6), Point(4, 5))); // e4 CPPUNIT_ASSERT(m_state->board().get(Point(4, 6)) == ChessPiece()); CPPUNIT_ASSERT(m_state->board().get(Point(4, 5)) == ChessPiece(ChessPiece::WHITE, ChessPiece::PAWN)); }