Updated: it's looking better
This commit is contained in:
parent
168ecb7488
commit
2cbeea0de9
3 changed files with 65 additions and 56 deletions
BIN
serpent
Executable file
BIN
serpent
Executable file
Binary file not shown.
109
serpent.c
109
serpent.c
|
@ -30,10 +30,6 @@
|
||||||
#include "serpent.h"
|
#include "serpent.h"
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
/* Absolute value macro */
|
|
||||||
#define ABS(x) (x) < 0 ? -(x) : (x)
|
|
||||||
/* */
|
|
||||||
|
|
||||||
// Variable to track if snake is alive
|
// Variable to track if snake is alive
|
||||||
bool is_alive = true;
|
bool is_alive = true;
|
||||||
|
|
||||||
|
@ -88,17 +84,17 @@ int main (int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize board
|
// Initialize board
|
||||||
board_t gameBoard = {
|
board_t board = {
|
||||||
.border = BOARD_CHAR,
|
.border = BOARD_CHAR,
|
||||||
.boardHeight = SCREEN_HEIGHT,
|
.boardHeight = SCREEN_HEIGHT,
|
||||||
.boardWidth = SCREEN_WIDTH
|
.boardWidth = SCREEN_WIDTH
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize the snake doubly-linked list */
|
/* Initialize the snake doubly-linked list */
|
||||||
snake = startSnake(&gameBoard);
|
snake = startSnake(&board);
|
||||||
|
|
||||||
/* Initialize the apple */
|
/* Initialize the apple */
|
||||||
apple = startApple(&gameBoard);
|
apple = startApple(&board);
|
||||||
|
|
||||||
/* Initialize window settings with ncurses */
|
/* Initialize window settings with ncurses */
|
||||||
initscr();
|
initscr();
|
||||||
|
@ -107,6 +103,13 @@ int main (int argc, char **argv) {
|
||||||
keypad(stdscr, TRUE);
|
keypad(stdscr, TRUE);
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
nodelay(stdscr, TRUE);
|
nodelay(stdscr, TRUE);
|
||||||
|
|
||||||
|
/* Check if the board size is greater than the screen size */
|
||||||
|
if (board.boardWidth > COLS || board.boardHeight > LINES) {
|
||||||
|
endwin();
|
||||||
|
printf("ERROR: Board size is larger than the terminal window.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
while (is_alive) {
|
while (is_alive) {
|
||||||
/* Take arrow key inputs */
|
/* Take arrow key inputs */
|
||||||
|
@ -116,10 +119,10 @@ int main (int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the snake position */
|
/* Update the snake position */
|
||||||
moveSnake(&gameBoard);
|
moveSnake(&board);
|
||||||
|
|
||||||
/* Redraw the frame */
|
/* Redraw the frame */
|
||||||
draw(&gameBoard);
|
draw(&board);
|
||||||
|
|
||||||
/* Refresh the window */
|
/* Refresh the window */
|
||||||
refresh();
|
refresh();
|
||||||
|
@ -163,8 +166,8 @@ snake_t *startSnake(board_t *board) {
|
||||||
|
|
||||||
head->prev = NULL;
|
head->prev = NULL;
|
||||||
head->next = NULL;
|
head->next = NULL;
|
||||||
head->pX = board->boardWidth / 2 + 1;
|
head->pX = board->boardWidth / 2;
|
||||||
head->pY = board->boardHeight / 2 + 1;
|
head->pY = board->boardHeight / 2;
|
||||||
|
|
||||||
snake_node *node = head;
|
snake_node *node = head;
|
||||||
for (int i = 1; i < START_SNAKE_SIZE; i++) {
|
for (int i = 1; i < START_SNAKE_SIZE; i++) {
|
||||||
|
@ -205,11 +208,9 @@ bool snakeOccupies(int x, int y, bool excludeHead) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (snake_ptr != NULL) {
|
while (snake_ptr != NULL) {
|
||||||
|
|
||||||
if (snake_ptr->pX == x && snake_ptr->pY == y) {
|
if (snake_ptr->pX == x && snake_ptr->pY == y) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
snake_ptr = snake_ptr->next;
|
snake_ptr = snake_ptr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,28 +231,24 @@ int snakeSize() {
|
||||||
|
|
||||||
apple_t *startApple(board_t *board) {
|
apple_t *startApple(board_t *board) {
|
||||||
apple_t *new_apple = malloc(sizeof(apple_t));
|
apple_t *new_apple = malloc(sizeof(apple_t));
|
||||||
srandom(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
new_apple->pX = random() % board->boardWidth + 1;
|
new_apple->pX = (random() % (board->boardWidth - 2)) + 1;
|
||||||
} while (new_apple->pX == board->boardHeight / 2 + 1);
|
new_apple->pY = (random() % (board->boardHeight - 2)) + 1;
|
||||||
|
} while (snakeOccupies(new_apple->pX, new_apple->pY, false));
|
||||||
new_apple->pY = random() % board->boardHeight + 1;
|
|
||||||
|
|
||||||
return new_apple;
|
return new_apple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void moveApple(board_t *board) {
|
void moveApple(board_t *board) {
|
||||||
int new_x;
|
int new_x, new_y;
|
||||||
int new_y;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
new_x = random() % board->boardWidth + 1;
|
new_x = (random() % (board->boardWidth - 2)) + 1;
|
||||||
new_y = random() % board->boardHeight + 1;
|
new_y = (random() % (board->boardHeight - 2)) + 1;
|
||||||
|
|
||||||
} while (snakeOccupies(new_x, new_y, true));
|
} while (snakeOccupies(new_x, new_y, true));
|
||||||
|
|
||||||
apple->pX = new_x;
|
apple->pX = new_x;
|
||||||
apple->pY = new_y;
|
apple->pY = new_y;
|
||||||
}
|
}
|
||||||
|
@ -295,12 +292,17 @@ void handleInput(int key) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveSnake (board_t *board) {
|
void moveSnake(board_t *board) {
|
||||||
if ((ABS(snake->dX) > 0) || (ABS(snake->dY) > 0)) {
|
if ((ABS(snake->dX) > 0) || (ABS(snake->dY) > 0)) {
|
||||||
if (!appleOccupies(snake->head->pX + snake->dX, snake->head->pY + snake->dY)) {
|
int new_head_x = snake->head->pX + snake->dX;
|
||||||
snake->tail->pX = snake->head->pX + snake->dX;
|
int new_head_y = snake->head->pY + snake->dY;
|
||||||
snake->tail->pY = snake->head->pY + snake->dY;
|
|
||||||
|
|
||||||
|
if (!appleOccupies(new_head_x, new_head_y)) {
|
||||||
|
// Move the tail to the new position
|
||||||
|
snake->tail->pX = new_head_x;
|
||||||
|
snake->tail->pY = new_head_y;
|
||||||
|
|
||||||
|
// Update the links in the snake
|
||||||
snake->tail->next = snake->head;
|
snake->tail->next = snake->head;
|
||||||
snake->head->prev = snake->tail;
|
snake->head->prev = snake->tail;
|
||||||
|
|
||||||
|
@ -311,40 +313,44 @@ void moveSnake (board_t *board) {
|
||||||
snake->head = snake->head->prev;
|
snake->head = snake->head->prev;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// The snake eats the apple
|
||||||
moveApple(board);
|
moveApple(board);
|
||||||
|
|
||||||
|
// Create a new head node
|
||||||
snake_node *new_head = malloc(sizeof(snake_node));
|
snake_node *new_head = malloc(sizeof(snake_node));
|
||||||
new_head->pX = snake->head->pX + snake->dX;
|
new_head->pX = new_head_x;
|
||||||
new_head->pY = snake->head->pY + snake->dY;
|
new_head->pY = new_head_y;
|
||||||
new_head->prev = NULL;
|
new_head->prev = NULL;
|
||||||
new_head->next = snake->head;
|
new_head->next = snake->head;
|
||||||
|
|
||||||
|
// Update the links in the snake
|
||||||
snake->head->prev = new_head;
|
snake->head->prev = new_head;
|
||||||
snake->head = new_head;
|
snake->head = new_head;
|
||||||
|
|
||||||
|
// Append a new node to the snake
|
||||||
appendSnakeNode(snake);
|
appendSnakeNode(snake);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snakeOccupies(snake->head->pX, snake->head->pY, false)) {
|
// Check for collisions and update the snake
|
||||||
is_alive = false;
|
if (snakeOccupies(new_head_x, new_head_y, false) ||
|
||||||
}
|
(new_head_x == 0) || (new_head_x == board->boardWidth - 1) ||
|
||||||
|
(new_head_y == 0) || (new_head_y == board->boardHeight - 1)) {
|
||||||
if ((snake->head->pX == 0) || (snake->head->pX == board->boardWidth + 1)) {
|
|
||||||
is_alive = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((snake->head->pY == 0) || (snake->head->pY == board->boardHeight + 1)) {
|
|
||||||
is_alive = false;
|
is_alive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(board_t *board) {
|
void draw(board_t *board) {
|
||||||
mvprintw(0, 0, "%c", board->border);
|
erase();
|
||||||
|
int i, j;
|
||||||
|
|
||||||
for (int i = 0; i < board->boardHeight; i++) {
|
for (i = 0; i < board->boardHeight; i++) {
|
||||||
mvaddch(i + 1, 0, board->border);
|
for (j = 0; j < board->boardWidth; j++) {
|
||||||
mvaddch(i + 1, board->boardWidth + 1, board->border);
|
if (i == 0 || i == board->boardHeight - 1) {
|
||||||
|
mvprintw(i, j, "%c", board->border);
|
||||||
for (int j = 0; j < board->boardWidth; j++) {
|
} else if (j == 0 || j == board->boardWidth - 1) {
|
||||||
mvaddch(i + 1, j + 1, ' ');
|
mvprintw(i, j, "%c", board->border);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +374,6 @@ void draw(board_t *board) {
|
||||||
|
|
||||||
mvaddch(apple->pY, apple->pX, FOOD);
|
mvaddch(apple->pY, apple->pX, FOOD);
|
||||||
|
|
||||||
mvprintw(board->boardHeight + 1, 0, "%c", board->border);
|
|
||||||
mvprintw(board->boardHeight + 3, 0, "Score: %d", snakeSize() - START_SNAKE_SIZE);
|
mvprintw(board->boardHeight + 3, 0, "Score: %d", snakeSize() - START_SNAKE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
serpent.h
12
serpent.h
|
@ -6,17 +6,21 @@
|
||||||
#define VERSION 0.1
|
#define VERSION 0.1
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
/* Absolute value macro */
|
||||||
|
#define ABS(x) (x) < 0 ? -(x) : (x)
|
||||||
|
/* */
|
||||||
|
|
||||||
/* global variables/constants */
|
/* global variables/constants */
|
||||||
#define START_SNAKE_SIZE 5 /* snake's initial size */
|
#define START_SNAKE_SIZE 2 /* snake's initial size */
|
||||||
#define SNAKE_BODY '*' /* snake's body */
|
#define SNAKE_BODY '*' /* snake's body */
|
||||||
#define SNAKE_HEAD_U 'v' /* head when going up */
|
#define SNAKE_HEAD_U 'v' /* head when going up */
|
||||||
#define SNAKE_HEAD_D '^' /* head when going down */
|
#define SNAKE_HEAD_D '^' /* head when going down */
|
||||||
#define SNAKE_HEAD_L '>' /* head when going left */
|
#define SNAKE_HEAD_L '>' /* head when going left */
|
||||||
#define SNAKE_HEAD_R '<' /* head when going right */
|
#define SNAKE_HEAD_R '<' /* head when going right */
|
||||||
#define FOOD '@' /* normal food */
|
#define FOOD '@' /* normal food */
|
||||||
#define BOARD_CHAR '+' /* character at corners of border */
|
#define BOARD_CHAR '#' /* character at corners of border */
|
||||||
#define SCREEN_WIDTH 30 /* the virtual screen width */
|
#define SCREEN_WIDTH 40 /* the virtual screen width */
|
||||||
#define SCREEN_HEIGHT 20 /* the virtual screen height */
|
#define SCREEN_HEIGHT 30 /* the virtual screen height */
|
||||||
#define SPEED 100 /* speed of the game */
|
#define SPEED 100 /* speed of the game */
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue