猜谜游戏
项目概要
本次猜谜游戏是一个简单的命令行游戏,玩家需要猜测计算机生成的随机数字,直到猜对为止。
功能介绍
1.游戏生成1--100的随机数字
2.游戏将玩家的输入变为整数,并让这个整数与系统生成的随机数进行比较
3.游戏能把比较结果告诉玩家,让玩家继续输入进行猜谜,直到猜出来为止
V1
代码如下
package main
import (
"fmt" //fmt包,进行输入输出功能
"math/rand"// 提供了随机数功能
)
func main() {
maxNum := 100
secretNumber := rand.Intn(maxNum) //rand。Intn()的功能是取1--maxnum之间的随机数
fmt.Println("The secret number is ", secretNumber)
}
但是这样做有一个弊端: rand.Intn()函数是根据伪随机数生成器(pseudo-random number generator)来实现的。
伪随机数生成器是根据一个初始种子值计算出一系列看似随机的数字,但实际上是根据某种算法推导出来的。因此,当种子值相同时,生成器产生的随机数序列也会相同。
在 Go 语言的 rand 包中,默认情况下,生成器的种子值是一个固定值(为了可复现性),这使得在每次运行程序时生成的随机数序列都是相同的。
为了产生不同的随机数序列,我们通常会通过修改种子值来确保每次运行程序时生成的随机数序列都不同。一种常用的方法是使用当前时间time.Now().UnixNano()作为种子,以确保每次运行时种子值都不同,从而生成不同的随机数序列。
V2
代码如下
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
num := 100
rand.Seed(time.Now().Unix())//rand.Seed()函数能把括号内的数变为新的种子生成器
secretnumber := rand.Intn(num)
fmt.Println("the secret num is:", secretnumber) //取秘密数字
}
V3
解决了随机数问题,接下来就要解决玩家的输入和输出问题
先看代码
reade := bufio.NewReader(os.Stdin)
input, err := reade.ReadString('\n')
if err != nil {
fmt.Println("An error occured while reading input. Please try again", err)
return
}
input = strings.Trim(input, "\r\n")
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
return
}
fmt.Println("you guess is:", guess)
}
在go语言中,提供了bufio包,能够让我们进行带缓冲的I/O操作,帮助我们更高效的处理输入输出操作
bufio.NewReader()函数创建了一个新的缓冲读取器,并将其赋值给变量reader。这样,reader就成为了一个可以从标准输入(键盘输入)读取数据的缓冲读取器。
通过这个reader变量,我们可以使用ReadString()、ReadBytes()、ReadLine()等方法来读取用户在终端输入的内容,并且由于使用了缓冲读取器,这样可以更高效地处理输入数据。
reade.ReadString()函数表示从第一个字符读取,直到读取到括号内的变量为止,并返回两个值,第一个值是读取到的字符,第二个值表示读取时可能出现的错误,方便我们进行排错
strings.Trim()函数用于在两侧去除用户输入中的换行符(\r和\n),并返回去除后的字符串
V4
接下来就要解决最后的游戏逻辑问题
代码如下
if guess>secretnumber {
fmt.Println("Your guess is bigger")
}else if guess<secretnumber{
fmt.Println("Your guess is smaller")
}else {
fmt.Println("Correct,you are right")
}
这部分比较简单,可以自行参考
V5
最后加一个循环,该项目就完成了
代码如下
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
func main() {
num := 100
rand.Seed(time.Now().Unix())
secretnumber := rand.Intn(num)
//fmt.Println("the secret num is:", secretnumber) //取秘密数字
fmt.Println("Please input your guess:")
reade := bufio.NewReader(os.Stdin)
for {
input, err := reade.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")
} else if guess < secretnumber {
fmt.Println("Your guess is smaller")
} else {
fmt.Println("Correct,you are right")
return
}
}
}
程序运行结果如下
Please input your guess:
45
you guess is: 45
Your guess is smaller
60
you guess is: 60
Your guess is bigger
50
you guess is: 50
Your guess is smaller
55
you guess is: 55
Your guess is bigger
Invalid input. Please enter an integer value
53
you guess is: 53
Your guess is bigger
52
you guess is: 52
Correct,you are right
第五个版本的代码使用了一个无限循环 for { ... },使得游戏可以持续进行,直到玩家猜对为止。
最后用break结束循环,游戏结束
课后作业
用scanf进行代码简化
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
num := 100
rand.Seed(time.Now().Unix())
secretnumber := rand.Intn(num)
//fmt.Println("the secret num is:", secretnumber) //取秘密数字
fmt.Println("Please input your guess:")
// reade := bufio.NewReader(os.Stdin)
var guess int
for {
// input, err := reade.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)
_, err := fmt.Scanf("%d", &guess)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
continue
}
if guess > secretnumber {
fmt.Println("Your guess is bigger")
} else if guess < secretnumber {
fmt.Println("Your guess is smaller")
} else {
fmt.Println("Correct,you are right")
return
}
}
}