程序员的 “棋” 乐无穷:Python 打造五子棋游戏攻略(人机对战和人人对战)

游戏两种模式,人机对战和人人对战。非常好玩!

运行展示

在这里插入图片描述

使用Python Tkinter开发五子棋游戏

在编程的奇妙世界中,开发一款属于自己的游戏是一件充满乐趣与挑战的事情。今天,我们就来深入探讨如何使用Python的Tkinter库打造一个经典的五子棋游戏,从基础的界面搭建到复杂的游戏逻辑实现,一步步揭开游戏开发的神秘面纱。

技术栈选择

Python作为一门简洁且功能强大的编程语言,拥有庞大的库生态系统,为开发者提供了丰富的工具。在图形界面开发领域,Tkinter是Python的标准GUI(Graphical User Interface)库,它简单易用,能够快速搭建出可视化界面,对于想要入门游戏开发的初学者来说是一个绝佳选择。

核心功能模块实现

初始化设置与常量定义

在开始编写具体的游戏逻辑前,我们先定义了一些重要的常量,这些常量将贯穿整个游戏的开发过程。

# 棋盘相关常量
BOARD_SIZE = 15
GRID_SIZE = 40
MARGIN = 50
PIECE_RADIUS = 18
# 颜色常量
BOARD_COLOR = "#F0D9B5"
BLACK_PIECE_COLOR = "black"
WHITE_PIECE_COLOR = "white"

BOARD_SIZE确定了棋盘的大小,GRID_SIZE定义了每个网格的尺寸,MARGIN是棋盘边缘与窗口边缘的空白间距,PIECE_RADIUS规定了棋子的半径大小,各种颜色常量则为棋盘和棋子赋予直观视觉效果。

棋盘绘制

棋盘是五子棋游戏的核心载体,我们使用Tkinter的Canvas组件来完成棋盘的绘制工作。

def draw_board(self):
    # 绘制棋盘横线竖线
    for i in range(BOARD_SIZE):
        # 绘制横线,计算起点和终点坐标后绘制
        start_x = MARGIN
        start_y = MARGIN + i * GRID_SIZE
        end_x = MARGIN + GRID_SIZE * (BOARD_SIZE - 1)
        end_y = start_y
        self.canvas.create_line(start_x, start_y, end_x, end_y, width=2)
        # 绘制竖线,计算起点和终点坐标后绘制
        start_x = MARGIN + i * GRID_SIZE
        start_y = MARGIN
        end_x = start_x
        end_y = MARGIN + GRID_SIZE * (BOARD_SIZE - 1)
        self.canvas.create_line(start_x, start_y, end_x, end_y, width=2)

    # 绘制天元和星位
    star_points = [(3, 3), (3, 11), (7, 7), (11, 3), (11, 11)]
    for x, y in star_points:
        # 计算中心坐标,绘制代表天元和星位的黑点
        center_x = MARGIN + x * GRID_SIZE
        center_y = MARGIN + y * GRID_SIZE
        self.canvas.create_oval(center_x - 3, center_y - 3,
                                center_x + 3, center_y + 3,
                                fill="black")

通过嵌套for循环绘制棋盘的横线和竖线,再遍历坐标列表绘制天元和星位。

游戏模式选择

为了丰富游戏的玩法,我们设计了人人对战和人机对战两种模式,玩家可以根据自己的喜好进行选择。在模式选择界面的实现中,我们要注意按钮的管理,避免出现重复按钮的问题。

def show_mode_selection(self):
    # 若游戏界面组件存在,先销毁
    if hasattr(self, 'canvas'):
        self.canvas.destroy()
    self.reset_button.pack_forget()  # 隐藏重置按钮
    self.close_button.pack()  # 显示关闭游戏按钮

    # 创建模式选择框架
    self.mode_frame = tk.Frame(self.root)
    self.mode_frame.pack(pady=50)

    # 创建人人对战按钮,绑定start_game方法并传入"pvp"参数
    pvp_button = tk.Button(self.mode_frame, text="人人对战", command=lambda: self.start_game("pvp"))
    pvp_button.pack(pady=10)

    # 创建人机对战按钮,绑定start_game方法并传入"pve"参数
    pve_button = tk.Button(self.mode_frame, text="人机对战", command=lambda: self.start_game("pve"))
    pve_button.pack(pady=10)

该方法先销毁已有游戏界面组件,隐藏重置按钮,显示关闭游戏按钮,再创建模式选择框架及对应按钮,绑定不同的操作逻辑。

棋子落子与判断

玩家通过鼠标点击棋盘来进行落子操作,这部分逻辑主要在on_click方法中实现。

