井字棋游戏

1. 游戏创建

1.1导包

from tkinter import *
import numpy as np
import math
import tkinter.messagebox

1.2 窗口内容

1.2.1创建一个窗口

root = Tk()  # 窗口名称
root.title("井字棋 from Sun")

1.2.2 创建一个框架,将其放置在窗口中

Frame1 = Frame(root)  # 框架
Frame1.pack()

1.2.3 创建一个用来绘制九宫格的画布w1

w1 = Canvas(Frame1, width=580, height=580, bg="white")  # 创建一个画布(Canvas),设置大小
w1.pack()    # w1:画布

1.3 绘制九宫格

  使用create_line在画布上绘制九宫格。

for i in range(0, 4):w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560)  # 绘制竖线w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)  # 绘制横线

运行结果:

1.4 定义一个全局变量

# 定义全局变量numnum = 0 # 记录点击的次数,用来决定点击后该画哪种图形# 定义一个3X3的数组AA = np.full((3, 3), 0) # 记录每个位置的图形# 0表示空,1表示叉号,2表示圆圈。

1.5 定义一个鼠标事件

根据鼠标的点击在网格中绘制“X”和“O”

def dawn(event):global w1global num, Afor i in range(0, 3):  # 确定被单击的网格单元格的行号。for j in range(0, 3):  # 确定被单击的网格单元格的行号。if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:breakif 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:breakif num % 2 == 0 and A[i][j] == 0:   # 如果当前玩家是 X并且该单元格为空,则绘制叉号。A[i][j] = 1   

1.6 创建图形“×”和“○”

1.6.1 创建“×”

# 使用create_line方法在指定位置绘制叉号。w1.create_line(110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2), width=5)w1.create_line(110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2), width=5)num += 1  # 增加点击次数。

1.6.2 创建“○”

# 使用create_oval方法在指定位置绘制圆圈。w1.create_oval(20 + 180 * i + 10, 20 + 180 * j + 10, 20 + 180 * (i + 1) - 10, 20 + 180 * (j + 1) - 10, width=5)num += 1

1.7 对弈结果:①“X”获胜  ②“O获胜”③ 平局

1.7.1 “O”获胜的所有可能性

  • 所有可能性:  ① 横向三个相邻单元格都包含 O。
  •                         ② 纵向三个相邻单元格都包含 O。
  •                         ③ 从左上角到右下角的对角线上的所有单元格都包含 O。
  •                         ④ 从右上角到左下角的对角线上的所有单元格都包含 O。

    

if (A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][2] == 2 or A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] ==A[2][2] == 2 or A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2):tkinter.messagebox.showinfo('Warning', '恭喜O获胜啦')

1.7.2 “X”获胜的所有可能性

  • 所有可能性:  ① 横向三个相邻单元格都包含 X。
    •                         ② 纵向三个相邻单元格都包含 X。
      •                         ③ 从左上角到右下角的对角线上的所有单元格都包含 X。
        •                         ④ 从右上角到左下角的对角线上的所有单元格都包含 X。
elif (A[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][2] == 1 or A[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] ==A[2][2] == 1 or  [0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1):tkinter.messagebox.showinfo('Warning', '恭喜X获胜啦')

1.7.3 平局的所有可能性

          每个棋子最多能走5步,当X走了5步时,则O只走了4步,所以XO加一起只能走9步,所以当没有棋子连在一起的时候,就该考虑是否已经走了9次,如果走了就此还没达到获胜条件时,那么这时候就是平局

    elif num == 9 and not (A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][2] == 2 or A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] ==A[2][2] == 2 or A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2 orA[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][2] == 1 or A[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] == A[2][2] == 1 orA[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] ==1):tkinter.messagebox.showinfo('Warning', 'woo平局啦!')

1.8 “退出”

1.8.1 退出的函数

def quit():root.quit()

1.8.2 退出的按钮

# 退出按钮button1 = Button(root, text="退出", font=('微软雅黑', 15), command=quit)button1.pack()

1.9 “重新开始”

1.9.1 重新开始的函数

def restart():global w1, num, Aw1.delete("all")  # 清除画布上所有的东西for i in range(0, 4):w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560)w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)num = 0A = np.full((3, 3), 0)w1.bind("<Button -1>", dawn)

1.9.1 从新开始的按钮

# 重新开始按钮button2 = Button(root, text="重新开始", font=('微软雅黑', 15), command=restart)button2.pack()

2. 完整代码

from tkinter import *
import numpy as np
import math
import tkinter.messageboxroot = Tk()  # 窗口名称
root.title("井字棋 from Sun")
# root.geometry("600x600")
Frame1 = Frame(root)  # 框架
Frame1.pack()
w1 = Canvas(Frame1, width=580, height=580, bg="white")  # 创建一个画布(Canvas),设置大小
w1.pack()    # w1:画布for i in range(0, 4):w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560)  # 绘制竖线w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)  # 绘制横线# 定义全局变量num
num = 0							# 记录点击的次数,用来决定点击后该画哪种图形
# 定义一个3X3的数组A
A = np.full((3, 3), 0)			# 记录每个位置的图形
# 0表示空,1表示叉号,2表示圆圈。def dawn(event):global w1global num, Afor i in range(0, 3):  # 确定被单击的网格单元格的行号。for j in range(0, 3):  # 确定被单击的网格单元格的行号。if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:breakif 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:breakif num % 2 == 0 and A[i][j] == 0:   # 如果当前玩家是 X并且该单元格为空,则绘制叉号。# 网格中的行 i 和列 jA[i][j] = 1   # 二维数组:A[i][j]# 使用create_line方法在指定位置绘制叉号。w1.create_line(110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2), width=5)w1.create_line(110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2), width=5)num += 1  # 增加点击次数。if num % 2 != 0 and A[i][j] == 0:   # 如果当前玩家是 O 并且该单元格为空,则绘制圆圈。A[i][j] = 2# 使用create_oval方法在指定位置绘制圆圈。w1.create_oval(20 + 180 * i + 10, 20 + 180 * j + 10, 20 + 180 * (i + 1) - 10, 20 + 180 * (j + 1) - 10, width=5)num += 1
# 0表示空,1表示叉号,2表示圆圈  # \ :换行if (A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][2] == 2 or A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] ==A[2][2] == 2 or A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2):# 从左上角到右下角的对角线上的所有单元格都包含 O or 从右上角到左下角的对角线上的所有单元格都包含 Otkinter.messagebox.showinfo('Warning', '恭喜O获胜啦')elif (A[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][2] == 1 or A[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] ==A[2][2] == 1 orA[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1):tkinter.messagebox.showinfo('Warning', '恭喜X获胜啦')elif num == 9 and not (A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][2] == 2 or A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] ==A[2][2] == 2 or A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2 orA[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][2] == 1 orA[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] == A[2][2] == 1 orA[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1):tkinter.messagebox.showinfo('Warning', 'woo平局啦!')def restart():global w1, num, Aw1.delete("all")  # 清除画布上所有的东西for i in range(0, 4):w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560)w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)num = 0A = np.full((3, 3), 0)w1.bind("<Button -1>", dawn)
def quit():root.quit()
# 退出按钮
button1 = Button(root, text="退出", font=('微软雅黑', 15), command=quit)
button1.pack()
# 重新开始按钮
button2 = Button(root, text="重新开始", font=('微软雅黑', 15), command=restart)
button2.pack()root.mainloop()

3. 运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/3905.shtml

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

相关文章

汽车底盘域的学习笔记

前言&#xff1a;底盘域分为传统车型底盘域和新能源车型底盘域&#xff08;新能源系统又可以分为纯电和混动车型&#xff0c;有时间可以再研究一下&#xff09; 1&#xff1a;传统车型底盘域 细分的话可以分为四个子系统 传动系统 行驶系统 转向系统 制动系统 1.1传动系…

什么样的内外网文档摆渡,可以实现安全高效传输?

内外网文档摆渡通常指的是在内网&#xff08;公司或组织的内部网络&#xff09;和外网&#xff08;如互联网&#xff09;之间安全地传输文件的过程。这个过程需要特别注意安全性&#xff0c;因为内网往往包含敏感数据&#xff0c;直接连接内网和外网可能会带来安全风险。因此会…

设计模式——终止模式之两阶段终止模式

文章目录 1. 错误思路2. 两阶段终止模式2.1 利用 isInterrupted2.2 利用停止标记interrupt-打断park Two Phase Termination 在一个线程 T1 中如何“优雅”终止线程 T2&#xff1f;这里的【优雅】指的是给 T2 一个料理后事的机会。 1. 错误思路 使用线程对象的 stop() 方法停…

GEM TSU Interface Details and IEEE 1588 Support

摘要&#xff1a;Xilinx ZNYQ ULTRASCALE MPSOC的GEM和1588的使用 对于FPGA来说&#xff0c;只需要勾选一些znyq的配置就行了&#xff0c;其余的都是软件的工作&#xff1b; 所有配置都勾选之后&#xff0c;最终会露出来的接口如下&#xff1a; GEM需要勾选的配置如下&#xf…

15.Blender Eevee和Cycles渲染引擎对比

初步介绍 Eevee是实时渲染的引擎&#xff0c;会省略一些解算方式&#xff0c;尤其对光线和阴影 Cycles会考虑这些因素&#xff0c;所以会对光线和阴影的表达更加真实&#xff0c;有一个实时光线追踪的功能 Cycles渲染完之后&#xff0c;每移动一次画面&#xff0c;都会重新渲染…

政安晨:【Keras机器学习示例演绎】(十九)—— 可视化网络学习内容

目录 简介 设置 建立特征提取模型 设置梯度上升过程 设置端到端滤波器可视化回路 可视化目标层中的前 64 个滤波器 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&…

基于Rust的多线程 Web 服务器

构建多线程 Web 服务器 在 socket 上监听 TCP 连接解析少量的 HTTP 请求创建一个合适的 HTTP 响应使用线程池改进服务器的吞吐量优雅的停机和清理注意&#xff1a;并不是最佳实践 创建项目 ~/rust ➜ cargo new helloCreated binary (application) hello package~/rust ➜ma…

