-
Notifications
You must be signed in to change notification settings - Fork 0
/
snake.c
120 lines (114 loc) · 2.52 KB
/
snake.c
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
#include "snake.h"
#include "settings.h"
#include "fatal.h"
#include <ncurses.h>
#include <stdlib.h>
extern Interface interface;
Snake CreateSnake(int length, char symbol)
{
Snake s;
if (((s = (Snake)malloc(sizeof(struct _snake))) == NULL)) // 空间的大小要正确啊!不然在后面的操作就有可能segmentation fault了
FatalError("Out of space!");
s->length = length, s->symbol = symbol;
if ((s->list = (List *)calloc(2, sizeof(Node *))) == NULL)
FatalError("Out of space!");
InitSnake(s);
return s;
}
void InitSnake(Snake s)
{
int i;
for (i = 0; i < s->length; i++)
InsertHead(s->list, INITIAL_Y, INITIAL_X + i); // 不能用Add()!!!
s->speed = DEFAULT_SPEED;
s->y_dir = INITIAL_DIRECTION_Y;
s->x_dir = INITIAL_DIRECTION_X;
}
void PrintSnake(Snake s)
{
Node *p = s->list->head;
while (p)
{
mvaddch(p->y, p->x, s->symbol);
p = p->next;
}
}
/* 只操作链表的头和尾实现蛇的移动 */
void MoveSnake(Snake s)
{
// move head
InsertHead(s->list, s->list->head->y + s->y_dir, s->list->head->x + s->x_dir);
mvaddch(s->list->head->y, s->list->head->x, s->symbol);
// move tail
mvaddch(s->list->tail->y, s->list->tail->x, BLANK);
DeleteTail(s->list);
// put cursor back
move(interface.lower_boundary, 0);
}
bool HitBoundary(Snake s)
{
if (s->list->head->y != 0 && s->list->head->y != interface.lower_boundary - 1 && s->list->head->x != 0 && s->list->head->x != interface.right_boundary - 1)
return false;
return true;
}
bool HitBody(Snake s)
{
Node *p = s->list->head;
while (p = p->next)
{
if (s->list->head->x == p->x && s->list->head->y == p->y)
return true;
}
return false;
}
bool OnSnake(Snake s, int y, int x)
{
Node *p;
for (p = s->list->head; p; p = p->next)
if (p->y == y && p->x == x)
return true;
return false;
}
void TurnUp(Snake s)
{
s->y_dir = -1;
s->x_dir = 0;
}
void TurnDown(Snake s)
{
s->y_dir = 1;
s->x_dir = 0;
}
void TurnLeft(Snake s)
{
s->y_dir = 0;
s->x_dir = -1;
}
void TurnRight(Snake s)
{
s->y_dir = 0;
s->x_dir = 1;
}
void EraseSnake(Snake s)
{
Node *p = s->list->head;
while (p)
{
mvaddch(p->y, p->x, BLANK);
p = p->next;
}
}
void DisposeSnake(Snake s)
{
Node *p = s->list->head, *tmp;
// delete the snake
while (p)
{
tmp = p->next;
free(p);
p = tmp;
}
// delete the list
free(s->list);
free(s);
}