猜谜游戏入门GO语言| 青训营笔记

206 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第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",若直接运行程序,结果如下

image.png

结果显示,我的输入并非整数,问题出在了上述代码的第一行,后缀去除。经过资料查阅得知,windows10/11系统会在按回车之后,在末尾加上\r\n作为换行。故我们去除后缀的时候应该改为

 input = strings.TrimSuffix(input, "\r\n") //去除字符串的"\n"后缀

修改后,运行结果如下

image.png

程序正常运行。


在本篇笔记中,我们利用猜谜游戏熟悉了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
      }
   }
}