猜谜游戏的优化
在上期,我们用Go语言构建了一个猜谜游戏,在这个游戏当中,程序首先会生成一个介于1到100之间的随机整数,然后提示玩家进行猜测。玩家每次输入一个数字,然后提示玩家进行猜测。玩家每次输入一个数字,程序会告诉玩家这个猜测的值是高于还是低于这个秘密的随机数,并且让玩家继续猜测。直到猜对为止,就会告诉玩家胜利并且退出程序。但是,一个小小的猜谜游戏的代码便已经高达44行,其性能也不高,占用资源较多,现在,让我们来试看看能不能优化代码,提高其性能并减少资源占用。
以下是上期的完整代码
为了生成随机数,我们需要用到math/rand包。首先我们要导入fmt包和math/rand包,定义一个变量,maxNum是你定义的最大值,我们用time.Now().UnixNano()来初始化随机种子。接下来是实现用户输入输出,并解析成数字,我们会用 bufio.NewReader 把一个文件转换成一个 reader 变量。现在我们有了一个秘密的值,然后也从用户的输入里面读到了一个值,我们来比较这两个值的大小。如果是用户输入的值比那个秘密的值要大的话,就告诉用户你猜的值太大了,请再试一次。如果是小了也同理,如果是相等的话,那么我们就告诉用户赢了。此时我们的程序大致可以正常工作了,但是玩家只能输入一次猜测,无论猜测是否正确,程序都会退出。为了让游戏可以正常玩下去,我们需要加一个循环。 具体实践过程和思路请看上一期
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("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.TrimSuffix(input, "\n")
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Println(err)
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
}
}
}
仔细观察代码不难发现,在生成随机数和实现判断逻辑阶段的代码基本上达到了最佳。所以,我们能优化的地方只有读取用户输入(第18行到第34)的阶段,在这个阶段中我们用了 bufio.NewReader 把一个文件转换成一个 reader 变量,reader 变量上会有很多用来操作一个流的操作,我们用它的 ReadString 方法来读取一行。虽然这样的操作可行,但是也给系统带来了较大的资源浪费。现在,我们来试着简化这一部分的代码。
优化代码
通过观察和是思考后,我发现可以用fmt.Scanf来简化这一部分的代码,现在让我们来试试看。
package main
import (
"fmt"
"math/rand"
"time"
)
...
fmt.Println("Please input your guess")
for {
var guess int
_, err := fmt.Scanf("%d\n", &guess)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
continue
}
fmt.Println("You guess is", guess)
...
好了,现在代码已经优化完成,试试看能不能运行吧。通过实验后,我们发现代码还是可以完美的运行,并且代码从原来的44行减少到33行。不仅如此,还大大提高了程序的性能,减少了资源的占用,是一次成功的优化。