Skip to content
Katsudon27Public

About

This is a terminal-based Chess game made with Ruby and TDD.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

180 Commits

Folders and files

Repository files navigation

CLI Chess Game

Hi there, this is a console-based Chess game that I made with Ruby for the final project in the Ruby module of The Odin Project curriculum.

What I have learnt/reinforced from working on this project:

  • Problem breakdown/solving
  • Object Oriented Programming (OOP)
  • Test Driven Development (TDD)
  • Factory Design Pattern
  • Serialisation

Table of Contents

Demo

This is a short demo of the game featuring The Scholar's Mate.

Demo of Chess game

Getting Started

Prerequisites

You should have the following installed on your local machine:

  • git
  • Ruby (version > 3.4.6)

Installation

  1. Clone the repo.
git clone https://github.com/Katsudon27/chess-top.git
  1. Navigate to the directory you used for step 1 and install gems.
bundle install
  1. Run the game.
ruby main.rb

Testing

  • To run the entire test suite, run rspec
  • To run the tests for non-piece classes individually, run
rspec spec/<filename>.rb
  • To run the tests for pieces individually, run
rspec spec/pieces/<filename>.rb

Implementation Details

Objects and Modules

Objects

  • Player: represents the player of the chess game and contains methods related to castling rights and getting player inputs.
  • Square: represents a square of the chess board and can be used to hold pieces.
  • Board: represents the chess board and contains a 2D array of square objects.
  • GameController: holds important information for the game state and controls the flow of the gameplay.
  • RuleEnforcer: contains methods that are relevant to the rules of chess such as returning the legal moves that can be made for a given piece on a square, capturing via en passant, castling etc.
  • Piece: the parent object for the chess pieces and contains the common methods to be inherited such as calculating the possible moves that each piece can make from a given position.
    • Bishop: contains symbol, letter and movement offsets of a Bishop piece.
    • King: contains symbol, letter, movement offsets and castling-related logic of a King piece.
    • Knight: contains symbol, letter and movement offsets of a Knight piece.
    • Pawn: contains symbol, letter, movement offsets, capturing movements of a Pawn piece.
    • Queen: contains symbol, letter and movement offsets of a Queen piece.
    • Rook: contains symbol, letter and movement offsets of a Rook piece.
  • PieceFactory: see below

Module

  • Display: contains methods for displaying board, game messages, player prompts and messages for invalid input.
  • UserInput: contains looping scripts for different user inputs.
  • NotationUtils: contains utility functions related to the algebraic notation used for representing the coordinates of squares on the chess board.

Factory Design Pattern

  • When implementing the import functionality of the chess board, I realised that I needed a way to instantiate the pieces dynamically but I didn't want to have direct object construction calls in the implementation of the method.
  • The Factory design pattern was used to provide an interface to dynamically instantiate the chess pieces based on the parsed letter.

Tests

I implemented this project with TDD so there are unit tests for all of the major features with considerations of various edge cases. I found them very useful during my subsequent refactoring work to avoid introducing breaking changes.

Though I should note that I didn't fully utilise mocking and stubbing as this project is quite complex in terms of object interactions and importing game states via FEN proved to be much more efficient for setting up test cases.

Serialisation

Serialisation is required for the saving/loading functionality of the game. I implemented serialisation with JSON to read and write the game state via #export of GameController in FEN and also the move history to account for threefold repetition when the game is loaded.

While using JSON would introduce an additional gem to be installed, I've used YAML before for the Mastermind Project so I wanted to try something new and the additional performance upside might come in handy for longer games with more extensive move history.

Features

Piece Movements

Each chess piece has their own movement and cannot move past friendly pieces (except for Knight).

Demo of piece movements

En Passant

When a pawn makes a double step and land itself beside an opponent pawn, the opponent pawn can move diagonally to the square that was passed over by the double-stepping pawn and capture the pawn.

Demo of en passant capture

Castling

Kingside and queenside castling were both implemented whereby under certain special rules, the king moves two squares towards the rook, and the rook moves over the king to the next square.

Demo of castling

Pawn Promotion

When a pawn is moved to the last row of the board, the player can promote it to a queen, rook, bishop or knight.

Demo of pawn promotion

Save and load game

Players can choose to save their current game at any point where they are prompted for inputs. At the start of the program, players will be given the choice to load a saved game or start a new one.

Demo of saving and loading game

Check

A player is checked when his king can be taken by an enemy piece.

Demo of check

Mate

A player is mated when he cannot make any legal move.

Demo of checkmate

Stalemate

A player is stalemated when he is mated but not checked.

Demo of stalemate

Threefold Repetition

If the same position with the same player to move is repeated three times in the game, the player to move can claim a draw.

Demo of threefold repetition

50-Move Rule

If there have been 50 consecutive moves for both players without any piece taken or any pawn move, a draw is declared.

Demo of 50 Move Rule

About

This is a terminal-based Chess game made with Ruby and TDD.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages