游戏主体

main
hnu202410040132 3 months ago
parent e6bc34ffa7
commit dcd128a798

@ -0,0 +1,215 @@
import tkinter as tk
from tkinter import messagebox
class NumberChess:
def __init__(self, root):
self.root = root
self.root.title("数字棋")
self.board = [[None for _ in range(3)] for _ in range(3)]
self.current_player = ""
self.buttons = [[None for _ in range(3)] for _ in range(3)]
self.selected_cell = None
self.penalty_highlight = None
self.is_penalty_window_open = False
self.create_board()
def create_board(self):
for i in range(3):
for j in range(3):
button = tk.Button(self.root, text="", width=10, height=3, bg="white",
command=lambda i=i, j=j: self.on_click(i, j))
button.grid(row=i, column=j)
self.buttons[i][j] = button
def on_click(self, i, j):
cell = self.board[i][j]
if self.selected_cell is None:
if cell is None:
self.board[i][j] = (1, self.current_player)
self.update_button(i, j)
if self.check_win():
messagebox.showinfo("游戏结束", f"{self.current_player} 方获胜!")
self.reset_game()
else:
punishment_triggered = self.check_special_rule()
if not punishment_triggered:
self.switch_player()
else:
number, player = cell
if player == self.current_player:
self.selected_cell = (i, j)
self.highlight_selected(i, j)
else:
if self.move_selected_to(i, j):
if self.check_win():
messagebox.showinfo("游戏结束", f"{self.current_player} 方获胜!")
self.reset_game()
else:
punishment_triggered = self.check_special_rule()
if not punishment_triggered:
self.switch_player()
self.clear_selection()
def move_selected_to(self, i, j):
si, sj = self.selected_cell
if abs(si - i) + abs(sj - j) != 1:
return False
selected_number, selected_player = self.board[si][sj]
target_cell = self.board[i][j]
if (target_cell is None or target_cell[1] != selected_player) and (abs(i - si) + abs(j - sj) == 1):
new_number = selected_number
if target_cell is not None:
new_number += target_cell[0]
self.board[i][j] = (new_number, selected_player)
self.board[si][sj] = None
self.update_button(si, sj)
self.update_button(i, j)
return True
return False
def highlight_selected(self, i, j):
for x in range(3):
for y in range(3):
if (x, y) == (i, j):
self.buttons[x][y].config(bg="yellow")
else:
self.update_button(x, y)
def clear_selection(self):
self.selected_cell = None
for i in range(3):
for j in range(3):
self.update_button(i, j)
def update_button(self, i, j):
cell = self.board[i][j]
if cell is None:
self.buttons[i][j].config(text="", bg="white")
else:
number, player = cell
bg_color = "red" if player == "" else "blue"
fg_color = "black"
cell_text = str(number)
if self.penalty_highlight and (i, j) in self.penalty_highlight:
index = self.penalty_highlight.index((i, j)) + 1
cell_text += f"_{index}"
bg_color = "lightgreen" # 使用绿色背景突出显示
self.buttons[i][j].config(text=cell_text, bg=bg_color, fg=fg_color)
def switch_player(self):
self.current_player = "" if self.current_player == "" else ""
def check_win(self):
for row in self.board:
for cell in row:
if cell and cell[0] >= 10:
return True
return False
def check_special_rule(self):
if not self.has_empty_cell():
self.apply_special_rule()
return True
return False
def has_empty_cell(self):
for row in self.board:
if None in row:
return True
return False
def apply_special_rule(self):
current_player_cells = []
for i in range(3):
for j in range(3):
cell = self.board[i][j]
if cell and cell[1] == self.current_player:
current_player_cells.append(cell)
if not current_player_cells:
return
max_number = max(cell[0] for cell in current_player_cells)
max_cells = [(i,j) for i in range(3) for j in range(3)
if self.board[i][j] and
self.board[i][j][1] == self.current_player and
self.board[i][j][0] == max_number]
if len(max_cells) == 1:
i, j = max_cells[0]
self.apply_number_reduction(i, j, None) # 传入 None 表示无窗口
else:
self._max_cells = max_cells.copy()
self.penalty_highlight = self._max_cells.copy()
self.ask_player_to_choose(max_cells)
def ask_player_to_choose(self, max_cells):
if self.is_penalty_window_open:
return
self.is_penalty_window_open = True
self._max_cells = max_cells
self.ask_window = tk.Toplevel(self.root)
self.ask_window.title("选择一个数字减1")
self.ask_window.grab_set()
self.ask_window.protocol("WM_DELETE_WINDOW", self.on_window_close)
label_text = f"请选择 {self.current_player} 方要减1的数字"
label = tk.Label(self.ask_window, text=label_text)
label.pack(padx=10, pady=10)
for idx, (i, j) in enumerate(max_cells):
cell = self.board[i][j]
color = "red" if cell[1] == "" else "blue"
frame = tk.Frame(self.ask_window,
highlightbackground=color,
highlightthickness=2)
coord_label = tk.Label(frame, text=f"({i+1}, {j+1})")
coord_label.pack()
button = tk.Button(frame,
text=str(cell[0]),
width=5,
height=2,
command=lambda i=i, j=j: self.apply_number_reduction(i, j, self.ask_window))
button.pack(padx=2, pady=2)
frame.pack(side=tk.LEFT, padx=5, pady=5)
def on_window_close(self):
messagebox.showwarning("警告", "必须选择一个棋子才能继续操作!", parent=self.ask_window)
self.ask_window.grab_set()
def apply_number_reduction(self, i, j, window):
number, player = self.board[i][j]
if number == 1:
self.board[i][j] = None
else:
self.board[i][j] = (number - 1, player)
self.penalty_highlight = None
self.update_button(i, j)
# 只有当 window 存在时才销毁
if window:
window.destroy()
self.is_penalty_window_open = False
self.switch_player()
def reset_game(self):
self.board = [[None for _ in range(3)] for _ in range(3)]
for i in range(3):
for j in range(3):
self.buttons[i][j].config(text="", bg="white")
self.current_player = ""
self.penalty_highlight = None
self.is_penalty_window_open = False
if __name__ == "__main__":
root = tk.Tk()
game = NumberChess(root)
root.mainloop()
Loading…
Cancel
Save