博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python制作井字棋小游戏
阅读量:3959 次
发布时间:2019-05-24

本文共 6931 字,大约阅读时间需要 23 分钟。

Python做三子棋游戏

这个是我刚开始了解做Python小游戏的时候第一个项目,因为简单好入手,实现它的过程是我开始摸索Python的GUI界面的入门之路。这个设计也都是按照自己对于这个游戏的理解,一步一步去实现它。

窗口

万能的窗口,实现窗口都可以进行简单的修改进行使用:

from tkinter import *root = Tk()         #窗口名称root.title("憨憨制作的三子棋")f1=Frame(root)f1.pack()w1 = Canvas(f1, width=580,height=580,background='lightcyan')#创建一个画布,设置大小和背景颜色w1.pack()root.mainloop()

在这里插入图片描述

画出棋盘

#画出棋盘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)

在这里插入图片描述

分别画横竖线,四条横线四条竖线,生成九个格子。也可以画出两横两竖,更加贴近井字形状。少画几条线就好,例如:

for i in range(1, 3):    w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560)    w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)

在这里插入图片描述

num = 0							#记录点击的次数,用来决定点击后该画哪种图形A = np.full((3, 3), 0)			#记录每个位置的图形

算法

每一次点击以后我们都要进行画图和判断是否达到获胜的条件。

设置函数

def dawn(event):    global w1    global num, A    for i in range(0, 3):        for j in range(0, 3):            if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:                break        if 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:            break    if num % 2 == 0 and A[i][j] == 0:        A[i][j] = 1        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))        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))        num += 1    if num % 2 != 0 and A[i][j] == 0:        A[i][j] = 2        w1.create_oval(20 + 180 * i, 20 + 180 * j, 20 + 180 * (i + 1), 20 + 180 * (j + 1))        num += 1    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('消息提示', '圆圈获胜')    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 \            A[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1:        tkinter.messagebox.showinfo('消息提示', '叉号获胜')w1.bind("

我们拆开进行分析:

首先是:点击位置的确定,得到我们的点击单元格,开始时我是用的是判断是否在方格的内切圆范围内,发现点击到方格的剩余部分会导致化的图形错位,通过进一步的分析发现,可以通过分别定位点击位置的横纵坐标,确定点击的方格。

for i in range(0, 3):        for j in range(0, 3):            if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:                break        if 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:            break

接着,确定了位置以后我们就开始判断当前位置是否能画图形,应该画什么图形,画❌是比较麻烦的需要进行复杂的计算,画⚪就比较简单。

if num % 2 == 0 and A[i][j] == 0:			#若为偶数就画叉号        A[i][j] = 1        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))        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))        num += 1    if num % 2 != 0 and A[i][j] == 0:		#若为奇数就画圆圈        A[i][j] = 2        w1.create_oval(20 + 180 * i, 20 + 180 * j, 20 + 180 * (i + 1), 20 + 180 * (j + 1))        num += 1

画完以后我们要判断是否达到获胜的条件,这里我没想到简便的方法,但是好在获胜的情况屈指可数,只有八种(横3,竖3,两个斜方向的)于是将八种情况列出进行判断是否达到获胜条件,而且两种图形都需要列出。

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('消息提示', '圆圈获胜')    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 \            A[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1:        tkinter.messagebox.showinfo('消息提示', '叉号获胜')

最后设置点击时间的获取以及退出按钮的设置。

w1.bind("

到这里游戏的每个代码都讲解完了。

在这里插入图片描述

附完整代码:

from tkinter import *import numpy as npimport mathimport tkinter.messageboxroot = Tk()         #窗口名称root.title("憨憨制作的三子棋")f1=Frame(root)f1.pack()w1 = Canvas(f1, width=580,height=580,background='lightcyan')w1.pack()#棋盘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)def dawn(event):    global w1    global num, A    for i in range(0, 3):        for j in range(0, 3):            if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:                break        if 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:            break    if num % 2 == 0 and A[i][j] == 0:        A[i][j] = 1        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))        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))        num += 1    if num % 2 != 0 and A[i][j] == 0:        A[i][j] = 2        w1.create_oval(20 + 180 * i, 20 + 180 * j, 20 + 180 * (i + 1), 20 + 180 * (j + 1))        num += 1    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('消息提示', '圆圈获胜')    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 \            A[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1:        tkinter.messagebox.showinfo('消息提示', '叉号获胜')w1.bind("

游戏实现只是个人的思路和操作,可能会有很多的不足,有愿意一起研究的朋友可以联系我,愿意虚心请教。

转载地址:http://evtzi.baihongyu.com/

你可能感兴趣的文章
bat拷贝文件
查看>>
Window设置生成dmp文件配置说明
查看>>
shell脚本实现删除指定日期之前的文件
查看>>
centos 7配置mysql yum源(自行选择哪个版本)
查看>>
批处理 %~dp0
查看>>
bat杀死bat进程
查看>>
zabbix监控snmp(1)
查看>>
zabbix监控snmp(2)
查看>>
zabbix监控snmp(3)
查看>>
windows时间同步周期设置
查看>>
shell通配符
查看>>
查询表和库的大小
查看>>
dbeaver连接mysql,提示没有驱动
查看>>
bat备份数据库
查看>>
linux数据库导出结果集且比对 && grep -v ---无法过滤的问题
查看>>
shell函数与自带变量
查看>>
linux下shell获取不到PID
查看>>
linux下mysql备份数据库
查看>>
shell脚本括号简单用法
查看>>
删除指定日期之前或之后的文件或目录
查看>>