Python Game Programming: Creating Gomoku with Pygame

Introduction to Python Game Development

This article explores how to create a simple Gomoku (Five in a Row) game using Python and the Pygame libray. Gomoku is a classic board game where two players take turns placing stones on a grid, aiming to be the first to create a continuous line of five stones.

Development Environment

For this project, we'll use Python 3.x along with the Pygame library. Pygame provides functionality for graphics, sound, and user input handling, making it ideal for simple 2D games.

Setting Up the Environment

First, ensure you have Python installed. Then, install Pygame using pip:

pip install pygame

Creating the Gomoku Game

Basic Structure

Our Gomoku game will consist of a game board, player turns, and win detection logic. Let's start by setting up the game window and initializing the board.

Game Implementation

import pygame
import sys

# Initialize Pygame
pygame.init()

# Constants
WINDOW_SIZE = 640
BOARD_SIZE = 15
CELL_SIZE = 40
BOARD_MARGIN = 40
LINE_WIDTH = 1
STONE_RADIUS = 18

# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BOARD_COLOR = (220, 179, 92)
EMPTY = 0
PLAYER_BLACK = 1
PLAYER_WHITE = 2

class GomokuGame:
    def __init__(self):
        self.screen = pygame.display.set_mode((WINDOW_SIZE, WINDOW_SIZE))
        pygame.display.set_caption('Python Gomoku Game')
        self.clock = pygame.time.Clock()
        self.board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
        self.current_player = PLAYER_BLACK
        self.game_over = False
        self.winner = None
        
    def reset_game(self):
        """Reset the game state"""
        self.board = [[EMPTY for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
        self.current_player = PLAYER_BLACK
        self.game_over = False
        self.winner = None
        
    def place_stone(self, row, col):
        """Place a stone on the board if the position is valid"""
        if 0 <= row < BOARD_SIZE and 0 <= col < BOARD_SIZE and self.board[row][col] == EMPTY:
            self.board[row][col] = self.current_player
            return True
        return False
    
    def check_win(self, row, col):
        """Check if the last move resulted in a win"""
        player = self.board[row][col]
        
        # Check all four directions
        directions = [(1, 0), (0, 1), (1, 1), (1, -1)]
        
        for dx, dy in directions:
            count = 1
            
            # Check forward direction
            for i in range(1, 5):
                r, c = row + dx * i, col + dy * i
                if 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and self.board[r][c] == player:
                    count += 1
                else:
                    break
            
            # Check backward direction
            for i in range(1, 5):
                r, c = row - dx * i, col - dy * i
                if 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and self.board[r][c] == player:
                    count += 1
                else:
                    break
            
            if count >= 5:
                return True
        
        return False
    
    def draw_board(self):
        """Draw the game board"""
        self.screen.fill(BOARD_COLOR)
        
        # Draw grid lines
        for i in range(BOARD_SIZE):
            # Horizontal lines
            pygame.draw.line(self.screen, BLACK, 
                            (BOARD_MARGIN, BOARD_MARGIN + i * CELL_SIZE),
                            (WINDOW_SIZE - BOARD_MARGIN, BOARD_MARGIN + i * CELL_SIZE), 
                            LINE_WIDTH)
            # Vertical lines
            pygame.draw.line(self.screen, BLACK, 
                            (BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN),
                            (BOARD_MARGIN + i * CELL_SIZE, WINDOW_SIZE - BOARD_MARGIN), 
                            LINE_WIDTH)
        
        # Draw border
        pygame.draw.rect(self.screen, BLACK, 
                        (BOARD_MARGIN - LINE_WIDTH, BOARD_MARGIN - LINE_WIDTH, 
                         (BOARD_SIZE - 1) * CELL_SIZE + 2 * LINE_WIDTH, 
                         (BOARD_SIZE - 1) * CELL_SIZE + 2 * LINE_WIDTH), 
                        LINE_WIDTH)
        
        # Draw star points
        star_points = [(3, 3), (3, 11), (11, 3), (11, 11), (7, 7)]
        for row, col in star_points:
            pygame.draw.circle(self.screen, BLACK,
                             (BOARD_MARGIN + col * CELL_SIZE, BOARD_MARGIN + row * CELL_SIZE), 5)
        
        # Draw stones
        for row in range(BOARD_SIZE):
            for col in range(BOARD_SIZE):
                if self.board[row][col] != EMPTY:
                    color = BLACK if self.board[row][col] == PLAYER_BLACK else WHITE
                    pos = (BOARD_MARGIN + col * CELL_SIZE, BOARD_MARGIN + row * CELL_SIZE)
                    pygame.draw.circle(self.screen, color, pos, STONE_RADIUS)
                    # Add a border to white stones for visibility
                    if self.board[row][col] == PLAYER_WHITE:
                        pygame.draw.circle(self.screen, BLACK, pos, STONE_RADIUS, 1)
    
    def draw_status(self):
        """Draw game status information"""
        if self.game_over:
            status_text = f"Game Over! {'Black' if self.winner == PLAYER_BLACK else 'White'} wins!"
        else:
            status_text = f"Current Player: {'Black' if self.current_player == PLAYER_BLACK else 'White'}"
        
        font = pygame.font.SysFont(None, 36)
        text = font.render(status_text, True, BLACK)
        text_rect = text.get_rect(center=(WINDOW_SIZE // 2, 20))
        self.screen.blit(text, text_rect)
    
    def handle_click(self, pos):
        """Handle mouse click events"""
        if self.game_over:
            return
        
        x, y = pos
        # Convert screen coordinates to board position
        col = round((x - BOARD_MARGIN) / CELL_SIZE)
        row = round((y - BOARD_MARGIN) / CELL_SIZE)
        
        if self.place_stone(row, col):
            if self.check_win(row, col):
                self.game_over = True
                self.winner = self.current_player
            else:
                # Switch players
                self.current_player = PLAYER_WHITE if self.current_player == PLAYER_BLACK else PLAYER_BLACK
    
    def run(self):
        """Main game loop"""
        running = True
        
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    self.handle_click(event.pos)
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_r:  # Reset game with 'R' key
                        self.reset_game()
            
            self.draw_board()
            self.draw_status()
            pygame.display.flip()
            self.clock.tick(30)
        
        pygame.quit()
        sys.exit()

# Run the game
if __name__ == "__main__":
    game = GomokuGame()
    game.run()

Game Features

  • 15x15 game board with traditional star points
  • Turn-based gameplay between black and white players
  • Win detection for five stones in a row (horizontal, vertical, or diagonal)
  • Visual indicators for current player
  • Game reset funcsionality (press 'R' key)

How to Play

  1. Run the script to launch the game window
  2. Black player goes first
  3. Click on any intersection to place a stone
  4. The game alternaets between players automatically
  5. The first player to get five stones in a row wins
  6. Press 'R' to reset the game at any time

Extending the Game

This basic implementation can be extended with additional features such as:

  • AI opponents using minimax algorithm
  • Sound effects for stone placement
  • Move history and undo functionality
  • Score tracking across multiple games
  • Network multiplayer capability

Tags: python pygame Gomoku game-development board-games

Posted on Wed, 20 May 2026 19:32:49 +0000 by perrohunter