Golang语言实现-贪吃蛇

前端之家收集整理的这篇文章主要介绍了Golang语言实现-贪吃蛇前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
package main

import (
    "fmt"
    "math/rand"
    "os"
    "time"
)

/* #include <windows.h> #include <conio.h> // 使用了WinAPI来移动控制台的光标 void gotoxy(int x,int y) { COORD c; c.X=x,c.Y=y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c); } // 从键盘获取一次按键,但不显示到控制台 int direct() { return _getch(); } */
import "C" // go中可以嵌入C语言的函数

// 表示光标的位置
type loct struct {
    i,j int
}

var (
    area = [20][20]byte{} // 记录了蛇、食物的信息
    food bool             // 当前是否有食物
    lead byte             // 当前蛇头移动方向
    head loct             // 当前蛇头位置
    tail loct             // 当前蛇尾位置
    size int              // 当前蛇身长度
)

// 随机生成一个位置,来放置食物
func place() loct {
    k := rand.Int() % 400
    return loct{k / 20,k % 20}
}

// 用来更新控制台的显示,在指定位置写字符,使用错误输出避免缓冲
draw(p loct,c byte) {
    C.gotoxy(C.int(p.i*2+4),C.int(p.j+2))
    fmt.Fprintf(os.Stderr,"%c",c)
}

init() {

    // 初始化蛇的位置和方向、首尾;初始化随机
    head,tail = loct{4,4},loct{4}
    lead,size = 'R',31);">1
    area[4][4] = 'H'
    rand.Seed(int64(time.Now().Unix()))

    // 输出初始画面
    fmt.Fprintln(os.Stderr,0);">` #-----------------------------------------# | | | | | | | | | * | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #-----------------------------------------# `)

    // 我们使用一个单独的go程来捕捉键盘的动作,因为是单独的,不怕阻塞
    go func() {
        for { // 函数只写入lead,外部只读取lead,无需设锁
            switch byte(C.direct()) {
            case 72:
                lead = 'U'
            75:
                lead = 'L'
            77:
                lead = 'R'
            80:
                lead = 'D'
            32:
                lead = 'P'
            }
        }
    }()
}

main// 主程序
    for {

        // 程序更新周期,400毫秒
        time.Sleep(time.Millisecond * 400)

        // 暂停,还是要有滴
        if lead == 'P' {
            continue
        }

        // 放置食物
        if !food {
            give := place()
            if area[give.i][give.j] == 0 { // 食物只能放在空闲位置
                area[give.i][give.j] = 'F'
                draw(give,0);">'$') // 绘制食物
                food = true
            }
        }

        // 我们在蛇头位置记录它移动的方向
        area[head.i][head.j] = lead

        // 根据lead来移动蛇头
        switch lead {
        case 'U':
            head.j--
        'L':
            head.i--
        'R':
            head.i++
        'D':
            head.j++
        }

        // 判断蛇头是否出界
        if head.i < 0 || head.i >= 20 || head.j < 0 || head.j >= 20 {
            C.gotoxy(0,31);">23) // 让光标移动到画面下方
            break           // 跳出死循环
        }

        // 获取蛇头位置的原值,来判断是否撞车,或者吃到食物
        eat := area[head.i][head.j]

        if eat == 'F' { // 吃到食物
            food = false

            // 增加蛇的尺寸,并且不移动蛇尾
            size++
        } else if eat == // 普通移动

            draw(tail,0);">' ') // 擦除蛇尾

            // 注意我们记录了它移动的方向
            dir := area[tail.i][tail.j]

            // 我们需要擦除蛇尾的记录
            area[tail.i][tail.j] = 0

            // 移动蛇尾
            switch dir {
            'U':
                tail.j--
            'L':
                tail.i--
            'R':
                tail.i++
            'D':
                tail.j++
            }
        } else { // 撞车了
            C.gotoxy(23)
            break
        }
        draw(head,0);">'*') // 绘制蛇头
    }

    // 收尾了
    switch {
    case size < 22:
        fmt.Fprintf(os.Stderr,0);">"Faild! You've eaten %d $\\n",size-1)
    42:
        fmt.Fprintf(os.Stderr,0);">"Try your best! You've eaten %d $\\n",168);">default:
        fmt.Fprintf(os.Stderr,0);">"Congratulations! You've eaten %d $\\n",31);">-1)
    }
}
//该片段来自于http://outofmemory.cn

猜你在找的Go相关文章