/*! * Returns true if \a side has material else false. */ bool HordeBoard::hasMaterial(Side side) const { for (int i = 0; i < arraySize(); i++) { if (side == pieceAt(i).side() && pieceAt(i).isValid()) return true; } return false; }
void CrazyhouseBoard::generateMovesForPiece(QVarLengthArray<Move>& moves, int pieceType, int square) const { // Generate drops if (square == 0) { const int size = arraySize(); const int maxRank = height() - 2; for (int i = 0; i < size; i++) { Piece tmp = pieceAt(i); if (!tmp.isEmpty()) continue; if (pieceType == Pawn) { Square sq(chessSquare(i)); if (sq.rank() < 1 || sq.rank() > maxRank) continue; } moves.append(Move(0, i, pieceType)); } } else WesternBoard::generateMovesForPiece(moves, pieceType, square); }
Chess::Piece GraphicsBoard::pieceTypeAt(const Chess::Square& square) const { GraphicsPiece* piece = pieceAt(square); if (piece == nullptr) return Chess::Piece(); return piece->pieceType(); }
void OukBoard::generateMovesForPiece(QVarLengthArray< Move >& moves, int pieceType, int square) const { MakrukBoard::generateMovesForPiece(moves, pieceType, square); Side side = sideToMove(); // Only consider King and Neang on their initial squares if ((pieceType != King || square != m_initialSquare[side][King]) && (pieceType != Maiden || square != m_initialSquare[side][Maiden])) return; // Return if the piece has moved already if (m_moveCount[side].value((OukPieceType)pieceType, -1) != 0) return; // No special moves for King in check if (pieceType == King && inCheck(side)) return; // Generate initial move option for King (leap of Horse) // and for Neang (forward two squares) int sign = (side == Side::White) ? 1 : -1; for (const auto& i: m_initialOffsets) { if (pieceType != i.type) continue; int target = square - i.offset * sign; const Piece& piece = pieceAt(target); if (piece.isEmpty()) moves.append(Move(square, target)); } }
bool OukBoard::vSetFenString(const QStringList& fen) { // At first assume that King and Maiden pieces have moved m_moveCount[Side::White][King] = 1; m_moveCount[Side::Black][King] = 1; m_moveCount[Side::White][Maiden] = 1; m_moveCount[Side::Black][Maiden] = 1; // parseCastlingRights is called via vSetFenString of base class if (!MakrukBoard::vSetFenString(fen)) return false; // Expect pieces on their initial squares if move counter is zero const OukPieceType types[2]{King, Maiden}; for (int side = Side::White; side <= Side::Black; side++) { for (auto type: types) { int index = m_initialSquare[side][type]; if ( m_moveCount[side][type] == 0 && pieceAt(index) != Piece(Side::Type(side), type)) return false; } } return true; }
//-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ if(x >= boardXOffset + (boardW)*hexW){ //We are clicking the right-hand side of the screen, so we are // picking up or putting back a piece if(whoseTurn == 1 && pl1spares > 0 && currentAction == 0){ currentAction = 1; pl1spares--; } else if(whoseTurn == 2 && pl2spares > 0 && currentAction == 0){ currentAction = 1; pl2spares--; } else if (whoseTurn == 1 && currentAction == 1){ currentAction = 0; pl1spares++; } else if (whoseTurn == 2 && currentAction == 1){ currentAction = 0; pl2spares++; } } else if(x > boardXOffset && x <= boardXOffset +(boardW)*hexW ) { //We are clicking on the board... if(currentAction == 1){ //...placing a new piece int whichRow = (y-boardYOffset+hexH/2)/hexH; int whichCol = (x-(boardXOffset+(whichRow%2)*(hexW/2))+hexW/2)/hexW; if(whichRow >= 0 && whichRow < boardH && whichCol >= 0 && whichCol < boardW){ if(canPlaceNewPiece(whichCol,whichRow)){ currentAction = 0; putPieceAt(whichCol,whichRow,whoseTurn); whoseTurn = 3 - whoseTurn; } } } else if(currentAction == 0){ //...picking up and old piece int whichRow = (y-boardYOffset+hexH/2)/hexH; int whichCol = (x-(boardXOffset+(whichRow%2)*(hexW/2))+hexW/2)/hexW; if(pieceAt(whichCol,whichRow) == whoseTurn){ selectedPieceX = whichCol; selectedPieceY = whichRow; currentAction = 2; putPieceAt(whichCol,whichRow,0); } } else if(currentAction == 2){ //...placing an old piece back on the board int whichRow = (y-boardYOffset+hexH/2)/hexH; int whichCol = (x-(boardXOffset+(whichRow%2)*(hexW/2))+hexW/2)/hexW; if(whichRow == selectedPieceY && whichCol == selectedPieceX){ currentAction = 0; putPieceAt(whichCol,whichRow,whoseTurn); } else if(whichRow >= 0 && whichRow < boardH && whichCol >= 0 && whichCol < boardW){ if(canPlaceOldPiece(whichCol, whichRow)){ currentAction = 0; putPieceAt(whichCol,whichRow,whoseTurn); whoseTurn = 3 - whoseTurn; } } } } }
void GraphicsBoard::movePiece(const Chess::Square& source, const Chess::Square& target) { GraphicsPiece* piece = pieceAt(source); Q_ASSERT(piece != nullptr); m_squares[squareIndex(source)] = nullptr; setSquare(target, piece); }
QString CrazyhouseBoard::sanMoveString(const Move& move) { Piece piece(pieceAt(move.sourceSquare())); QVarLengthArray<int> squares; normalizePieces(piece, squares); QString str(WesternBoard::sanMoveString(move)); restorePieces(piece, squares); return str; }
Result LosersBoard::result() { Side winner; QString str; // Checkmate/Stalemate if (!canMove()) { winner = sideToMove(); str = tr("%1 gets mated").arg(winner.toString()); return Result(Result::Win, winner, str); } // Lost all pieces int pieceCount = 0; for (int i = 0; i < arraySize(); i++) { if (pieceAt(i).side() == sideToMove() && ++pieceCount > 1) break; } if (pieceCount <= 1) { winner = sideToMove(); str = tr("%1 lost all pieces").arg(winner.toString()); return Result(Result::Win, winner, str); } // 50 move rule if (reversibleMoveCount() >= 100) { str = tr("Draw by fifty moves rule"); return Result(Result::Draw, Side::NoSide, str); } // 3-fold repetition if (repeatCount() >= 2) { str = tr("Draw by 3-fold repetition"); return Result(Result::Draw, Side::NoSide, str); } return Result(); }
void CrazyhouseBoard::normalizePieces(Piece piece, QVarLengthArray<int>& squares) { if (!piece.isValid()) return; Piece prom(piece.side(), promotedPieceType(piece.type())); Piece base(piece.side(), normalPieceType(piece.type())); if (base == prom) return; const int size = arraySize(); for (int i = 0; i < size; i++) { if (pieceAt(i) == prom) { squares.append(i); setSquare(i, base); } } }
bool HordeBoard::vIsLegalMove(const Move& m) { if (!StandardBoard::vIsLegalMove(m)) return false; /* * Workaround for Stockfish (lichess.org) asymmetry: * accept en passant on 3rd (6th) rank only. */ int src = m.sourceSquare(); int tgt = m.targetSquare(); Piece piece = pieceAt(src); if (piece.type() != Pawn || tgt != enpassantSquare()) return true; int targetRank = chessSquare(tgt).rank(); return targetRank == 2 || targetRank == height() - 3; }
bool ChessBoard::turn(int row, int column) { if( !m_selected_piece ) return false; // get possible turns QScopedPointer< const QList<QSize> > trns(m_selected_piece->getPossibleTurns( column, row )); // current coords QSize cur_coords = m_selected_piece->getCoords(); QList<QSize>::const_iterator it; for(it = trns->begin(); it != trns->end(); it++) { QSize coords_sum = b_black_bottom ^ m_selected_piece->m_bWhite ? cur_coords - (*it) : cur_coords + (*it); if( coords_sum == turn_coords ) { emit figureMoved(cur_coords, turn_coords); PiecePtr &turned = pieceAt(column, row); m_selected_piece->setCoords(turn_coords); turned.swap(m_selected_piece); return true; } } return false; }
bool ChessBoard::cellClick(int row, int column) { if( row >= 0 && row < m_board_size && column >=0 && column < m_board_size ) { QSize turn_coords = QSize( column, row ); // check if piece clicked for the 1st time PiecePtr& _selected = pieceAt( column, row ); if( _selected ) { m_selected_piece.swap(_selected); return true; } QSize from = m_selected_piece->getCoords(); if( turn( row, column ) ) { writeLog(from, turn_coords); return true; } else return false; } return false; }
void drawBoard(){ //NOTE: This will need to be adapted to your board // data structure! //For each board hex... for(int y=0;y<boardH;y++){ for(int x=0;x<boardW;x++){ //Calculate the center, and draw the border float offset = (hexW/2) * (y%2); ofSetColor(0, 0, 0); drawHex(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen); if(pieceAt(x,y) != 0){ //If there is a playing piece in the current hex, // draw it if(pieceAt(x,y) == 1){ ofSetColor(255,255,255); } else { ofSetColor(0,0,0); } ofCircle(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen/2); } else { //This is an unoccupied space, but we might need to draw some // highlights... if(currentAction == 1){ //If the user is trying to place a new piece, // higlight the space if it is valid to place the piece here ofSetColor(64,192,64); //green highlight if(canPlaceNewPiece(x, y)){ ofCircle(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen/2); } } else if(currentAction == 2){ //If the user is trying to move an old piece, // higlight the space if it is valid to place the piece here ofSetColor(64,192,64); //green if(canPlaceOldPiece(x, y)){ ofCircle(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen/2); } } } } } if(currentAction == 1){ //If placing a new piece, draw the piece that the user is placing // at the mouse location if(whoseTurn == 1){ ofSetColor(255,255,255); } else { ofSetColor(0,0,0); } ofCircle(ofGetMouseX(),ofGetMouseY(),sideLen/2); } else if(currentAction == 2){ //If moving an old piece... //...show where it is being moved FROM ofSetColor(64,64,192); //blue float offset = (hexW/2) * (selectedPieceY%2); ofCircle(boardXOffset+selectedPieceX*hexW+offset,boardYOffset+selectedPieceY*hexH,sideLen/2); //...and also show the piece in the player's "hand" being moved if(whoseTurn == 1){ ofSetColor(255,255,255); } else { ofSetColor(0,0,0); } ofCircle(ofGetMouseX(),ofGetMouseY(),sideLen/2); } }