python实现简单的井字棋小游戏

 更新时间:2022年05月04日 12:35:41   作者:壹屋安源  
这篇文章主要为大家详细介绍了python实现简单的井字棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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("<Button -1>", dawn)

我们拆开进行分析:

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

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("<Button -1>", dawn)
def quit():
    root.quit()
button1 = Button(root, text="退出", font=('楷体', 20), command=quit)
button1.pack()

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

附完整代码:

from tkinter import *
import numpy as np
import math
import tkinter.messagebox
root = 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 = 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("<Button -1>", dawn)
def quit():
    root.quit()
button1 = Button(root, text="退出", font=('楷体', 20), command=quit)
button1.pack()
root.mainloop()

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • python3中http协议提供文件服务器功能详解

    python3中http协议提供文件服务器功能详解

    http协议是互联网的通用基础协议,也可以利用其来开发文件服务器,给客户提供文件浏览,查看,下载,上传等功能,这篇文章主要介绍了python3中http协议提供文件服务器功能,需要的朋友可以参考下
    2023-06-06
  • Python实现截屏的函数

    Python实现截屏的函数

    这篇文章主要介绍了Python实现截屏的函数,可实现Python针对屏幕的截屏功能,非常简单实用,需要的朋友可以参考下
    2015-07-07
  • python基础操作列表切片解析

    python基础操作列表切片解析

    列表和字符串一样,列表同样可以截取和被索引,列表被截取后返回一个包含所需元素的新列表,List中的元素是可以改变的,需要的朋友可以参考下
    2023-04-04
  • 利用Python开发微信支付的注意事项

    利用Python开发微信支付的注意事项

    如今支付的引入是很多互联网产品都需要的。为了让用户用着更方便快捷,集成像支付宝、微信支付这样的第三方支付也就成了常有的事。今天跟着小编就来看看微信支付开发中几个值得注意的地方,涉及代码之处均用 Python 编写。
    2016-08-08
  • Python中的Decimal使用及说明

    Python中的Decimal使用及说明

    这篇文章主要介绍了Python中的Decimal使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 使用Python第三方库pygame写个贪吃蛇小游戏

    使用Python第三方库pygame写个贪吃蛇小游戏

    这篇文章主要介绍了使用Python第三方库pygame写个贪吃蛇小游戏,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • Python面向对象之静态属性、类方法与静态方法分析

    Python面向对象之静态属性、类方法与静态方法分析

    这篇文章主要介绍了Python面向对象之静态属性、类方法与静态方法,结合实例形式分析了Python面向对象程序设计中静态属性、类方法及静态方法相关概念、使用方法及操作注意事项,需要的朋友可以参考下
    2018-08-08
  • Python实现Opencv cv2.Canny()边缘检测

    Python实现Opencv cv2.Canny()边缘检测

    这篇博客将介绍Canny边缘检测的概念,并利用cv2.Canny()实现边缘检测,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 浅析python递归函数和河内塔问题

    浅析python递归函数和河内塔问题

    这篇文章主要介绍了python递归函数和河内塔问题,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-04-04
  • 零基础也能看懂的python内置csv模块教程

    零基础也能看懂的python内置csv模块教程

    这篇博客就为你介绍一个知识点,python 内置模块 csv 。让大家一文就看懂csv csv(Comma-Separated Values)文件是什么?以及python 中的 csv 文件清晰解法读取文件写入文件 csv 文件其它说明
    2021-11-11

最新评论