-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsnake.go
135 lines (112 loc) · 2.74 KB
/
snake.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
//"github.com/davecgh/go-spew/spew"
"math"
)
const (
SNAKE_DIRECTION_UP Direction = iota
SNAKE_DIRECTION_RIGHT
SNAKE_DIRECTION_DOWN
SNAKE_DIRECTION_LEFT
)
type Direction byte
func (direction Direction) angle() int {
return int(direction) * 90
}
type Snake struct {
direction Direction
body Body
}
type Body []Node
type Node struct {
x int
y int
}
func (body Body) Contains(node Node) bool {
for _, n := range body {
if node == n {
return true
}
}
return false
}
func (snake *Snake) Move(screenSize ScreenSize, fruit Node) CharacterStatus {
newHead := snake.newHead(screenSize)
if snake.body.Contains(newHead) {
return CHARACTER_STATUS_DEAD
} else if newHead == fruit {
snake.growInScreenSize(screenSize)
return CHARACTER_STATUS_GROW
} else {
snake.moveInScreenSize(screenSize)
return CHARACTER_STATUS_MOVE
}
}
func (snake *Snake) moveInScreenSize(screenSize ScreenSize) {
snake.body = snake.body[1:]
head := snake.newHead(screenSize)
snake.body = append(snake.body, head)
}
func (snake *Snake) growInScreenSize(screenSize ScreenSize) {
head := snake.newHead(screenSize)
snake.body = append(snake.body, head)
}
func (snake *Snake) newHead(screenSize ScreenSize) Node {
head := snake.head()
var newHead Node
switch snake.direction {
case SNAKE_DIRECTION_RIGHT:
newHead = Node{x: head.x + 1, y: head.y}
case SNAKE_DIRECTION_DOWN:
newHead = Node{x: head.x, y: head.y + 1}
case SNAKE_DIRECTION_LEFT:
newHead = Node{x: head.x - 1, y: head.y}
case SNAKE_DIRECTION_UP:
newHead = Node{x: head.x, y: head.y - 1}
}
if screenSize.width > 0 {
if newHead.x < 0 { // over left edge
newHead.x = screenSize.width - 1
} else if newHead.x >= screenSize.width { // over right edge
newHead.x = screenSize.width - newHead.x
}
}
if screenSize.height > 0 {
if newHead.y < 0 { // over top edge
newHead.y = screenSize.height - 1
} else if newHead.y >= screenSize.height { // over bottom edge
newHead.y = screenSize.height - newHead.y
}
}
return newHead
}
func (snake *Snake) Len() int {
return len(snake.body)
}
func (snake *Snake) head() Node {
return snake.body[snake.Len()-1]
}
func (snake *Snake) Turn(direction Direction) {
// You can't turn to opposite direction
angle := float64(direction.angle() - snake.direction.angle())
if math.Abs(angle) == 180.0 {
return
}
snake.direction = direction
}
func (snake *Snake) Draw() {
for _, node := range snake.body {
DrawPoint(node.x, node.y, COLOR_CHARACTER)
}
}
func (snake *Snake) Body() Body {
return snake.body
}
// TODO: init with position, direction & length
func NewSnake() *Snake {
snake := Snake{}
// give default
snake.direction = SNAKE_DIRECTION_RIGHT
snake.body = Body{Node{x: 0, y: 0}, Node{x: 1, y: 0}}
return &snake
}