|
|
@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
import tkinter as tk
|
|
|
|
|
|
|
|
from tkinter import messagebox
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Gobang:
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
|
|
self.window = tk.Tk()
|
|
|
|
|
|
|
|
self.window.title("五子棋")
|
|
|
|
|
|
|
|
self.window.geometry("660x700")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.canvas = tk.Canvas(self.window, bg="#CDBA96", width=660, height=660)
|
|
|
|
|
|
|
|
self.canvas.pack()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.restart_btn = tk.Button(self.window, text="重新开始", command=self.restart)
|
|
|
|
|
|
|
|
self.restart_btn.pack()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 游戏参数
|
|
|
|
|
|
|
|
self.grid_size = 30 # 网格间距
|
|
|
|
|
|
|
|
self.offset = 30 # 棋盘边距
|
|
|
|
|
|
|
|
self.board_size = 15 # 棋盘尺寸(15x15)
|
|
|
|
|
|
|
|
self.piece_size = 13 # 棋子半径
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化棋盘
|
|
|
|
|
|
|
|
self.board = [[0] * self.board_size for _ in range(self.board_size)]
|
|
|
|
|
|
|
|
self.current_player = 1 # 当前玩家(1: 黑棋,2: 白棋)
|
|
|
|
|
|
|
|
self.game_over = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.draw_board()
|
|
|
|
|
|
|
|
self.canvas.bind("<Button-1>", self.click_handler)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def draw_board(self):
|
|
|
|
|
|
|
|
# 绘制棋盘网格
|
|
|
|
|
|
|
|
for i in range(self.board_size):
|
|
|
|
|
|
|
|
x_start = self.offset + i * self.grid_size
|
|
|
|
|
|
|
|
y_start = self.offset
|
|
|
|
|
|
|
|
x_end = self.offset + i * self.grid_size
|
|
|
|
|
|
|
|
y_end = self.offset + (self.board_size - 1) * self.grid_size
|
|
|
|
|
|
|
|
self.canvas.create_line(x_start, y_start, x_end, y_end)
|
|
|
|
|
|
|
|
self.canvas.create_line(y_start, x_start, y_end, x_end)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def draw_piece(self, row, col):
|
|
|
|
|
|
|
|
# 绘制棋子
|
|
|
|
|
|
|
|
x = self.offset + col * self.grid_size
|
|
|
|
|
|
|
|
y = self.offset + row * self.grid_size
|
|
|
|
|
|
|
|
color = "black" if self.current_player == 1 else "white"
|
|
|
|
|
|
|
|
self.canvas.create_oval(x - self.piece_size, y - self.piece_size,
|
|
|
|
|
|
|
|
x + self.piece_size, y + self.piece_size,
|
|
|
|
|
|
|
|
fill=color, outline=color)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def click_handler(self, event):
|
|
|
|
|
|
|
|
if self.game_over:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 计算点击位置对应的棋盘坐标
|
|
|
|
|
|
|
|
col = round((event.x - self.offset) / self.grid_size)
|
|
|
|
|
|
|
|
row = round((event.y - self.offset) / self.grid_size)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if 0 <= row < self.board_size and 0 <= col < self.board_size:
|
|
|
|
|
|
|
|
if self.board[row][col] == 0:
|
|
|
|
|
|
|
|
self.board[row][col] = self.current_player
|
|
|
|
|
|
|
|
self.draw_piece(row, col)
|
|
|
|
|
|
|
|
if self.check_win(row, col):
|
|
|
|
|
|
|
|
self.show_winner()
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.current_player = 2 if self.current_player == 1 else 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_win(self, row, col):
|
|
|
|
|
|
|
|
# 检查四个方向是否五连
|
|
|
|
|
|
|
|
directions = [(1, 0), (0, 1), (1, 1), (1, -1)] # 水平,垂直,对角线
|
|
|
|
|
|
|
|
for dr, dc in directions:
|
|
|
|
|
|
|
|
count = 1
|
|
|
|
|
|
|
|
# 正向检查
|
|
|
|
|
|
|
|
r, c = row + dr, col + dc
|
|
|
|
|
|
|
|
while 0 <= r < self.board_size and 0 <= c < self.board_size:
|
|
|
|
|
|
|
|
if self.board[r][c] == self.current_player:
|
|
|
|
|
|
|
|
count += 1
|
|
|
|
|
|
|
|
r += dr
|
|
|
|
|
|
|
|
c += dc
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
# 反向检查
|
|
|
|
|
|
|
|
r, c = row - dr, col - dc
|
|
|
|
|
|
|
|
while 0 <= r < self.board_size and 0 <= c < self.board_size:
|
|
|
|
|
|
|
|
if self.board[r][c] == self.current_player:
|
|
|
|
|
|
|
|
count += 1
|
|
|
|
|
|
|
|
r -= dr
|
|
|
|
|
|
|
|
c -= dc
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if count >= 5:
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def show_winner(self):
|
|
|
|
|
|
|
|
self.game_over = True
|
|
|
|
|
|
|
|
winner = "黑方" if self.current_player == 1 else "白方"
|
|
|
|
|
|
|
|
messagebox.showinfo("游戏结束", f"{winner}获胜!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def restart(self):
|
|
|
|
|
|
|
|
self.canvas.delete("all")
|
|
|
|
|
|
|
|
self.board = [[0] * self.board_size for _ in range(self.board_size)]
|
|
|
|
|
|
|
|
self.current_player = 1
|
|
|
|
|
|
|
|
self.game_over = False
|
|
|
|
|
|
|
|
self.draw_board()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
|
|
|
self.window.mainloop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
game = Gobang()
|
|
|
|
|
|
|
|
game.run()
|