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.结果展示
源码
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课太完美了,没有其他建议了。

浙公网安备 33010602011771号