基于python的ai五子棋游戏

news2025/1/6 19:23:09

游戏

运行代码后,点击"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.coloradmin.cn/o/2270613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 软件I2C读写

单片机学习&#xff01; 目录 前言 一、软件I2C读写代码框架 二、I2C初始化 三、六个时序基本单元 3.1 引脚操作的封装和改名 3.2 起始条件执行逻辑 3.3 终止条件执行逻辑 3.4 发送一个字节 3.5 接收一个字节 3.5 发送应答&接收应答 3.5.1 发送应答 3.5.2 接…

多光谱图像的处理和分析方法有哪些?

一、预处理方法 1、辐射校正&#xff1a; 目的&#xff1a;消除或减少传感器本身、大气条件以及太阳光照等因素对多光谱图像辐射亮度值的影响&#xff0c;使得图像的辐射值能够真实反映地物的反射或发射特性。 方法&#xff1a;包括传感器校正和大气校正。传感器校正主要是根…

服务器数据恢复—离线盘数超过热备盘数导致raidz阵列崩溃的数据恢复

服务器数据恢复环境&故障&#xff1a; 一台配有32块硬盘的服务器在运行过程中突然崩溃不可用。经过初步检测&#xff0c;基本上确定服务器硬件不存在物理故障。管理员重启服务器后问题依旧。需要恢复该服务器中的数据。 服务器数据恢复环境&#xff1a; 1、将服务器中硬盘…

Jenkins管理多版本python环境

场景&#xff1a;项目有用到python3.8和3.9&#xff0c;python环境直接安装在jenkins容器内。 1、进入jenkins容器 docker exec -it jenkins /bin/bash 2、安装前置编译环境 # 提前安装&#xff0c;以便接下来的配置操作 apt-get -y install gcc automake autoconf libtool ma…

《机器学习》从入门到实战——逻辑回归

目录 一、简介 二、逻辑回归的原理 1、线性回归部分 2、逻辑函数&#xff08;Sigmoid函数&#xff09; 3、分类决策 4、转换为概率的形式使用似然函数求解 5、对数似然函数 ​编辑 6、转换为梯度下降任务 三、逻辑回归拓展知识 1、数据标准化 &#xff08;1&#xf…

开发小工具:ping地址

开发小工具&#xff1a;ping地址 import socketdef tcp_port_scan(ip,port):#创建套接字socksocket.socket(socket.AF_INET,socket.SOCK_STREAM)#设置超时sock.settimeout(0.2)try:#发请求result sock.connect_ex((ip,port))if result 0:print(f{ip}--{port}接口连接成功)res…

41.1 预聚合提速实战项目之需求分析和架构设计

本节重点介绍 : 需求分析架构设计 需求分析 使用预聚合提速查询并且降低高基数查询对后端的压力用户无需变更grafana上的查询语句&#xff0c;后端自动替换效果图 架构设计 架构图 解决方案说明 heavy_query对用户侧表现为查询速度慢在服务端会导致资源占用过多甚至打挂…

同三维T80004ES H.265高清SDI编码器

1路SDI 1路3.5音频输入,1路SDI环出 产品简介&#xff1a; 同三维T80004ES高标清SDI音视频编码器支持1路高清或1路标清SDI音视频&#xff0c;1路3.5MM独立音频接口采集功能。编码输出双码流H.265/H.264格式&#xff0c;音频 MP3/AAC格式。编码码率可调&#xff0c;画面质量可控制…

C#高级篇 反射和属性详解【代码之美系列】

&#x1f380;&#x1f380;&#x1f380;代码之美系列目录&#x1f380;&#x1f380;&#x1f380; 一、C# 命名规则规范 二、C# 代码约定规范 三、C# 参数类型约束 四、浅析 B/S 应用程序体系结构原则 五、浅析 C# Async 和 Await 六、浅析 ASP.NET Core SignalR 双工通信 …

MySQL5.7.26-Linux-安装(2024.12)

文章目录 1.下载压缩包1.访问MySQL版本归档2.找到5.7.26并下载3.百度网盘 2.Linux安装1.卸载原来的MySQL8.0.26&#xff08;如果没有则无需在意&#xff09;1.查看所有mysql的包2.批量卸载3.删除残留文件**配置文件**&#xff08;默认路径&#xff09;&#xff1a; 4.**验证卸载…

数据分析思维(六):分析方法——相关分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

前 5 名 IPhone 解锁工具/软件

设备已禁用并且您无法访问它&#xff1f;如果您无法通过密码解锁&#xff0c;尝试 iPhone 解锁软件可能是最好的解决方案。 虽然市场上有很多免费或付费的 iPhone 解锁工具&#xff0c;但您可能不知道它们之间的区别以及如何选择最适合您的工具。 本文将介绍 5 款iPhone 解锁…

【LeetCode Hot100 回溯】组合、排列、子集、分割、N皇后、单词搜索、括号生成、电话号码的字母组合

回溯 组合问题组合总和全排列子集分割回文串N皇后电话号码的字母组合单词搜索括号生成 组合问题 给定两个整数 n 和 k&#xff0c;返回 1 … n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 树形结构&#xff1…

Docker--Docker Container(容器) 之 操作实例

容器的基本操作 容器的操作步骤其实很简单&#xff0c;根据拉取的镜像&#xff0c;进行启动&#xff0c;后可以查看容器&#xff0c;不用时停止容器&#xff0c;删除容器。 下面简单演示操作步骤 1.创建并运行容器 例如&#xff0c;创建一个名为"my-nginx"的交互…

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…

Python爬虫入门实例:Python7个爬虫小案例(附源码)

引言 随着互联网的快速发展&#xff0c;数据成为了新时代的石油。Python作为一种高效、易学的编程语言&#xff0c;在数据采集领域有着广泛的应用。本文将详细讲解Python爬虫的原理、常用库以及实战案例&#xff0c;帮助读者掌握爬虫技能。 一、爬虫原理 爬虫&#xff0c;又…

LeetCode - 初级算法 数组(只出现一次的数字)

只出现一次的数字 这篇文章讨论如何找到一个数组中只出现一次的数字,确保算法的时间复杂度为线性,且只使用常量额外空间。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定一个非空整数数组 nums,除了某个元素只出现一次以外,其余每个元素均出现两…

【视频笔记】基于PyTorch从零构建多模态(视觉)大模型 by Umar Jamil【持续更新】

视频链接: 基于PyTorch从零构建多模态(视觉)大模型 by Umar Jamil 从头编写一个视觉语言模型:PloyGamma,是谷歌的一个模型 1:原始图像 2:视觉编码器(本文是viT),通过对比学习进行训练。这个对比学习最开始是CLIP,后来被谷歌改成了SigLIP 3:线性投影层 4:如何将图…

Doris 2.1 Deleting Data 学习笔记

1 Deleting Data with DELETE Command 1.1 Delete by Specifying a Filter Predicate DELETE FROM table_name [table_alias] [PARTITION partition_name | PARTITIONS (partition_name [

基于51单片机(STC12C5A60S2)和8X8彩色点阵屏(WS2812B驱动)的小游戏《贪吃蛇》(普中开发板矩阵按键控制)

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、定时器02、矩阵按键3、8X8彩色点阵屏 四、主函数总结 系列文章目录 前言 《贪吃蛇》&#xff0c;一款经典的、怀旧的小游戏&#xff0c;单片机入门必写程序。 以《贪吃蛇》为载体&#xff0c;熟悉各种屏幕的使…