这是我参与「第五届青训营」伴学笔记创作活动的第 11 天
通过之前对于Go语言的学习,我开始上手学习和完善实战的例子,文本主要针对:猜谜游戏这个实例。
猜谜游戏
游戏规则
在这个游戏里面,程序首先会生成一个介于 1 到 100 之间的随机整数,然后提示玩家进行猜测玩家每次输入一个数字,程序会告诉玩家这个猜测的值是高于还是低于那个秘密的随机数,并且让玩家再次猜测。如果猜对了,就告诉玩家胜利并且退出程序。
技术说明
随机数、随机数种子、获取当前时间戳、读取终端输入方式
1.随机数
Go生成随机数需要引入math/rand包,Intn(n int)函数可以生成一个0~n的非负随机整数数,包含0不包含n也就是[0,n)。
但在v1版本中,我们发现虽然使用了rand函数,但每次生成的随机数都是同一个数字。
原因:
通过查看rand的文档,发现在使用rand.Intn()之前需要设置随机数种子,否则的话每一次都会生成相同的随机数序列。一般惯例用法是在程序启动的时候,用启动的时间戳来初始化随机数种子time.now.unix。
2.实现真正的随机数————随机种子
- 使用rand函数生成随机数之前需要设置随机数种子,否则的话每一次都会生成相同的随机数序列。用启动的时间戳(Unix时间)来初始化随机数种子。
- 代码:rand.Seed(time.Now().UnixNano())
- 上述代码实现用户输入输出,并理解析成数字。
3.读取用户输入
-
示例代码中用bufio.NewReader将文件转为reader变量,并且用它的ReadString方法根据换行符来读取一行,然后需要去掉换行符,并且利用strconv.Atoi()将输入的字符串转化为数字
-
每个程序执行的时候都会打开几个文件,stdin stdout等, stdin文件可以用os.Stdin来得到。
-
直接操作这个文件很不方便,因此可以用bufio.NewReader把一个文件转换成一个reader变量,reader变量上会有很多用来操作一个流的操作,我们可以用它的ReadString方法来读取一行。
-
如果失败,打印错误并退出。ReadString返回的结果包含结尾的换行符,把它去掉,再转换成数字。如果转换失败,同样打印错误,退出。
代码:
input = strings.Trim(input, "\r\n") //去掉换行符
guess, err := strconv.Atoi(input) //转数字
4.逻辑判断以及循环
- 将guess变量的值与生成的随机数secretNumber进行比较,最后加上循环即可
- 学过常见的编程语言以及知道逻辑关系都很好完成这一步
5.作业:改进代码
利用fmt.Scanf函数简化代码
- 定义一个变量用于Scanf接收
- fmt.Scanf("%d\n", &guess)利用上guess,同时将换行符一起判断
- 写err的错误处理
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
fmt.Println("Please input your guess")
var guess int
for {
_, err := fmt.Scanf("%d\n", &guess)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
continue
}
// fmt.Println("You guess is", guess)
if guess > secretNumber {
fmt.Println("Your guess is bigger than the secret number. Please try again")
} else if guess < secretNumber {
fmt.Println("Your guess is smaller than the secret number. Please try again")
} else {
fmt.Println("Correct, you Legend!")
break
}
}
}
总结
通过本次猜谜游戏实战项目,不仅重新温习了 Go 语言基础知识,还深入学习了课堂上没有学习的一些细节,比如说scanf的换行问题,明天继续加油,详细完善之前的实战和工程的作业任务。
引用
PPT:Go 语言上手 - 基础语法 .pptx - 飞书云文档 (feishu.cn)