How to Make a Checkers Game with Python
Tags: python, gamedev, tutorial
Published: 2024-07-02 11:40:28

Creating a Checkers game in Python can be a rewarding project that introduces various concepts of game development, including graphical user interfaces (GUIs), game logic, and event handling.

For this guide, we'll use the `pygame` library, which is a popular choice for developing games in Python due to its simplicity and powerful features.

## How to Make a Checkers Game with Python

### Prerequisites

1. **Python**: Make sure you have Python installed on your machine. You can download it from [python.org](https://www.python.org/downloads/).
2. **Pygame**: Install the `pygame` library using pip:
    ```bash
    pip install pygame
    ```

### Setting Up the Project

Create a new directory for your Checkers game project and navigate into it:

```bash
mkdir checkers_game
cd checkers_game
```

Create a new Python file for the game logic:

```bash
touch main.py
```

### Step 1: Importing Libraries

In your `main.py`, start by importing the necessary libraries:

```python
import pygame
import sys
from pygame.locals import *
```

### Step 2: Initializing Pygame

Initialize `pygame` and set up the main game window:

```python
pygame.init()

# Constants
WIDTH, HEIGHT = 800, 800
ROWS, COLS = 8, 8
SQUARE_SIZE = WIDTH // COLS

# RGB Colors
RED = (255, 0, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
GREY = (128, 128, 128)

# Create the game window
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Checkers')
```

### Step 3: Drawing the Board

Create a function to draw the checkerboard:

```python
def draw_board(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))
```

### Step 4: Creating the Piece Class

Define a class to represent the game pieces:

```python
class Piece:
    PADDING = 15
    OUTLINE = 2

    def __init__(self, row, col, color):
        self.row = row
        self.col = col
        self.color = color
        self.king = False

        if self.color == RED:
            self.direction = -1
        else:
            self.direction = 1

        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:
            crown = pygame.image.load('crown.png')
            crown = pygame.transform.scale(crown, (44, 25))
            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: Creating the Board Class

Define a class to represent the board and manage the pieces:

```python
class Board:
    def __init__(self):
        self.board = []
        self.red_left = self.white_left = 12
        self.red_kings = self.white_kings = 0
        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 6: Creating the Game Class

Define a class to manage the game state:

```python
class Game:
    def __init__(self, win):
        self._init()
        self.win = win

    def update(self):
        self.board.draw(self.win)
        pygame.display.update()

    def _init(self):
        self.selected = None
        self.board = Board()
        self.turn = RED
        self.valid_moves = {}

    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 (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 change_turn(self):
        self.valid_moves = {}
        if self.turn == RED:
            self.turn = WHITE
        else:
            self.turn = RED
```

### Step 7: Main Game Loop

Add the main game loop to handle events and updates:

```python
def main():
    run = True
    clock = pygame.time.Clock()
    game = Game(WIN)

    while run:
        clock.tick(60)

        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()

def get_row_col_from_mouse(pos):
    x, y = pos
    row = y // SQUARE_SIZE
    col = x // SQUARE_SIZE
    return row, col

if __name__ == "__main__":
    main()
```

### Conclusion

This guide outlines the basic structure of a Checkers game in Python using `pygame`, [here](https://play-checkers.online/) is an online demo of the game. You can further enhance this game by adding features such as enforcing rules for jumps, highlighting valid moves, and creating a user interface for start and end screens.

This project covers essential concepts in game development, such as:
- Handling user inputs and events.
- Drawing and updating the game board and pieces.
- Managing game state and transitions.

Feel free to expand on this guide by adding more advanced features and polishing the game mechanics. Happy coding!