How to Make a Checkers Game with Python
Creating a Checkers game in Python is an exciting project that combines several important programming concepts, including object-oriented programming, game logic, and graphical user interfaces (GUIs).
For this guide, we'll use the popular Pygame library, which is well-suited for creating 2D games. Pygame provides the tools needed to manage game windows, draw shapes and images, handle user input, and manage the game loop.
Prerequisites
Before we begin, ensure you have Python and Pygame installed on your system. You can install Pygame using pip:
pip install pygame
Step 1: Setting Up the Project Structure
First, create a project directory for your Checkers game. Inside this directory, create the following files:
main.py
: The main game file where the game loop will reside.constants.py
: A file to store all constant values, such as colors, dimensions, etc.board.py
: A file to manage the game board.piece.py
: A file to manage the individual pieces.game.py
: A file to manage the game logic and state.
Step 2: Defining Constants
In constants.py
, define the constants for your game. These constants will include colors, dimensions, and other settings.
# constants.py
import pygame
# Screen dimensions
WIDTH, HEIGHT = 800, 800
ROWS, COLS = 8, 8
SQUARE_SIZE = WIDTH // COLS
# Colors
RED = (255, 0, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
GREY = (128, 128, 128)
# Piece
CROWN = pygame.transform.scale(pygame.image.load('assets/crown.png'), (44, 25))
Step 3: Creating the Game Board
In board.py
, create a class to represent the game board. This class will handle drawing the board and managing the state of the pieces.
# board.py
import pygame
from .constants import *
class Board:
def __init__(self):
self.board = []
self.create_board()
def draw_squares(self, win):
win.fill(BLACK)
for row in range(ROWS):
for col in range(row % 2, COLS, 2):
pygame.draw.rect(win, RED, (row*SQUARE_SIZE, col*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
def create_board(self):
for row in range(ROWS):
self.board.append([])
for col in range(COLS):
if col % 2 == ((row + 1) % 2):
if row < 3:
self.board[row].append(Piece(row, col, WHITE))
elif row > 4:
self.board[row].append(Piece(row, col, RED))
else:
self.board[row].append(0)
else:
self.board[row].append(0)
def draw(self, win):
self.draw_squares(win)
for row in range(ROWS):
for col in range(COLS):
piece = self.board[row][col]
if piece != 0:
piece.draw(win)
Step 4: Creating the Pieces
In piece.py
, create a class to represent individual pieces. This class will handle drawing the pieces and managing their state.
# piece.py
import pygame
from .constants import *
class Piece:
PADDING = 15
OUTLINE = 2
def __init__(self, row, col, color):
self.row = row
self.col = col
self.color = color
self.king = False
self.x = 0
self.y = 0
self.calc_pos()
def calc_pos(self):
self.x = SQUARE_SIZE * self.col + SQUARE_SIZE // 2
self.y = SQUARE_SIZE * self.row + SQUARE_SIZE // 2
def make_king(self):
self.king = True
def draw(self, win):
radius = SQUARE_SIZE//2 - self.PADDING
pygame.draw.circle(win, GREY, (self.x, self.y), radius + self.OUTLINE)
pygame.draw.circle(win, self.color, (self.x, self.y), radius)
if self.king:
win.blit(CROWN, (self.x - CROWN.get_width()//2, self.y - CROWN.get_height()//2))
def move(self, row, col):
self.row = row
self.col = col
self.calc_pos()
Step 5: Managing Game Logic
In game.py
, create a class to manage the game logic, including updating the state of the board, moving pieces, and handling captures.
# game.py
import pygame
from .constants import *
from .board import Board
class Game:
def __init__(self, win):
self._init()
self.win = win
def _init(self):
self.selected = None
self.board = Board()
self.turn = RED
self.valid_moves = {}
def update(self):
self.board.draw(self.win)
self.draw_valid_moves(self.valid_moves)
pygame.display.update()
def reset(self):
self._init()
def select(self, row, col):
if self.selected:
result = self._move(row, col)
if not result:
self.selected = None
self.select(row, col)
piece = self.board.get_piece(row, col)
if piece != 0 and piece.color == self.turn:
self.selected = piece
self.valid_moves = self.board.get_valid_moves(piece)
return True
return False
def _move(self, row, col):
piece = self.board.get_piece(row, col)
if self.selected and piece == 0 and (row, col) in self.valid_moves:
self.board.move(self.selected, row, col)
skipped = self.valid_moves[(row, col)]
if skipped:
self.board.remove(skipped)
self.change_turn()
else:
return False
return True
def draw_valid_moves(self, moves):
for move in moves:
row, col = move
pygame.draw.circle(self.win, BLUE, (col * SQUARE_SIZE + SQUARE_SIZE//2, row * SQUARE_SIZE + SQUARE_SIZE//2), 15)
def change_turn(self):
self.valid_moves = {}
if self.turn == RED:
self.turn = WHITE
else:
self.turn = RED
Step 6: Creating the Main Game Loop
In main.py
, create the main game loop that initializes the game and handles user input.
# main.py
import pygame
from .constants import *
from .game import Game
FPS = 60
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Checkers')
def get_row_col_from_mouse(pos):
x, y = pos
row = y // SQUARE_SIZE
col = x // SQUARE_SIZE
return row, col
def main():
run = True
clock = pygame.time.Clock()
game = Game(WIN)
while run:
clock.tick(FPS)
if game.winner() != None:
print(game.winner())
run = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
row, col = get_row_col_from_mouse(pos)
game.select(row, col)
game.update()
pygame.quit()
main()
Conclusion
With the above steps, you should have a basic but functional Checkers game. The game board and pieces are drawn, and you can select and move pieces according to the rules of Checkers. The game logic handles piece movement, turn changes, and capturing pieces.
This guide provides a solid foundation for your Checkers game. You can expand on this by adding more features such as AI opponents, a better user interface, and additional game rules.
Feel free to modify and enhance the code to suit your needs, and happy coding!
Subscribe to my newsletter
Read articles from Hichem MG directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Hichem MG
Hichem MG
Python dev, coding enthusiast, problem solver. Passionate about clean code and tech innovation.