游戏介绍
运用Golang来构建一个猜数字的游戏,首先生成一个介于某范围(可以是1到100之间)的随机整数,然后提示玩家进行猜测。玩家每输入一个数字,程序会告诉玩家这个猜测值是大于这个随机数还是小于这个随机数或者是等于这个随机数,如猜错,会让玩家再次进行猜测,直至猜对,告诉玩家猜对退出猜谜游戏。
实现方法
(1)生成随机数
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
maxNum := 100
rand.New(rand.NewSource(time.Now().UnixNano()))
//rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
}
我导入了需要使用的三个包,分别是 fmt(用于格式化输出)、math/rand(用于生成随机数)、以及 time(用于获取当前时间)。为了确保每次运行程序时,随机数生成器的种子都是不同的,产生不同的随机数序列,调用了rand.new()。然后调用 Intn 方法生成一个随机数,范围在 0 到 maxNum-1(即 0 到 99)。最后,将生成的随机数存储在 secretNumber 变量中。
说明:rand.Seed() 用于设置全局随机数生成器的种子,影响程序中所有的随机数生成。而 rand.New() 用于创建一个新的随机数生成器,可以更灵活地控制生成随机数的过程,特别是需要多个独立的随机数生成器时。
(2)两种用户数据输入方式
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n') // 以'\n'为判断读取一行的内容
if err != nil { // 判断系统是否正确读入,若读取失败,则反馈给用户
fmt.Println("An error occured while reading input. Please try again", err)
continue
}
input = strings.TrimSuffix(input, "\r\n") //去除字符串的"\n"后缀
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
continue
}
fmt.Println("Your guess is", guess)
打印提示信息,要求用户输入他们的猜测,创建一个 bufio.Reader 对象,用于从标准输入(键盘)读取数据,使用 reader.ReadString() 从标准输入读取一行用户输入的内容,直到遇到换行符 ('\n'),其中读取的内容包括换行符,所以在后续操作需要讲字符转换数字之前,需要去除这个换行符,去除输入字符串末尾的回车 ("\r\n"),这是因为在 Windows 系统上,每行末尾有一个回车换行符,将去除回车后的输入字符串转换为整数,如果转换输入的字符串为整数时发生错误(用户输入了非整数内容),则进行错误处理。
以上用户输入部分可以通过fmt.scanf来简化这部分代码,如下所示
var guess int
_, err := fmt.Scanf("%d\n", &guess)
if err != nil {
fmt.Println("An error occured while reading input. Please try again", err)
continue
}
fmt.Println("You guess is", guess)
使用 fmt.Scanf 读取用户输入的整数,格式化字符串 "%d\n" 表示读取一个整数,然后读取一个换行符。用户输入的整数会被转换并存储在 guess 变量中。
说明:使用 fmt.Scanf 可以使代码更紧凑,适用于简单的输入处理,如果用户输入的内容不符合格式化字符串中指定的格式,fmt.Scanf 通常不提供明确的错误消息,可能需要进一步的处理。使用 bufio.NewReader 可以提供更多的控制和更明确的错误处理,适用于需要更复杂输入处理的情况,可以使用 bufio.NewReader 来处理不同的输入情况,而不仅限于整数。
(3)循环判断用户猜测结果
考虑到用户可能需要多次输入才能猜对,我们需要将读入、判断等写入循环之中。其次,对于读取到的整数,我们需要与之间生成的秘密随机数进行比较判断,用到 if-else if-else 分支结构。
for {
_, err := fmt.Scanf("%d\n", &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语言的知识点:
- 导入包(Import):您导入了
bufio、fmt、math/rand、os、strconv和strings包,用于不同的功能,如读取输入、格式化输出、生成随机数、转换字符串等。 - 变量声明(Variable Declaration):您使用
var关键字声明了变量maxNum、secretNumber、input和guess。 - 随机数生成(Random Number Generation):通过
rand.Seed和rand.Intn方法,您生成了一个随机数secretNumber,作为猜测的目标。 - 时间处理(Time Handling):通过
time.Now().UnixNano()获取当前时间的纳秒部分,用于设置随机数生成器的种子。 - 输入读取(Input Reading):使用
bufio.NewReader读取标准输入,并使用reader.ReadString获取用户输入的内容。 - 类型转换(Type Conversion):通过
strconv.Atoi将用户输入的字符串转换为整数类型。 - 字符串处理(String Manipulation):使用
strings.TrimSuffix去除字符串末尾的回车换行符。 - 循环(Loop):通过
for循环来持续获取用户输入,直到猜测正确为止。 - 条件判断(Conditional Statements):使用
if、else if和else来判断用户猜测与目标随机数之间的关系。 - 格式化输出(Formatted Output):通过
fmt.Println输出提示信息、用户猜测的值,以及猜测结果的反馈。 - 循环终止(Loop Termination):通过
break语句来终止循环,一旦用户猜测正确。 - 错误处理(Error Handling):在读取输入、类型转换等步骤中,您使用
err变量来捕获和处理潜在的错误。