summaryrefslogtreecommitdiff
path: root/body.c
blob: ad0641129d1aabefdfb9add52c15c9ae49e91947 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>

#include "include/body.h"

typedef struct node{
	int x;
	int y;
	struct node *next;
} NODE;

typedef struct snake{
	NODE *head; //"head" will be the physical tail of the snake
	NODE *tail; //"tail" will be the physical head of the snake
	int length;
} SNAKE;

//private prototypes
NODE *makeNode(int x, int y);
void deleteNode(NODE *np);
void increaseSnake(SNAKE *sp);

//public functions
SNAKE *makeSnake(int startx, int starty, int len){
	SNAKE *new = malloc(sizeof(SNAKE));
	NODE *np;

	assert(new != NULL);

	new->length = len;

	new->head = makeNode(startx-len+1, starty);
	np = new->head;
	len--;

	while(len > 0){
		np->next = makeNode(startx-len+1, starty);
		np = np->next;
		len--;
	}

	new->tail = np;

	return new;
}

void deleteSnake(SNAKE *sp){
	NODE *hold;

	if(sp != NULL){
		while(sp->head != NULL){
			hold = sp->head;
			sp->head = sp->head->next;
			deleteNode(hold);
		}
	}

	free(sp);
	return;
}

void updateSnake(SNAKE *sp, int dir, int maxx, int maxy, bool *collision, int *fruit_loc, bool *fruit, int *score){
	NODE *np;

	if(sp == NULL) return;

	//move the "back" to the "front" (note that sp->tail will not be set until after np->x and np->y are set)
	np = sp->head;
	sp->head = sp->head->next;
	sp->tail->next = np;
	np->next = NULL;

	//dir decides direction the snake is moving
	switch(dir){
		case(0): //snake is moving up
			np->x = sp->tail->x;
			np->y = sp->tail->y-1;
			break;

		case(1): //snake is moving right
			np->x = sp->tail->x+1;
			np->y = sp->tail->y;
			break;

		case(2): //snake is moving down
			np->x = sp->tail->x;
			np->y = sp->tail->y+1;
			break;

		case(3): //snake is moving left
			np->x = sp->tail->x-1;
			np->y = sp->tail->y;
	}

	//update tail pointer
	sp->tail = np;

	//check if eating fruit
	if(*fruit && sp->tail->x == *fruit_loc && sp->tail->y == *(fruit_loc + 1)){
		*fruit = false;
		(*score)++;

		//need to increase snake size
		increaseSnake(sp);
	}

	//check collision
	*collision = checkSnake(sp, maxx, maxy);

	return;
}

//true = collision, false = no collision
bool checkSnake(SNAKE *sp, int maxx, int maxy){
	NODE *np;

	if(sp == NULL) return true;

	//check if oob
	if(sp->tail->x < 0 || sp->tail->x >= maxx || sp->tail->y < 0 || sp->tail->y >= maxy) return true;

	//check if collision with body (check each cell)
	np = sp->head;
	while(np != sp->tail && np != NULL){
		if(sp->tail->x == np->x && sp->tail->y == np->y) return true;
		np = np->next;
	}

	return false;
}

int getSnakeTailx(SNAKE *sp){

	if(sp != NULL && sp->tail != NULL) return sp->tail->x;
	return -1;

}
int getSnakeTaily(SNAKE *sp){

	if(sp != NULL && sp->tail != NULL) return sp->tail->y;
	return -1;

}

int getSnakeHeadx(SNAKE *sp){

	if(sp != NULL && sp->head != NULL) return sp->head->x;
	return -1;

}

int getSnakeHeady(SNAKE *sp){

	if(sp != NULL && sp->head != NULL) return sp->head->y;
	return -1;

}
			
//private functions
NODE *makeNode(int x, int y){
	NODE *new = malloc(sizeof(NODE));
	assert(new != NULL);

	new->x = x;
	new->y = y;
	new->next = NULL;

	return new;
}

void deleteNode(NODE *np){

	if(np != NULL) free(np);

	return;
}

void increaseSnake(SNAKE *sp){
	int xdiff = sp->head->next->x - sp->head->x;
	int ydiff = sp->head->next->y - sp->head->y;
	NODE *new = makeNode(sp->head->x - xdiff, sp->head->y - ydiff);

	new->next = sp->head;
	sp->head = new;
	sp->length++;

	return;
}