前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言实现控制台贪吃蛇

Go语言实现控制台贪吃蛇

作者头像
李海彬
发布2018-03-19 10:06:53
1.7K0
发布2018-03-19 10:06:53
举报
文章被收录于专栏:Golang语言社区Golang语言社区

各位好

今天在关注GO相关文章的时候,看到一篇关于go语言实现贪吃蛇的文章,原文地址:http://outofmemory.cn ;尝试编译了下并录制了一段操作视频供大家“欣赏” 如下:

源码 如下:


代码语言:javascript
复制
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}
}
// 用来更新控制台的显示,在指定位置写字符,使用错误输出避免缓冲
func draw(p loct, c byte) {
    C.gotoxy(C.int(p.i*2+4), C.int(p.j+2))
    fmt.Fprintf(os.Stderr, "%c", c)
}
func init() {    
// 初始化蛇的位置和方向、首尾;初始化随机数
    head, tail = loct{4, 4}, loct{4, 4}
    lead, size = 'R', 1
    area[4][4] = 'H'
    rand.Seed(int64(time.Now().Unix()))    
// 输出初始画面
    fmt.Fprintln(os.Stderr,        `
  #-----------------------------------------#
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |         *                               |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  |                                         |
  #-----------------------------------------#
`)    
// 我们使用一个单独的go程来捕捉键盘的动作,因为是单独的,不怕阻塞
    go func() {        
          for { // 函数只写入lead,外部只读取lead,无需设锁
            switch byte(C.direct()) {            
            case 72:
                lead = 'U'
            case 75:
                lead = 'L'
            case 77:
                lead = 'R'
            case 80:
                lead = 'D'
            case 32:
                lead = 'P'
            }
        }
    }()
}
func 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, '$') // 绘制食物
                food = true
            }
        }        // 我们在蛇头位置记录它移动的方向
        area[head.i][head.j] = lead        // 根据lead来移动蛇头
        switch lead {        case 'U':
            head.j--        case 'L':
            head.i--        case 'R':
            head.i++        case 'D':
            head.j++
        }        // 判断蛇头是否出界
        if head.i < 0 || head.i >= 20 || head.j < 0 || head.j >= 20 {
            C.gotoxy(0, 23) // 让光标移动到画面下方
            break           // 跳出死循环
        }        // 获取蛇头位置的原值,来判断是否撞车,或者吃到食物
        eat := area[head.i][head.j]        
            if eat == 'F' { // 吃到食物
            food = false

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

            draw(tail, ' ') // 擦除蛇尾

            // 注意我们记录了它移动的方向
            dir := area[tail.i][tail.j]            
            // 我们需要擦除蛇尾的记录
            area[tail.i][tail.j] = 0

            // 移动蛇尾
            switch dir {            case 'U':
                tail.j--            case 'L':
                tail.i--            case 'R':
                tail.i++            case 'D':
                tail.j++
            }
        } else { // 撞车了
            C.gotoxy(0, 23)            break
        }
        draw(head, '*') // 绘制蛇头
    }    // 收尾了
    switch {    
          case size < 22:
                fmt.Fprintf(os.Stderr, "Faild! You've eaten %d $\\n", size-1)    
          case size < 42:
                fmt.Fprintf(os.Stderr, "Try your best! You've eaten %d $\\n", size-1)    
          default:
                fmt.Fprintf(os.Stderr, "Congratulations! You've eaten %d $\\n", size-1)
    }
}//该片段来自于http://outofmemory.cn

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档