Go 语言的实战案例(1) | 青训营笔记

44 阅读3分钟

案例一:猜谜游戏

内容:程序设定一个数字,用户每输入一个数字,程序便会告诉用户所输入的数字是大于还是小于程序设定的数字,直到用户输入数字与程序所给定的数字相同,游戏结束。

生成随机数

代码如下:

结果如下: image.png

代码解释:

这段代码使用Go语言实现了一个猜数字游戏。
其中,maxNum定义了最大的随机数,
rand.Seed(time.Now().UnixNano())用于生成随机数的种子,
secretNumber := rand.Intn(maxNum)生成一个0到maxNum-1之间的随机整数作为猜测对象,并将其赋值给变量secretNumber。
最后,通过fmt.Println()函数输出猜测对象secretNumber的值。

读取用户输入输出

代码如下:

    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 secret number is ", secretNumber)

        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.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)

    }

结果如下:

image.png 代码解释:

这段代码是在猜数字游戏的基础上增加了用户输入和判断的功能。
其中,通过bufio包提供的NewReader()函数和os包提供的Stdin变量创建一个新的读取器,等待用户输入,
然后使用ReadString('\n')函数读取用户输入内容,并使用Trim()函数去除输入内容中的换行符,将其赋值给input变量。
接着,使用strconv包提供的Atoi()函数将input转换为整数类型guess,并对转换过程中的错误进行了处理。
最后,通过fmt包提供的Println()函数输出猜测数guess的值。

实现判断逻辑

代码如下:

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 secret number is ", secretNumber)

    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.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)
    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!")
    }

}

发现问题:无法进行输入

原因和解决:这段代码可能会出现无法输入的情况是因为程序在等待用户输入时被阻塞了,这通常是因为NewReader()函数会将标准输入流中的内容读取完毕后才会返回,而此时标准输入流可能已经被其他程序或操作系统占用。解决方法可以尝试将程序运行在终端模式下,或者在终端中清除缓冲区的残留数据,或者使用其他方式获取用户输入。

结果如下:

image.png

代码解释:

这段代码实现了一个猜数字游戏,其中程序会生成一个介于0和给定maxNum(这里为100)之间的随机整数,用户需要通过命令行输入猜测的数字,并与程序生成的随机数进行比较,如果猜测正确则输出“Correct, you Legend!”,反之则输出“Your guess is bigger/smaller than the secret number. Please try again”。
具体地,程序首先使用rand包提供的Seed()函数设置随机数生成器的种子值为当前时间的纳秒数,然后使用rand包提供的Intn()函数生成一个介于0和maxNum之间的随机整数作为secretNumber。接着,程序通过fmt包提供的Println()函数提示用户进行输入。使用bufio包提供的NewReader()函数和os包提供的Stdin变量创建一个新的读取器等待用户输入,使用ReadString('\n')函数读取用户输入内容并将其赋值给input变量。在此过程中,程序会捕获并处理可能发生的错误,并使用strings包提供的Trim()函数去除字符串中的换行符等无用字符。
接下来,程序使用strconv包提供的Atoi()函数将input转换为整数类型guess,同样地,程序会捕获并处理转换过程中可能发生的错误。最后,程序输出猜测数guess的值,并通过if-else语句判断guess与secretNumber的大小关系,输出相应的提示信息。

实现游戏循环

代码如下:

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

}

结果如下:

image.png

代码解释:

这段代码是在之前猜数字游戏的基础上,添加了一个for循环,让用户可以进行多次尝试,直到猜测正确才停止循环。
具体地,程序首先使用rand包提供的Seed()函数设置随机数生成器的种子值为当前时间的纳秒数,然后使用rand包提供的Intn()函数生成一个介于0和maxNum之间的随机整数作为secretNumber。与之前的代码不同的是,程序将输出secretNumber的语句注释掉了,避免给用户提示信息。
接着,程序通过fmt包提供的Println()函数提示用户进行输入。使用bufio包提供的NewReader()函数和os包提供的Stdin变量创建一个新的读取器等待用户输入,然后进入一个无限循环体,直到用户猜测正确才跳出循环。在每一轮循环中,程序会使用ReadString('\n')函数读取用户输入内容并将其赋值给input变量。在此过程中,程序会捕获并处理可能发生的错误,并使用strings包提供的Trim()函数去除字符串中的换行符等无用字符。
接下来,程序使用strconv包提供的Atoi()函数将input转换为整数类型guess,同样地,程序会捕获并处理转换过程中可能发生的错误。最后,程序输出猜测数guess的值,并通过if-else语句判断guess与secretNumber的大小关系,输出相应的提示信息。如果猜测正确,则输出“Correct, you Legend!”并使用break跳出循环,否则继续下一轮循环。