Pygame 五子棋编程

编程说明: pygame编程五子棋程序。

设计流程:新建棋盘,落子画圆,校验五子相连,赢家信息显示,自动重启下一局,程序打包成exe。

关键点

    新建棋盘:考虑线的间隔,需提前计算好。

    落子画圆:考虑黑白交替,已落子坐标位不可重复落子。

    校验五子相连:分成横、竖、左斜、右斜四个方向的相连,其中如果第一个为白子,第二个不为同色的白子,则列表清零重新计算,当列表出现五子相连即列表长度出现5个值,则跳出循环,提示赢家信息。

    赢家信息显示:先提前获取系统字体简称,设定正确的字体,否则中文显示为方框设定函数为pygame.font.SysFont("simhei",25)。

    程序打包成exe:准备.ico图标,使用指令在cmd框下执行Pyinstaller -F -w -i wzq.ico wzq.py 指定icon图标进行打包,在cmd黑框查看生成文件路径,找到生成的exe文件即可,坑为Pyinstaller确认为最新版本,版本过旧会报错导致打包失败,pip升级或者卸载重装即可。

参考链接:

1.pygame基础教程

https://blog.csdn.net/qq_40801987/article/details/121506910

2.Python Pygame制作简单五子棋游戏(详细代码+解释)

https://blog.csdn.net/weixin_43918046/article/details/119521845?spm=1001.2014.3001.5506

3.python中的tkinter库弹窗messagebox详解

https://www.jb51.net/article/216076.htm

4.pygame在屏幕上显示中文的方法

https://www.jianshu.com/p/eeea79aaf4b8

5.pygame基础语法

https://www.cnblogs.com/liuzhongkun/p/16165288.html

效果展示

Pygame 五子棋编程_第1张图片

Pygame 五子棋编程_第2张图片

程序详情

# encoding:utf-8

#调用pygame库

import pygame

import sys

#调用常用关键字常量,例当产生 KEYDOWN 或 KEYUP 事件时,key 属性描述具体哪个按键被按下

from pygame.locals import QUIT,KEYDOWN

import numpy as np

# from tkinter import *

# from tkinter import messagebox  #一方获胜后弹出面板,第二种显示样式

#判断鼠标的落点

def find_pos(x,y):

    for i in range(27,670,44):

        for j in range(27,670,44):

            L1=i-22

            L2=i+22

            R1=j-22

            R2=j+22

            if x>=L1 and x<=L2 and y>=R1 and y<=R2:

                return i,j

    return x,y

#已落子不可以重复落子

def check_over_pos(x,y,over_pos):

    for val in over_pos:

        if val[0][0]==x and val[0][1]==y:

            return False  #表示已落子

    return True #表示没有落子

#判断五子连心

def check_win(over_pos):

    mp=np.zeros([15,15],dtype=int)

    for val in over_pos:

        x=int((val[0][0]-27)/44)

        y=int((val[0][1]-27)/44)

        if val[1]==white_color: #通过颜色判断白子

            mp[x][y]=2#表示白子

        else:

            mp[x][y]=1#表示黑子

    for i in range(15): #查看有没竖型五子相连。例横坐标为0,查看纵坐标是否有五子相连的白子或者黑子

        pos1=[]

        pos2=[]

        for j in range(15):

            if mp[i][j]==1:  #把黑子保存到列表post1

                pos1.append([i,j])

            else:

                pos1=[] #关键点,如果下次循环不为白色,则列表情空,重新计算,保证只有五子相连才保存列表,下面横竖左斜右斜计算同理。

            if mp[i][j]==2: #把白子保存到列表post2

                pos2.append([i,j]) #关键点,如果下次循环不为黑色,则列表情空,重新计算,保证只有五子相连才保存列表下面横竖左斜右斜计算同理。

            else:

                pos2=[]

            if len(pos1)>=5: #五子连心

                return(1,pos1)

            if len(pos2)>=5:

                return [2,pos2]

    for j in range(15): #查看有没横型五子相连。例竖坐标为0,查看横坐标是否有五子相连的白子或者黑子

        pos1=[]

        pos2=[]

        for i in range(15):

            if mp[i][j]==1:

                pos1.append([i,j])

            else:

                pos1=[]

            if mp[i][j]==2:

                pos2.append([i,j])

            else:

                pos2=[]

            if len(pos1)>=5:

                return(1,pos1)

            if len(pos2)>=5:

                return [2,pos2]

    for i in range(15): #查看有没左斜型五子相连。

        for j in range(15):

            pos1=[]

            pos2=[]

            for k in range(15):

                if i+k>=15 or j+k>=15:

                    break

                if mp[i+k][j+k]==1:

                    pos1.append([i+k,j+k])

                else:

                    pos1=[]

                if mp[i+k][j+k]==2:

                    pos2.append([i+k,j+k])

                else:

                    pos2=[]

                if len(pos1)>=5:

                    return(1,pos1)

                if len(pos2)>=5:

                    return [2,pos2]

    for i in range(15): #查看有没右斜型五子相连。

        for j in range(15):

            pos1=[]

            pos2=[]

            for k in range(15):

                if i+k>=15 or j-k<0:

                    break

                if mp[i+k][j-k]==1:

                    pos1.append([i+k,j-k])

                else:

                    pos1=[]

                if mp[i+k][j-k]==2:

                    pos2.append([i+k,j-k])

                else:

                    pos2=[]

                if len(pos1)>=5:

                    return(1,pos1)

                if len(pos2)>=5:

                    return [2,pos2]

    return [0,[]]

