~~~
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
~~~

- Go語言基礎篇
- Go語言簡介
- Go語言教程
- Go語言環境安裝
- Go語言結構
- Go語言基礎語法
- Go語言數據類型
- Go語言變量
- Go語言提高篇
- Go語言實現貪吃蛇
- Go 諺語
- 解決連通性問題的四種算法
- golang 幾種字符串的連接方式
- Go JSON 技巧
- Go += 包版本
- Golang 編譯成 DLL 文件
- Go指南:牛頓法開方
- Go語言異步服務器框架原理和實現
- Golang適合高并發場景的原因分析
- 如何設計并實現一個線程安全的 Map ?(上篇)
- go語言執行cmd命令關機、重啟等
- IT雜項
- IT 工程師的自我管理
- IT界不為人知的14個狗血故事
- Go語言版本說明
- Go 1.10中值得關注的幾個變化
- Golang面試題解析
- Golang面試題
- Golang語言web開發
- golang 模板(template)的常用基本語法
- go語言快速入門:template模板
- Go Template學習筆記
- LollipopGo框架
- 框架簡介
- Golang語言版本設計模式
- 設計模式-單例模式
- Golang語言資源下載
- 公眾賬號
- leaf
- 合作講師
- 公開課目錄