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
- Run the script to launch the game window
- Black player goes first
- Click on any intersection to place a stone
- The game alternaets between players automatically
- The first player to get five stones in a row wins
- 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