20243113 2025-5-14《Python程序设计》实验四报告

20243113 2025-5-14 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2431
姓名: 应超群
学号:20243113
实验教师:王志强
实验日期:2025年5月14日
必修/选修: 公选课

一. 实验内容

实现五子棋小游戏,并附带撤回功能

二. 实验过程及结果

1.pygame库安装与搭建

  • (1)打开设置,进入项目下面的python解释器,在里面下载安装pygame库




  • (2)导入pygame、sys库


2.初始化pygame并搭建窗口

点击查看代码
import pygame
import sys

size = width, height = 1200,1000
color = (255,255,255)

pygame.init()
windows = pygame.display.set_mode(size)
clock = pygame.time.Clock()

me_font = pygame.font.Font('./fonts/SIMLI.TTF', 60,)#字体自己下载放到指定位置
pygame.display.set_caption('五子棋')

while True:
    clock.tick(60)
    windows.fill(color)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    pygame.display.update()

效果展示

3.棋盘与棋子绘制

  • 函数以及一些变量编写

    通过使用pygame里面自带的画线实现棋盘,画圆实现棋子

点击查看代码
qp_d = 65
start = (45,45)

def qipan():
    for i in range(0,15):
        pygame.draw.line(windows,(0,0,0),(45+qp_d*i,45),(45+qp_d*i,955),2)
        pygame.draw.line(windows,(0,0,0),(45,45+qp_d*i),(955,45+qp_d*i,),2)

def Whiteqi(whitexy):
    pygame.draw.circle(windows, (255,255,255), whitexy, 30)
    pygame.draw.circle(windows, (0,0,0), whitexy, 30,2)

def Blackqi(blackxy):
    pygame.draw.circle(windows, (0, 0, 0), blackxy, 30)

展示

注:
关于棋盘靠右,是为了留出空间放功能按钮(比如撤回)

4.鼠标响应并且实现轮换下棋(先黑)

  • 1代表黑棋,2代表白棋,0代表什么都没有,用二维数组存储信息,可以表示坐标。
    鼠标检测用pygame中的函数,当鼠标响应时,根据位置判断属于棋盘哪个交叉点,并记录下来此时的
    位置,存储带数组中,之后在棋盘上显示出来
点击查看代码
board=[[0 for _ in range(15)] for _ in range(15)]  #1为黑棋,2为白棋

def place(mouse):
    global current
    i = (mouse[0]-start[0]+32)//qp_d #X
    j = (mouse[1]-start[1]+32)//qp_d #Y
    if 0<=i<15 and 0<=j<15 and board[j][i] == 0:
        board[j][i] = current
        current = 2 if current == 1 else 1

def qi():
    for i in range(0,15):
        for j in range(0,15):
            if board[j][i]==1:
                Blackqi((45+qp_d*i,45+qp_d*j))
            if board[j][i]==2:
                Whiteqi((45+qp_d*i,45+qp_d*j))

......

while True:
    clock.tick(60)
    windows.fill(color)
    qipan()
    qi()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse = pygame.mouse.get_pos()
            place(mouse)
    pygame.display.update()

5.实现输赢判断,并且展示出画面

  • (1)输赢判断功能实现

    判断一个方向上连续5个棋子是否相同,即判断二维数组中(1,0),(0,1),(1,1),(1,-1)
    四个“方向”存储的数据是否均为1或者2

点击查看代码
gameover = 0

def win(player):
    global gameover
    dic = [(1,0),(0,1),(1,1),(1,-1)]
    for i in range(0,15):
        for j in range(0,15):
            if board[i][j] !=player:
                continue
            for dx,dy in dic:
                count = 0
                for step in range(0,5):
                    x=i+dx*step
                    y=j+dy*step
                    if 0<=x<15 and 0<=y<15 and board[x][y]==player:
                        count+=1
                if count==5:
                    gameover = 1
                    return True
    return False
  • (2)将输赢结果展示出来
点击查看代码
heise = me_font.render("黑色胜利",0,(0,0,0),(255,255,255))
baise = me_font.render("白色胜利",0,(0,0,0),(255,255,255))
heiserect = heise.get_rect(center=(width/2,height/2))
baiserect = baise.get_rect(center=(width/2,height/2))

......


    if win(1):
        windows.blit(heise, heiserect)
    elif win(2):
        windows.blit(baise, baiserect)

结果展示(白色胜利效果一样,不做展示)

6.悔棋功能实现

  • (1)代码实现

    主要是通过通过history记录下来放置棋子的时候的坐标值以及当时下的对象(保证下棋对象不会错乱)
    撤回时,将最后一个history记录的数据对应的坐标上数据改为0(没有棋子),然后下棋对象改为对应
    的对象

点击查看代码
def huiqi():
    global current
    if len(history)==0:
        return False
    J,I,C = history.pop()
    board[J][I]=0
    current = C
  • (2)图形化
点击查看代码
chehui = me_font.render("撤回",0,(0,0,0))
chehuirect = chehui.get_rect(center=(width-105,height/2))

anniu = (width-180,height/2-40,150,80)

......

    pygame.draw.rect(windows, (0, 255, 0), anniu)
    windows.blit(chehui, chehuirect)

......

            if anniu[0]<=mouse[0]<=anniu[0]+150 and anniu[1]<=mouse[1]<=anniu[1]+80:
                huiqi()
                pygame.draw.rect(windows, (0,0,255), anniu)
                windows.blit(chehui, chehuirect)
                pygame.display.update()

展示

7.结果展示

gitee

源码
import pygame
import sys