kaggle之皮肤癌数据的深度学习测试

kaggle之皮肤癌数据的深度学习测试 近期一直在肝深度学习 很久之前&#xff0c;曾经上手搞过一段时间的深度学习&#xff0c;似乎是做轮胎花纹的识别&#xff0c;当初用的是TensorFlow&#xff0c;CPU版本的&#xff0c;但已经很长时间都没弄过了 现在因为各种原因&#xff…

全面解析平台工程与 DevOps 的区别与联系

平台工程的概念非常流行&#xff0c;但很多开发人员仍然不清楚它是如何实际运作的&#xff0c;这是非常正常的。 平台工程是与 DevOps 并行吗&#xff1f;还是可以相互替代&#xff1f;或者 DevOps 和平台工程是两个完全不同的概念&#xff1f; 一种比较容易将两者区分开来的方…

打包的意义 作用等前端概念集合 webpack基础配置等

基础网页是什么&#xff1f; 在学校最基础的三剑客 原生JS CSS H5就可以开发静态网页了 对于浏览器而言也能识别这些基础的文件和语法&#xff0c;真正的所见即所得&#xff0c;非常直接。 为什么要使用框架库&#xff1f; 对于常用的前端框架而言&#xff0c;无论是Vue Rea…

普通屏幕已过时?裸眼3D屏幕显示效果更胜一筹!

随着多媒体技术的迅猛进步&#xff0c;我们日常生活中的内容展现方式&#xff0c;已经经历了前所未有的变革。在这其中&#xff0c;裸眼3D屏幕的应用&#xff0c;无疑是最为引人注目的亮点&#xff0c;它相较于传统屏幕&#xff0c;在显示效果上展现出了鲜明的优势&#xff0c;…

RGB灯珠的控制-单片机通用模板

RGB灯珠的控制-单片机通用模板 一、RGB控制的原理二、RGB.c的实现三、RGB.h的实现四、color色彩空间变换以及控制渐变一、RGB控制的原理 ①通过IO发送脉冲识别0/1编码,组合24Bit的RGB数据,从而控制RGB;②每个RGB灯珠通过DIN、DOU进行级联起来;③通过HSV色彩转换成RGB从而控…

ArcGIS批量寻找图层要素中的空洞

空洞指的是图层中被要素包围所形成的没有被要素覆盖的地方&#xff0c;当图层要素数量非常庞大时&#xff0c;寻找这些空洞就不能一个一个的通过目测去寻找了&#xff0c;需要通过使用工具来实现这一目标。 一、【要素转线】工具 利用【要素转线】工具可以将空洞同图层要素处于…

【触摸案例-多点触摸的案例 Objective-C语言】

一、我们来做这个多点触摸的案例 1.首先呢,按着这个option键啊,可以模拟多点触摸, 然后呢,再去怎么着去画圈儿, 它这个里边就会产生一个imageView,跟着你去变,会有这么一个效果, 那么,首先啊,我们新建一个项目, Name:03-多点触摸的案例 1)首先,我们把控制器的v…

Xcode for Mac:强大易用的集成开发环境

Xcode for Mac是一款专为苹果开发者打造的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它集成了代码编辑器、编译器、调试器等一系列开发工具&#xff0c;让开发者能够在同一界面内完成应用的开发、测试和调试工作。 Xcode for Mac v15.2正式版下载 Xcode支持多种编程…

ShardingSphere 5.x 系列【25】 数据分片原理之 SQL 解析

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 分片执行流程1.1 Simple Push Down1.2 SQL Federation2. SQL 解析2.1 解析…

分布式WEB应用中会话管理的变迁之路

Session一词直译为“会话”&#xff0c;意指有始有终的一系列动作&#xff0f;消息。Session是Web应用蓬勃发展的产物之一&#xff0c;在Web应用中隐含有“面向连接”和“状态保持”两个含义&#xff0c;同时也指代了Web服务器与客户端之间进行状态保持的解决方案。 在Web应用…

基于JAVA实现的推箱子小游戏

Java推箱子小游戏实现&#xff1a; 推箱子小游戏曾经在我们的童年给我们带来了很多乐趣。推箱子这款游戏现在基本上没人玩了&#xff0c;甚至在新一代人的印象中都已毫无记忆了。。。但是&#xff0c;这款游戏可以在一定程度上锻炼自己的编程能力。 窗口画面设计&#xff1a;i…

8点法估计基础矩阵

估计基础矩阵 文章目录 估计基础矩阵8点法归一化 8点法 8点法 根据两幅图像中8个对应点对之间的关系&#xff0c;采用SVD求 解最小二乘方 约束&#xff1a;det(F) 0 假设已知N对点的对应关系&#xff1a; { x i , x i ′ } i 1 N \{x_i,x^{\prime}_i\}_{i1}^N {xi​,xi′​…

Mysql索引规范及原理分析

1 Mysql存储引擎 MySQL中的数据用各种不同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力&#xff0c;这些不同的技术以及配套的功能在MySQL中称为存储引擎。 存储引擎是MySQL将数据存储在文件系统中的存储方…