Checkers game

This module contains the game code, it handles the game logic, user input, rendering the game and animations, and the game loop. It does not include the AI’s code nor the program’s entry point.

Board

class checkers.Board(string: Optional[str] = None)

Manages the game board state.

Create a new board with the default configuration or from a string.

Default board configuration:

grid: str = (
    " 2 2 2 2"
    "2 2 2 2 "
    " 2 2 2 2"
    ". . . . "
    " . . . ."
    "1 1 1 1 "
    " 1 1 1 1"
    "1 1 1 1 "
)
Parameters

string (str, optional) – The string representation of the board. A string of length Tile.Count * Tile.Count and containing only " .12ab".

grid

A string representation of the board.

Type

str

AdjacentTiles() Iterator[checkers.vec2]

Return an iterator of all adjacent tiles to the given position.

Does not check if the position is a valid tile, it will return diagonally adjacent tiles either way. However, it will not return tiles that are not within the board.

Parameters

pos (vec2) – The position to get the adjacent tiles for.

Yields

vec2 – The adjacent tile.

AllTiles: list[checkers.vec2] = [vec2(0, 0), vec2(1, 0), vec2(2, 0), vec2(3, 0), vec2(4, 0), vec2(5, 0), vec2(6, 0), vec2(7, 0), vec2(0, 1), vec2(1, 1), vec2(2, 1), vec2(3, 1), vec2(4, 1), vec2(5, 1), vec2(6, 1), vec2(7, 1), vec2(0, 2), vec2(1, 2), vec2(2, 2), vec2(3, 2), vec2(4, 2), vec2(5, 2), vec2(6, 2), vec2(7, 2), vec2(0, 3), vec2(1, 3), vec2(2, 3), vec2(3, 3), vec2(4, 3), vec2(5, 3), vec2(6, 3), vec2(7, 3), vec2(0, 4), vec2(1, 4), vec2(2, 4), vec2(3, 4), vec2(4, 4), vec2(5, 4), vec2(6, 4), vec2(7, 4), vec2(0, 5), vec2(1, 5), vec2(2, 5), vec2(3, 5), vec2(4, 5), vec2(5, 5), vec2(6, 5), vec2(7, 5), vec2(0, 6), vec2(1, 6), vec2(2, 6), vec2(3, 6), vec2(4, 6), vec2(5, 6), vec2(6, 6), vec2(7, 6), vec2(0, 7), vec2(1, 7), vec2(2, 7), vec2(3, 7), vec2(4, 7), vec2(5, 7), vec2(6, 7), vec2(7, 7)]

Static list of all positions inside the board.

IsInBoard() bool

Check if the given position is inside the board.

IsTile() bool

Check if the given position is a valid tile.

Tiles: list[checkers.vec2] = [vec2(1, 0), vec2(3, 0), vec2(5, 0), vec2(7, 0), vec2(0, 1), vec2(2, 1), vec2(4, 1), vec2(6, 1), vec2(1, 2), vec2(3, 2), vec2(5, 2), vec2(7, 2), vec2(0, 3), vec2(2, 3), vec2(4, 3), vec2(6, 3), vec2(1, 4), vec2(3, 4), vec2(5, 4), vec2(7, 4), vec2(0, 5), vec2(2, 5), vec2(4, 5), vec2(6, 5), vec2(1, 6), vec2(3, 6), vec2(5, 6), vec2(7, 6), vec2(0, 7), vec2(2, 7), vec2(4, 7), vec2(6, 7)]

Static list of all valid tiles on the board, used for fast iteration over all tiles.

copy() checkers.Board

Clone the board, used for the AI’s branching algorithm.

get(pos: checkers.vec2) checkers.Tile

Return information about the tile at the given position.

Parameters

pos (vec2) – The queried position.

Returns

The tile at the given position or Tile.NO_TILE if the position is invalid.

Return type

Tile

get_piece_moves(pos: checkers.vec2) Iterator[tuple[checkers.vec2, bool]]

Return an iterator of all possible moves for the piece at the given position.

