当前位置: 首页 > article >正文

基于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()

http://www.kler.cn/a/457443.html

相关文章:

  • CUTLASS:高性能 CUDA 线性代数模板库详解
  • 如何修复 WordPress 中的“Error establishing a database connection”问题
  • 工业以太网交换机怎么挑选?
  • 理解生成协同促进?华为诺亚提出ILLUME,15M数据实现多模态理解生成一体化
  • 2025决战智驾:从中阶卷到L3,车企需要抓好一个数据闭环
  • Nginx1.20.2-Linux-安装
  • .net core 的算法与数据结构
  • 【华为OD-E卷-取出尽量少的球 100分(python、java、c++、js、c)】
  • 【Pandas】pandas Series to_numpy
  • 路由器刷机TP-Link tp-link-WDR5660 路由器升级宽带速度
  • TCP/IP网络协议攻击
  • PyTorch快速入门教程【小土堆】之TensorBoard的使用
  • 深度学习的魔法世界
  • SpringCloud 系列教程:微服务的未来(二)Mybatis-Plus的条件构造器、自定义SQL、Service接口基本用法
  • RabbitMQ的优缺点:深入解析消息队列的核心力量
  • Mac mini m4安装PD和Crack和关闭SIP
  • 安全运营 -- splunk restapi 最小权限
  • 如何提高Redis服务器的最大打开文件数限制
  • Flutter实现可拖拽操作Draggable
  • Pytorch注意力机制应用到具体网络方法(闭眼都会版)
  • vue导入导出excel、设置单元格文字颜色、背景色、合并单元格(使用xlsx-js-style库)
  • R 语言科研绘图第 11 期 --- 柱状图-基础
  • Linux -- 从抢票逻辑理解线程互斥
  • 酷瓜云课堂(内网版)v1.1.8 发布,局域网在线学习平台方案
  • 关于新手学习React的一些忠告
  • Selenium+Java(21):Jenkins发送邮件报错Not sent to the following valid addresses解决方案