GO语言上手实战入门 | 青训营

117 阅读4分钟

猜谜游戏

项目概要

本次猜谜游戏是一个简单的命令行游戏,玩家需要猜测计算机生成的随机数字,直到猜对为止。

功能介绍

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),并返回去除后的字符串

`strconv.Atoi`函数可以将括号内的变量改为数字,注意必须是整数,不然会返回一个错误的数

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
		}
	}
}