这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。
猜谜游戏:熟悉GO语言基本输入输出、循环判断
猜谜游戏:程序首先生成一个介于1到100之间的随机整数,然后提示玩家猜测。玩家每输入一个数字,程序会告诉这个玩家猜大了、猜小了还是猜中了,猜中则游戏胜利并退出程序。
以下分析该程序核心代码(完整代码见文末)
(1)生成随机数
为了在每次程序运行时生成不同的随机数,我们需要利用GO语言math/rand库中的种子生成,代码如下。
import (
'fmt'
'math/rand'
'time'
)
func main() {
maxNum := 100 // 设置最大值为100
rand.Seed(time.Now().UnixNano()) //获取系统时间 确保每次生成不同的随机数
secretNumber := rand.Intn(maxNUm) // 生成范围在[1,100]之间的随机数
}
相信大家应该都用过其他语言生成随机数,大多数语言生成随机数都需要使用Seed()种子函数来生成不重复的种子,此处不过多赘述。
(2)数据读入与格式判断
由于我们是交互式程序,我们需要清楚用户的输入格式,判断其是否按照要求输入,同时对于程序可能出现的读取错误进行反馈。其次,我们需要将输入转换为我们需要的、逻辑上更直接的整数格式。
fmt.Println("Please input yout guess") // 让用户输入猜测数字
reader := bufio.NewReader(os.Stdin) // 使用系统标准读入
input, err := reader.ReaderString('\n') // 以'\n'为判断读取一行的内容
if err != nil { // 判断系统是否正确读入,若读取失败,则反馈给用户
fmt.Println("An error occured while reading input. Please try again", err)
continue
}
input = strings.TrimSuffix(input, "\n") //去除字符串的"\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) // 反馈输入`
(3)循环判断
首先,我们考虑到用户可能需要多次输入才能猜对,我们需要将读入、判断等写入循环之中。其次,对于读取到的整数,我们需要与之间生成的随机数进行比较判断,用到 if else 分支结构。
reader := bufio.NewReader(os.Stdin) // 承接上一段代码
for {
input, err := reader.ReadString('\n')
......
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
}
}
(4)补充
对于其中个别函数以及基础语法知识就不深入介绍了,可以从网上资料或者书本中找到许多详细的讲解。此处针对我在运行时遇到的一个小问题进行分享。
input = strings.TrimSuffix(input, "\n") //去除字符串的"\n"后缀
guess, err := strconv.Atoi(input) // 将其转换为整数
if err != nil { // 判断是否转换失败 若用户输入非整数 则失败 反馈给用户
fmt.Println("Invalid input. Please enter an integer value")
continue
}
代码中,这一行是为了去除之前读取用户输入的文末换行符"\n",若直接运行程序,结果如下
结果显示,我的输入并非整数,问题出在了上述代码的第一行,后缀去除。经过资料查阅得知,windows10/11系统会在按回车之后,在末尾加上\r\n作为换行。故我们去除后缀的时候应该改为
input = strings.TrimSuffix(input, "\r\n") //去除字符串的"\n"后缀
修改后,运行结果如下
程序正常运行。
在本篇笔记中,我们利用猜谜游戏熟悉了GO语言的基础输入输出、赋值、循环判断语法。文章中出现错误、讲解不清楚等问题欢迎大家指正。
完整代码如下
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 scret 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.TrimSuffix(input, "\r\n")
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
//return
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
}
}
}