Go 语言实战——猜数字游戏 | 青训营

173 阅读2分钟

通过一个简单的猜字谜案例,体会 GoLand

游戏中,程序首先会生成一个 1 到 100 内的随机整数,程序会告诉玩家猜的数字和正确数字相比是大了还是小了,并且让玩家继续猜直到猜对为止。

1 生成随机数

要生成一个 1 到 100 之间的随机数,可以利用 GoLang 中 math/rand 包,通过 Intn()函数生成随机数

代码如下:

// 生产一个 100 以内随机数
	maxNum := 100
	secretNum := rand.Intn(maxNum)
	fmt.Println("The secretNum is", secretNum)

2 用户输入处理

需求:实现用户输入输出,并解析成数字

  • 每个程序执行的时候都会打开几个文件,stdin stdout stderr 等
  • stdin 文件可以用 os.Stdin 来得到,直接操作这个文件很不方便,我们

会用 bufio.NewReader 把个文件转换成个 reader 变量。reader 变

量上会有很多用来操作一个流的操作,我们可以用它的 ReadString 方

法来读取一行。如果失败了的话,我们打印错误并能退出。

  • ReadString 返回的结果包含结尾的换行符,我们把它去掉,再转换成

数字。如果转换失败,我们同样打印错误,退出。

// 处理用户输入
fmt.Println("Please input your guess")
// 获取输入流
reader := bufio.NewReader(os.Stdin)
// 通过输入流获取一行用户输入
input, err := reader.ReadString('\n')
if err != nil {
    fmt.Println("An error occured while reading input. Please try again!", err)
    return
}
// 去除用户输入的字符串最后的换行符
input = strings.TrimSuffix(input, "\r\n")
// 将字符串转换成数字
guess, err := strconv.Atoi(input)
if err != nil {
    fmt.Println("Invaild input,Please enter an integer again", err)
    return
}
fmt.Println("Your guess is", guess)

3 判断逻辑编写

把用户输入的数值和随机生成的数字作比较,如果用户输入的数字比真实数字大/小,就提示用户猜测的数字大了/小了。可以用 if...else...分支结构判断,代码如下:

if guess > secretNum {
    fmt.Println("Your guess is bigger than the secret number!")
} else if guess < secretNum {
    fmt.Println("Your guess is smaller than the secret number!")
} else {
    fmt.Println("Correct,your legend")
    break
}

4 循环逻辑编写

代码写到现在,功能已经完成的差不多了,但是还有一个问题,就是程序只会执行一次,即无论玩家是否猜对程序都会退出,而我们想要的效果是只有玩家猜对才会退出程序。

要改变以上情况,需要用到循环,Golang 中只有 for 循环,代码如下:

for {
		fmt.Println("Please input your guess")
		reader := bufio.NewReader(os.Stdin)
		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("Invaild input,Please enter an integer again", err)
			continue
		}
		fmt.Println("Your guess is", guess)

		if guess > secretNum {
			fmt.Println("Your guess is bigger than the secret number!")
		} else if guess < secretNum {
			fmt.Println("Your guess is smaller than the secret number!")
		} else {
			fmt.Println("Correct,your legend")
			break
		}
	}

利用 for 、continue、break 实现循环效果

5 完整代码

完整代码如下:

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
)

func main() {

	// 生产一个 100 以内随机数
	maxNum := 100
	secretNum := rand.Intn(maxNum)
	fmt.Println("The secretNum is", secretNum)

	// 处理用户输入
	for {
		fmt.Println("Please input your guess")
		reader := bufio.NewReader(os.Stdin)
		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("Invaild input,Please enter an integer again", err)
			continue
		}
		fmt.Println("Your guess is", guess)

		if guess > secretNum {
			fmt.Println("Your guess is bigger than the secret number!")
		} else if guess < secretNum {
			fmt.Println("Your guess is smaller than the secret number!")
		} else {
			fmt.Println("Correct,your legend")
			break
		}
	}
}