├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md └── src ├── CMakeLists.txt ├── Textures ├── arial.ttf ├── b_bishop.png ├── b_king.png ├── b_knight.png ├── b_pawn.png ├── b_queen.png ├── b_rook.png ├── w_bishop.png ├── w_king.png ├── w_knight.png ├── w_pawn.png ├── w_queen.png └── w_rook.png ├── board.cpp ├── board.h ├── chessGame.cpp ├── chessGame.h ├── main.cpp ├── piece.cpp ├── piece.h ├── pieceTextures.cpp └── pieceTextures.h /.gitignore: -------------------------------------------------------------------------------- 1 | ### C++ ### 2 | # Prerequisites 3 | *.d 4 | 5 | # Compiled Object files 6 | *.slo 7 | *.lo 8 | *.o 9 | *.obj 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Compiled Dynamic libraries 16 | *.so 17 | *.dylib 18 | *.dll 19 | 20 | # Fortran module files 21 | *.mod 22 | *.smod 23 | 24 | # Compiled Static libraries 25 | *.lai 26 | *.la 27 | *.a 28 | *.lib 29 | 30 | # Executables 31 | *.exe 32 | *.out 33 | *.app 34 | 35 | build/ 36 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(Chess-SFML) 3 | 4 | find_package(SFML 2.5 COMPONENTS graphics window system REQUIRED) 5 | add_subdirectory(src) 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Lefti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **Two player chess made with C++ and SFML(2D Graphics).** 2 | 3 | 4 | You need to have SFML installed to compile. 5 | https://www.sfml-dev.org/download/sfml/2.5.1/ 6 | 7 | Compile Instructions: 8 | 9 | Windows MinGW: 10 | 11 | 1) g++ -c main.cpp board.cpp piece.cpp pieceTextures.cpp chessGame.cpp -I \include -mwindows 12 | 2) g++ main.o board.o piece.o pieceTextures.o chessGame.o -mwindows -L \lib -lsfml-graphics -lsfml-window -lsfml-system 13 | 3) You need to have sfml-graphics-2.dll , sfml-system-2.dll and sfml-window-2.dll in the same folder as the exe 14 | 4) Open a.exe 15 | 16 | 17 | Linux GCC: 18 | 19 | 1) g++ -c main.cpp board.cpp piece.cpp pieceTextures.cpp chessGame.cpp 20 | 2) g++ main.o board.o piece.o pieceTextures.o chessGame.o -lsfml-graphics -lsfml-window -lsfml-system 21 | 3) ./a.out 22 | 23 | CMake: 24 | 25 | 1) mkdir build && cd build 26 | 2) cmake .. 27 | Your executable should now be in build/src/Chess-SFML. To properly run it you need to place it near the Textures folder. 28 | 29 | 30 | ## **Made By Lefti: https://github.com/Lefti97** 31 | 32 | 33 | Piece textures taken from: 34 | https://opengameart.org/content/chess-pieces-and-board-squares 35 | Copyright/Attribution Notice: 36 | JohnPablok's improved Cburnett chess set. 37 | 38 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(FILES 2 | board.cpp 3 | board.h 4 | chessGame.cpp 5 | chessGame.h 6 | main.cpp 7 | piece.cpp 8 | piece.h 9 | pieceTextures.cpp 10 | pieceTextures.h 11 | ) 12 | 13 | add_executable(${CMAKE_PROJECT_NAME} ${FILES}) 14 | target_link_libraries(${CMAKE_PROJECT_NAME} sfml-graphics sfml-window sfml-system) 15 | -------------------------------------------------------------------------------- /src/Textures/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/arial.ttf -------------------------------------------------------------------------------- /src/Textures/b_bishop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/b_bishop.png -------------------------------------------------------------------------------- /src/Textures/b_king.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/b_king.png -------------------------------------------------------------------------------- /src/Textures/b_knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/b_knight.png -------------------------------------------------------------------------------- /src/Textures/b_pawn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/b_pawn.png -------------------------------------------------------------------------------- /src/Textures/b_queen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/b_queen.png -------------------------------------------------------------------------------- /src/Textures/b_rook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/b_rook.png -------------------------------------------------------------------------------- /src/Textures/w_bishop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/w_bishop.png -------------------------------------------------------------------------------- /src/Textures/w_king.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/w_king.png -------------------------------------------------------------------------------- /src/Textures/w_knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/w_knight.png -------------------------------------------------------------------------------- /src/Textures/w_pawn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/w_pawn.png -------------------------------------------------------------------------------- /src/Textures/w_queen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/w_queen.png -------------------------------------------------------------------------------- /src/Textures/w_rook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lefti97/Chess-SFML/071d91ee9ec30171cee26b0c22efc8cdf91e1f89/src/Textures/w_rook.png -------------------------------------------------------------------------------- /src/board.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This code file contains member functions of board.h 3 | */ 4 | 5 | #include "board.h" 6 | 7 | Board::Board(sf::Color col1, sf::Color col2){ 8 | load(col1,col2); 9 | } 10 | 11 | // Member function that sets Board stuff, can choose square colors in parameters 12 | void Board::load(sf::Color col1, sf::Color col2){ 13 | for(int i=0; i<8;i++){ 14 | 15 | bool tmpColor = ((i % 2)==0)?true:false; 16 | 17 | for(int j=0; j<8;j++){ 18 | 19 | m_boardSquares[j + (i * 8)].setPosition(sf::Vector2f( j*64.f , i*64.f )); 20 | m_boardSquares[j + (i * 8)].setSize(sf::Vector2f(64.f, 64.f)); 21 | m_boardSquares[j + (i * 8)].setFillColor(tmpColor ? col1 : col2); 22 | 23 | tmpColor = !tmpColor; 24 | } 25 | } 26 | } 27 | 28 | // Draw class on SFML Window 29 | void Board::draw(sf::RenderTarget& target, sf::RenderStates states) const{ 30 | for(int i=0;i<64;i++){ 31 | target.draw(m_boardSquares[i]); 32 | } 33 | } -------------------------------------------------------------------------------- /src/board.h: -------------------------------------------------------------------------------- 1 | /* 2 | This header file contains the Board class. 3 | */ 4 | 5 | #ifndef _BOARD_H 6 | #define _BOARD_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | class Board : public sf::Drawable{ 13 | 14 | public: 15 | 16 | Board(sf::Color col1 = sf::Color::White, sf::Color col2 = sf::Color::Black); 17 | 18 | // Member function that sets Board stuff, can choose square colors in parameters 19 | void load(sf::Color col1 = sf::Color::White, sf::Color col2 = sf::Color::Black); 20 | 21 | private: 22 | 23 | std::array m_boardSquares; 24 | 25 | // Draw class on SFML Window 26 | virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; 27 | 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /src/chessGame.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This code file contains member functions of chessGame.h 3 | */ 4 | 5 | #include "chessGame.h" 6 | 7 | 8 | ChessGame::ChessGame(sf::Color bordCol1 = sf::Color::White, sf::Color bordCol2 = sf::Color::Black) 9 | : board(bordCol1,bordCol2) 10 | { 11 | // The code is taking account of these indexes. 12 | // Changing them may brake normal chess rules. 13 | // Comment out pieces if you want to remove some pieces at beggining. 14 | 15 | font.loadFromFile("Textures/arial.ttf"); 16 | 17 | 18 | infoRestart.setFillColor(sf::Color::White); 19 | infoRestart.setOutlineThickness(-5.f); 20 | infoRestart.setOutlineColor(sf::Color::Black); 21 | infoRestart.setPosition(sf::Vector2f(512.f,0.f)); 22 | infoRestart.setSize(sf::Vector2f(256.f, 50.f)); 23 | 24 | textRestart.setFont(font); 25 | textRestart.setString("RESTART"); 26 | textRestart.setCharacterSize(24); 27 | textRestart.setStyle(sf::Text::Bold); 28 | textRestart.setFillColor(sf::Color::Black); 29 | textRestart.setPosition(infoRestart.getPosition().x + 75.f, infoRestart.getPosition().y + 10.f); 30 | 31 | textTurn.setFont(font); 32 | textTurn.setCharacterSize(24); 33 | textTurn.setStyle(sf::Text::Bold); 34 | textTurn.setFillColor(sf::Color::White); 35 | textTurn.setPosition(530.f, 70.f); 36 | 37 | textSituation.setFont(font); 38 | textSituation.setCharacterSize(24); 39 | textSituation.setStyle(sf::Text::Bold); 40 | textSituation.setFillColor(sf::Color::White); 41 | textSituation.setPosition(530.f, 110.f); 42 | 43 | textLastMove.setFont(font); 44 | textLastMove.setCharacterSize(24); 45 | textLastMove.setStyle(sf::Text::Bold); 46 | textLastMove.setFillColor(sf::Color::White); 47 | textLastMove.setPosition(530.f, 200.f); 48 | 49 | 50 | restart(); 51 | 52 | } 53 | 54 | 55 | 56 | void ChessGame::restart(){ 57 | 58 | selected = false; 59 | playerTurn = true; 60 | playerTurnCheck = false; 61 | mate = false; 62 | turn = 1; 63 | 64 | blackPieces[0].setPiece('R', false, 7); 65 | blackPieces[1].setPiece('N', false, 6); 66 | blackPieces[2].setPiece('B', false, 5); 67 | blackPieces[3].setPiece('K', false, 4); 68 | blackPieces[4].setPiece('Q', false, 3); 69 | blackPieces[5].setPiece('B', false, 2); 70 | blackPieces[6].setPiece('N', false, 1); 71 | blackPieces[7].setPiece('R', false, 0); 72 | 73 | whitePieces[0].setPiece('R', true, 56); 74 | whitePieces[1].setPiece('N', true, 57); 75 | whitePieces[2].setPiece('B', true, 58); 76 | whitePieces[3].setPiece('Q', true, 59); 77 | whitePieces[4].setPiece('K', true, 60); 78 | whitePieces[5].setPiece('B', true, 61); 79 | whitePieces[6].setPiece('N', true, 62); 80 | whitePieces[7].setPiece('R', true, 63); 81 | 82 | 83 | for(int i=8;i<16;i++){ 84 | whitePieces[i].setPiece('P', true, 48 +(i-8)); 85 | blackPieces[i].setPiece('P', false, 15 - (i-8) ); 86 | } 87 | 88 | calcPossibleMoves(); 89 | 90 | textLastMove.setString(" "); 91 | 92 | 93 | } 94 | 95 | void ChessGame::updateInfo(){ 96 | textTurn.setString("Turn: " + std::to_string(turn)); 97 | textLastMove.setString(lastMove); 98 | 99 | if(!mate){ 100 | if(playerTurn) 101 | textSituation.setString("White's Turn"); 102 | else 103 | textSituation.setString("Blacks's Turn"); 104 | 105 | if(playerTurnCheck) 106 | textSituation.setString(textSituation.getString() + "\nCheck"); 107 | } 108 | else{ 109 | if(playerTurnCheck){ 110 | if(playerTurn) 111 | textSituation.setString("CHECKMATE\nBlack Wins"); 112 | else 113 | textSituation.setString("CHECKMATE\nWhite Wins"); 114 | } 115 | else{ 116 | textSituation.setString("STALEMATE\nIts a DRAW"); 117 | } 118 | 119 | } 120 | } 121 | 122 | 123 | 124 | void ChessGame::draw(sf::RenderTarget& target, sf::RenderStates states) const{ 125 | target.clear(sf::Color::Black); 126 | 127 | target.draw(board); 128 | target.draw(infoRestart); 129 | target.draw(textRestart); 130 | target.draw(textTurn); 131 | target.draw(textSituation); 132 | target.draw(textLastMove); 133 | 134 | if((selectedPiece != NULL) && (selected)){ 135 | for(int i=0; igetPossibleMoves().size();i++){ 156 | sf::RectangleShape tmp; 157 | tmp.setPosition(sf::Vector2f((selectedPiece->getPossibleMoves().at(i) % 8) * 64.f , (selectedPiece->getPossibleMoves().at(i) / 8) * 64.f)); 158 | tmp.setSize(sf::Vector2f(64.f, 64.f)); 159 | tmp.setFillColor(sf::Color(0x66b4cc50)); 160 | possibleMovesSquares.push_back(tmp); 161 | } 162 | 163 | sf::RectangleShape tmp; 164 | tmp.setPosition(sf::Vector2f((selectedPiece->getPosition() % 8) * 64.f , (selectedPiece->getPosition() / 8) * 64.f)); 165 | tmp.setSize(sf::Vector2f(64.f, 64.f)); 166 | tmp.setFillColor(sf::Color(0x00000000)); 167 | tmp.setOutlineColor(sf::Color::Red); 168 | tmp.setOutlineThickness(-3.f); 169 | possibleMovesSquares.push_back(tmp); 170 | 171 | return; 172 | 173 | } 174 | 175 | 176 | 177 | bool ChessGame::selectPiece(int pos){ 178 | 179 | for(int i=0; i<16; i++){ 180 | if(playerTurn){ // If white turn 181 | if(whitePieces[i].getPosition() == pos){ 182 | selectedPiece = &whitePieces[i]; 183 | selected = true; 184 | break; 185 | } 186 | } 187 | else{ // If black turn 188 | if(blackPieces[i].getPosition() == pos){ 189 | selectedPiece = &blackPieces[i]; 190 | selected = true; 191 | break; 192 | } 193 | } 194 | selected = false; 195 | } 196 | 197 | if(!selected){ 198 | selectedPiece = NULL; 199 | possibleMovesSquares.clear(); 200 | return selected; 201 | } 202 | 203 | 204 | createMovesSquares(); 205 | 206 | return selected; 207 | } 208 | 209 | 210 | 211 | void ChessGame::moveSelected(int pos){ 212 | bool validMove{false}; 213 | 214 | if((selectedPiece == NULL) || !selected ) //Probably doesnt need both 215 | return; 216 | 217 | // Check pos with the Piece's possibleMoves 218 | for(int i=0;igetPossibleMoves().size();i++){ 219 | if(pos == selectedPiece->getPossibleMoves().at(i)){ 220 | validMove = true; 221 | break; 222 | } 223 | } 224 | 225 | if(validMove){ 226 | 227 | // If Castling Move 228 | if((selectedPiece->getType() == 'K') && (!selectedPiece->getMoved())){ 229 | if(selectedPiece->getPlayer()){ // If white 230 | // whitePieces[0] Bot Left Rook, whitePieces[7] Bot Right Rook 231 | if(pos == 62) 232 | whitePieces[7].setPosition(61); 233 | else if(pos == 58) 234 | whitePieces[0].setPosition(59); 235 | } 236 | else{ // If Black 237 | // blackPieces[7] Top Left Rook, blackPieces[0] Top Right Rook 238 | if(pos == 6) 239 | blackPieces[0].setPosition(5); 240 | else if(pos == 2) 241 | blackPieces[7].setPosition(3); 242 | } 243 | } 244 | 245 | 246 | 247 | 248 | // If Pawn double move (set en passant) 249 | // White pawn -16, Black pawn +16 250 | if((selectedPiece->getType() == 'P')){ 251 | if(!selectedPiece->getMoved()){ 252 | if(pos == (selectedPiece->getPosition() - 16)){ 253 | selectedPiece->setEnPassant(selectedPiece->getPosition() - 8); 254 | } 255 | else if(pos == (selectedPiece->getPosition() + 16)){ 256 | selectedPiece->setEnPassant(selectedPiece->getPosition() + 8); 257 | } 258 | } 259 | else{ 260 | for(int i=0; i<16; i++){ 261 | if(playerTurn){ 262 | if(pos == blackPieces[i].getEnPassant()) 263 | blackPieces[i].setPosition(pos); 264 | } 265 | else{ 266 | if(pos == whitePieces[i].getEnPassant()) 267 | whitePieces[i].setPosition(pos); 268 | } 269 | } 270 | } 271 | } 272 | if(selectedPiece->getMoved()){ 273 | for(int i=0; i<16; i++){ 274 | whitePieces[i].setEnPassant(-1); 275 | blackPieces[i].setEnPassant(-1); 276 | } 277 | } 278 | 279 | 280 | selectedPiece->setPosition(pos); 281 | 282 | 283 | 284 | 285 | lastMove = "Last Turn:\n" + selectedPiece->toString(); 286 | for(int i=0; i<16; i++){ 287 | if(selectedPiece->getPlayer()){ // If White 288 | if(blackPieces[i].getPosition() == pos){ 289 | blackPieces[i].setPosition(-1); 290 | break; 291 | } 292 | } 293 | else{ // If Black 294 | if(whitePieces[i].getPosition() == pos){ 295 | whitePieces[i].setPosition(-1); 296 | break; 297 | } 298 | } 299 | } 300 | 301 | 302 | 303 | if(playerTurnCheck){ 304 | playerTurnCheck = false; 305 | } 306 | 307 | playerTurn = !playerTurn; // Here player turn changes 308 | calcPossibleMoves(); 309 | } 310 | 311 | selectedPiece = NULL; 312 | selected = false; 313 | 314 | } 315 | 316 | 317 | 318 | void ChessGame::calcPossibleMoves(){ 319 | 320 | Piece* tmpPiece; 321 | 322 | // LOOP for every piece 323 | for(int x=0; x<32; x++){ 324 | 325 | if(x<16) 326 | tmpPiece = &whitePieces[x]; 327 | else 328 | tmpPiece = &blackPieces[x-16]; 329 | tmpPiece->getPossibleMoves().clear(); 330 | tmpPiece->getDangerMoves().clear(); 331 | 332 | if(tmpPiece->getPosition() == -1) 333 | continue; 334 | 335 | // Calculate Moves for tmpPiece by piece type 336 | switch (tmpPiece->getType()) 337 | { 338 | case 'K': 339 | calcKingMoves(tmpPiece); 340 | break; 341 | case 'Q': 342 | calcQueenMoves(tmpPiece); 343 | break; 344 | case 'R': 345 | calcRookMoves(tmpPiece); 346 | break; 347 | case 'B': 348 | calcBishopMoves(tmpPiece); 349 | break; 350 | case 'N': 351 | calcKnightMoves(tmpPiece); 352 | break; 353 | case 'P': 354 | calcPawnMoves(tmpPiece); 355 | break; 356 | default: 357 | std::cerr << "Error piece type does not exist.\n"; 358 | break; 359 | } 360 | } 361 | 362 | 363 | // Erase illegal moves on current player's pieces 364 | for(int x = 0; x < 16; x++){ 365 | if(playerTurn){ 366 | eraseMoves(&whitePieces[x]); 367 | } 368 | else{ 369 | eraseMoves(&blackPieces[x]); 370 | } 371 | } 372 | 373 | 374 | 375 | checkMate(); 376 | 377 | 378 | updateInfo(); 379 | turn++; 380 | } 381 | 382 | 383 | 384 | 385 | void ChessGame::eraseMoves(Piece* tmpPiece){ 386 | 387 | if(tmpPiece->getPosition() == -1) 388 | return; 389 | 390 | 391 | if(tmpPiece->getPlayer() == playerTurn){ 392 | 393 | // Erase moves on same team pieces 394 | 395 | for(int i = 0; i<16; i++){ 396 | for(int j = 0; jgetPossibleMoves().size();j++){ 397 | 398 | if(tmpPiece->getPlayer()){ // White 399 | if(tmpPiece->getPossibleMoves().at(j) == whitePieces[i].getPosition()){ 400 | tmpPiece->getPossibleMoves().erase( tmpPiece->getPossibleMoves().begin() + j ); 401 | break; 402 | } 403 | } 404 | else{ // Black 405 | if(tmpPiece->getPossibleMoves().at(j) == blackPieces[i].getPosition()){ 406 | tmpPiece->getPossibleMoves().erase( tmpPiece->getPossibleMoves().begin() + j ); 407 | break; 408 | } 409 | } 410 | } 411 | } 412 | 413 | // Erase King moves on attacked squares 414 | if(tmpPiece->getType() == 'K'){ 415 | for(int j=0; j < tmpPiece->getPossibleMoves().size(); j++){ 416 | for(int i=0; i < 16; i++){ 417 | int o{0}; 418 | if(tmpPiece->getPlayer()){ // White 419 | for(o=0; o < blackPieces[i].getPossibleMoves().size();o++){ 420 | if(tmpPiece->getPossibleMoves().at(j) == blackPieces[i].getPossibleMoves().at(o)){ 421 | tmpPiece->getPossibleMoves().erase( tmpPiece->getPossibleMoves().begin() + j-- ); 422 | break; 423 | } 424 | } 425 | if( (o != blackPieces[i].getPossibleMoves().size())) 426 | break;; 427 | } 428 | else{ // Black 429 | for(o=0; o < whitePieces[i].getPossibleMoves().size();o++){ 430 | if(tmpPiece->getPossibleMoves().at(j) == whitePieces[i].getPossibleMoves().at(o)){ 431 | tmpPiece->getPossibleMoves().erase( tmpPiece->getPossibleMoves().begin() + j-- ); 432 | break; 433 | } 434 | } 435 | if( (o != whitePieces[i].getPossibleMoves().size())) 436 | break;; 437 | } 438 | } 439 | } 440 | } 441 | 442 | 443 | // Erase moves that put current piece's king in check 444 | if(tmpPiece->getType() != 'K'){ 445 | for(int i=0; i<16; i++){ 446 | if ( playerTurn && (blackPieces[i].getDangerMoves().size() > 1) ){ 447 | for(int j=0; jgetPosition()){ 449 | std::vector tmpMoves; 450 | for(int x=0; xgetPossibleMoves().size(); x++){ 451 | for(int k=0; kgetPossibleMoves().at(x) == blackPieces[i].getDangerMoves().at(k)) 453 | tmpMoves.push_back( tmpPiece->getPossibleMoves().at(x) ); 454 | } 455 | } 456 | tmpPiece->getPossibleMoves().clear(); 457 | tmpPiece->getPossibleMoves() = tmpMoves; 458 | break; 459 | } 460 | } 461 | } 462 | else if(!playerTurn && (whitePieces[i].getDangerMoves().size() > 1) ){ 463 | for(int j=0; jgetPosition()){ 465 | std::vector tmpMoves; 466 | for(int x=0; xgetPossibleMoves().size(); x++){ 467 | for(int k=0; kgetPossibleMoves().at(x) == whitePieces[i].getDangerMoves().at(k)) 469 | tmpMoves.push_back( tmpPiece->getPossibleMoves().at(x) ); 470 | } 471 | } 472 | tmpPiece->getPossibleMoves().clear(); 473 | tmpPiece->getPossibleMoves() = tmpMoves; 474 | break; 475 | } 476 | } 477 | } 478 | } 479 | } 480 | 481 | 482 | } 483 | } 484 | 485 | 486 | 487 | 488 | void ChessGame::calcKingMoves(Piece* tmpPiece){ 489 | 490 | int piecePos{tmpPiece->getPosition()}; 491 | tmpPiece->getPossibleMoves().clear(); 492 | 493 | if((piecePos / 8) != 0){ 494 | tmpPiece->getPossibleMoves().push_back(piecePos - 8); 495 | if((piecePos % 8) != 0) 496 | tmpPiece->getPossibleMoves().push_back(piecePos - 9); 497 | if((piecePos % 8) != 7) 498 | tmpPiece->getPossibleMoves().push_back(piecePos - 7); 499 | } 500 | if((piecePos / 8) != 7){ 501 | tmpPiece->getPossibleMoves().push_back(piecePos + 8); 502 | if((piecePos % 8) != 0) 503 | tmpPiece->getPossibleMoves().push_back(piecePos + 7); 504 | if((piecePos % 8) != 7) 505 | tmpPiece->getPossibleMoves().push_back(piecePos + 9); 506 | } 507 | if((piecePos % 8) != 0) 508 | tmpPiece->getPossibleMoves().push_back(piecePos - 1); 509 | if((piecePos % 8) != 7) 510 | tmpPiece->getPossibleMoves().push_back(piecePos + 1); 511 | 512 | 513 | //calcCastling(tmpPiece); 514 | } 515 | 516 | 517 | 518 | 519 | 520 | void ChessGame::calcQueenMoves(Piece* tmpPiece){ 521 | 522 | int piecePos{tmpPiece->getPosition()}; 523 | int posCounter{1}; 524 | 525 | bool dangerMove{false}; 526 | bool finishLoop{false}; 527 | 528 | tmpPiece->getPossibleMoves().clear(); 529 | tmpPiece->getDangerMoves().clear(); 530 | 531 | // Queen moves left on X axis 532 | while( ((piecePos-posCounter) >= 0) && ((piecePos/8) == ((piecePos-posCounter)/8)) ){ 533 | 534 | if(!finishLoop){ 535 | for(int i = 0; i<16; i++){ 536 | if( ( whitePieces[i].getPosition() == (piecePos-posCounter) ) || ( blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 537 | finishLoop = true; 538 | break; 539 | } 540 | } 541 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 542 | } 543 | 544 | if(!dangerMove){ 545 | // whitePieces[4] is white King , blackPieces[3] is black King 546 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 547 | if(!playerTurn){ 548 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 549 | dangerMove = true; 550 | } 551 | else{ 552 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 553 | dangerMove = true; 554 | } 555 | 556 | } 557 | 558 | posCounter += 1; 559 | } 560 | 561 | 562 | // Queen moves right on X axis 563 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 564 | finishLoop = false; 565 | posCounter = 1; 566 | while( (piecePos/8) == ((piecePos+posCounter)/8) ){ 567 | if(!finishLoop){ 568 | for(int i = 0; i<16; i++){ 569 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || ( blackPieces[i].getPosition() == (piecePos+posCounter) ) ){ 570 | finishLoop = true; 571 | break; 572 | } 573 | } 574 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 575 | } 576 | 577 | if(!dangerMove){ 578 | // whitePieces[4] is white King , blackPieces[3] is black King 579 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 580 | if(!playerTurn){ 581 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 582 | dangerMove = true; 583 | } 584 | else{ 585 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 586 | dangerMove = true; 587 | } 588 | 589 | } 590 | 591 | posCounter += 1; 592 | } 593 | //Queen moves up on Y axis 594 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 595 | finishLoop = false; 596 | posCounter = 8; 597 | while(((piecePos-posCounter) >= 0) && (posCounter < 64) && ((piecePos%8) == ((piecePos-posCounter)%8)) ){ 598 | if(!finishLoop){ 599 | for(int i = 0; i<16; i++){ 600 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 601 | finishLoop = true; 602 | break; 603 | } 604 | } 605 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 606 | } 607 | 608 | if(!dangerMove){ 609 | // whitePieces[4] is white King , blackPieces[3] is black King 610 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 611 | if(!playerTurn){ 612 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 613 | dangerMove = true; 614 | } 615 | else{ 616 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 617 | dangerMove = true; 618 | } 619 | 620 | } 621 | 622 | posCounter += 8; 623 | } 624 | //Queen moves down on Y axis 625 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 626 | finishLoop = false; 627 | posCounter = 8; 628 | while(((piecePos+posCounter) <= 63) && (posCounter < 64) && ((piecePos%8) == ((piecePos+posCounter)%8)) ){ 629 | if(!finishLoop){ 630 | for(int i = 0; i<16; i++){ 631 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 632 | finishLoop = true; 633 | break; 634 | } 635 | } 636 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 637 | } 638 | 639 | if(!dangerMove){ 640 | // whitePieces[4] is white King , blackPieces[3] is black King 641 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 642 | if(!playerTurn){ 643 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 644 | dangerMove = true; 645 | } 646 | else{ 647 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 648 | dangerMove = true; 649 | } 650 | } 651 | 652 | posCounter += 8; 653 | } 654 | // Queen moves towards top left 655 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 656 | finishLoop = false; 657 | posCounter = 9; 658 | while( ((piecePos-posCounter) >= 0) && (((piecePos-posCounter) % 8) < (piecePos % 8)) ){ 659 | if(!finishLoop){ 660 | for(int i = 0; i<16; i++){ 661 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 662 | finishLoop = true; 663 | break; 664 | } 665 | } 666 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 667 | } 668 | 669 | if(!dangerMove){ 670 | // whitePieces[4] is white King , blackPieces[3] is black King 671 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 672 | if(!playerTurn){ 673 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 674 | dangerMove = true; 675 | } 676 | else{ 677 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 678 | dangerMove = true; 679 | } 680 | } 681 | 682 | posCounter += 9; 683 | } 684 | // Queen moves towards bottom right 685 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 686 | finishLoop = false; 687 | posCounter = 9; 688 | while( ((piecePos+posCounter) <= 63) && (((piecePos+posCounter) % 8) > (piecePos % 8)) ){ 689 | if(!finishLoop){ 690 | for(int i = 0; i<16; i++){ 691 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 692 | finishLoop = true; 693 | break; 694 | } 695 | } 696 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 697 | } 698 | 699 | if(!dangerMove){ 700 | // whitePieces[4] is white King , blackPieces[3] is black King 701 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 702 | if(!playerTurn){ 703 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 704 | dangerMove = true; 705 | } 706 | else{ 707 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 708 | dangerMove = true; 709 | } 710 | } 711 | 712 | posCounter += 9; 713 | } 714 | // Queen moves towards top right 715 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 716 | finishLoop = false; 717 | posCounter = 7; 718 | while( ((piecePos-posCounter) >= 0) && (((piecePos-posCounter) % 8) > (piecePos % 8)) ){ 719 | if(!finishLoop){ 720 | for(int i = 0; i<16; i++){ 721 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 722 | finishLoop = true; 723 | break; 724 | } 725 | } 726 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 727 | } 728 | 729 | if(!dangerMove){ 730 | // whitePieces[4] is white King , blackPieces[3] is black King 731 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 732 | if(!playerTurn){ 733 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 734 | dangerMove = true; 735 | } 736 | else{ 737 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 738 | dangerMove = true; 739 | } 740 | } 741 | 742 | posCounter += 7; 743 | } 744 | // Queen moves towards bottom left 745 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 746 | finishLoop = false; 747 | posCounter = 7; 748 | while( ((piecePos+posCounter) <= 63) && (((piecePos+posCounter) % 8) < (piecePos % 8)) ){ 749 | if(!finishLoop){ 750 | for(int i = 0; i<16; i++){ 751 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 752 | finishLoop = true; 753 | break; 754 | } 755 | } 756 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 757 | } 758 | 759 | if(!dangerMove){ 760 | // whitePieces[4] is white King , blackPieces[3] is black King 761 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 762 | if(!playerTurn){ 763 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 764 | dangerMove = true; 765 | } 766 | else{ 767 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 768 | dangerMove = true; 769 | } 770 | } 771 | 772 | posCounter += 7; 773 | } 774 | 775 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 776 | 777 | 778 | if(!tmpPiece->getDangerMoves().empty()){ 779 | int collisions{0}; 780 | for(int j=0; jgetDangerMoves().size(); j++){ 781 | for(int i=0; i<16; i++){ 782 | if(tmpPiece->getDangerMoves().at(j) == blackPieces[i].getPosition()){ 783 | collisions++; 784 | if(!tmpPiece->getPlayer()) 785 | collisions++; 786 | } 787 | if(tmpPiece->getDangerMoves().at(j) == whitePieces[i].getPosition()){ 788 | collisions++; 789 | if(tmpPiece->getPlayer()) 790 | collisions++; 791 | } 792 | } 793 | } 794 | 795 | if(collisions > 2) 796 | tmpPiece->getDangerMoves().clear(); 797 | } 798 | 799 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPosition() ); 800 | 801 | } 802 | 803 | 804 | 805 | 806 | 807 | void ChessGame::calcRookMoves(Piece* tmpPiece){ 808 | 809 | int piecePos = tmpPiece->getPosition(); 810 | int posCounter{1}; 811 | 812 | bool dangerMove{false}; 813 | bool finishLoop{false}; 814 | 815 | tmpPiece->getPossibleMoves().clear(); 816 | tmpPiece->getDangerMoves().clear(); 817 | 818 | // Rook moves left on X axis 819 | while( ((piecePos-posCounter) >= 0) && ((piecePos/8) == ((piecePos-posCounter)/8)) ){ 820 | if(!finishLoop){ 821 | for(int i = 0; i<16; i++){ 822 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 823 | finishLoop = true; 824 | break; 825 | } 826 | } 827 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 828 | } 829 | 830 | if(!dangerMove){ 831 | // whitePieces[4] is white King , blackPieces[3] is black King 832 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 833 | if(!playerTurn){ 834 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 835 | dangerMove = true; 836 | } 837 | else{ 838 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 839 | dangerMove = true; 840 | } 841 | } 842 | 843 | posCounter += 1; 844 | } 845 | 846 | // Rook moves right on X axis 847 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 848 | finishLoop = false; 849 | posCounter = 1; 850 | while( (piecePos/8) == ((piecePos+posCounter)/8) ){ 851 | if(!finishLoop){ 852 | for(int i = 0; i<16; i++){ 853 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 854 | finishLoop = true; 855 | break; 856 | } 857 | } 858 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 859 | } 860 | 861 | if(!dangerMove){ 862 | // whitePieces[4] is white King , blackPieces[3] is black King 863 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 864 | if(!playerTurn){ 865 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 866 | dangerMove = true; 867 | } 868 | else{ 869 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 870 | dangerMove = true; 871 | } 872 | } 873 | 874 | posCounter += 1; 875 | } 876 | 877 | // Rook moves up on Y axis 878 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 879 | finishLoop = false; 880 | posCounter = 8; 881 | while(((piecePos-posCounter) >= 0) && (posCounter < 64) && ((piecePos%8) == ((piecePos-posCounter)%8)) ){ 882 | if(!finishLoop){ 883 | for(int i = 0; i<16; i++){ 884 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 885 | finishLoop = true; 886 | break; 887 | } 888 | } 889 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 890 | } 891 | 892 | if(!dangerMove){ 893 | // whitePieces[4] is white King , blackPieces[3] is black King 894 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 895 | if(!playerTurn){ 896 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 897 | dangerMove = true; 898 | } 899 | else{ 900 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 901 | dangerMove = true; 902 | } 903 | } 904 | 905 | posCounter += 8; 906 | } 907 | 908 | // Rook moves down on Y axis 909 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 910 | finishLoop = false; 911 | posCounter = 8; 912 | while(((piecePos+posCounter) <= 63) && (posCounter < 64) && ((piecePos%8) == ((piecePos+posCounter)%8)) ){ 913 | if(!finishLoop){ 914 | for(int i = 0; i<16; i++){ 915 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 916 | finishLoop = true; 917 | break; 918 | } 919 | } 920 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 921 | } 922 | 923 | if(!dangerMove){ 924 | // whitePieces[4] is white King , blackPieces[3] is black King 925 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 926 | if(!playerTurn){ 927 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 928 | dangerMove = true; 929 | } 930 | else{ 931 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 932 | dangerMove = true; 933 | } 934 | } 935 | 936 | posCounter += 8; 937 | } 938 | 939 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 940 | 941 | 942 | if(!tmpPiece->getDangerMoves().empty()){ 943 | int collisions{0}; 944 | for(int j=0; jgetDangerMoves().size(); j++){ 945 | for(int i=0; i<16; i++){ 946 | if(tmpPiece->getDangerMoves().at(j) == blackPieces[i].getPosition()){ 947 | collisions++; 948 | if(!tmpPiece->getPlayer()) 949 | collisions++; 950 | } 951 | if(tmpPiece->getDangerMoves().at(j) == whitePieces[i].getPosition()){ 952 | collisions++; 953 | if(tmpPiece->getPlayer()) 954 | collisions++; 955 | } 956 | } 957 | } 958 | 959 | if(collisions > 2) 960 | tmpPiece->getDangerMoves().clear(); 961 | } 962 | 963 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPosition() ); 964 | 965 | } 966 | 967 | 968 | 969 | 970 | 971 | void ChessGame::calcBishopMoves(Piece* tmpPiece){ 972 | 973 | //Normal Bishop Moving 974 | int piecePos{tmpPiece->getPosition()}; 975 | int posCounter{9}; 976 | 977 | bool dangerMove{false}; 978 | bool finishLoop{false}; 979 | 980 | tmpPiece->getPossibleMoves().clear(); 981 | tmpPiece->getDangerMoves().clear(); 982 | 983 | // Bishop moves towards top left 984 | while( ((piecePos-posCounter) >= 0) && (((piecePos-posCounter) % 8) < (piecePos % 8)) ){ 985 | if(!finishLoop){ 986 | for(int i = 0; i<16; i++){ 987 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 988 | finishLoop = true; 989 | break; 990 | } 991 | } 992 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 993 | } 994 | 995 | if(!dangerMove){ 996 | // whitePieces[4] is white King , blackPieces[3] is black King 997 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 998 | if(!playerTurn){ 999 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 1000 | dangerMove = true; 1001 | } 1002 | else{ 1003 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 1004 | dangerMove = true; 1005 | } 1006 | } 1007 | 1008 | posCounter += 9; 1009 | } 1010 | 1011 | // Bishop moves towards bottom right 1012 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 1013 | finishLoop = false; 1014 | posCounter = 9; 1015 | while( ((piecePos+posCounter) <= 63) && (((piecePos+posCounter) % 8) > (piecePos % 8)) ){ 1016 | if(!finishLoop){ 1017 | for(int i = 0; i<16; i++){ 1018 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 1019 | finishLoop = true; 1020 | break; 1021 | } 1022 | } 1023 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 1024 | } 1025 | 1026 | if(!dangerMove){ 1027 | // whitePieces[4] is white King , blackPieces[3] is black King 1028 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 1029 | if(!playerTurn){ 1030 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 1031 | dangerMove = true; 1032 | } 1033 | else{ 1034 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 1035 | dangerMove = true; 1036 | } 1037 | } 1038 | 1039 | posCounter += 9; 1040 | } 1041 | 1042 | // Bishop moves towards top right 1043 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 1044 | finishLoop = false; 1045 | posCounter = 7; 1046 | while( ((piecePos-posCounter) >= 0) && (((piecePos-posCounter) % 8) > (piecePos % 8)) ){ 1047 | if(!finishLoop){ 1048 | for(int i = 0; i<16; i++){ 1049 | if( (whitePieces[i].getPosition() == (piecePos-posCounter)) || (blackPieces[i].getPosition() == (piecePos-posCounter)) ){ 1050 | finishLoop = true; 1051 | break; 1052 | } 1053 | } 1054 | tmpPiece->getPossibleMoves().push_back(piecePos-posCounter); 1055 | } 1056 | 1057 | if(!dangerMove){ 1058 | // whitePieces[4] is white King , blackPieces[3] is black King 1059 | tmpPiece->getDangerMoves().push_back(piecePos-posCounter); 1060 | if(!playerTurn){ 1061 | if( (piecePos-posCounter) == blackPieces[3].getPosition() ) 1062 | dangerMove = true; 1063 | } 1064 | else{ 1065 | if( (piecePos-posCounter) == whitePieces[4].getPosition() ) 1066 | dangerMove = true; 1067 | } 1068 | } 1069 | 1070 | posCounter += 7; 1071 | } 1072 | 1073 | // Bishop moves towards bottom left 1074 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 1075 | finishLoop = false; 1076 | posCounter = 7; 1077 | while( ((piecePos+posCounter) <= 63) && (((piecePos+posCounter) % 8) < (piecePos % 8)) ){ 1078 | if(!finishLoop){ 1079 | for(int i = 0; i<16; i++){ 1080 | if( (whitePieces[i].getPosition() == (piecePos+posCounter)) || (blackPieces[i].getPosition() == (piecePos+posCounter)) ){ 1081 | finishLoop = true; 1082 | break; 1083 | } 1084 | } 1085 | tmpPiece->getPossibleMoves().push_back(piecePos+posCounter); 1086 | } 1087 | 1088 | if(!dangerMove){ 1089 | // whitePieces[4] is white King , blackPieces[3] is black King 1090 | tmpPiece->getDangerMoves().push_back(piecePos+posCounter); 1091 | if(!playerTurn){ 1092 | if( (piecePos+posCounter) == blackPieces[3].getPosition() ) 1093 | dangerMove = true; 1094 | } 1095 | else{ 1096 | if( (piecePos+posCounter) == whitePieces[4].getPosition() ) 1097 | dangerMove = true; 1098 | } 1099 | } 1100 | 1101 | posCounter += 7; 1102 | } 1103 | 1104 | if(!dangerMove) tmpPiece->getDangerMoves().clear(); 1105 | 1106 | 1107 | if(!tmpPiece->getDangerMoves().empty()){ 1108 | int collisions{0}; 1109 | for(int j=0; jgetDangerMoves().size(); j++){ 1110 | for(int i=0; i<16; i++){ 1111 | if(tmpPiece->getDangerMoves().at(j) == blackPieces[i].getPosition()){ 1112 | collisions++; 1113 | if(!tmpPiece->getPlayer()) 1114 | collisions++; 1115 | } 1116 | if(tmpPiece->getDangerMoves().at(j) == whitePieces[i].getPosition()){ 1117 | collisions++; 1118 | if(tmpPiece->getPlayer()) 1119 | collisions++; 1120 | } 1121 | } 1122 | } 1123 | 1124 | if(collisions > 2) 1125 | tmpPiece->getDangerMoves().clear(); 1126 | } 1127 | 1128 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPosition() ); 1129 | 1130 | 1131 | } 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | void ChessGame::calcKnightMoves(Piece* tmpPiece){ 1138 | 1139 | tmpPiece->getPossibleMoves().clear(); 1140 | 1141 | int piecePos{tmpPiece->getPosition()}; 1142 | 1143 | if((piecePos / 8) != 0 ){ 1144 | if((piecePos % 8) >= 2 ) 1145 | tmpPiece->getPossibleMoves().push_back(piecePos - 10); 1146 | if( (piecePos % 8) <= 5 ) 1147 | tmpPiece->getPossibleMoves().push_back(piecePos - 6); 1148 | if((piecePos / 8) != 1){ 1149 | if((piecePos % 8) >= 1 ) 1150 | tmpPiece->getPossibleMoves().push_back(piecePos - 17); 1151 | if((piecePos % 8) <= 6 ) 1152 | tmpPiece->getPossibleMoves().push_back(piecePos - 15); 1153 | } 1154 | } 1155 | if((piecePos / 8) != 7){ 1156 | if((piecePos % 8) >= 2 ) 1157 | tmpPiece->getPossibleMoves().push_back(piecePos + 6); 1158 | if( (piecePos % 8) <= 5 ) 1159 | tmpPiece->getPossibleMoves().push_back(piecePos + 10); 1160 | if((piecePos / 8) != 6){ 1161 | if((piecePos % 8) >= 1 ) 1162 | tmpPiece->getPossibleMoves().push_back(piecePos + 15); 1163 | if((piecePos % 8) <= 6 ) 1164 | tmpPiece->getPossibleMoves().push_back(piecePos + 17); 1165 | } 1166 | } 1167 | 1168 | tmpPiece->getDangerMoves().clear(); 1169 | 1170 | for(int i = 0; i < tmpPiece->getPossibleMoves().size(); i++){ 1171 | 1172 | if(!playerTurn){ 1173 | if( (tmpPiece->getPossibleMoves().at(i)) == blackPieces[3].getPosition() ) 1174 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPossibleMoves().at(i) ); 1175 | } 1176 | else{ 1177 | if( (tmpPiece->getPossibleMoves().at(i)) == whitePieces[4].getPosition() ) 1178 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPossibleMoves().at(i) ); 1179 | } 1180 | 1181 | } 1182 | 1183 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPosition() ); 1184 | 1185 | } 1186 | 1187 | 1188 | 1189 | 1190 | void ChessGame::calcPawnMoves(Piece* tmpPiece){ 1191 | 1192 | 1193 | tmpPiece->getPossibleMoves().clear(); 1194 | 1195 | int piecePos{tmpPiece->getPosition()}; 1196 | 1197 | if (tmpPiece->getPlayer()){ // If pawn is white 1198 | if((piecePos / 8) != 0){ 1199 | int i{0}; 1200 | for(i = 0; i<16;i++){ 1201 | if((whitePieces[i].getPosition() == (piecePos - 8) ) || (blackPieces[i].getPosition() == (piecePos - 8) )) 1202 | break; 1203 | } 1204 | if((i == 16) && playerTurn){ 1205 | tmpPiece->getPossibleMoves().push_back(piecePos - 8); 1206 | 1207 | if(!tmpPiece->getMoved()){ 1208 | for(i = 0; i<16;i++){ 1209 | if((whitePieces[i].getPosition() == (piecePos - 16) ) || (blackPieces[i].getPosition() == (piecePos - 16) )) 1210 | break; 1211 | } 1212 | if(i == 16) 1213 | tmpPiece->getPossibleMoves().push_back(piecePos - 16); 1214 | } 1215 | } 1216 | 1217 | if((piecePos % 8) != 0){ 1218 | for(i = 0; i<16; i++){ 1219 | if( !playerTurn || (blackPieces[i].getPosition() == (piecePos - 9)) || (whitePieces[i].getPosition() == (piecePos - 9)) ){ 1220 | tmpPiece->getPossibleMoves().push_back(piecePos - 9); 1221 | break; 1222 | } 1223 | else if((blackPieces[i].getEnPassant() == (piecePos - 9)) && (blackPieces[i].getEnPassant() != -1)){ 1224 | tmpPiece->getPossibleMoves().push_back(piecePos - 9); 1225 | break; 1226 | } 1227 | } 1228 | } 1229 | 1230 | if((piecePos % 8) != 7){ 1231 | for(i = 0; i<16; i++){ 1232 | if( !playerTurn || (blackPieces[i].getPosition() == (piecePos - 7)) || (whitePieces[i].getPosition() == (piecePos - 7)) ){ 1233 | tmpPiece->getPossibleMoves().push_back(piecePos - 7); 1234 | break; 1235 | } 1236 | else if((blackPieces[i].getEnPassant() == (piecePos - 7)) && (blackPieces[i].getEnPassant() != -1)){ 1237 | tmpPiece->getPossibleMoves().push_back(piecePos - 7); 1238 | break; 1239 | } 1240 | } 1241 | } 1242 | 1243 | } 1244 | else{ // MUST PROMOTE PAWN 1245 | tmpPiece->setPiece('Q', tmpPiece->getPlayer(), tmpPiece->getPosition(), true); 1246 | calcQueenMoves(tmpPiece); 1247 | return; 1248 | } 1249 | 1250 | 1251 | } 1252 | else{ //if pawn is black 1253 | 1254 | if((piecePos / 8) != 7){ 1255 | int i{0}; 1256 | for(i = 0; i<16;i++){ 1257 | if((whitePieces[i].getPosition() == (piecePos + 8) ) || (blackPieces[i].getPosition() == (piecePos + 8) )) 1258 | break; 1259 | } 1260 | if((i == 16) && !playerTurn){ 1261 | tmpPiece->getPossibleMoves().push_back(piecePos + 8); 1262 | 1263 | if(!tmpPiece->getMoved()){ 1264 | for(i = 0; i<16;i++){ 1265 | if((whitePieces[i].getPosition() == (piecePos + 16) ) || (blackPieces[i].getPosition() == (piecePos + 16) )) 1266 | break; 1267 | } 1268 | if(i == 16) 1269 | tmpPiece->getPossibleMoves().push_back(piecePos + 16); 1270 | } 1271 | } 1272 | 1273 | if((piecePos % 8) != 0){ 1274 | for(i = 0; i<16; i++){ 1275 | if( playerTurn || (whitePieces[i].getPosition() == (piecePos + 7)) || (blackPieces[i].getPosition() == (piecePos + 7)) ){ 1276 | tmpPiece->getPossibleMoves().push_back(piecePos + 7); 1277 | break; 1278 | } 1279 | else if((whitePieces[i].getEnPassant() == (piecePos + 7)) && (whitePieces[i].getEnPassant() != -1)){ 1280 | tmpPiece->getPossibleMoves().push_back(piecePos + 7); 1281 | break; 1282 | } 1283 | } 1284 | } 1285 | 1286 | if((piecePos % 8) != 7){ 1287 | for(i = 0; i<16; i++){ 1288 | if( playerTurn || (whitePieces[i].getPosition() == (piecePos + 9)) || (blackPieces[i].getPosition() == (piecePos + 9)) ){ 1289 | tmpPiece->getPossibleMoves().push_back(piecePos + 9); 1290 | break; 1291 | } 1292 | else if((whitePieces[i].getEnPassant() == (piecePos + 9)) && (whitePieces[i].getEnPassant() != -1)){ 1293 | tmpPiece->getPossibleMoves().push_back(piecePos + 9); 1294 | break; 1295 | } 1296 | } 1297 | } 1298 | 1299 | } 1300 | else{ // MUST PROMOTE PAWN 1301 | tmpPiece->setPiece('Q', tmpPiece->getPlayer(), tmpPiece->getPosition(), true); 1302 | calcQueenMoves(tmpPiece); 1303 | return; 1304 | } 1305 | } 1306 | 1307 | tmpPiece->getDangerMoves().clear(); 1308 | 1309 | for(int i = 0; i < tmpPiece->getPossibleMoves().size(); i++){ 1310 | 1311 | if(!playerTurn){ 1312 | if( (tmpPiece->getPossibleMoves().at(i)) == blackPieces[3].getPosition() ) 1313 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPossibleMoves().at(i) ); 1314 | } 1315 | else{ 1316 | if( (tmpPiece->getPossibleMoves().at(i)) == whitePieces[4].getPosition() ) 1317 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPossibleMoves().at(i) ); 1318 | } 1319 | 1320 | } 1321 | 1322 | tmpPiece->getDangerMoves().push_back( tmpPiece->getPosition() ); 1323 | 1324 | } 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | void ChessGame::calcCastling(Piece* tmpPiece){ 1331 | 1332 | if( playerTurnCheck || (tmpPiece->getType() != 'K') || tmpPiece->getMoved() || (tmpPiece->getPlayer() != playerTurn)) 1333 | return; 1334 | 1335 | 1336 | if(tmpPiece->getPlayer()){ // If White King 1337 | // whitePieces[0] Bot Left Rook, whitePieces[7] Bot Right Rook 1338 | if(!whitePieces[7].getMoved()){ 1339 | int i{0}; 1340 | for(i=0;i<16;i++){ 1341 | if((whitePieces[i].getPosition() == 61) || (whitePieces[i].getPosition() == 62)){ 1342 | i=17; 1343 | break; 1344 | } 1345 | if((blackPieces[i].getPosition() == 61) || (blackPieces[i].getPosition() == 62)){ 1346 | i = 17; 1347 | break; 1348 | } 1349 | } 1350 | if(i == 16){ 1351 | for(i=0; i<16; i++){ 1352 | for(int j=0; jgetPossibleMoves().push_back(62); 1364 | } 1365 | } 1366 | 1367 | if(!whitePieces[0].getMoved()){ 1368 | int i{0}; 1369 | for(i=0;i<16;i++){ 1370 | if((whitePieces[i].getPosition() == 57) || (whitePieces[i].getPosition() == 58) || (whitePieces[i].getPosition() == 59)){ 1371 | i=17; 1372 | break; 1373 | } 1374 | if((blackPieces[i].getPosition() == 57) || (blackPieces[i].getPosition() == 58) || (blackPieces[i].getPosition() == 59)){ 1375 | i =17; 1376 | break; 1377 | } 1378 | } 1379 | if(i == 16){ 1380 | for(i=0; i<16; i++){ 1381 | for(int j=0; jgetPossibleMoves().push_back(58); 1392 | } 1393 | } 1394 | } 1395 | else{ // If Black King 1396 | // blackPieces[7] Top Left Rook, blackPieces[0] Top Right Rook 1397 | if(!blackPieces[7].getMoved()){ 1398 | int i{0}; 1399 | for(i=0;i<16;i++){ 1400 | if((whitePieces[i].getPosition() == 3) || (whitePieces[i].getPosition() == 2) || (whitePieces[i].getPosition() == 1)){ 1401 | i=17; 1402 | break; 1403 | } 1404 | if((blackPieces[i].getPosition() == 3) || (blackPieces[i].getPosition() == 2) || (blackPieces[i].getPosition() == 1)){ 1405 | i=17; 1406 | break; 1407 | } 1408 | } 1409 | if(i == 16){ 1410 | for(i=0; i<16; i++){ 1411 | for(int j=0; jgetPossibleMoves().push_back(2); 1422 | } 1423 | } 1424 | 1425 | if(!blackPieces[0].getMoved()){ 1426 | int i{0}; 1427 | for(i=0;i<16;i++){ 1428 | if((whitePieces[i].getPosition() == 5) || (whitePieces[i].getPosition() == 6)){ 1429 | i=17; 1430 | break; 1431 | } 1432 | if((blackPieces[i].getPosition() == 5) || (blackPieces[i].getPosition() == 6)){ 1433 | i=17; 1434 | break; 1435 | } 1436 | } 1437 | if(i == 16){ 1438 | for(i=0; i<16; i++){ 1439 | for(int j=0; jgetPossibleMoves().push_back(6); 1450 | } 1451 | } 1452 | } 1453 | } 1454 | 1455 | 1456 | 1457 | 1458 | void ChessGame::checkMate(){ 1459 | // No more than two piece can check a King. 1460 | // A single check can be unchecked either by the King moving to 1461 | // a square that is not attacked, or if another piece blocks/kills the attacking piece 1462 | // A double check can be unchecked only by moving the checked King 1463 | 1464 | Piece* check1{NULL}; 1465 | Piece* check2{NULL}; 1466 | 1467 | // Check if current player's King is in check 1468 | // whitePieces[4] is white King , blackPieces[3] is black King 1469 | for(int i = 0; i<16; i++){ 1470 | if(playerTurn){ // White turn 1471 | for(int j=0; j < blackPieces[i].getPossibleMoves().size(); j++){ 1472 | if(whitePieces[4].getPosition() == blackPieces[i].getPossibleMoves().at(j)){ 1473 | if(check1 == NULL){ 1474 | playerTurnCheck = true; 1475 | check1 = &blackPieces[i]; 1476 | break; 1477 | } 1478 | else if(check2 == NULL){ 1479 | //playerTurnCheck = true; 1480 | check2 = &blackPieces[i]; 1481 | break; 1482 | } 1483 | } 1484 | } 1485 | } 1486 | else{ // Black turn 1487 | for(int j=0; j < whitePieces[i].getPossibleMoves().size(); j++){ 1488 | if(blackPieces[3].getPosition() == whitePieces[i].getPossibleMoves().at(j)){ 1489 | if(check1 == NULL){ 1490 | playerTurnCheck = true; 1491 | check1 = &whitePieces[i]; 1492 | break; 1493 | } 1494 | else if(check2 == NULL){ 1495 | //playerTurnCheck = true; 1496 | check2 = &whitePieces[i]; 1497 | break; 1498 | } 1499 | } 1500 | } 1501 | } 1502 | 1503 | if(check2 != NULL) 1504 | break; 1505 | } 1506 | 1507 | // Check which current player pieces moves put its King out of check 1508 | // If no moves then Check Mate, current player loses 1509 | if(playerTurnCheck){ 1510 | if(check2 != NULL){ // If double check, clear current player's pieces moves except king's 1511 | if(playerTurn) 1512 | for(int i=0; i<16; i++) 1513 | if(whitePieces[i].getType() != 'K') 1514 | whitePieces[i].getPossibleMoves().clear(); 1515 | else 1516 | for(int i=0; i<16; i++) 1517 | if(blackPieces[i].getType() != 'K') 1518 | blackPieces[i].getPossibleMoves().clear(); 1519 | } 1520 | else{ // If single check 1521 | 1522 | for(int j=0; j<16; j++){ // pieces array counter 1523 | std::vector tmpMoves; 1524 | 1525 | if(playerTurn){ // If White turn 1526 | if(whitePieces[j].getType() == 'K') 1527 | continue; 1528 | for(int o = 0; o < whitePieces[j].getPossibleMoves().size(); o++){ 1529 | if(whitePieces[j].getPossibleMoves().empty()) 1530 | break; 1531 | for(int i=0; i < check1->getDangerMoves().size(); i++){ // Checking piece moves counter 1532 | if((whitePieces[j].getPossibleMoves().at(o) == check1->getDangerMoves().at(i)) ){ 1533 | tmpMoves.push_back( whitePieces[j].getPossibleMoves().at(o) ); 1534 | break; 1535 | } 1536 | } 1537 | } 1538 | 1539 | whitePieces[j].getPossibleMoves().clear(); 1540 | whitePieces[j].getPossibleMoves() = tmpMoves; 1541 | } 1542 | else{ // If Black turn 1543 | if(blackPieces[j].getType() == 'K') 1544 | continue; 1545 | for(int o = 0; o < blackPieces[j].getPossibleMoves().size(); o++){ 1546 | if(blackPieces[j].getPossibleMoves().empty()) 1547 | break; 1548 | for(int i=0; i < check1->getDangerMoves().size(); i++){ // Checking piece moves counter 1549 | if((blackPieces[j].getPossibleMoves().at(o) == check1->getDangerMoves().at(i)) ){ 1550 | tmpMoves.push_back( blackPieces[j].getPossibleMoves().at(o) ); 1551 | break; 1552 | } 1553 | } 1554 | } 1555 | blackPieces[j].getPossibleMoves().clear(); 1556 | blackPieces[j].getPossibleMoves() = tmpMoves; 1557 | } 1558 | } 1559 | } 1560 | 1561 | 1562 | //Bug fix 1563 | // whitePieces[4] is white King , blackPieces[3] is black King 1564 | Piece* curKing; 1565 | if(playerTurn){ 1566 | curKing = &whitePieces[4]; 1567 | } 1568 | else{ 1569 | curKing = &blackPieces[3]; 1570 | } 1571 | if(check1 != NULL){ 1572 | if((check1->getType() == 'Q') || (check1->getType() == 'R' || (check1->getType() == 'B'))){ 1573 | int checkPos{check1->getPosition()}; 1574 | 1575 | if((check1->getType() == 'Q') || (check1->getType() == 'R')){ 1576 | for(int i=0; i< curKing->getPossibleMoves().size(); i++){ 1577 | if(curKing->getPossibleMoves().at(i) != checkPos){ 1578 | if ((curKing->getPossibleMoves().at(i) % 8) == (checkPos % 8)) 1579 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1580 | else if((curKing->getPossibleMoves().at(i) / 8) == (checkPos / 8)) 1581 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1582 | } 1583 | } 1584 | } 1585 | 1586 | for(int i=0; i< curKing->getPossibleMoves().size(); i++){ 1587 | if(curKing->getPossibleMoves().at(i) != checkPos){ 1588 | if((curKing->getPosition()%8) < (checkPos%8)){ // King left of Check 1589 | if((curKing->getPosition()/8) < (checkPos/8)){ // King top of Check 1590 | if( ((curKing->getPossibleMoves().at(i)%8) < (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) < (curKing->getPosition()/8)) ) 1591 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1592 | } 1593 | else if((checkPos/8) < (curKing->getPosition()/8)){ // King under Check 1594 | if( ((curKing->getPossibleMoves().at(i)%8) < (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) > (curKing->getPosition()/8)) ) 1595 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1596 | } 1597 | } 1598 | else if((checkPos%8) < (curKing->getPosition()%8) ){ // King right of Check 1599 | if((curKing->getPosition()/8) < (checkPos/8)){ // King top of Check 1600 | if( ((curKing->getPossibleMoves().at(i)%8) > (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) < (curKing->getPosition()/8)) ) 1601 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1602 | } 1603 | else if((checkPos/8) < (curKing->getPosition()/8)){ // King under Check 1604 | if( ((curKing->getPossibleMoves().at(i)%8) > (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) > (curKing->getPosition()/8)) ) 1605 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1606 | } 1607 | } 1608 | } 1609 | } 1610 | } 1611 | } 1612 | //Bug fix 1613 | if(check2 != NULL){ 1614 | if((check2->getType() == 'Q') || (check2->getType() == 'R' || (check2->getType() == 'B'))){ 1615 | int checkPos{check2->getPosition()}; 1616 | 1617 | if((check2->getType() == 'Q') || (check2->getType() == 'R')){ 1618 | for(int i=0; i< curKing->getPossibleMoves().size(); i++){ 1619 | if(curKing->getPossibleMoves().at(i) != checkPos){ 1620 | if ((curKing->getPossibleMoves().at(i) % 8) == (checkPos % 8)) 1621 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1622 | else if((curKing->getPossibleMoves().at(i) / 8) == (checkPos / 8)) 1623 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1624 | } 1625 | } 1626 | } 1627 | 1628 | for(int i=0; i< curKing->getPossibleMoves().size(); i++){ 1629 | if(curKing->getPossibleMoves().at(i) != checkPos){ 1630 | if((curKing->getPosition()%8) < (checkPos%8)){ // King left of Check 1631 | if((curKing->getPosition()/8) < (checkPos/8)){ // King top of Check 1632 | if( ((curKing->getPossibleMoves().at(i)%8) < (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) < (curKing->getPosition()/8)) ) 1633 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1634 | } 1635 | else if((checkPos/8) < (curKing->getPosition()/8)){ // King under Check 1636 | if( ((curKing->getPossibleMoves().at(i)%8) < (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) > (curKing->getPosition()/8)) ) 1637 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1638 | } 1639 | } 1640 | else if((checkPos%8) < (curKing->getPosition()%8) ){ // King right of Check 1641 | if((curKing->getPosition()/8) < (checkPos/8)){ // King top of Check 1642 | if( ((curKing->getPossibleMoves().at(i)%8) > (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) < (curKing->getPosition()/8)) ) 1643 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1644 | } 1645 | else if((checkPos/8) < (curKing->getPosition()/8)){ // King under Check 1646 | if( ((curKing->getPossibleMoves().at(i)%8) > (curKing->getPosition()%8)) && ((curKing->getPossibleMoves().at(i)/8) > (curKing->getPosition()/8)) ) 1647 | curKing->getPossibleMoves().erase( curKing->getPossibleMoves().begin() + i--); 1648 | } 1649 | } 1650 | } 1651 | } 1652 | } 1653 | } 1654 | 1655 | } 1656 | else{ 1657 | calcCastling(&whitePieces[4]); 1658 | calcCastling(&blackPieces[3]); 1659 | } 1660 | 1661 | // Check if current player has any available moves 1662 | int i{0}; 1663 | for(i=0; i<16; i++){ 1664 | if(playerTurn){ 1665 | if(!whitePieces[i].getPossibleMoves().empty()) 1666 | break; 1667 | } 1668 | else{ 1669 | if(!blackPieces[i].getPossibleMoves().empty()) 1670 | break; 1671 | } 1672 | } 1673 | if(i==16){ 1674 | mate = true; 1675 | } 1676 | 1677 | } -------------------------------------------------------------------------------- /src/chessGame.h: -------------------------------------------------------------------------------- 1 | /* 2 | This header file contains th ChessGame class. 3 | contains the whole game. 4 | */ 5 | 6 | #ifndef _CHESSGAME_H 7 | #define _CHESSGAME_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "board.h" 14 | #include "piece.h" 15 | 16 | class ChessGame: public sf::Drawable{ 17 | private: 18 | Board board; 19 | std::array whitePieces; 20 | std::array blackPieces; 21 | Piece* selectedPiece; 22 | std::vector possibleMovesSquares; 23 | std::string lastMove; 24 | 25 | sf::RectangleShape infoRestart; 26 | 27 | sf::Font font; 28 | sf::Text textRestart; 29 | sf::Text textTurn; 30 | sf::Text textSituation; 31 | sf::Text textLastMove; 32 | 33 | 34 | bool selected; 35 | bool playerTurn; // true = White turn, false = Black Turn 36 | bool playerTurnCheck; 37 | bool mate; 38 | int turn; 39 | 40 | void createMovesSquares(); 41 | 42 | void calcPossibleMoves(); 43 | void calcKingMoves(Piece* tmpPiece); 44 | void calcQueenMoves(Piece* tmpPiece); 45 | void calcRookMoves(Piece* tmpPiece); 46 | void calcBishopMoves(Piece* tmpPiece); 47 | void calcKnightMoves(Piece* tmpPiece); 48 | void calcPawnMoves(Piece* tmpPiece); 49 | void calcCastling(Piece* tmpPiece); 50 | 51 | void eraseMoves(Piece* tmpPiece); 52 | 53 | void checkMate(); 54 | 55 | void updateInfo(); 56 | 57 | virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; 58 | 59 | public: 60 | ChessGame(sf::Color bordCol1, sf::Color bordCol2); 61 | 62 | bool getSelected(){return selected;} 63 | 64 | bool getMate(){return mate;} 65 | 66 | bool selectPiece(int pos); 67 | 68 | void moveSelected(int pos); 69 | 70 | void restart(); 71 | 72 | 73 | 74 | }; 75 | 76 | 77 | #endif -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This code file (main.cpp) contains the main function that runs the game 3 | all libraries that must be used have to be included here. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "chessGame.h" 9 | 10 | 11 | int main(){ 12 | ChessGame chess(sf::Color(0xf3bc7aff),sf::Color(0xae722bff)); 13 | 14 | sf::RenderWindow window(sf::VideoMode(768,512), "Chess", sf::Style::Titlebar | sf::Style::Close); 15 | window.setVerticalSyncEnabled(true); 16 | 17 | while(window.isOpen()){ 18 | 19 | sf::Event event; 20 | 21 | while(window.pollEvent(event)){ 22 | 23 | if(event.type == sf::Event::Closed) 24 | window.close(); 25 | 26 | if(event.type == sf::Event::MouseButtonPressed){ 27 | if(event.mouseButton.button == sf::Mouse::Left){ 28 | if((0 <= event.mouseButton.x) && (event.mouseButton.x <= 512) && (0 <= event.mouseButton.y) && (event.mouseButton.y <= 512)){ 29 | unsigned int buttonPos{(event.mouseButton.x/64) + ((event.mouseButton.y/64) * (8 * (512/window.getSize().y)))}; 30 | 31 | if(!chess.getSelected()) 32 | chess.selectPiece(buttonPos); 33 | else 34 | chess.moveSelected(buttonPos); 35 | } 36 | else if((517 <= event.mouseButton.x) && (event.mouseButton.x <= 763) && (5 <= event.mouseButton.y) && (event.mouseButton.y <= 45)){ 37 | chess.restart(); 38 | } 39 | } 40 | } 41 | } 42 | 43 | window.draw(chess); 44 | window.display(); 45 | } 46 | } -------------------------------------------------------------------------------- /src/piece.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This code file contains member functions of piece.h 3 | */ 4 | 5 | #include "piece.h" 6 | 7 | void Piece::setPiece(char type, bool player, int pos, bool moved){ 8 | setType(type); 9 | setPlayer(player); 10 | setPosition(pos); //m_moved true 11 | setMoved(moved); // m_moved false 12 | } 13 | 14 | std::string Piece::toString(){ 15 | std::string str; 16 | 17 | str += m_player?"White ":"Black "; 18 | 19 | switch (m_type) 20 | { 21 | case 'K': 22 | str += "King "; 23 | break; 24 | case 'Q': 25 | str += "Queen "; 26 | break; 27 | case 'R': 28 | str += "Rook "; 29 | break; 30 | case 'B': 31 | str += "Bishop "; 32 | break; 33 | case 'N': 34 | str += "Knight "; 35 | break; 36 | case 'P': 37 | str += "Pawn "; 38 | break; 39 | default: 40 | str += "??? "; 41 | break; 42 | } 43 | 44 | str += "\nto position\nX: "; 45 | str += std::to_string((m_position%8)+1); 46 | str += " Y: "; 47 | str += std::to_string((m_position/8)+1); 48 | str += '\n'; 49 | 50 | 51 | return str; 52 | 53 | } 54 | 55 | void Piece::move(){ 56 | if(m_position<=-1 || 64<=m_position){ 57 | m_position = -1; 58 | m_sprite.setColor(sf::Color(0x00000000)); 59 | m_sprite.setPosition(sf::Vector2f((m_position % 8) * 64.f + 32.f, (m_position / 8) * 64.f + 32.f)); 60 | possibleMoves.clear(); 61 | m_moved = true; 62 | } 63 | else{ 64 | m_sprite.setPosition(sf::Vector2f((m_position % 8) * 64.f + 32.f, (m_position / 8) * 64.f + 32.f)); 65 | m_moved = true; 66 | } 67 | return; 68 | } 69 | 70 | void Piece::setTexture(){ 71 | m_sprite = sf::Sprite(); 72 | switch (m_type) 73 | { 74 | case 'K': 75 | m_sprite.setTexture(m_player ? PieceTextures::whiteKing : PieceTextures::blackKing); 76 | break; 77 | case 'Q': 78 | m_sprite.setTexture(m_player ? PieceTextures::whiteQueen : PieceTextures::blackQueen); 79 | break; 80 | case 'R': 81 | m_sprite.setTexture(m_player ? PieceTextures::whiteRook : PieceTextures::blackRook); 82 | break; 83 | case 'B': 84 | m_sprite.setTexture(m_player ? PieceTextures::whiteBishop : PieceTextures::blackBishop); 85 | break; 86 | case 'N': 87 | m_sprite.setTexture(m_player ? PieceTextures::whiteKnight : PieceTextures::blackKnight); 88 | break; 89 | case 'P': 90 | m_sprite.setTexture(m_player ? PieceTextures::whitePawn : PieceTextures::blackPawn); 91 | break; 92 | default: 93 | std::cerr << "Error piece type does not exist.\n"; 94 | break; 95 | } 96 | m_sprite.setOrigin(sf::Vector2f(m_sprite.getTexture()->getSize().x/2 , m_sprite.getTexture()->getSize().y/2)); 97 | m_sprite.setScale(sf::Vector2f(0.375f,0.375f)); 98 | } -------------------------------------------------------------------------------- /src/piece.h: -------------------------------------------------------------------------------- 1 | /* 2 | This header file contains the Piece class. 3 | */ 4 | 5 | #ifndef _PIECE_H 6 | #define _PIECE_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "pieceTextures.h" 13 | 14 | class Piece : public sf::Drawable{ 15 | 16 | public: 17 | 18 | Piece(char type='P', bool player=true, int pos=-1, bool moved=false) 19 | : m_type{type}, m_player{player}, 20 | m_position{-1}, m_moved{true}, enPassant{-1} 21 | { } 22 | 23 | void setPiece(char type, bool player, int pos, bool moved=false); 24 | 25 | void setType(char ch){m_type = ch; setTexture();} 26 | char getType() {return m_type;} 27 | 28 | void setPlayer(bool bl){m_player = bl; setTexture();} 29 | bool getPlayer() {return m_player;} 30 | 31 | void setPosition(int pos){m_position = pos; move();} 32 | int getPosition() {return m_position;} 33 | 34 | void setMoved(bool moved){m_moved = moved;} 35 | bool getMoved() {return m_moved;} 36 | 37 | void setEnPassant(int x){enPassant = x;} 38 | int getEnPassant() {return enPassant;} 39 | 40 | std::vector& getPossibleMoves(){return possibleMoves;} 41 | std::vector& getDangerMoves(){return dangerMoves;} 42 | 43 | std::string toString(); 44 | 45 | private: 46 | sf::Sprite m_sprite; 47 | std::vector possibleMoves; 48 | std::vector dangerMoves; // Moves that endanger opposite king 49 | 50 | char m_type; //'K'=King , 'Q' = Queen , 'R' = Rook , 'B' = Bishop , 'N' = Knight , 'P' = Pawn 51 | bool m_player; // true == White , false == Black 52 | int m_position; // 0-63 board, -1 dead 53 | int enPassant; 54 | bool m_moved; 55 | 56 | void setTexture(); 57 | void move(); 58 | 59 | virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const 60 | { target.draw(m_sprite); } 61 | }; 62 | 63 | #endif -------------------------------------------------------------------------------- /src/pieceTextures.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This code file contains static member initialisations 3 | of pieceTextures.h 4 | */ 5 | 6 | #include "pieceTextures.h" 7 | 8 | sf::Texture PieceTextures::loadTexture(std::string str){ 9 | sf::Texture tmp; 10 | if (!tmp.loadFromFile(str)) 11 | std::cout << "Error loading file\n"; 12 | return tmp; 13 | } 14 | 15 | sf::Texture PieceTextures::blackKing = PieceTextures::loadTexture("Textures/b_king.png"); 16 | sf::Texture PieceTextures::blackQueen = PieceTextures::loadTexture("Textures/b_queen.png"); 17 | sf::Texture PieceTextures::blackRook = PieceTextures::loadTexture("Textures/b_rook.png"); 18 | sf::Texture PieceTextures::blackKnight = PieceTextures::loadTexture("Textures/b_knight.png"); 19 | sf::Texture PieceTextures::blackBishop = PieceTextures::loadTexture("Textures/b_bishop.png"); 20 | sf::Texture PieceTextures::blackPawn = PieceTextures::loadTexture("Textures/b_pawn.png"); 21 | 22 | sf::Texture PieceTextures::whiteKing = PieceTextures::loadTexture("Textures/w_king.png"); 23 | sf::Texture PieceTextures::whiteQueen = PieceTextures::loadTexture("Textures/w_queen.png"); 24 | sf::Texture PieceTextures::whiteRook = PieceTextures::loadTexture("Textures/w_rook.png"); 25 | sf::Texture PieceTextures::whiteKnight = PieceTextures::loadTexture("Textures/w_knight.png"); 26 | sf::Texture PieceTextures::whiteBishop = PieceTextures::loadTexture("Textures/w_bishop.png"); 27 | sf::Texture PieceTextures::whitePawn = PieceTextures::loadTexture("Textures/w_pawn.png"); 28 | -------------------------------------------------------------------------------- /src/pieceTextures.h: -------------------------------------------------------------------------------- 1 | /* 2 | This header file contains the PieceTextures class. 3 | */ 4 | 5 | #ifndef _PIECE_TEXTURES_H 6 | #define _PIECE_TEXTURES_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | class PieceTextures{ 13 | public: 14 | static sf::Texture blackKing; 15 | static sf::Texture blackQueen; 16 | static sf::Texture blackRook; 17 | static sf::Texture blackKnight; 18 | static sf::Texture blackBishop; 19 | static sf::Texture blackPawn; 20 | 21 | static sf::Texture whiteKing; 22 | static sf::Texture whiteQueen; 23 | static sf::Texture whiteRook; 24 | static sf::Texture whiteKnight; 25 | static sf::Texture whiteBishop; 26 | static sf::Texture whitePawn; 27 | 28 | static sf::Texture loadTexture(std::string str); 29 | }; 30 | 31 | #endif --------------------------------------------------------------------------------