当前位置:首页|资讯

自学CS61A Project1 Hog(追加篇)(第一期)

作者:翻车水王汪轓发布时间:2024-10-20

前言

我是愚谷ノ園みら,简称愚園みら,本账号的使用者之一的负责分享学习笔记的oc。啊,我不会干涉各位号主们的其他事物,只会默默在专栏文件夹里发CS/AI相关的学习笔记。


总之,みら最近开始学习CS61A。打算记一点笔记激励自己学下去!


说实话我已经把算分的东西写完了,接下来可以进入下一项作业了吧……

不过我还是想看看ui怎么写的。


啊,忘了说的CS61A是一门CS相关的课?总之是UC Berkeley的CS入门课。嘛反正点开这篇文章的人应该不需要我来介绍CS61A是什么了(大概……)


以下部分都是基于已经装完环境,下载了相关课件,并且会使用ok进行评分的假设。

其实我也没怎么认真看课和课件,英语让人头大。


我也是初学者,请多包涵~如有错误,敬请斧正!


总之是正文

因为很懒,我将会把这一段东西再重新,呃,再复制粘贴很多遍。

CS61A的第一个project是要制作一个叫hog的小游戏。以下是一些关于这个project的一些碎碎念,希望能帮到有需要的同学们。

详情请参考:https://cs61a.org/proj/hog/

这是Hog项目的主要网站(作业要求),本文之后的内容将会围绕这里的题目。

以及课程课本的翻译件:https://composingprograms.netlify.app/

非常好课本,使我的理解加深十倍甚至九倍。


如果把Hog的规则和追加规则也写进来的话,太长了,恕我贴一下第一篇的链接,请诸君自己看一看~


hog_ui


在本篇中,我们将会解析`hog_ui.py`,通过命令行玩这个小游戏的程序。


啊,这个时候我是不是应该说明一些东西?在python中,print可以把结果输出在命令行里。也可以通过命令行输入。但我们之前做的东西根本没有输入输出,就是眼看着它跑完程序,所以需要一些方法让它的输出可见,也允许我们输入东西。


以下是一段输入和输出的例子,玩家vs电脑。

其中"How many dice will you roll?"之后,玩家需要输入0~10的整数。


那么这是怎么做到的呢?


本文会把整段代码直接照搬过来。


首先是从我们之前作业写好的hog里搬运东西。这很好,作业写不完连ui都用不了,作业的bug会导致ui也报错。


输出部分

接下来,是打印游戏事件所用的函数。


纯输出部分会包含上文例子里除了类似

Player 0 , you have AA and your opponent has BB

How many dice will you roll? C

的所有内容。

这个函数的作用是模拟一个游戏的进行,然后打印出模拟过程中发生了什么事。

以及,当然还有游戏结束时的双方总分。


play函数是之前作业第五题(此事在本系列第三篇文稿中也有记载)写的函数。


如果我没记错(我真没记错),play给出的输出只有双方分数,而不能打印游戏过程中的状态。


但是我们需要看到过程中到底发生了什么事。


那么这是怎么解决的呢?老师给出的代码并没有改变play函数(毕竟是作业部分),而是对strategy, sus_update和dice动手了。


注意此处play里的输入值都是陌生的东西:

但printing_strategy, sus_update_and_print, printing_dice都是我们在作业中看到的函数的套壳产物。


每一个套壳都让程序在这个过程中输出必要的文字。


`printing_strategy`


函数`printing_strategy`的作用是把原有的策略包装一下,让它能打印出玩家/电脑选择的投掷数。


它的输出样子:"The score is 0 to 0 and Player 0 rolls 5 dice..."

这个函数的输入是策略(函数)以及使用策略的who,输出当然也需要是一个策略(函数),因此先定义了一个新函数。


而这个新函数的作用就只是在内部print一下当前的状态以及根据策略决定的投掷骰子数量。它的输入和原本的策略相同,输出也是相同的。


哦!原来还可以这样操作!


`printing_dice`

这个函数也是这么玩的。它的输出函数`dice_and_print()`每次在返回投掷结果`outcome`之前,还会`print`以下投掷的`outcome`,并以空格结束每次的print。


`sus_update_and_print`


现在来看`sus_update_and_print`,巧妙的是,可以说它是基于`printing_dice`的。

这段代码首先print出了一个左括号,然后掷骰子,再print右括号,写出最终到了几分,再写出加分过程。

按照我们的想象,会是"  [ ] => 16; 0 + 16 = 16"这样,那括号里的数字,像

"  [ 3 2 2 6 3 ] => 16; 0 + 16 = 16"这样是怎么来的呢?


奥秘藏在`take_turn(num_rolls, player_score, opponent_score, dice)`这段代码里,更准确地说,是在`dice`里面。执行的时候,这里的`dice`实际上是个`printing_dice`。(在调用函数的时候用的是`printing_dice`。)而这种骰子每次投掷出一个数就会打印它。


也就是说,打印这个过程的不是运行游戏的函数,而是投掷骰子的函数。


接下来到了这个函数的第二部分:判定是否触发Sus Fuss规则。若出发,再额外说明。

这里就非常朴实无华了。先计算当前总分和触发Sus Fuss后的总分,如果两者不同,就提示触发规则,并增分。否则直接换行。

示例(触发):

"  [ 4 3 6 4 5 ] => 22; 16 + 22 = 38 triggering **Sus Fuss**, increasing to 41"

示例(不触发):

"  [ 3 3 1 1 6 ] => 1; 0 + 1 = 1"


最终,由于本函数本质依然还是`sus_update`函数套壳,它的输出依然要与`sus_update`保持一致,因此返回`score`


以上是追加篇第一期内容,由于写不下,后面的部分就要留给第二篇了。



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1