diff --git a/wuziqi_game.py b/wuziqi_game.py new file mode 100644 index 0000000..b0be548 --- /dev/null +++ b/wuziqi_game.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sat May 24 19:54:17 2025 + +@author: zhangzekai +""" + +import pygame +from enum import Enum + +# 初始化pygame +pygame.init() + +# 常量定义 +SCREEN_SIZE = (600, 600) +CELL_SIZE = 40 +CELL_NUM = 15 +SPACE = 20 +STAR_POINTS = [(4, 4), (10, 10), (10, 4), (4, 10), (7, 7)] + +# 颜色常量 +BACKGROUND_COLOR = (204, 153, 102) +LINE_COLOR = (200, 200, 200) +BLACK_CHESS_COLOR = (30, 30, 30) +WHITE_CHESS_COLOR = (225, 225, 225) +STAR_POINT_COLOR = (0, 0, 0) +TEXT_COLOR = (210, 210, 0) + +# 游戏状态枚举 +class GameState(Enum): + ONGOING = 1 + BLACK_WIN = 2 + WHITE_WIN = 3 + +# 初始化窗口 +screen = pygame.display.set_mode(SCREEN_SIZE) +pygame.display.set_caption('五子棋-EduCoder') + +# 初始化游戏状态 +board = [[0 for _ in range(CELL_NUM)] for _ in range(CELL_NUM)] # 棋盘状态 0:空 1:黑 2:白 +current_player = 1 # 当前玩家 1:黑 2:白 +game_state = GameState.ONGOING + +def get_line_num(tx, ty, dx, dy, board, player): + """计算指定方向连续棋子数量""" + count = 0 + while True: + tx += dx + ty += dy + if not (0 <= tx < CELL_NUM and 0 <= ty < CELL_NUM): + break + if board[ty][tx] != player: + break + count += 1 + return count + +def check_win(board, x, y, player): + """检查是否获胜""" + directions = [ + [(-1, 0), (1, 0)], # 水平 + [(0, -1), (0, 1)], # 垂直 + [(-1, -1), (1, 1)], # 主对角线 + [(-1, 1), (1, -1)] # 副对角线 + ] + for d in directions: + dx1, dy1 = d[0] + dx2, dy2 = d[1] + num1 = get_line_num(x, y, dx1, dy1, board, player) + num2 = get_line_num(x, y, dx2, dy2, board, player) + if num1 + num2 + 1 >= 5: + return True + return False + +def draw_board(): + """绘制棋盘""" + screen.fill(BACKGROUND_COLOR) + # 绘制网格线 + for i in range(CELL_NUM): + pygame.draw.line(screen, LINE_COLOR, + (SPACE, SPACE + i * CELL_SIZE), + (SPACE + (CELL_NUM-1)*CELL_SIZE, SPACE + i * CELL_SIZE)) + pygame.draw.line(screen, LINE_COLOR, + (SPACE + i * CELL_SIZE, SPACE), + (SPACE + i * CELL_SIZE, SPACE + (CELL_NUM-1)*CELL_SIZE)) + # 绘制星位 + for (x, y) in STAR_POINTS: + if board[y][x] == 0: + center = (x * CELL_SIZE + SPACE, y * CELL_SIZE + SPACE) + pygame.draw.circle(screen, STAR_POINT_COLOR, center, 3) + # 绘制棋子 + for y in range(CELL_NUM): + for x in range(CELL_NUM): + if board[y][x] == 1: + color = BLACK_CHESS_COLOR + elif board[y][x] == 2: + color = WHITE_CHESS_COLOR + else: + continue + center = (x * CELL_SIZE + SPACE, y * CELL_SIZE + SPACE) + pygame.draw.circle(screen, color, center, 16) + # 绘制胜利信息 + if game_state != GameState.ONGOING: + font = pygame.font.Font(None, 60) + text = "Black Wins!" if game_state == GameState.BLACK_WIN else "White Wins!" + text_surface = font.render(text, True, TEXT_COLOR) + text_rect = text_surface.get_rect(center=(SCREEN_SIZE[0]//2, SCREEN_SIZE[1]//2)) + screen.blit(text_surface, text_rect) + +def handle_click(pos): + """处理鼠标点击事件""" + global current_player, game_state + x, y = pos + # 转换为棋盘坐标 + grid_x = (x - SPACE) / CELL_SIZE + grid_y = (y - SPACE) / CELL_SIZE + # 检查是否在棋盘范围内 + if not (0 <= grid_x < CELL_NUM and 0 <= grid_y < CELL_NUM): + return + # 计算最近交叉点坐标 + xi = round(grid_x) + yi = round(grid_y) + # 检查落点有效性 + if board[yi][xi] != 0: + return + # 检查点击精度(距离交叉点不超过1/4格子) + distance = ((grid_x - xi)**2 + (grid_y - yi)**2)**0.5 + if distance > 0.25: + return + # 落子 + board[yi][xi] = current_player + # 检查胜利 + if check_win(board, xi, yi, current_player): + game_state = GameState.BLACK_WIN if current_player == 1 else GameState.WHITE_WIN + else: + current_player = 2 if current_player == 1 else 1 + +# 游戏主循环 +running = True +while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + elif event.type == pygame.MOUSEBUTTONUP and game_state == GameState.ONGOING: + handle_click(pygame.mouse.get_pos()) + + draw_board() + pygame.display.update() + +pygame.quit() +exit() \ No newline at end of file