golang学习实例-猜拳小游戏

来源:互联网 发布:连云港 知乎 编辑:程序博客网 时间:2024/05/24 20:07

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


主程序源码:

package mainimport ("bufio" // 输入输出"fmt""math""math/rand""os""strconv""time")//rock, paper, scissorsconst (rock     int = 1scissors int = 2paper    int = 3rockName     string = "石头"scissorsName string = "剪刀"paperName    string = "布"win  int = 1lose int = -1draw int = 0)// 拳的结构type Finger struct {value intname  string}func createFinger(n int) (finger Finger) {switch n {case rock:finger.value = rockfinger.name = rockNamecase scissors:finger.value = scissorsfinger.name = scissorsNamecase paper:finger.value = paperfinger.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 = rockfinger.name = rockNamecase 1:finger.value = scissorsfinger.name = scissorsNamecase 2:finger.value = paperfinger.name = paperName}return}func main() {var aiFinger, userFinger Fingerreader := 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 mainimport ("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]intexcept 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].csexcept := cases[i].exceptresult := 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电脑出拳为:  布你出拳为:  石头你输了,继续输入:9exit code 0, process exited normally.

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

cases := [...]struct {cs     [2]intexcept 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")







原创粉丝点击