commit e491eef5214078afe13da6a4e745659ddf7c88a0
parent def33a23cd09f8e2e2da44e8c20869fcff626289
Author: amin <dev@aminmesbah.com>
Date: Fri, 2 Dec 2016 07:48:08 +0000
Implement snake as linked list.
FossilOrigin-Name: 379593fc4149e519dada1797698b7daa3ee741acff1efe623afeedec1f0694fb
Diffstat:
M | curssses.c | | | 175 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
1 file changed, 124 insertions(+), 51 deletions(-)
diff --git a/curssses.c b/curssses.c
@@ -15,13 +15,103 @@ typedef enum
DOWN,
} direction;
-typedef struct
+typedef struct segment segment;
+struct segment
{
- char symbol;
int x;
int y;
+ segment *prev;
+ segment *next;
+};
+
+typedef struct snake snake;
+struct snake
+{
+ char symbol;
direction d;
-} snake;
+ int length;
+ segment *head;
+ segment *tail;
+};
+
+snake* snake_init()
+{
+ segment *first = malloc(sizeof(segment));
+ first->x = COLS / 2;
+ first->y = LINES / 2;
+ first->prev = 0;
+ first->next = 0;
+
+ snake *s = malloc(sizeof(snake));
+ s->symbol = 'o';
+ s->d = RIGHT;
+ s->length = 1;
+ s->head = first;
+ s->tail = first;
+
+ return s;
+}
+
+void snake_add_segment(snake *s)
+{
+ segment *new = malloc(sizeof(segment));
+ new->x = s->tail->x;
+ new->y = s->tail->y;
+ new->prev = s->tail;
+ new->next = 0;
+
+ s->tail->next = new;
+ s->tail = new;
+ s->length++;
+}
+
+void snake_move(snake *s)
+{
+ segment *current = s->tail;
+ while (current != s->head)
+ {
+ current->x = current->prev->x;
+ current->y = current->prev->y;
+ current = current->prev;
+ }
+
+ switch (s->d)
+ {
+ case LEFT:
+ {
+ --s->head->x;
+ } break;
+ case RIGHT:
+ {
+ ++s->head->x;
+ } break;
+ case UP:
+ {
+ --s->head->y;
+ } break;
+ case DOWN:
+ {
+ ++s->head->y;
+ } break;
+ }
+
+ if (s->head->y >= LINES)
+ {
+ s->head->y = 0;
+ }
+ else if (s->head->y < 0)
+ {
+ s->head->y = LINES - 1;
+ }
+ if (s->head->x >= COLS)
+ {
+ s->head->x = 0;
+ }
+ else if (s->head->x < 0)
+ {
+ s->head->x = COLS - 1;
+ }
+}
int main(void)
{
@@ -35,87 +125,70 @@ int main(void)
keypad(stdscr, TRUE);
curs_set(0);
- snake s;
- s.symbol = 'o';
- s.x = COLS / 2;
- s.y = LINES / 2;
+ snake *s = snake_init();
+ for (int i = 0; i < 4; ++i)
+ {
+ snake_add_segment(s);
+ }
int input = 0;
while (1)
{
-
input = getch();
- erase();
-
- printw("Position: (%d, %d) Total: [%d, %d]", s.x, s.y, COLS, LINES);
switch (input)
{
case KEY_LEFT:
case 'h':
{
- s.d = LEFT;
+ s->d = LEFT;
} break;
case KEY_RIGHT:
case 'l':
{
- s.d = RIGHT;
+ s->d = RIGHT;
} break;
case KEY_UP:
case 'k':
{
- s.d = UP;
+ s->d = UP;
} break;
case KEY_DOWN:
case 'j':
{
- s.d = DOWN;
- } break;
- }
-
- switch (s.d)
- {
- case LEFT:
- {
- --s.x;
- } break;
- case RIGHT:
- {
- ++s.x;
+ s->d = DOWN;
} break;
- case UP:
+ case 'p':
{
- --s.y;
- } break;
- case DOWN:
- {
- ++s.y;
- } break;
+ // pause until keypress
+ nodelay(stdscr, FALSE);
+ getch();
+ nodelay(stdscr, TRUE);
+ }
}
- if (s.y == LINES)
- {
- s.y = 0;
- }
- else if (s.y < 0)
- {
- s.y = LINES - 1;
- }
- if (s.x == COLS)
- {
- s.x = 0;
- }
- else if (s.x < 0)
+ erase();
+
+ snake_move(s);
+
+ mvprintw(
+ 0, 0,
+ "Screen: [%d, %d]\nSnake Length: %d\nHead: (%d, %d)\nTail: (%d, %d)",
+ COLS, LINES, s->length, s->head->x, s->head->y, s->tail->x, s->tail->y);
+
+ segment *current = s->head;
+ int i = 0;
+ while (current != 0)
{
- s.x = COLS - 1;
+ mvaddch(current->y, current->x, s->symbol);
+ mvprintw(i+4, 0, "Segment %d (%d, %d)", i+1, current->x, current->y);
+ current = current->next;
+ i++;
}
- mvaddch(s.y, s.x, s.symbol);
-
refresh();
usleep(SECOND / FPS);
}
-
clear();
endwin();
exit(0);