93
社区成员




课程:《Python程序设计》
班级: 2342
姓名: 张靖雯
学号:20234205
实验教师:王志强
实验日期:2024年5月14日
必修/选修: 专选课
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等。
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒。
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等。
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
为体现本学期Python课程的综合学习成果,我根据王老师所教学的知识以及我在CSDN社区搜集的资料,编写了一个2048小游戏。通过使用 Turtle 模块实现了2048游戏的基本功能,包括图形界面的绘制、数字方块的移动合并、游戏状态的判断等。
游戏规则为:在4x4的方格中,通过上、下、左、右四个方向的移动,将相同数字的方块合并,直到得到一个数字为2048的方块或者无法继续移动时游戏结束。
以下为2048小游戏的制作过程。
导入Turtle库,进行图形界面的绘制。
运用面向对象相关知识,定义一个BackGround类,用来绘制游戏的背景(包括背景方块、标题、分数等)。
利用draw_block 方法,通过循环在指定位置绘制背景方块,然后绘制其他形状并填充白色,形成整体的游戏界面。
绘制其他背景元素。
定义主界面,绘制标题、分数等。
利用judge 方法判断游戏是否失败或者是否达成2048,并显示相应提示文字。
遍历数字方块的字典,检查是否还有可以移动的位置。
无位置可移动,显示游戏失败的提示文字。
如果有某个方块的数字达到2048,显示达成2048的提示文字。
利用win_lose_clear 方法清除游戏失败或者达成2048的提示文字,以便后续操作。
利用show_score 方法显示当前分数和最高分。如果当前分数高于最高分,则更新最高分并将其保存到文件。
定义一个Block类,表示游戏中的数字方块,包括数字的显示和颜色的设置。
利用draw 方法绘制数字方块。
使用字典 dic_draw 存储数字与颜色的映射关系,根据方块的数字选择对应的颜色。
绘制方块的形状。
绘制数字,按照数字选择数字的颜色,并在方块中心显示数字。
定义一个Game类,用来控制游戏的初始化、重启、方块增长、移动等功能。
利用init 方法实现初始化游戏,绘制游戏的背景,生成初始数字方块(画出16个海龟对应16个数字块)。
利用restart 方法实现重启游戏,清空方块、重置分数,并调用 grow 方法生成新的数字方块。
利用grow 方法在空白方块位置随机生成数字2或4的方块。根据游戏规则,生成2的概率大于生成4的概率。
利用move_up 方法实现向上移动操作。
move_down 方法实现向下移动操作。
move_left 方法实现向左移动操作。
move_right 方法实现向右移动操作。
通过调用 move_move 方法处理四列或四行的移动。
判断是否有方块移动,有才能继续出现新的数字块。
利用move 方法实现方块的移动和合并。
利用list_oper 方法对数字列表进行合并操作。遍历数字列表,将相邻相同的数字合并,合并后的数字乘以2,得到新的数字列表,然后将新的数字列表赋值给对应的方块。
标志位 count 表示数字列表是否有变化,用于判断是否有方块移动。
下载安装pygame。
编写好代码后,我尝试运行程序并进行调试,最终达到以下效果:
在运行代码后,游戏窗口会显示2048游戏的初始界面。
玩家可以使用上、下、左、右方向键进行移动操作。
游戏成功达成2048或无法继续移动时,会显示相应的提示文字,按空格键可重新开始游戏。
游戏所得最高分的纪录会保存在 score.txt 文件中。
以下为所编写2048游戏的源代码:
import turtle , random
class BackGround(turtle.Turtle):
def init(self):
super().init()
self.penup()
self.ht()
def draw_block(self):
self.shape('bg.gif')
for i in allpos:
self.goto(i)
self.stamp()
self.color('white', 'white')
self.goto(-215, 120)
self.begin_fill()
self.goto(215, 120)
self.goto(215, 110)
self.goto(-215, 110)
self.end_fill()
self.shape('title.gif')
self.goto(-125, 210)
self.stamp()
self.shape('score.gif')
self.goto(125, 245)
self.stamp()
self.shape('top_score.gif')
self.goto(125, 170)
self.stamp()
def judge(self):
global flag_win, flag_win_lose_text
self.color('blue')
judge = 0
for i in block_dic.values():
for j in block_dic.values():
if i.num == 0 or i.num == j.num and i.distance(j) == 100:
judge += 1
if judge == 0:
self.write(' GAME OVER\n重新开始请按空格键', align='center', font=('黑体', 30, 'bold'))
flag_win_lose_text = False
if flag_win is True:
for k in block_dic.values():
if k.num == 2048:
flag_win = False
self.write(' 达成2048\n继续游戏请按回车键', align='center', font=('黑体', 30, 'bold'))
flag_win_lose_text = False
def win_lose_clear(self):
global flag_win_lose_text
self.clear()
flag_win_lose_text = True
def show_score(self):
global score, top_score
if score > top_score:
top_score = score
with open('.\\score.txt', 'w') as f:
f.write(f'{top_score}')
self.color('white')
self.goto(125, 210)
self.clear()
self.write(f'{score}', align='center', font=('Arial', 20, 'bold'))
self.goto(125, 135)
self.write(f'{top_score}', align='center', font=('Arial', 20, 'bold'))
class Block(turtle.Turtle):
def init(self):
super().init()
self.ht()
self.penup()
self.num = 0
def draw(self):
self.clear()
dic_draw = {2: '#eee6db', 4: '#efe0cd', 8: '#f5af7b',
16: '#fb9660', 32: '#f57d5a', 64: '#f95c3d',
128: '#eccc75', 256: '#eece61', 512: '#efc853',
1024: '#ebc53c', 2048: '#eec430', 4096: '#aeb879',
8192: '#aab767', 16384: '#a6b74f'}
if self.num > 0:
self.color(f'{dic_draw[self.num]}')
self.begin_fill()
self.goto(self.xcor()+48, self.ycor()+48)
self.goto(self.xcor()-96, self.ycor())
self.goto(self.xcor(), self.ycor()-96)
self.goto(self.xcor()+96, self.ycor())
self.goto(self.xcor(), self.ycor()+96)
self.end_fill()
self.goto(self.xcor()-48, self.ycor()-68)
if self.num > 4:
self.color('white')
else:
self.color('#6d6058')
self.write(f'{self.num}', align='center', font=('Arial', 27, 'bold'))
self.goto(self.xcor(), self.ycor()+20)
class Game():
def init(self):
back = BackGround()
back.draw_block()
for i in allpos:
block = Block()
block.goto(i)
block_dic[i] = block
game.grow()
def restart(self):
global score, flag_win_lose_text
score = 0
for i in block_dic.values():
i.num = 0
i.clear()
win_lose_text.clear()
game.grow()
flag_win_lose_text = True
def grow(self):
block_list = []
for i in allpos:
if block_dic[i].num == 0:
block_list.append(block_dic[i])
turtle_choice = random.choice(block_list)
turtle_choice.num = random.choice([2, 2, 2, 2, 4])
turtle_choice.draw()
win_lose_text.judge()
show_score_text.show_score()
ms.update()
def move_up(self):
allpos1 = allpos[::4]
allpos2 = allpos[1::4]
allpos3 = allpos[2::4]
allpos4 = allpos[3::4]
self.move_move(allpos1, allpos2, allpos3, allpos4)
def move_down(self):
allpos1 = allpos[-4::-4]
allpos2 = allpos[-3::-4]
allpos3 = allpos[-2::-4]
allpos4 = allpos[-1::-4]
self.move_move(allpos1, allpos2, allpos3, allpos4)
def move_left(self):
allpos1 = allpos[:4]
allpos2 = allpos[4:8]
allpos3 = allpos[8:12]
allpos4 = allpos[12:16]
self.move_move(allpos1, allpos2, allpos3, allpos4)
def move_right(self):
allpos1 = allpos[-1:-5:-1]
allpos2 = allpos[-5:-9:-1]
allpos3 = allpos[-9:-13:-1]
allpos4 = allpos[-13:-17:-1]
self.move_move(allpos1, allpos2, allpos3, allpos4)
def move_move(self, allpos1, allpos2, allpos3, allpos4):
if flag_win_lose_text is True:
count1 = self.move(allpos1)
count2 = self.move(allpos2)
count3 = self.move(allpos3)
count4 = self.move(allpos4)
if count1 or count2 or count3 or count4:
self.grow()
def move(self, pos_list):
num_list = []
for i in pos_list:
num_list.append(block_dic[i].num)
new_num_list, count = self.list_oper(num_list)
for j in range(len(new_num_list)):
block_dic[pos_list[j]].num = new_num_list[j]
block_dic[pos_list[j]].draw()
return count
def list_oper(self, num_list):
global score
count = True
temp = []
new_temp = []
for j in num_list:
if j != 0:
temp.append(j)
flag = True
for k in range(len(temp)):
if flag:
if k < len(temp)-1 and temp[k] == temp[k+1]:
new_temp.append(temp[k]*2)
flag = False
score += temp[k]
else:
new_temp.append(temp[k])
else:
flag = True
for m in range(len(num_list)-len(new_temp)):
new_temp.append(0)
if new_temp == num_list:
count = False
return(new_temp, count)
if name == 'main':
ms = turtle.Screen()
ms.setup(430, 630, 400, 50)
ms.bgcolor('gray')
ms.title('2048')
ms.tracer(0)
ms.register_shape('bg.gif')
ms.register_shape('title.gif')
ms.register_shape('score.gif')
ms.register_shape('top_score.gif')
block_dic = {}
allpos = [(-150, 50), (-50, 50), (50, 50), (150, 50),
(-150, -50), (-50, -50), (50, -50), (150, -50),
(-150, -150), (-50, -150), (50, -150), (150, -150),
(-150, -250), (-50, -250), (50, -250), (150, -250)]
flag_win = True
flag_win_lose_text = True
score = 0
with open('.\score.txt', 'r') as f:
top_score = int(f.read())
show_score_text = BackGround()
win_lose_text = BackGround()
game = Game()
game.init()
ms.listen()
ms.onkey(game.move_up, 'Up')
ms.onkey(game.move_down, 'Down')
ms.onkey(game.move_left, 'Left')
ms.onkey(game.move_right, 'Right')
ms.onkey(win_lose_text.win_lose_clear, 'Return')
ms.onkey(game.restart, 'space')
ms.mainloop()
以下为录制的2048游戏运行视频:
问题1:按照教程编写好代码之后,程序始终无法运行。
问题1解决方案:在社区中搜集资料并询问同学后,发现安装pygame库出现错误,将其正确安装后,程序即可正常运行。
问题2:代码后,PyCharm没有自动打开一个窗口来显示游戏的图形界面。
问题2解决方案:检查代码中的图形界面初始化部分,发现此处代码编写有误,及时更正后,程序正常运行。
本次实验的感想体会:
在课堂上听讲、跟随老师编写代码时,我深深体会到了Python的实用性。而在我亲自动手尝试去运用所学知识编写程序甚至是开发小游戏时,我更加体会到了Python的趣味性。在制作2048小游戏的过程中,我体会到了编程的魅力和挑战。对我来说,这是一次非常有趣且有意义的经历,让我更加热爱使用Python进行编程并享受其带来的乐趣。这次实验不仅让我在实践中巩固了本学期学习的Python知识与技能,而且让我坚定了在课程结束后也要更加深入学习Python的想法。
课程总结
通过这一学期的学习,我对Python的基础知识有了深入的了解,并且掌握了Python在编程领域中的基本应用。课程从Python的语法基础讲起,逐步深入到数据类型、条件语句、循环结构、函数定义与调用、模块与包的使用等核心内容。此外,我们还学习了socket网络编程技术、正则表达式以及爬虫的应用等高级主题。
感想体会:
首先我要特别感谢温柔又细心的王志强老师,您耐心细致的讲解大大减少了我对Python课程的畏难心理。我原本以为Python课会是严肃枯燥的,却没想到您让它变得如此轻松愉悦、生动有趣。
通过一学期的Python课程学习,我感触最深的就是Python对我自信的启迪,原来我也可以掌握这些看似只有理科生擅长的领域。从最初只能一行一行抄写老师的代码的零基础小白,到现在能够通过查阅资料自主编写出可运行程序的Python入门学习者,我感到受益匪浅。
临近期末时,我给我的一个计算机专业的朋友展示了在本学期我运用Python课上学习的知识所编写的代码以及程序运行的成果,他感到十分惊讶,并表示如果使用他所学习的C语言来实现这些成果会非常繁琐,而Python仅仅需要几行代码竟然就可以实现(尤其是运用Socket技术进行客户端和服务端的通信),这也大大体现了Python的魅力所在。Python语言简洁明了,易于上手,而且功能强大,能够处理各种复杂的任务。通过编写程序,我们能够将自己的想法和创意转化为实际的成果,这种成就感让我对继续深入学习Python产生了更加浓厚的兴趣。在之后的学习生活中,我也希望能够继续深入了解Python,通过不断学习和实践来提高自己的编程能力和解决问题的能力。
课程建议
建议鼓励同学们自主成立学习小组,以便能够一起研究,互帮互助。这也能使课堂变得更加有趣,增加同学们学习Python的主动性,减少畏难情绪,课堂氛围也会更好。
建议进一步增加实践环节,更直观地了解Python在实际项目中的应用。Python的理论知识有一定难度,同学们在听课过程中可能会产生畏难心理以至于听课效果不佳。增加实操环节能使课堂更加生动,便于同学们对知识点的掌握。
再次感谢王老师这一学期的辛勤付出和无私奉献。祝您工作顺利,身体健康,家庭幸福!