这是一个很经典的案例,我们将使用Golang来构建一个猜数字的游戏。
内容介绍
在这个游戏里面,程序首先会生成一个介于1~100之间的随机整数,然后提示玩家进行猜测。玩家每次输入一个数字,程序会告诉玩家这个猜测的值是高于还是低于那个秘密的随机数,并且让玩家再次猜测。如果猜对了就告诉玩家胜利并且退出程序。
设计
想要完成一件事,就要在大脑中提前构思一下完成这件事的框架。当然,做猜字谜游戏也不例外。我们想要的效果:
- 生成一个随机数
- 从用户那里接收数据
- 程序比较数据与生成的随机数
- 返回比较结果
一、生成一个随机数
我们先从第一步开始,在Java中我们可以使用math/rand包 生成随机数。在Golang中也不例外,甚至名字都一样,我们使用math/rand包生成随机数。导入了math/rand包,我们就可以完成第一步:
import (
"fmt"
"math/rand"
)
然后我们这样写主方法
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
fmt.Println("The secret number is ", secretNumber)
}
需要注意的是:
- 第一行我们定义了一个变量
maxNum,这是用来界定随机数的最大值100。 - 第二行很关键,因为使用这个包之前需要设置随机数种子,否则的话每一次生成相同的随机序列,一般的惯例用法是在程序启动的时候,用启动的时间戳来初始化随机种子。我们用
time.now.unix来初始化随机种子。 - 第三行,我们调用
Intn函数,生成了一个随机数并存入变量secretNumber中
二、接收数据
我们先从底层逻辑开始。
每个程序执行的时候都会打开几个文件,stdin stdout stderr等,stdin 文件(in也就是输入流)可以用 os.Stdin 来得到。
但是,直接操作这个文件很不方便,我们会用 bufio.NewReader 把一个文件转换成一个 reader 变量。
reader变量上会有很多用来操作一个流的操作,我们可以用它的 ReadString 方法来读取一行。
如果读取失败,我们能打印错误并退出。
注意!
ReadString返回的结果包含结尾的换行符,我们应当先把它去掉,再转换成数字。如果转换失败,我们同样打印错误,退出。
代码如下:
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
input = strings.Trim(input, "\r\n")//去掉换行符
guess, err := strconv.Atoi(input)//将输入转化为数字
三、比较数据并返回结果
我们直接用if判断并返回就好
if err != nil {
fmt.Println("An error occured while reading input. Please try again", err)
return
}
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
return
}
这样一个猜谜游戏就做好了
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
// fmt.Println("The secret number is ", secretNumber)
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin)
for {
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("An error occured while reading input. Please try again", err)
continue
}
input = strings.Trim(input, "\r\n")
guess, err := strconv.Atoi(input)
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
}
}
}
但是玩家只能输入一次猜测,无论猜测是否正确,程序都会退出。
为了改变这种行为,让游戏可以正常玩下去,我们需要加一个循环,我们把刚刚的代码挪到一个for循环里面,然后再把return改成continue,以便于在出错的时候能够继续循环,在用户输入正确的时候break,这样才能在用户胜利的时候退出游戏。
怎么样是不是很简单呢?