-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.go
104 lines (86 loc) · 1.61 KB
/
game.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package snake
import (
"time"
"github.com/nsf/termbox-go"
)
var (
pointsChan = make(chan int)
keyboardEventsChan = make(chan keyboardEvent)
)
// Game type
type Game struct {
arena *arena
score int
isOver bool
}
func initialSnake() *snake {
return newSnake(RIGHT, []coord{
coord{x: 1, y: 1},
coord{x: 1, y: 2},
coord{x: 1, y: 3},
coord{x: 1, y: 4},
})
}
func initialScore() int {
return 0
}
func initialArena() *arena {
return newArena(initialSnake(), pointsChan, 20, 50)
}
func (g *Game) end() {
g.isOver = true
}
func (g *Game) moveInterval() time.Duration {
ms := 100 - (g.score / 10)
return time.Duration(ms) * time.Millisecond
}
func (g *Game) retry() {
g.arena = initialArena()
g.score = initialScore()
g.isOver = false
}
func (g *Game) addPoints(p int) {
g.score += p
}
// NewGame creates new Game object
func NewGame() *Game {
return &Game{arena: initialArena(), score: initialScore()}
}
// Start starts the game
func (g *Game) Start() {
if err := termbox.Init(); err != nil {
panic(err)
}
defer termbox.Close()
go listenToKeyboard(keyboardEventsChan)
if err := g.render(); err != nil {
panic(err)
}
mainloop:
for {
select {
case p := <-pointsChan:
g.addPoints(p)
case e := <-keyboardEventsChan:
switch e.eventType {
case MOVE:
d := keyToDirection(e.key)
g.arena.snake.changeDirection(d)
case RETRY:
g.retry()
case END:
break mainloop
}
default:
if !g.isOver {
if err := g.arena.moveSnake(); err != nil {
g.end()
}
}
if err := g.render(); err != nil {
panic(err)
}
time.Sleep(g.moveInterval())
}
}
}