基于python的ai五子棋游戏
游戏
运行代码后,点击"Enable AI Opponent"按钮,AI将作为白棋自动下棋。
玩家作为黑棋,点击棋盘落子。
AI会根据当前棋盘局势自动选择落子位置。
界面
代码
import tkinter as tk
from tkinter import messagebox
BOARD_SIZE = 15
CELL_SIZE = 40
STONE_RADIUS = 15
BOARD_COLOR = "#DEB887"
class Gomoku:
def __init__(self, root):
self.root = root
self.root.title("Gomoku")
self.root.resizable(False, False)
self.board = [[0] * BOARD_SIZE for _ in range(BOARD_SIZE)] # 0: empty, 1: black, 2: white
self.is_black_turn = True # Black goes first
self.ai_enabled = False # Whether AI opponent is enabled
self.canvas = tk.Canvas(root, width=BOARD_SIZE * CELL_SIZE, height=BOARD_SIZE * CELL_SIZE, bg=BOARD_COLOR)
self.canvas.pack()
self.draw_board()
self.canvas.bind("<Button-1>", self.on_mouse_click)
# Add AI toggle button
self.ai_button = tk.Button(root, text="Enable AI Opponent", command=self.toggle_ai)
self.ai_button.pack()
def draw_board(self):
self.canvas.delete("all")
for i in range(BOARD_SIZE):
self.canvas.create_line(0, i * CELL_SIZE, BOARD_SIZE * CELL_SIZE, i * CELL_SIZE) # Draw horizontal lines
self.canvas.create_line(i * CELL_SIZE, 0, i * CELL_SIZE, BOARD_SIZE * CELL_SIZE) # Draw vertical lines
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
if self.board[i][j] == 1:
self.canvas.create_oval(i * CELL_SIZE - STONE_RADIUS, j * CELL_SIZE - STONE_RADIUS,
i * CELL_SIZE + STONE_RADIUS, j * CELL_SIZE + STONE_RADIUS, fill="black")
elif self.board[i][j] == 2:
self.canvas.create_oval(i * CELL_SIZE - STONE_RADIUS, j * CELL_SIZE - STONE_RADIUS,
i * CELL_SIZE + STONE_RADIUS, j * CELL_SIZE + STONE_RADIUS, fill="white")
def on_mouse_click(self, event):
if self.is_black_turn or not self.ai_enabled:
x = (event.x + CELL_SIZE // 2) // CELL_SIZE
y = (event.y + CELL_SIZE // 2) // CELL_SIZE
if 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and self.board[x][y] == 0:
self.place_stone(x, y)
if self.check_win(x, y):
winner = "Black" if self.is_black_turn else "White"
messagebox.showinfo("Game Over", f"{winner} wins!")
self.reset_board()
else:
self.is_black_turn = not self.is_black_turn
if self.ai_enabled and not self.is_black_turn:
self.ai_move()
def place_stone(self, x, y):
self.board[x][y] = 1 if self.is_black_turn else 2
self.draw_board()
def reset_board(self):
self.board = [[0] * BOARD_SIZE for _ in range(BOARD_SIZE)]
self.is_black_turn = True
self.draw_board()
def check_win(self, x, y):
player = self.board[x][y]
return self.check_direction(x, y, 1, 0, player) or \
self.check_direction(x, y, 0, 1, player) or \
self.check_direction(x, y, 1, 1, player) or \
self.check_direction(x, y, 1, -1, player)
def check_direction(self, x, y, dx, dy, player):
count = 1
for i in range(1, 5):
nx, ny = x + i * dx, y + i * dy
if 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and self.board[nx][ny] == player:
count += 1
else:
break
for i in range(1, 5):
nx, ny = x - i * dx, y - i * dy
if 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and self.board[nx][ny] == player:
count += 1
else:
break
return count >= 5
def toggle_ai(self):
self.ai_enabled = not self.ai_enabled
self.ai_button.config(text="Disable AI Opponent" if self.ai_enabled else "Enable AI Opponent")
if self.ai_enabled and not self.is_black_turn:
self.ai_move()
def ai_move(self):
best_score = -1
best_move = None
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
if self.board[i][j] == 0:
score = self.evaluate_position(i, j)
if score > best_score:
best_score = score
best_move = (i, j)
if best_move:
self.place_stone(*best_move)
if self.check_win(*best_move):
winner = "White"
messagebox.showinfo("Game Over", f"{winner} wins!")
self.reset_board()
else:
self.is_black_turn = not self.is_black_turn
def evaluate_position(self, x, y):
# Simple scoring system
score = 0
for dx, dy in [(1, 0), (0, 1), (1, 1), (1, -1)]:
score += self.evaluate_direction(x, y, dx, dy, 2) # AI is White
score += self.evaluate_direction(x, y, dx, dy, 1) # Block Black
return score
def evaluate_direction(self, x, y, dx, dy, player):
count = 0
for i in range(1, 5):
nx, ny = x + i * dx, y + i * dy
if 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and self.board[nx][ny] == player:
count += 1
else:
break
for i in range(1, 5):
nx, ny = x - i * dx, y - i * dy
if 0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE and self.board[nx][ny] == player:
count += 1
else:
break
return count ** 2 # More consecutive stones, higher score
if __name__ == "__main__":
root = tk.Tk()
game = Gomoku(root)
root.mainloop()