Skip to content

Commit

Permalink
major refactoring
Browse files Browse the repository at this point in the history
highlight selected piece
unhighlight and cancel selection with esc
add files for webassembly build
  • Loading branch information
spiroskou committed Aug 22, 2024
1 parent de5adaf commit aad4217
Show file tree
Hide file tree
Showing 24 changed files with 10,519 additions and 155 deletions.
17 changes: 8 additions & 9 deletions Board/Board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static PieceColor getOpponentColor()
return PieceColor::White;
}

static PieceColor getColor()
PieceColor getCurrentPlayerColor()
{
if (turn_counter % 2 != 0) {
return PieceColor::White;
Expand Down Expand Up @@ -230,7 +230,7 @@ int Board::checkForPromotion(int dest_row, int dest_col)
if (!tmp_piece) return 0;

if (tmp_piece->getType() == PieceType::Pawn && (dest_row == 0 || dest_row == 7)) {
setPiece(dest_row, dest_col, std::make_shared<Queen>(getColor()));
setPiece(dest_row, dest_col, std::make_shared<Queen>(getCurrentPlayerColor()));
return 1;
}

Expand Down Expand Up @@ -315,22 +315,22 @@ bool Board::isStalemate()
std::shared_ptr<King> king = getKing(getOpponentColor(), kingRow, kingCol);

// If the king is in check, it's not a stalemate
if (isKingInCheck(getColor())) {
if (isKingInCheck(getCurrentPlayerColor())) {
return false;
}

// Iterate through all pieces of the current player
for (int row = 0; row < 8; ++row) {
for (int col = 0; col < 8; ++col) {
std::shared_ptr<Piece> piece = getPiece(row, col);
if (piece && piece->getColor() == getColor()) {
if (piece && piece->getColor() == getCurrentPlayerColor()) {
// Check all possible moves for this piece
for (int destRow = 0; destRow < 8; ++destRow) {
for (int destCol = 0; destCol < 8; ++destCol) {
if (piece->isValidMove(row, col, destRow, destCol)) {
// Simulate the move
std::shared_ptr<Piece> tmpPiece = replace(row, col, destRow, destCol);
bool stillInCheck = isKingInCheck(getColor());
bool stillInCheck = isKingInCheck(getCurrentPlayerColor());
restore(row, col, destRow, destCol, tmpPiece);

// If the move does not leave the king in check, it's not a stalemate
Expand Down Expand Up @@ -406,7 +406,7 @@ MoveResult Board::move(int src_row, int src_col, int trg_row, int trg_col)

std::shared_ptr<Piece> tmp_piece = replace(src_row, src_col, trg_row, trg_col);

if (isKingInCheck(getColor())) {
if (isKingInCheck(getCurrentPlayerColor())) {
restore(src_row, src_col, trg_row, trg_col, tmp_piece);
return MoveResult::KingInCheck;
}
Expand Down Expand Up @@ -473,7 +473,7 @@ int Board::evaluate() const
for (int col = 0; col < 8; ++col) {
auto piece = getPiece(row, col);
if (piece) {
if (piece->getColor() == getColor()) {
if (piece->getColor() == getCurrentPlayerColor()) {
score -= piece->getValue();
} else {
score += piece->getValue();
Expand Down Expand Up @@ -527,8 +527,7 @@ Move findBestMove(int depth)
{
int bestValue = std::numeric_limits<int>::max();
Move bestMove {-1, -1, -1, -1};
PieceColor currentTurn = PieceColor::Black; // Assuming AI plays as Black
std::vector<Move> moves = board->getPossibleMoves(currentTurn);
std::vector<Move> moves = board->getPossibleMoves(getCurrentPlayerColor());

for (const Move& move : moves) {
std::shared_ptr<Piece> capturedPiece = board->getPiece(move.dest_row, move.dest_col);
Expand Down
1 change: 1 addition & 0 deletions Board/Board.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ void IncrementTurnCounter();
int getTurnCounter();
MoveResult makeTheMove(int src_row, int src_col, int trg_row, int trg_col);
Move findBestMove(int depth);
PieceColor getCurrentPlayerColor();
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ find_package(SDL2_image REQUIRED)

# Print the variables to see their values
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
include_directories(Board Pieces)
include_directories(Board Pieces Config)

# Add source to this project's executable.
add_executable (OpenChess "main.cpp" "Pieces/Piece.h" "Pieces/King.h" "Pieces/King.cpp" "Pieces/Rook.h" "Pieces/Rook.cpp" "Pieces/Queen.h" "Pieces/Queen.cpp" "Pieces/Pawn.h" "Pieces/Pawn.cpp" "Pieces/Bishop.h" "Pieces/Bishop.cpp" "Pieces/Knight.h" "Pieces/Knight.cpp" "Board/Board.cpp" "Board/Board.h" "ChessSDL.cpp" "ChessSDL.h" "Pieces/Piece.cpp")
add_executable (OpenChess "main.cpp" "Pieces/Piece.h" "Pieces/King.h" "Pieces/King.cpp" "Pieces/Rook.h" "Pieces/Rook.cpp" "Pieces/Queen.h" "Pieces/Queen.cpp" "Pieces/Pawn.h" "Pieces/Pawn.cpp" "Pieces/Bishop.h" "Pieces/Bishop.cpp" "Pieces/Knight.h" "Pieces/Knight.cpp" "Board/Board.cpp" "Board/Board.h" "ChessSDL.cpp" "ChessSDL.h" "Pieces/Piece.cpp" "Config/Config.cpp" "Config/Config.h" )

target_link_libraries(OpenChess SDL2::SDL2 SDL2::SDL2main SDL2_image::SDL2_image)

Expand Down
224 changes: 161 additions & 63 deletions ChessSDL.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#include <map>
#include <string>
#include <SDL.h>
#include "ChessSDL.h"
#include <vector>
#include <memory>

#include "ChessSDL.h"
#include "Board.h"
#include <SDL_image.h>
#include "Config.h"

static std::map<std::string, SDL_Texture*> textures;
static SDL_Renderer* renderer;
Expand Down Expand Up @@ -56,7 +58,7 @@ static SDL_Window* create_SDL_Window(std::string name)
std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
IMG_Quit();
SDL_Quit();
nullptr;
return nullptr;
}
return window;
}
Expand Down Expand Up @@ -118,66 +120,50 @@ void ChessSDL_Close()
SDL_Quit();
}

int ChessSDL_MakePreparations()
static void ChessSDL_RenderPiece(int row, int col)
{
if (init_SDL()) {
return 1;
}
std::shared_ptr<Board> board = getBoard();
std::shared_ptr<Piece> piece = board->getPiece(row, col);

if (init_SDL_Image()) {
return 1;
}

window = create_SDL_Window("ChessGame");
if (!window) {
return 1;
}
if (piece) {
std::string imagePath;

renderer = create_SDL_Renderer(window);
if (!renderer) {
return 1;
imagePath = piece->getImagePath();
SDL_Texture* texture = getTexture(imagePath);
if (texture) {
SDL_Rect pieceRect = { col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE };
SDL_RenderCopy(renderer, texture, nullptr, &pieceRect);
}
}
}

if (!loadMedia(renderer)) {
std::cerr << "Failed to load media!" << std::endl;
ChessSDL_Close();
return 1;
static void ChessSDL_HighlightSelectedTile(SDL_Renderer *renderer, int selectedRow, int selectedCol, bool revert)
{
if (!revert) {
SDL_SetRenderDrawColor(renderer, 255, 255, 130, 255);
} else {
bool isWhiteTile = (selectedRow + selectedCol) % 2 == 0;

if (isWhiteTile) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // White
} else {
SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255); // Gray
}
}

return 0;
SDL_Rect tile = { selectedCol * TILE_SIZE, selectedRow * TILE_SIZE, TILE_SIZE, TILE_SIZE };
SDL_RenderFillRect(renderer, &tile);
ChessSDL_RenderPiece(selectedRow, selectedCol);
}

void ChessSDL_HighlightLastMove()
static void ChessSDL_HighlightSelection(int selectedRow, int selectedCol, bool revert)
{
std::shared_ptr<Board> board = getBoard();
Move move = board->getLastMove();

if (move.src_col == -1) return;

SDL_Renderer* renderer = getRenderer();

SDL_SetRenderDrawColor(renderer, 255, 255, 130, 255);
SDL_Rect tile = { move.src_col * TILE_SIZE, move.src_row * TILE_SIZE, TILE_SIZE, TILE_SIZE };
SDL_RenderFillRect(renderer, &tile);
tile = { move.dest_col * TILE_SIZE, move.dest_row * TILE_SIZE, TILE_SIZE, TILE_SIZE };
SDL_RenderFillRect(renderer, &tile);

std::shared_ptr<Piece> piece = board->getPiece(move.dest_row, move.dest_col);
if (piece) {
std::string imagePath;

imagePath = piece->getImagePath();
SDL_Texture* texture = getTexture(imagePath);
if (texture) {
SDL_Rect pieceRect = { move.dest_col * TILE_SIZE, move.dest_row * TILE_SIZE, TILE_SIZE, TILE_SIZE };
SDL_RenderCopy(renderer, texture, nullptr, &pieceRect);
}
}

ChessSDL_HighlightSelectedTile(renderer, selectedRow, selectedCol, revert);
SDL_RenderPresent(renderer);
}

void ChessSDL_RenderChessBoard(bool lastMove)
static void ChessSDL_RenderChessBoard()
{
SDL_Renderer* renderer = getRenderer();

Expand All @@ -199,25 +185,58 @@ void ChessSDL_RenderChessBoard(bool lastMove)
white = !white;

// Render the piece on the board
std::shared_ptr<Board> board = getBoard();
std::shared_ptr<Piece> piece = board->getPiece(row, col);
if (piece) {
std::string imagePath;

imagePath = piece->getImagePath();
SDL_Texture* texture = getTexture(imagePath);
if (texture) {
SDL_Rect pieceRect = { col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE };
SDL_RenderCopy(renderer, texture, nullptr, &pieceRect);
}
}
ChessSDL_RenderPiece(row, col);
}
white = !white;
}

SDL_RenderPresent(renderer);
}

static void ChessSDL_HighlightLastMove()
{
ChessSDL_RenderChessBoard();

SDL_Renderer* renderer = getRenderer();
std::shared_ptr<Board> board = getBoard();
Move move = board->getLastMove();

if (lastMove) ChessSDL_HighlightLastMove();
if (move.src_col == -1) return;

ChessSDL_HighlightSelectedTile(renderer, move.src_row, move.src_col, false);
ChessSDL_HighlightSelectedTile(renderer, move.dest_row, move.dest_col, false);
SDL_RenderPresent(renderer);
}

int ChessSDL_MakePreparations()
{
if (init_SDL()) {
return 1;
}

if (init_SDL_Image()) {
return 1;
}

window = create_SDL_Window("ChessGame");
if (!window) {
return 1;
}

renderer = create_SDL_Renderer(window);
if (!renderer) {
return 1;
}

if (!loadMedia(renderer)) {
std::cerr << "Failed to load media!" << std::endl;
ChessSDL_Close();
return 1;
}

ChessSDL_RenderChessBoard();

return 0;
}

static void showCheckmateMessage()
Expand Down Expand Up @@ -277,5 +296,84 @@ void ChessSDL_ShowMoveMessage(MoveResult res)
default:
break;
}
}

static void ChessSDL_HandleMoveResult(const MoveResult& res, bool &quit, int row = -1, int col = -1)
{
if (res == MoveResult::Checkmate || res == MoveResult::Stalemate) {
ChessSDL_HighlightLastMove();
ChessSDL_ShowMoveMessage(res);
quit = true;
}
if (res == MoveResult::ValidMove) {
ChessSDL_HighlightLastMove();
IncrementTurnCounter();
}
if (res == MoveResult::InvalidMove) {
ChessSDL_HighlightSelection(row, col, true);
}
ChessSDL_ShowMoveMessage(res);
}

void ChessSDL_HandleGameLoop()
{
const Config& config = getConfigurations();
bool quit = false;
SDL_Event e;
std::shared_ptr<Board> board = getBoard();
static bool isPieceSelected = false;
static int selectedRow = -1;
static int selectedCol = -1;

while (!quit) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
quit = true;
} else if (e.type == SDL_MOUSEBUTTONDOWN) {
int x, y;
SDL_GetMouseState(&x, &y);
int row = y / TILE_SIZE;
int col = x / TILE_SIZE;

if (!isPieceSelected) {
auto selectedPiece = board->getPiece(row, col);
if (selectedPiece && selectedPiece->getColor() == getCurrentPlayerColor()) {
isPieceSelected = true;
selectedRow = row;
selectedCol = col;

// Highlight the selected piece
ChessSDL_HighlightSelection(selectedRow, selectedCol, false);
}
} else {
int src_row = selectedRow;
int src_col = selectedCol;
int dest_row = row;
int dest_col = col;
isPieceSelected = false;

MoveResult res = makeTheMove(src_row, src_col, dest_row, dest_col);
ChessSDL_HandleMoveResult(res, quit, selectedRow, selectedCol);

if (quit == true) break;
}
} else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
if (isPieceSelected) {
ChessSDL_HighlightSelection(selectedRow, selectedCol, true);
isPieceSelected = false;
selectedRow = -1;
selectedCol = -1;
}
}
}

if (config.AI_OPPONENT) {
// AI's turn (Player 2)
if (getTurnCounter() % 2 == 0 && !quit) { // Assuming AI plays as Black
Move aiMove = findBestMove(config.depth);
MoveResult aiRes = makeTheMove(aiMove.src_row, aiMove.src_col, aiMove.dest_row, aiMove.dest_col);
ChessSDL_HandleMoveResult(aiRes, quit);
}
}
}
}
7 changes: 2 additions & 5 deletions ChessSDL.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <string>
#include "Board.h"
enum class MoveResult;

const int ROWS = 8;
const int COLS = 8;
Expand All @@ -11,6 +10,4 @@ const int TILE_SIZE = SCREEN_WIDTH / COLS;

int ChessSDL_MakePreparations();
void ChessSDL_Close();
void ChessSDL_RenderChessBoard(bool lastMove);
void ChessSDL_ShowMoveMessage(MoveResult res);
void ChessSDL_HighlightLastMove();
void ChessSDL_HandleGameLoop();
Loading

0 comments on commit aad4217

Please sign in to comment.