20234205 实验四《Python程序设计》实验报告

20234205张靖雯 2024-05-28 23:57:28

20234205 2023-2024-2 《Python程序设计》实验4报告

课程:《Python程序设计》
班级: 2342
姓名: 张靖雯
学号:20234205
实验教师:王志强
实验日期:2024年5月14日
必修/选修: 专选课

1.实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。

例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等。
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒。
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等。

注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

2. 实验过程及结果

为体现本学期Python课程的综合学习成果,我根据王老师所教学的知识以及我在CSDN社区搜集的资料,编写了一个2048小游戏。通过使用 Turtle 模块实现了2048游戏的基本功能,包括图形界面的绘制、数字方块的移动合并、游戏状态的判断等。

游戏规则为:在4x4的方格中,通过上、下、左、右四个方向的移动,将相同数字的方块合并,直到得到一个数字为2048的方块或者无法继续移动时游戏结束。
以下为2048小游戏的制作过程。

导入Turtle库,进行图形界面的绘制。

img

运用面向对象相关知识,定义一个BackGround类,用来绘制游戏的背景(包括背景方块、标题、分数等)。

img

利用draw_block 方法,通过循环在指定位置绘制背景方块,然后绘制其他形状并填充白色,形成整体的游戏界面。

img

绘制其他背景元素。

img

定义主界面,绘制标题、分数等。

img

利用judge 方法判断游戏是否失败或者是否达成2048,并显示相应提示文字。

img

遍历数字方块的字典,检查是否还有可以移动的位置。

img

无位置可移动,显示游戏失败的提示文字。

img

如果有某个方块的数字达到2048,显示达成2048的提示文字。

img

利用win_lose_clear 方法清除游戏失败或者达成2048的提示文字,以便后续操作。

img

利用show_score 方法显示当前分数和最高分。如果当前分数高于最高分,则更新最高分并将其保存到文件。

img

定义一个Block类,表示游戏中的数字方块,包括数字的显示和颜色的设置。

img

利用draw 方法绘制数字方块。

img

使用字典 dic_draw 存储数字与颜色的映射关系,根据方块的数字选择对应的颜色。

img

绘制方块的形状。

img

绘制数字,按照数字选择数字的颜色,并在方块中心显示数字。

img

定义一个Game类,用来控制游戏的初始化、重启、方块增长、移动等功能。

img

利用init 方法实现初始化游戏,绘制游戏的背景,生成初始数字方块(画出16个海龟对应16个数字块)。

img

利用restart 方法实现重启游戏,清空方块、重置分数,并调用 grow 方法生成新的数字方块。

img

利用grow 方法在空白方块位置随机生成数字2或4的方块。根据游戏规则,生成2的概率大于生成4的概率。

img

利用move_up 方法实现向上移动操作。

img

move_down 方法实现向下移动操作。

img

move_left 方法实现向左移动操作。

img

move_right 方法实现向右移动操作。

img

通过调用 move_move 方法处理四列或四行的移动。

img

判断是否有方块移动,有才能继续出现新的数字块。

img

利用move 方法实现方块的移动和合并。

img

利用list_oper 方法对数字列表进行合并操作。遍历数字列表,将相邻相同的数字合并,合并后的数字乘以2,得到新的数字列表,然后将新的数字列表赋值给对应的方块。

img

标志位 count 表示数字列表是否有变化,用于判断是否有方块移动。

img

下载安装pygame。

img

编写好代码后,我尝试运行程序并进行调试,最终达到以下效果:

  • 在运行代码后,游戏窗口会显示2048游戏的初始界面。

    img

  • 玩家可以使用上、下、左、右方向键进行移动操作。

  • 游戏成功达成2048或无法继续移动时,会显示相应的提示文字,按空格键可重新开始游戏。

    img

  • 游戏所得最高分的纪录会保存在 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游戏运行视频:

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

  • 问题1:按照教程编写好代码之后,程序始终无法运行。

  • 问题1解决方案:在社区中搜集资料并询问同学后,发现安装pygame库出现错误,将其正确安装后,程序即可正常运行。

  • 问题2:代码后,PyCharm没有自动打开一个窗口来显示游戏的图形界面。

  • 问题2解决方案:检查代码中的图形界面初始化部分,发现此处代码编写有误,及时更正后,程序正常运行。

本次实验的感想体会:
在课堂上听讲、跟随老师编写代码时,我深深体会到了Python的实用性。而在我亲自动手尝试去运用所学知识编写程序甚至是开发小游戏时,我更加体会到了Python的趣味性。在制作2048小游戏的过程中,我体会到了编程的魅力和挑战。对我来说,这是一次非常有趣且有意义的经历,让我更加热爱使用Python进行编程并享受其带来的乐趣。这次实验不仅让我在实践中巩固了本学期学习的Python知识与技能,而且让我坚定了在课程结束后也要更加深入学习Python的想法。

4. 本学期Python课程的总结、体会及建议

  1. 课程总结
    通过这一学期的学习,我对Python的基础知识有了深入的了解,并且掌握了Python在编程领域中的基本应用。课程从Python的语法基础讲起,逐步深入到数据类型、条件语句、循环结构、函数定义与调用、模块与包的使用等核心内容。此外,我们还学习了socket网络编程技术、正则表达式以及爬虫的应用等高级主题。

  2. 感想体会:
    首先我要特别感谢温柔又细心的王志强老师,您耐心细致的讲解大大减少了我对Python课程的畏难心理。我原本以为Python课会是严肃枯燥的,却没想到您让它变得如此轻松愉悦、生动有趣。
    通过一学期的Python课程学习,我感触最深的就是Python对我自信的启迪,原来我也可以掌握这些看似只有理科生擅长的领域。从最初只能一行一行抄写老师的代码的零基础小白,到现在能够通过查阅资料自主编写出可运行程序的Python入门学习者,我感到受益匪浅。
    临近期末时,我给我的一个计算机专业的朋友展示了在本学期我运用Python课上学习的知识所编写的代码以及程序运行的成果,他感到十分惊讶,并表示如果使用他所学习的C语言来实现这些成果会非常繁琐,而Python仅仅需要几行代码竟然就可以实现(尤其是运用Socket技术进行客户端和服务端的通信),这也大大体现了Python的魅力所在。Python语言简洁明了,易于上手,而且功能强大,能够处理各种复杂的任务。通过编写程序,我们能够将自己的想法和创意转化为实际的成果,这种成就感让我对继续深入学习Python产生了更加浓厚的兴趣。在之后的学习生活中,我也希望能够继续深入了解Python,通过不断学习和实践来提高自己的编程能力和解决问题的能力。

  3. 课程建议

  • 建议鼓励同学们自主成立学习小组,以便能够一起研究,互帮互助。这也能使课堂变得更加有趣,增加同学们学习Python的主动性,减少畏难情绪,课堂氛围也会更好。

  • 建议进一步增加实践环节,更直观地了解Python在实际项目中的应用。Python的理论知识有一定难度,同学们在听课过程中可能会产生畏难心理以至于听课效果不佳。增加实操环节能使课堂更加生动,便于同学们对知识点的掌握。

再次感谢王老师这一学期的辛勤付出和无私奉献。祝您工作顺利,身体健康,家庭幸福!

...全文
196 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

93

社区成员

发帖
与我相关
我的任务
社区描述
Python程序设计作业
软件构建 高校 北京·丰台区
社区管理员
  • blackwall0321
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