A piece can move one tile diagonally in its player’s direction. If the piece is a king, it can move in any direction. If there is an enemy piece on the tile and the space behind it is empty, the piece jump over the enemy piece and capture it. Capturing a piece means the piece is removed from the board.

Parameters

pos (vec2) – The position of the piece to get the moves for.

Yields
  • vec2 – The target position of the move.

  • bool – Whether the move is a capture.

Notes

If a player has at least one capturing move available, they have to make a capturing move. This method doesn’t handle that, see Game.generate_moves().

get_player_pieces(player: checkers.Player) Iterator[checkers.vec2]

Return an iterator of all pieces belonging to the given player.

Loops over all tiles and yields positions of tiles belonging to the given player.

Parameters

player (Player) – The player to get the pieces for.

Yields

vec2 – The position of the piece.

move(pos: checkers.vec2, pos2: checkers.vec2) None

Move a piece, capturing an enemy piece if applicable.

This method does not validate the move. If there is a tile between the two positions, the piece at that tile will be captured.

Parameters
  • pos (vec2) – The position of the piece to move.

  • pos2 (vec2) – The target position of the move.

score(player: checkers.Player) int

Evaluate the board configuration in favor of the given player.

This is the scoring function used by the AI. The oponent’s score is subtracted from the player’s score.

Scoring principles:

  • Score is proportional to the number of the player’s pieces.

  • King pieces are worth more than normal pieces.

  • Normal pieces get a bonus if they stick to the edges of the board.

Parameters

player (Player) – The player to evaluate the board for.

Returns

The score of the player.

Return type

int

set(pos: checkers.vec2, value: checkers.Tile) None

Set the tile at the given position.

Parameters
  • pos (vec2) – The position to set the tile at.

  • value (Tile) – The value to set the tile to.

Notes

  • This method does not check if the position is valid.

  • This method only uses the Tile._value property, so any object that implements it can be used.

ColorPalette

class checkers.ColorPalette(*params: str)

Used for coloring a player’s pieces.

Primary light and dark should be a lighter/darker version of the primary color. Secondary should be a contrasting color to primary.

May be initialized with an arbitrary amount of colors (up to 6).

Parameters