#获胜信息 一方获胜后在(250,0)坐标显示获胜信息

def message_rt(message_text):

    # fonts=pygame.font.get_fonts()

    # print(fonts) #查看系统字体

    text=pygame.font.SysFont("simhei",25) #坑,中文显示都是方框

    print(message_text)

    print(message_text.encode("utf-8"))

    text_fmt=text.render(message_text,1,(255,0,0))

    screen.blit(text_fmt,(250,0))

while True:  #一局结束重新开始下一局

    #初始化pygame

    pygame.init()

    #窗口创建

    #获取对显示系统的访问,并创建一个窗口screen

    #窗口大小为670x670

    screen=pygame.display.set_mode((670,670))

    screen_color=[255,165,79] #背景颜色,[255,165,79]对应为棕色

    line_color=[0,0,0] #线条颜色,[0,0,0]对应黑色

    flag=False

    tm=0

    over_pos=[]

    white_color=[255,255,255]

    black_color=[0,0,0]

    while True: #不断训练刷新画布

        for event in pygame.event.get(): #获取事件,如果鼠标点击右上角关闭按钮,关闭

            if event.type in (QUIT,KEYDOWN):

                pygame.quit()

                sys.exit()

        screen.fill(screen_color)  #清屏,重新开始

        #画棋盘

        for i in range(27,670,44):

            #先画竖线

            if i==27 or i==670-27: #边缘线稍微粗一些

                pygame.draw.line(screen,line_color,[i,27],[i,670-27],4)

            else:

                pygame.draw.line(screen,line_color,[i,27],[i,670-27],2)

            #先画横线

            if i==27 or i==670-27: #边缘线稍微粗一些

                pygame.draw.line(screen,line_color,[27,i],[670-27,i],4)

            else:

                pygame.draw.line(screen,line_color,[27,i],[670-27,i],2)

        #在棋盘中心画个小圆表示正中心位置

        pygame.draw.circle(screen,line_color,[27+44*7,27+44*7],8,0)

        for val in over_pos: #显示所有落下的棋子

            pygame.draw.circle(screen,val[1],val[0],20,0)

        #判断是否存在五子连心

        res=check_win(over_pos)

        if res[0]!=0:

            for pos in res[1]:

                pygame.draw.rect(screen,[238,48,167],[pos[0]*44+27-22,pos[1]*44+27-22,44,44],2,5)

            pygame.display.update()  #刷新显示,需要刷新后在界面显示变化

        if res[0]==2:

            # Tk().wm_withdraw()

            # messagebox.showinfo("白棋获胜","恭喜白棋一方获胜")

            message_rt(u"恭喜白棋一方获胜")  #赢家信息显示

            pygame.display.update()

            pygame.time.wait(1000)

            break  #游戏结束,停止下面的操作

        elif res[0]==1:

            # Tk().wm_withdraw()

            # messagebox.showinfo("黑棋获胜","恭喜黑棋一方获胜")

            message_rt(u"恭喜黑棋一方获胜") #赢家信息显示

            pygame.display.update()

            pygame.time.wait(1000)

            break  #游戏结束,停止下面的操作

        #获取鼠标的坐标,调用函数find_pos,判断是否可以落子

        x,y=pygame.mouse.get_pos()

        x,y=find_pos(x,y)

        pygame.draw.rect(screen,[0,229,238],[x-22,y-22,44,44],2,1)

        #鼠标左键表示落子,tm用来延时的,因为每次循环时间间隔很断,容易导致明明只按了一次左键,却被多次获取,认为我按了多次

        keys_pressed=pygame.mouse.get_pressed() #获取鼠标按键信息

        if keys_pressed[0] and tm ==0:

            flag=True

            if check_over_pos(x,y,over_pos):

                if len(over_pos)%2==0:

                    over_pos.append([[x,y],black_color])

                else:

                    over_pos.append([[x,y],white_color])

        #鼠标左键的延时作用

        if flag:

            tm +=1

        if tm%20==0:  #延迟时间设定20ms

            flag=False

            tm=0

        for val in over_pos:

            pygame.draw.circle(screen,val[1],val[0],20,0)

        pygame.display.update()

     程序打包为exe

准备.ico图标和上面py文件,cmd输入指令,然后执行完成后找到对应exe保存路径即可。

Pygame 五子棋编程_第3张图片

Pygame 五子棋编程_第4张图片

1人点赞

技术

你可能感兴趣的:(技术,pygame,python,开发语言)