一、代码实现
废话不多说,直接上代码( 娱乐向
’‘)
// 五子棋 规格:15*15
import tkinter as tk
from tkinter import messagebox
import time
class GomokuGame:
def __init__(self, root):
self.root = root
self.root.title("Gomoku 五子棋")
self.board_size = 15
#self.board_size = 19
self.cell_size = 40
self.canvas = tk.Canvas(self.root, width=self.board_size * self.cell_size, height=self.board_size * self.cell_size)
self.canvas.pack()
self.timer_label = tk.Label(self.root, text="剩余时间: 2:00", font=("Helvetica", 14))
self.timer_label.pack()
self.score_label = tk.Label(self.root, text="玩家A 胜: 0 负: 0 | 玩家B 胜: 0 负: 0", font=("Helvetica", 12))
self.score_label.pack()
self.undo_button = tk.Button(self.root, text="悔棋", command=self.undo_move)
self.undo_button.pack(side=tk.LEFT)
self.next_game_button = tk.Button(self.root, text="下一局", command=self.new_game)
self.next_game_button.pack(side=tk.LEFT)
self.end_game_button = tk.Button(self.root, text="结束对局", command=self.end_game)
self.end_game_button.pack(side=tk.RIGHT)
self.player_scores = {"黑": {"胜": 0, "负": 0}, "白": {"胜": 0, "负": 0}} # 初始化玩家胜负记录
self.reset_game()
self.create_ui()
self.canvas.bind("<Button-1>", self.make_move)
self.update_timer()
def reset_game(self):
self.board = [[None for _ in range(self.board_size)] for _ in range(self.board_size)]
self.current_player = "黑"
self.moves = []
self.undo_count = {"黑": 0, "白": 0}
self.is_game_over = False
self.start_time = time.time()
def create_ui(self):
self.canvas.delete("all") # 清空画布,防止重叠
for i in range(self.board_size):
self.canvas.create_line(self.cell_size // 2, self.cell_size // 2 + i * self.cell_size, self.cell_size // 2 + (self.board_size - 1) * self.cell_size, self.cell_size // 2 + i * self.cell_size)
self.canvas.create_line(self.cell_size // 2 + i * self.cell_size, self.cell_size // 2, self.cell_size // 2 + i * self.cell_size, self.cell_size // 2 + (self.board_size - 1) * self.cell_size)
# 标记常见的5个参考点
reference_points = [
(3, 3), (3, 11), (7, 7), (11, 3), (11, 11)
# (3, 3), (3, 15), (9, 9), (15, 3), (15, 15)
]
for x, y in reference_points:
self.canvas.create_oval(
x * self.cell_size + self.cell_size // 2 - 3,
y * self.cell_size + self.cell_size // 2 - 3,
x * self.cell_size + self.cell_size // 2 + 3,
y * self.cell_size + self.cell_size // 2 + 3,
fill="black"4
)
def update_timer(self):
if not self.is_game_over:
elapsed_time = time.time() - self.start_time
remaining_time = 120 - elapsed_time
if remaining_time <= 0:
self.show_time_up_warning()
remaining_time = 120
self.start_time = time.time()
minutes = int(remaining_time // 60)
seconds = int(remaining_time % 60)
self.timer_label.config(text=f"剩余时间: {minutes:02d}:{seconds:02d}")
self.root.after(1000, self.update_timer)
def show_time_up_warning(self):
messagebox.showwarning("提醒", "您已超过2分钟,请尽快下棋!")
def make_move(self, event):
if self.is_game_over:
return
# 计算棋子应该放置的交叉点位置
x = round((event.x - self.cell_size // 2) / self.cell_size)
y = round((event.y - self.cell_size // 2) / self.cell_size)
if x < 0 or y < 0 or x >= self.board_size or y >= self.board_size or self.board[x][y] is not None:
return
self.board[x][y] = self.current_player
self.moves.append((x, y))
self.start_time = time.time()
radius = self.cell_size * 0.392 # 棋子半径为栅格边长的0.392倍
color = "black" if self.current_player == "黑" else "white"
self.canvas.create_oval(
x * self.cell_size + self.cell_size // 2 - radius,
y * self.cell_size + self.cell_size // 2 - radius,
x * self.cell_size + self.cell_size // 2 + radius,
y * self.cell_size + self.cell_size // 2 + radius,
fill=color
)
if self.check_winner(x, y):
self.is_game_over = True
self.player_scores[self.current_player]["胜"] += 1
self.player_scores["白" if self.current_player == "黑" else "黑"]["负"] += 1
self.update_score_label()
messagebox.showinfo("游戏结束", f"{self.current_player}玩家获胜!")
else:
self.current_player = "白" if self.current_player == "黑" else "黑"
def check_winner(self, x, y):
directions = [(1, 0), (0, 1), (1, 1), (1, -1)]
for dx, dy in directions:
count = 1
for direction in (1, -1):
nx, ny = x + dx * direction, y + dy * direction
while 0 <= nx < self.board_size and 0 <= ny < self.board_size and self.board[nx][ny] == self.current_player:
count += 1
nx += dx * direction
ny += dy * direction
if count >= 5:
return True
return False
def undo_move(self):
if self.is_game_over:
return
if self.undo_count[self.current_player] < 1 and self.moves:
x, y = self.moves.pop()
self.board[x][y] = None
self.undo_count[self.current_player] += 1
# 恢复棋盘格子的颜色,而不是直接填充背景色
self.canvas.create_rectangle(
x * self.cell_size + self.cell_size // 2 - self.cell_size // 2,
y * self.cell_size + self.cell_size // 2 - self.cell_size // 2,
x * self.cell_size + self.cell_size // 2 + self.cell_size // 2,
y * self.cell_size + self.cell_size // 2 + self.cell_size // 2,
fill="saddlebrown", outline="black" # 使用与背景一致的颜色,并加上线条来恢复网格
)
self.current_player = "白" if self.current_player == "黑" else "黑"
def new_game(self):
self.reset_game()
self.create_ui()
def end_game(self):
self.is_game_over = True
result = f"玩家A 胜: {self.player_scores['黑']['胜']} 负: {self.player_scores['黑']['负']} \n玩家B 胜: {self.player_scores['白']['胜']} 负: {self.player_scores['白']['负']}"
messagebox.showinfo("结算画面", result)
self.root.quit()
def update_score_label(self):
score_text = f"玩家A 胜: {self.player_scores['黑']['胜']} 负: {self.player_scores['黑']['负']} | 玩家B 胜: {self.player_scores['白']['胜']} 负: {self.player_scores['白']['负']}"
self.score_label.config(text=score_text)
if __name__ == "__main__":
root = tk.Tk()
game = GomokuGame(root)
root.mainloop()
2、.py文件打包成.exe文件
要将Python代码打包成一个在Windows上无需安装Python环境即可运行的可执行文件(.exe),可以使用PyInstaller工具。
步骤一:安装PyInstaller
首先,您需要在您的开发环境中安装PyInstaller。可以win+R cmd 通过pip进行安装:
pip install pyinstaller
步骤二:打包Python脚本
使用命令行进入您存放Python脚本的目录。
cd path\to\your\script
运行PyInstaller命令
pyinstaller --onefile --windowed Wuziqi.py
这里的–onefile参数表示将所有依赖打包到一个可执行文件中,–windowed参数表示不显示命令行窗口(适用于GUI应用程序)。
步骤三:查找生成的可执行文件
打包完成后,PyInstaller会在您的项目目录中生成一个dist文件夹,里面包含了打包好的Wuziqi.exe文件。