golang学习实例-猜拳小游戏

hnxxwyq · · 2184 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

学了一段golang,觉得应该实践一下,写了这个猜拳小游戏,顺带着学习下go testing。


主程序源码:

package main

import (
	"bufio" // 输入输出
	"fmt"
	"math"
	"math/rand"
	"os"
	"strconv"
	"time"
)

//rock, paper, scissors
const (
	rock     int = 1
	scissors int = 2
	paper    int = 3

	rockName     string = "石头"
	scissorsName string = "剪刀"
	paperName    string = "布"

	win  int = 1
	lose int = -1
	draw int = 0
)

// 拳的结构
type Finger struct {
	value int
	name  string
}

func createFinger(n int) (finger Finger) {
	switch n {
	case rock:
		finger.value = rock
		finger.name = rockName
	case scissors:
		finger.value = scissors
		finger.name = scissorsName
	case paper:
		finger.value = paper
		finger.name = paperName
	}
	return
}

func isAiWin(ai Finger, user Finger) int {

	result := ai.value - user.value

	// 如果是石头和布的比较,比较值正负取反
	if int(math.Abs(float64(result))) == paper-rock {
		result = -(result)
	}

	if result < 0 {
		return win
	} else if result > 0 {
		return lose
	}

	return draw
}

func randFinger() (finger Finger) {
	rand := rand.New(rand.NewSource(time.Now().UnixNano()))
	switch rand.Intn(3) {
	case 0:
		finger.value = rock
		finger.name = rockName
	case 1:
		finger.value = scissors
		finger.name = scissorsName
	case 2:
		finger.value = paper
		finger.name = paperName
	}
	return
}

func main() {

	var aiFinger, userFinger Finger
	reader := bufio.NewReader(os.Stdin)

	fmt.Printf("请输入你要出的拳:%d->石头,%d->剪刀,%d->布, 9->退出\n", rock, scissors, paper)
	for {
		data, _, err := reader.ReadLine()

		if err != nil {
			fmt.Println("程序出错")
			break
		}

		input, err := strconv.Atoi(string(data))

		if err != nil {
			fmt.Println("格式不对,请输入数字:", input)
			continue
		}

		if input == 9 {
			break
		}

		switch input {
		case rock, scissors, paper:
			aiFinger = randFinger()
			fmt.Println("电脑出拳为: ", aiFinger.name)

			userFinger = createFinger(input)
			fmt.Println("你出拳为: ", userFinger.name)

			aiWin := isAiWin(aiFinger, userFinger)
			if aiWin == win {
				fmt.Println("你输了,继续输入:")
			} else if aiWin == lose {
				fmt.Println("你赢了,继续输入:")
			} else {
				fmt.Println("平局,继续输入:")
			}
		default:
			fmt.Println("输入不合要求,继续输入:")
		}

	}

}


testing 源码

package main

import (
	"testing" // 加载test包
)

func TestCreateFinger(t *testing.T) {
	// 顺带掌握以下struct作为map value的初始化
	cases := map[int]Finger{
		rock:     Finger{rock, rockName},
		scissors: Finger{scissors, scissorsName},
		paper:    Finger{paper, paperName},
		6:        Finger{}, // other
	}

	for cs, except := range cases {
		result := createFinger(cs)
		if result != except {
			t.Errorf("case %v, except %v, result %v", cs, except, result)
		}
	}
}

func TestIsAiWin(t *testing.T) {
	// 顺带掌握以下struct作为array element的初始化
	cases := [...]struct {
		cs     [2]int
		except int
	}{
		{[2]int{paper, rock}, win},
		{[2]int{rock, paper}, lose},
		{[2]int{rock, scissors}, win},
		{[2]int{scissors, rock}, lose},
		{[2]int{scissors, paper}, win},
		{[2]int{paper, scissors}, lose},

		{[2]int{scissors, scissors}, draw},
	}

	for i := 0; i < len(cases); i++ {
		cs := cases[i].cs
		except := cases[i].except

		result := isAiWin(createFinger(cs[0]), createFinger(cs[1]))

		if result != except {
			t.Errorf("case %v, except %v, result %v", cs, except, result)
		}
	}
}

执行预览

请输入你要出的拳:1->石头,2->剪刀,3->布, 9->退出
3
电脑出拳为:  石头
你出拳为:  布
你赢了,继续输入:
2
电脑出拳为:  布
你出拳为:  剪刀
你赢了,继续输入:
1
电脑出拳为:  石头
你出拳为:  石头
平局,继续输入:
1
电脑出拳为:  剪刀
你出拳为:  石头
你赢了,继续输入:
1
电脑出拳为:  布
你出拳为:  石头
你输了,继续输入:
9
exit code 0, process exited normally.

实践过程中,还是发现诸多问题,例如丢失类型是长出现的问题,例如

cases := [...]struct {
		cs     [2]int
		except int
	}{
		{[2]int{paper, rock}, win},
		{[2]int{rock, paper}, lose},
		{[2]int{rock, scissors}, win},
		{[2]int{scissors, rock}, lose},
		{[2]int{scissors, paper}, win},
		{[2]int{paper, scissors}, lose},

		{{scissors, scissors}, draw}, //原来设想[2]int是可以省略,但是在这里会造语义分析失败,从而丢失cs的数据

	}

一些疑问

import分开的话(即中间有空行的话),fmt是不会将之顺序对调,不知道会不会对import产生影响
import (
	"bufio" // 输入输出
	"os"

	"fmt"
	"strconv"

	"math"
	"math/rand"
	"time"
)

不分开的话,会是这样
import (
	"bufio" // 输入输出
	"fmt"
	"math"
	"math/rand"
	"os"
	"strconv"
	"time"
)








有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:hnxxwyq

查看原文:golang学习实例-猜拳小游戏

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2184 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传