游戏两种模式,人机对战和人人对战。非常好玩!
运行展示
使用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算法。
本文只展示了部分代码