Updated: it's looking better

This commit is contained in:
Lian Drake 2023-12-07 12:08:32 -04:00
parent 168ecb7488
commit 2cbeea0de9
3 changed files with 65 additions and 56 deletions

BIN
serpent Executable file

Binary file not shown.

View file

@ -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();
@ -108,6 +104,13 @@ int main (int argc, char **argv) {
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 */
int c = getch(); int c = getch();
@ -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,26 +231,22 @@ 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;
@ -297,10 +294,15 @@ 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);
} }

View file

@ -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 */
/* */ /* */