加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang学习实例-猜拳小游戏

发布时间:2020-12-16 18:58:52 所属栏目:大数据 来源:网络整理
导读:学了一段golang,觉得应该实践一下,写了这个猜拳小游戏,顺带着学习下go testing。 主程序源码: package mainimport ("bufio" // 输入输出"fmt""math""math/rand""os""strconv""time")//rock,paper,scissorsconst (rock int = 1scissors int = 2paper int

学了一段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,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},scissors},{[2]int{scissors,{[2]int{paper,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,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,{{scissors,//原来设想[2]int是可以省略,但是在这里会造语义分析失败,从而丢失cs的数据

	}

一些疑问

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

	"fmt"
	"strconv"

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读