SFML Chess Game

Complete Technical Documentation & Architecture Guide

GitHub GitHub Repository Download PDF

Project Overview

This is a fully-featured chess game built with C++ and SFML (Simple and Fast Multimedia Library). The project implements complete chess rules, a graphical user interface, save/load functionality, and game state management.

♟️ Complete Chess Rules

All piece movements, check, checkmate, and stalemate detection

🎨 Graphical Interface

Beautiful SFML-based board with custom piece sprites

💾 Save/Load System

Persistent game states and high score tracking

⚙️ Settings Management

Customizable sound and theme preferences

File Structure

File Purpose Lines of Code
main.cpp Main game loop and event handling ~180
board.cpp/h Board state and initialization ~40
moves.cpp/h Move validation for all pieces ~150
checkmate.cpp/h Check, checkmate, stalemate logic ~250
render.cpp/h Graphics rendering and textures ~120
menu.cpp/h Main menu and pause menu UI ~280
ending.cpp/h End game screen and results ~100
save.cpp/h Game state serialization ~50
settings.cpp/h User preferences management ~30
highscores.cpp/h Win tracking and statistics ~40

System Architecture

Program Flow

Program Start
Load Settings & Scores
Main Menu
Game Loop
Move Processing
Check/Checkmate Detection
End Game / Menu

Data Flow Architecture

    // Global Board State (board.cpp)
    char board[8][8];
    // Chess board representation
    char turn = 'w'; // Current player ('w' or 'b')
    int whiteWins = 0; // White victories
    int blackWins = 0; // Black victories 
    // Main Game Loop (main.cpp)
    while (window.isOpen() && inGame) {
        // 1. Event Processing
        if (mouse click) {
        windowToBoard(mousePos); // Convert to board
        coords
        isMoveValid(from, to); // Validate move
        isKingInCheck(side); // Check legality
        isCheckmate(opponent); // Win condition
        }
                                        
    // 2. Rendering
    drawBoardAndPieces(window);
    drawHighlight(selectedSquare);
    }

Module Dependencies

🎮
main.cpp

Dependencies: All modules (orchestrator)

Role: Central game loop, event handling, state transitions

📋
board.cpp

Dependencies: None (core data)

Role: Maintains board state and turn tracking

♟️
moves.cpp

Dependencies: board.cpp

Role: Validates piece-specific move rules

👑
checkmate.cpp

Dependencies: board.cpp, moves.cpp

Role: Advanced game state detection (check, checkmate, stalemate)

Module Documentation

📋
board.h / board.cpp
Core Module

Purpose: Manages the chess board state and global game variables

void initializeBoard()
Sets up the initial chess position with all pieces in their starting squares
void printBoardConsole()
Debug function to print the board state to console

Global Variables:

extern char board[8][8]; // 8x8 chess board extern char turn; // 'w' or 'b' extern int whiteWins; // Win counter extern int blackWins; // Win counter
♟️
moves.h / moves.cpp
Logic Module

Purpose: Validates all chess piece movements according to chess rules

bool isMoveValid(int sr, int sc, int dr, int dc)
Master function that validates any move based on piece type and game state
bool isPawnMove(...)
Validates pawn moves: forward 1/2 squares, diagonal captures
bool isRookMove(...)
Validates rook moves: straight lines (horizontal/vertical)
bool isBishopMove(...)
Validates bishop moves: diagonal lines
bool isKnightMove(...)
Validates knight moves: L-shape (2+1 squares)
bool isQueenMove(...)
Validates queen moves: combination of rook + bishop
bool isKingMove(...)
Validates king moves: one square in any direction
bool isPathClear(...)
Checks if there are no pieces blocking the path between two squares
👑
checkmate.h / checkmate.cpp
Advanced Logic

Purpose: Implements check, checkmate, and stalemate detection

bool isSquareAttacked(int r, int c, char attackerColor)
Determines if a square is under attack by a given color
bool findKing(char side, int *kr, int *kc)
Locates the king position for a given side
bool isKingInCheck(char side)
Checks if the specified side's king is currently in check
bool hasAnyLegalMove(char side)
Determines if a player has any legal moves available (critical for checkmate/stalemate)
bool isCheckmate(char side)
Returns true if the side is in checkmate (in check + no legal moves)
bool isStalemate(char side)
Returns true if the side is in stalemate (not in check + no legal moves)
int getLegalKingMoves(char side, int out[16])
Gets all legal king moves for a side (used for UI hints)

Attack Detection Algorithm:

// Checks all possible attack vectors bool isSquareAttacked(int r, int c, char attackerColor) { // 1. Check pawn attacks (diagonal) // 2. Check knight attacks (L-shapes) // 3. Check rook/queen attacks (lines) // 4. Check bishop/queen attacks (diagonals) // 5. Check king adjacency return anyAttackFound; }
🎨
render.h / render.cpp
Graphics Module