def on_click(self, event):
    if self.mode == "pve" and not self.is_player_turn:
        return  # 如果是人机对战且不是玩家回合,忽略点击事件
    # 计算点击的格子坐标
    x = int((event.x - MARGIN + GRID_SIZE / 2) // GRID_SIZE)
    y = int((event.y - MARGIN + GRID_SIZE / 2) // GRID_SIZE)
    if 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and self.board[y][x] == 0:
        # 落子,更新棋盘状态
        player = 1 if self.current_player == 1 else 2
        self.board[y][x] = player
        # 绘制棋子,根据玩家身份选择颜色
        center_x = MARGIN + x * GRID_SIZE
        center_y = MARGIN + y * GRID_SIZE
        color = BLACK_PIECE_COLOR if player == 1 else WHITE_PIECE_COLOR
        self.canvas.create_oval(center_x - PIECE_RADIUS, center_y - PIECE_RADIUS,
                                center_x + PIECE_RADIUS, center_y + PIECE_RADIUS,
                                fill=color, outline=color)
        # 检查是否有玩家获胜
        if self.check_win(x, y):
            # 确定获胜者,弹出提示框,重置游戏
            winner = "黑子(玩家1)" if player == 1 else ("白子(玩家2)" if self.mode == "pvp" else "白子(AI)")
            messagebox.showinfo("游戏结束", f"{winner} 获胜!")
            self.reset_to_mode_selection()
        elif all(self.board[i][j]!= 0 for i in range(BOARD_SIZE) for j in range(BOARD_SIZE)):
            # 检查是否平局,弹出提示框,重置游戏
            messagebox.showinfo("游戏结束", "平局!")
            self.reset_to_mode_selection()
        else:
            # 切换玩家,在人机对战且AI回合时调用ai_move方法
            self.current_player = 3 - self.current_player
            self.is_player_turn = not self.is_player_turn
            if self.mode == "pve" and not self.is_player_turn:
                self.ai_move()

此方法先判断点击事件是否有效,再计算坐标、落子、绘制棋子,接着检查获胜或平局情况,最后处理玩家切换和AI下棋。

人机对战AI实现

在人机对战模式中,AI的表现直接影响游戏的趣味性和挑战性。这里我们采用了一种简单但有效的评估算法来实现AI的下棋逻辑。

def ai_move(self):
    best_score = -1
    best_moves = []
    for y in range(BOARD_SIZE):
        for x in range(BOARD_SIZE):
            if self.board[y][x] == 0:
                score = self.evaluate_move(x, y, 2)
                if score > best_score:
                    best_score = score
                    best_moves = [(x, y)]
                elif score == best_score:
                    best_moves.append((x, y))
    if best_moves:
        x, y = random.choice(best_moves)
        # 落子,更新棋盘状态
        self.board[y][x] = 2
        # 绘制棋子
        center_x = MARGIN + x * GRID_SIZE
        center_y = MARGIN + y * GRID_SIZE
        color = WHITE_PIECE_COLOR
        self.canvas.create_oval(center_x - PIECE_RADIUS, center_y - PIECE_RADIUS,
                                center_x + PIECE_RADIUS, center_y + PIECE_RADIUS,
                                fill=color, outline=color)
        # 检查是否有AI获胜
        if self.check_win(x, y):
            # 确定获胜者,弹出提示框,重置游戏
            winner = "白子(AI)"
            messagebox.showinfo("游戏结束", f"{winner} 获胜!")
            self.reset_to_mode_selection()
        elif all(self.board[i][j]!= 0 for i in range(BOARD_SIZE) for j in range(BOARD_SIZE)):
            # 检查是否平局,弹出提示框,重置游戏
            messagebox.showinfo("游戏结束", "平局!")
            self.reset_to_mode_selection()
        else:
            # 切换玩家
            self.current_player = 1
            self.is_player_turn = True

AI通过遍历棋盘空位置,计算评分找到最佳落子点,落子后检查游戏状态并处理玩家切换。

按钮管理与游戏重置

为了让玩家能够方便地重新开始游戏,同时避免按钮显示异常,我们实现了按钮管理和游戏重置功能。

def create_reset_button(self):
    # 创建重置按钮
    self.reset_button = tk.Button(self.root, text="重置游戏", command=self.reset_to_mode_selection)
    self.reset_button.pack_forget()  # 初始时隐藏

def create_close_button(self):
    # 创建关闭游戏按钮
    self.close_button = tk.Button(self.root, text="关闭游戏", command=self.root.destroy)
    self.close_button.pack_forget()  # 初始时隐藏

def start_game(self, mode):
    # 隐藏模式选择框架
    self.mode_frame.pack_forget()
    self.close_button.pack_forget()  # 隐藏关闭游戏按钮
    self.mode = mode
    self.create_game_widgets()
    self.reset_game()
    self.is_player_turn = True
    self.reset_button.pack()  # 显示重置按钮
    if mode == "pve" and self.current_player == 2:
        # 如果是人机对战且 AI 先手,让 AI 先下棋
        self.ai_move()

def reset_to_mode_selection(self):
    self.reset_button.pack_forget()  # 隐藏重置按钮
    self.close_button.pack()  # 显示关闭游戏按钮
    self.show_mode_selection()

在初始化时创建重置按钮和关闭游戏按钮并隐藏,在游戏开始时显示重置按钮、隐藏关闭游戏按钮,游戏结束回到模式选择界面时,隐藏重置按钮、显示关闭游戏按钮。

总结

通过以上详细的步骤,我们成功地使用Python和Tkinter实现了一个功能完备的五子棋游戏。这个过程不仅让我们熟悉了Tkinter库的各种组件和事件处理机制,还深入理解了游戏开发中的核心概念,如状态管理、逻辑判断和简单的AI算法。

本文只展示了部分代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据攻城小狮子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值