*params (str, default #000000) – Hex strings in the format of #RRGGBB.

primary

Color of pieces which can move.

Type

pygame.Color

primary_light

Color of the currently selected piece.

Type

pygame.Color

primary_dark

Color of pieces which cannot move.

Type

pygame.Color

secondary

Color of possible move indicators.

Type

pygame.Color

secondary_light

Unused.

Type

pygame.Color

secondary_dark

Unused.

Type

pygame.Color

Notes

Secondary light and dark variants are currently unused and don’t have to be set.

Drawer

class checkers.Drawer

Handles rendering of the game.

Uses pygame for cross-platform rendering.

screen

A surface representing the game window.

Type

pygame.Surface

font

The default font used for rendering text.

Type

pygame.font.Font

font_debug

A smaller mono-spaced font used for debugging.

Type

pygame.font.Font

animation

The current animation being played.

Type

PieceAnimation

AnimationDuration: int = 200

The duration of animations in milliseconds.

FontSize: int = 13

The default font size.

Framerate: int = 60

The maximum refresh rate of the game.

animate(pos: checkers.vec2, pos2: checkers.vec2) None

Sets up an animation to move a piece from one position to another.

property animating: bool

Whether or not an animation is currently playing.

draw(game: checkers.Game) None

Draws the game to the screen.

  1. Clears the screen and draws the board.

  2. Draws the pieces.

  3. If env.DEBUG is set draws extra debugging information.

  4. If the game is over, draws the victory message.

Parameters

game (Game) – The game object to draw information from.

draw_debug(game: checkers.Game) None

Draws extra debug information to the screen.

Labels each tile with its position. In the top-left corner it displays:

  • The current player’s turn.

  • The position of the selected piece, if any.

  • The AI’s score, as of its last turn.

  • How long the AI’s last computation took.

  • The depth to which the AI last searched.

Parameters

game (Game) – The game object to draw information from.

See also

env.DEBUG

draw_piece(pos: checkers.vec2, game: checkers.Game) None

Draws a piece to the screen.

Handles animations and different piece states and types.

  • If the piece is being animated, interpolates between the origin and destination positions in regards to the animations progress.

  • If the piece cannot currently be moved it is drawn in a darker color.

  • If the piece is currently selected, it is drawn offset, in a lighter color, with a shadow under it and its possible moves are drawn in a contrasting color.

  • Otherwise if a piece can be moved but is not currently selected, it is drawn using the default color.

A normal piece is drawn as a circle, while a king piece is drawn as a square with rounded corners.

Parameters
  • pos (vec2) – The position of the piece to draw.

  • game (Game) – The game object to draw information from.

draw_tile(pos: checkers.vec2) None

Draws a board tile to the screen.

A tile is represented as a white square.

Parameters

pos (vec2) – The position of the tile to draw.

draw_victory(player: checkers.Player) None

Draws the victory message to the screen.

Prints “Game Over! <player> wins!” in large letters to the center of the screen.

Parameters

player (Player) – The player who won the game, used to determine the color of the text and congratulations message.

save_screenshot(name: str) None

Saves a screenshot of the game as <name>.png.

setup_window() None

Creates the game window and loads fonts.

Game

class checkers.Game

Takes care of game logic and user input.

For example, makes sure players make capturing moves if they have any available, handles piece movement, checks for victory clauses, handles user piece selection and movement, etc.

board

Stores the board layout.

Type

Board

clock

Used to control the framerate.

Type

pygame.time.Clock

drawer

Rendering abstraction class.

Type

Drawer

refresh

Whether the game should be redrawn, is used to limit redrawing if nothing changed.

Type

bool

victor

The player that won the game, once the game is over or None if the game is still ongoing.

Type

Optional[Player]

active_player

The player whose turn it is.

Type

Player

selected_piece

The position of the piece that is currently selected (only applies to human players).

Type

Optional[vec2]

locked_piece

If a multi-jump is in progress, this is the position of the piece that is currently locked.

Type

Optional[vec2]

moves

A dictionary of all possible moves from each piece’s position.

Type

defaultdict[vec2, list[vec2]]

computer_data

Results of the last AI computation.

Type

ComputerData

check_win() None

Check if the game is over.

If the current player doesn’t have any pieces left or all their pieces are unable to move, the player loses.

draw() None

Render the game if refresh is True or an animation is running Drawer.animating.

generate_moves() None

Generate all possible moves for the current player.

Loops over all pieces belonging to the current player and generates all possible moves for each piece. If at least one of the moves is a capturing move, only capturing moves are kept.

Notes

This method is called whenever a piece is moved or it becomes the other player’s turn. The result isn’t returned, but stored in moves.

get_moves(pos: checkers.vec2) list[checkers.vec2]

Get all possible moves for a piece, this does not generate new moves, it merely returns cached moves for the piece.

handle_click(click: pygame.math.Vector2) None

Handle a click by a human player.

Finds the tile that was clicked and does the following:

  • If a piece is already selected and the tile is a valid move, move the piece.

  • If the tile contains a piece the player can move, select it.

  • Otherwise deselect the currently selected piece.

Parameters

click (pygame.math.Vector2) – The position of the click.

move_piece(pos: checkers.vec2, pos2: checkers.vec2) None

Move a piece, with game logic.

On top of calling Board.move() does the following:

  • Begins an animation of the move.

  • If the piece reaches the other side and is not a king, it becomes a king and the turn ends immediately.

  • Otherwise if a capturing move is made, the piece is locked.

  • New moves are generated.

  • If the player cannot make any more captures with this piece, the turn ends.

Parameters
  • pos (vec2) – The position of the piece to move.

  • pos2 (vec2) – The target position of the move.

next_turn() None

End the current player’s turn and begin the next player’s turn.

Resets the locked piece and selected piece. Checks if the game is over.

See also

check_win()

update() None

Processes user and computer input.

Does nothing if the game is over. If the current player is the user, forwards mouse clicks to handle_click(). If it’s the computer’s turn, queries the computer for a move.

There are some available keyboard shortcuts:

  • q: Quit the game.

  • space: Save a screenshot of the game as screenshot.png.

This function also handles sleeping in accordance to Drawer.Framerate, as to not overload the CPU.

See also

draw()

Piece

class checkers.Piece(c: str)

A piece on the board, movable by it’s owner.

Should be treated as immutable. Initialize a Piece from its character representation.

Possible characters are:
  • 1: Player 1’s piece

  • 2: Player 2’s piece

  • a: Player 1’s king piece

  • b: Player 2’s king piece

Parameters

c (str) – The character representation of the piece.

Raises

AssertionError – If the character representation is invalid.

player

The player who owns the piece.

Type

Player

king

Whether the piece is a king or a normal piece.

Type

bool

See also

Tile, Player

Size: int = 45

PieceAnimation

class checkers.PieceAnimation(origin: Optional[checkers.vec2], destination: Optional[checkers.vec2], progress: float)

Holds state about the currently animated piece.

destination: Optional[checkers.vec2]

The position of the piece after the animation.

origin: Optional[checkers.vec2]

The position of the piece before the animation.

progress: float

A value from 0 to 1, representing the progress of the animation.

Player

class checkers.Player(color_palette: checkers.ColorPalette, name: str)

One of the two players in the game.

Should be treated as immutable. There is a static instance for each player, which acts as a enumeration. Each instance holds a color palette for its pieces.

Parameters
  • color_palette (ColorPalette) – The color palette of the player.

  • name (str) – The name of the player.

colors

Defines the drawing color of the player’s pieces.

Type

ColorPalette

name

Used to congratulate the player in the victory screen.

Type

str

See also

Piece

ONE: checkers.Player = <checkers.Player object>

Static instance of the first player, the human player.

Players: list[checkers.Player] = [<checkers.Player object>, <checkers.Player object>]

Static list of all players.

TWO: checkers.Player = <checkers.Player object>

Static instance of the second player, the computer player.

other() checkers.Player

Returns a reference to the other player.

Tile

class checkers.Tile(c: str)

A tile on the board, doesn’t have to be a valid position, may have a piece on it.

Should be treated as immutable. Initialize a Tile from its character representation.

Possible characters are:
  • [space]: No tile

  • .: Empty tile

  • 1: Player 1’s piece

  • 2: Player 2’s piece

  • a: Player 1’s king piece

  • b: Player 2’s king piece

Parameters

c (str) – The character representation of the tile.

Raises

AssertionError – If the character representation is invalid.

piece

The piece on the tile, or None if there is no piece.

Type

Optional[Piece]

See also

Piece

Count: int = 8

Board width and height in tiles.

EMPTY: checkers.Tile = <checkers.Tile object>

Static instance of empty tile.

NO_TILE: checkers.Tile = <checkers.Tile object>

Static instance of invalid tile position.

Size: int = 100

Tile size in pixels.

empty() bool

Return whether the tile doesn’t have a piece on it. If the tile isn’t valid returns True.

vec2

class checkers.vec2(x: int, y: int)

A 2D vector used for to represent a position on the board.

Parameters
  • x (int) – The x-coordinate of the vector.

  • y (int) – The y-coordinate of the vector.

x

The x-coordinate of the vector.

Type

int

y

The y-coordinate of the vector.

Type

int

center(other: checkers.vec2) Optional[checkers.vec2]

Return the center of two vectors.

Parameters

other (vec2) – The other vector.

Returns

The center of the two vectors, or None if the center doesn’t fall on an integer grid.

Return type

Optional[vec2]

distance(other: checkers.vec2) int

Return the Manhattan distance between two vectors.

Parameters

other (vec2) – The other vector.

Returns

The distance between the two vectors.

Return type

int

vectorize

checkers.vectorize(generator: Iterator[tuple[int, int]]) Iterator[checkers.vec2]

Convert a generator of tuples to a generator of vectors.

Parameters

generator (Iterator[tuple[int, int]]) – The generator to convert.

Yields

vec2 – The converted generator.