Purpose: Handles all SFML rendering including board, pieces, and highlights

void loadTextures()
Loads all piece sprites and board texture from assets folder
void drawBoardAndPieces(sf::RenderWindow &window)
Renders the chess board and all pieces in their current positions
void drawHighlight(sf::RenderWindow &window, int r, int c)
Draws a semi-transparent yellow highlight on the selected square
std::pair<int,int> windowToBoard(sf::RenderWindow &window, sf::Vector2i mousePos)
Converts mouse pixel coordinates to board row/column indices

Piece Texture Mapping:

static const char* pieceFiles[12] = { "assets/pieces/white_pawn.png", "assets/pieces/white_rook.png", "assets/pieces/white_knight.png", "assets/pieces/white_bishop.png", "assets/pieces/white_queen.png", "assets/pieces/white_king.png", "assets/pieces/black_pawn.png", // ... and so on };
💾
save.h / save.cpp
Persistence

Purpose: Manages game state serialization to files

void saveGameToFile(const char* filename)
Saves current board state, turn, and scores to file
bool loadGameFromFile(const char* filename)
Loads a previously saved game state from file

Save File Format:

rnbqkbnr // Row 0 (black back rank) pppppppp // Row 1 (black pawns) // Rows 2-5 (empty or pieces) PPPPPPPP // Row 6 (white pawns) RNBQKBNR // Row 7 (white back rank) w // Current turn ('w' or 'b') 0 // White wins 0 // Black wins

Game Logic Deep Dive

Move Validation System

The game uses a multi-layered validation system to ensure all moves are legal:

Layer 1: Basic Validation

bool isMoveValid(int sr, int sc, int dr, int dc) { // 1. Check bounds if (!isInside(sr,sc) || !isInside(dr,dc)) return false; // 2. Check if there's a piece to move if (board[sr][sc] == ' ') return false; // 3. Check turn ownership if (turn == 'w' && !isWhitePiece(board[sr][sc])) return false; // 4. Can't capture own pieces if (isSameColor(board[sr][sc], board[dr][dc])) return false; // 5. Call piece-specific validation return isPawnMove(...) || isRookMove(...) || ...; }

Layer 2: Piece-Specific Rules

Example: Pawn Movement

bool isPawnMove(int sr, int sc, int dr, int dc) { int dir = isWhitePiece(board[sr][sc]) ? -1 : 1; // Forward move (1 square) if (dc == sc && dr == sr + dir && board[dr][dc] == ' ') return true; // Initial double move if (dc == sc && dr == sr + 2*dir && sr == startRow) return true; // Diagonal capture if (abs(dc - sc) == 1 && dr == sr + dir && board[dr][dc] != ' ') return true; return false; }

Layer 3: Check Validation

After a move is made, the game ensures the king is not in check:

// In main.cpp game loop char savedDest = board[r][c]; char savedSrc = board[selR][selC]; // Try the move board[r][c] = savedSrc; board[selR][selC] = ' '; // Check if our own king is in check if (isKingInCheck(turn)) { // Illegal! Undo the move board[selR][selC] = savedSrc; board[r][c] = savedDest; continue; } // Move is legal - check for checkmate if (isCheckmate(opponent)) { recordWin(turn); showEndingScreen(); }

Checkmate Detection Algorithm

bool isCheckmate(char side) { // Must be in check AND have no legal moves return isKingInCheck(side) && !hasAnyLegalMove(side); } bool hasAnyLegalMove(char side) { // Try every possible move for this side for (int sr = 0; sr < 8; sr++) { for (int sc = 0; sc < 8; sc++) { if (board[sr][sc] belongs to side) { for (int dr = 0; dr < 8; dr++) { for (int dc = 0; dc < 8; dc++) { if (isLegalMove(sr,sc,dr,dc)) { // Simulate move makeMove(); bool stillInCheck = isKingInCheck(side); undoMove(); if (!stillInCheck) return true; // Found a legal move! } } } } } } return false; // No legal moves found }

Board Representation

The board uses a character-based 2D array where:

  • Uppercase letters = White pieces (P, R, N, B, Q, K)
  • Lowercase letters = Black pieces (p, r, n, b, q, k)
  • Space character = Empty square
  • Row 0 = Black's back rank (top of screen)
  • Row 7 = White's back rank (bottom of screen)

User Interface System

Menu System

📱
menu.cpp - Main Menu

Features:

  • Start New Game
  • Load Saved Game
  • Settings Configuration
  • High Scores Display
  • Exit Game
MenuResult mainMenu(sf::RenderWindow &window) { // Create menu buttons with hover effects const char* items[] = { "Start New Game", "Load Game", "Settings", "High Scores", "Exit" }; // Event loop with hover and click detection while (window.isOpen()) { if (mouseOver(button)) { button.setFillColor(hoverColor); } if (clicked(button)) { return correspondingMenuResult; } } }
⏸️
Pause Menu

Accessed during gameplay by pressing P key

  • Resume - Return to game
  • Save Game - Save current state
  • Exit to Main Menu - Abandon current game
🏆
ending.cpp - End Game Screen

Game Result Types:

enum GameResult { WHITE_WINS, // White checkmated black BLACK_WINS, // Black checkmated white DRAW, // Mutual agreement (not implemented) STALEMATE // No legal moves, not in check }; bool showEndingScreen(sf::RenderWindow &window, GameResult result) { // Display result with styled text // Options: "Play Again" or "Exit to Main Menu" // Returns true if player wants to play again }

Rendering Pipeline

Load Textures
Draw Board Background
Draw All Pieces
Draw Selection Highlight
Display Window

Mouse-to-Board Coordinate Conversion

std::pair<int,int> windowToBoard(sf::RenderWindow &window, sf::Vector2i mousePos) { float cellW = window.getSize().x / 8.0f; float cellH = window.getSize().y / 8.0f; int col = int(mousePos.x / cellW); // 0-7 int row = int(mousePos.y / cellH); // 0-7 return {row, col}; }

Keyboard Controls

Key Action Context
ESC Exit to main menu During game or settings
P Pause menu During game
S Quick save During game
Mouse Click Select piece / Make move During game
Enter / Space Play again End screen

Build & Compilation Guide

⚠️ Prerequisites

  • SFML 2.6.2 - Graphics library
  • MinGW/G++ - C++ compiler (Windows)
  • GCC - C++ compiler (Linux/Mac)
  • Assets folder - Chess piece images and board texture

Windows Compilation

# Compile command (adjust SFML path to your installation) g++ main.cpp board.cpp moves.cpp render.cpp menu.cpp checkmate.cpp \ save.cpp highscores.cpp settings.cpp ending.cpp -o chess_game \ -I"/c/SFML-2.6.2/include" \ -L"/c/SFML-2.6.2/lib" \ -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio # Run the game ./chess_game

Linux Compilation

# Install SFML (Ubuntu/Debian) sudo apt-get install libsfml-dev # Compile g++ main.cpp board.cpp moves.cpp render.cpp menu.cpp checkmate.cpp \ save.cpp highscores.cpp settings.cpp ending.cpp -o chess_game \ -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio # Run ./chess_game

Required Directory Structure


                    chess_game/
                    │
                    ├── main.cpp
                    ├── board.cpp / board.h
                    ├── moves.cpp / moves.h
                    ├── checkmate.cpp / checkmate.h
                    ├── render.cpp / render.h
                    ├── menu.cpp / menu.h
                    ├── ending.cpp / ending.h
                    ├── save.cpp / save.h
                    ├── highscores.cpp / highscores.h
                    ├── settings.cpp / settings.h
                    │
                    ├── assets/
                    │ ├── board.png
                    │ └── pieces/
                    │ ├── white_pawn.png
                    │ ├── white_rook.png
                    │ ├── white_knight.png
                    │ ├── white_bishop.png
                    │ ├── white_queen.png
                    │ ├── white_king.png
                    │ ├── black_pawn.png
                    │ ├── black_rook.png
                    │ ├── black_knight.png
                    │ ├── black_bishop.png
                    │ ├── black_queen.png
                    │ └── black_king.png
                    │
                    ├── savegame.txt (auto-generated)
                    ├── highscores.dat (auto-generated)
                    └── settings.cfg (auto-generated)
                

Common Compilation Issues

Error Solution
Cannot find SFML headers Verify -I flag points to SFML include directory
Undefined reference to SFML functions Check -L flag and ensure all -lsfml-* libraries are linked
Failed to load font Ensure Arial font exists at C:/Windows/Fonts/arial.ttf (Windows)
Failed to load textures Create assets/pieces/ folder with all PNG files
Window doesn't open SFML DLLs must be in same directory as executable (Windows)

Runtime Files Generated

savegame.txt

Stores the current game state including:

  • 8x8 board configuration (8 lines)
  • Current turn (w or b)
  • White wins count
  • Black wins count

highscores.dat

Simple text file with two integers:

5 // White wins 3 // Black wins

settings.cfg

User preferences:

1 // Sound on (1) or off (0) 0 // Theme: 0 = default, 1 = alternate

Performance Notes

  • Game runs at 60 FPS (capped via window.setFramerateLimit(60))
  • Checkmate detection uses brute-force search (acceptable for chess)
  • Texture loading happens once at startup
  • No dynamic memory allocation during gameplay