diff options
Diffstat (limited to 'src/body.c')
-rw-r--r-- | src/body.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/src/body.c b/src/body.c new file mode 100644 index 0000000..bfee083 --- /dev/null +++ b/src/body.c @@ -0,0 +1,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; +} |