current = 1
size = width, height = 1200,1000
color = (255,255,255)
qp_d = 65
start = (45,45)
board=[[0 for _ in range(15)] for _ in range(15)]  #1为黑棋,2为白棋
gameover = 0
history = []


def qipan():
    for i in range(0,15):
        pygame.draw.line(windows,(0,0,0),(45+qp_d*i,45),(45+qp_d*i,955),2)
        pygame.draw.line(windows,(0,0,0),(45,45+qp_d*i),(955,45+qp_d*i,),2)

def Whiteqi(whitexy):
    pygame.draw.circle(windows, (255,255,255), whitexy, 30)
    pygame.draw.circle(windows, (0,0,0), whitexy, 30,2)

def Blackqi(blackxy):
    pygame.draw.circle(windows, (0, 0, 0), blackxy, 30)

def place(mouse):
    global current
    global history
    i = (mouse[0]-start[0]+32)//qp_d #X
    j = (mouse[1]-start[1]+32)//qp_d #Y
    if 0<=i<15 and 0<=j<15 and board[j][i] == 0:
        history.append((j, i, current))
        board[j][i] = current
        current = 2 if current == 1 else 1

def qi():
    for i in range(0,15):
        for j in range(0,15):
            if board[j][i]==1:
                Blackqi((45+qp_d*i,45+qp_d*j))
            if board[j][i]==2:
                Whiteqi((45+qp_d*i,45+qp_d*j))

def win(player):
    global gameover
    dic = [(1,0),(0,1),(1,1),(1,-1)]
    for i in range(0,15):
        for j in range(0,15):
            if board[i][j] !=player:
                continue
            for dx,dy in dic:
                count = 0
                for step in range(0,5):
                    x=i+dx*step
                    y=j+dy*step
                    if 0<=x<15 and 0<=y<15 and board[x][y]==player:
                        count+=1
                if count==5:
                    gameover = 1
                    return True
    return False

def huiqi():
    global current
    if len(history)==0:
        return False
    J,I,C = history.pop()
    board[J][I]=0
    current = C

pygame.init()
windows = pygame.display.set_mode(size)
clock = pygame.time.Clock()

me_font = pygame.font.Font('./fonts/SIMLI.TTF', 60,)
heise = me_font.render("黑色胜利",0,(0,0,0),(255,255,255))
baise = me_font.render("白色胜利",0,(0,0,0),(255,255,255))
heiserect = heise.get_rect(center=(width/2,height/2))
baiserect = baise.get_rect(center=(width/2,height/2))
chehui = me_font.render("撤回",0,(0,0,0))
pygame.display.set_caption('五子棋')
chehuirect = chehui.get_rect(center=(width-105,height/2))
anniu = (width-180,height/2-40,150,80)

while True:

    clock.tick(60)
    windows.fill(color)
    qipan()
    qi()
    pygame.draw.rect(windows, (0, 255, 0), anniu)
    windows.blit(chehui, chehuirect)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse = pygame.mouse.get_pos()
            place(mouse)
            mouse = pygame.mouse.get_pos()
            if anniu[0]<=mouse[0]<=anniu[0]+150 and anniu[1]<=mouse[1]<=anniu[1]+80:
                huiqi()
                pygame.draw.rect(windows, (0,0,255), anniu)
                windows.blit(chehui, chehuirect)
                pygame.display.update()
        if gameover:
            if event.type == pygame.MOUSEBUTTONDOWN:
                gameover = 0
                current = 1
                board = [[0 for _ in range(15)] for _ in range(15)]
                qipan()

    if gameover:
        windows.fill(color)
    if win(1):
        windows.blit(heise, heiserect)
    elif win(2):
        windows.blit(baise, baiserect)
    pygame.display.update()

视频展示

三. 实验过程中遇到的问题和解决过程

  • 问题1:对于输赢判断的功能实现不了解
  • 问题1解决方案:通过询问AI,学会了实现方法,具体参考上文。

其他(感悟、思考等)

1.课程感想体会

当初选python是听了学长的建议,说是电赛用得上,但是现在回头看来,python给我的好处远不止于此。
初学python时,当王志强老师敲了print("Hello World!")的时候,让我明白了python那么火的原因之一,它太简单了,不用像c语言,敲一堆之后才能输出,格式要求也很死。但让我更得劲的是那个pycharm的Tab,真好用(比codeblock好使多了)。
在python课堂上,王志强老师的性格可以说是python学习的又一个催化剂,老师签到的神奇签到手势(建议每次换个套路),上课时敲代码的例子(哪吒还有同学的名字等等)让我们在学习的过程中感到欢乐的同时,也记住了每个代码的作用,赞。
最后的python作业,其实在很小的时候,我就有个写游戏的梦,之前一直没有接触过编程,一直到大一的时候,学习了c语言,但是c语言教的和我想的似乎有一点不同,也没有教图形化的代码,然后选修课学习了python,虽然也没有教图形化的知识,但是这次结课作业给了我动力,我自学了pygame的相关知识,通过不断询问ai以及查找相关资料,完成了这份五子棋小游戏的编写,写完的时候很有成就感,而且,也算完成了小时候的梦。
总而言之,python课上,我不仅学会了python,更收获了更高层次的好处,就像前面说的,现在回头看去,python给我的感觉绝对和之前大有改变。

2.意见和建议

建议增加课堂互动,有效防止走神;建议上课的时候,举一些有逼格的例子(想起了那个AI的哪吒),有效增加学生学习兴趣;python课太完美了,没有其他建议了。

参考资料

posted @ 2025-05-28 21:36  fish3113  阅读(70)  评论(0)    收藏  举报