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.
99
serpent.c
99
serpent.c
|
@ -30,10 +30,6 @@
|
|||
#include "serpent.h"
|
||||
/* */
|
||||
|
||||
/* Absolute value macro */
|
||||
#define ABS(x) (x) < 0 ? -(x) : (x)
|
||||
/* */
|
||||
|
||||
// Variable to track if snake is alive
|
||||
bool is_alive = true;
|
||||
|
||||
|
@ -88,17 +84,17 @@ int main (int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Initialize board
|
||||
board_t gameBoard = {
|
||||
board_t board = {
|
||||
.border = BOARD_CHAR,
|
||||
.boardHeight = SCREEN_HEIGHT,
|
||||
.boardWidth = SCREEN_WIDTH
|
||||
};
|
||||
|
||||
/* Initialize the snake doubly-linked list */
|
||||
snake = startSnake(&gameBoard);
|
||||
snake = startSnake(&board);
|
||||
|
||||
/* Initialize the apple */
|
||||
apple = startApple(&gameBoard);
|
||||
apple = startApple(&board);
|
||||
|
||||
/* Initialize window settings with ncurses */
|
||||
initscr();
|
||||
|
@ -108,6 +104,13 @@ int main (int argc, char **argv) {
|
|||
curs_set(0);
|
||||
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) {
|
||||
/* Take arrow key inputs */
|
||||
int c = getch();
|
||||
|
@ -116,10 +119,10 @@ int main (int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* Update the snake position */
|
||||
moveSnake(&gameBoard);
|
||||
moveSnake(&board);
|
||||
|
||||
/* Redraw the frame */
|
||||
draw(&gameBoard);
|
||||
draw(&board);
|
||||
|
||||
/* Refresh the window */
|
||||
refresh();
|
||||
|
@ -163,8 +166,8 @@ snake_t *startSnake(board_t *board) {
|
|||
|
||||
head->prev = NULL;
|
||||
head->next = NULL;
|
||||
head->pX = board->boardWidth / 2 + 1;
|
||||
head->pY = board->boardHeight / 2 + 1;
|
||||
head->pX = board->boardWidth / 2;
|
||||
head->pY = board->boardHeight / 2;
|
||||
|
||||
snake_node *node = head;
|
||||
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) {
|
||||
|
||||
if (snake_ptr->pX == x && snake_ptr->pY == y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
snake_ptr = snake_ptr->next;
|
||||
}
|
||||
|
||||
|
@ -230,26 +231,22 @@ int snakeSize() {
|
|||
|
||||
apple_t *startApple(board_t *board) {
|
||||
apple_t *new_apple = malloc(sizeof(apple_t));
|
||||
srandom(time(NULL));
|
||||
srand(time(NULL));
|
||||
|
||||
do {
|
||||
new_apple->pX = random() % board->boardWidth + 1;
|
||||
} while (new_apple->pX == board->boardHeight / 2 + 1);
|
||||
|
||||
new_apple->pY = random() % board->boardHeight + 1;
|
||||
new_apple->pX = (random() % (board->boardWidth - 2)) + 1;
|
||||
new_apple->pY = (random() % (board->boardHeight - 2)) + 1;
|
||||
} while (snakeOccupies(new_apple->pX, new_apple->pY, false));
|
||||
|
||||
return new_apple;
|
||||
}
|
||||
|
||||
|
||||
void moveApple(board_t *board) {
|
||||
int new_x;
|
||||
int new_y;
|
||||
int new_x, new_y;
|
||||
|
||||
do {
|
||||
new_x = random() % board->boardWidth + 1;
|
||||
new_y = random() % board->boardHeight + 1;
|
||||
|
||||
new_x = (random() % (board->boardWidth - 2)) + 1;
|
||||
new_y = (random() % (board->boardHeight - 2)) + 1;
|
||||
} while (snakeOccupies(new_x, new_y, true));
|
||||
|
||||
apple->pX = new_x;
|
||||
|
@ -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 (!appleOccupies(snake->head->pX + snake->dX, snake->head->pY + snake->dY)) {
|
||||
snake->tail->pX = snake->head->pX + snake->dX;
|
||||
snake->tail->pY = snake->head->pY + snake->dY;
|
||||
int new_head_x = snake->head->pX + snake->dX;
|
||||
int new_head_y = 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->head->prev = snake->tail;
|
||||
|
||||
|
@ -311,40 +313,44 @@ void moveSnake (board_t *board) {
|
|||
snake->head = snake->head->prev;
|
||||
|
||||
} else {
|
||||
// The snake eats the apple
|
||||
moveApple(board);
|
||||
|
||||
// Create a new head node
|
||||
snake_node *new_head = malloc(sizeof(snake_node));
|
||||
new_head->pX = snake->head->pX + snake->dX;
|
||||
new_head->pY = snake->head->pY + snake->dY;
|
||||
new_head->pX = new_head_x;
|
||||
new_head->pY = new_head_y;
|
||||
new_head->prev = NULL;
|
||||
new_head->next = snake->head;
|
||||
|
||||
// Update the links in the snake
|
||||
snake->head->prev = new_head;
|
||||
snake->head = new_head;
|
||||
|
||||
// Append a new node to the snake
|
||||
appendSnakeNode(snake);
|
||||
}
|
||||
|
||||
if (snakeOccupies(snake->head->pX, snake->head->pY, false)) {
|
||||
is_alive = false;
|
||||
}
|
||||
|
||||
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)) {
|
||||
// Check for collisions and update the snake
|
||||
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)) {
|
||||
is_alive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(board_t *board) {
|
||||
mvprintw(0, 0, "%c", board->border);
|
||||
erase();
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; i < board->boardHeight; i++) {
|
||||
mvaddch(i + 1, 0, board->border);
|
||||
mvaddch(i + 1, board->boardWidth + 1, board->border);
|
||||
|
||||
for (int j = 0; j < board->boardWidth; j++) {
|
||||
mvaddch(i + 1, j + 1, ' ');
|
||||
for (i = 0; i < board->boardHeight; i++) {
|
||||
for (j = 0; j < board->boardWidth; j++) {
|
||||
if (i == 0 || i == board->boardHeight - 1) {
|
||||
mvprintw(i, j, "%c", board->border);
|
||||
} else if (j == 0 || j == board->boardWidth - 1) {
|
||||
mvprintw(i, j, "%c", board->border);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,7 +374,6 @@ void draw(board_t *board) {
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
12
serpent.h
12
serpent.h
|
@ -6,17 +6,21 @@
|
|||
#define VERSION 0.1
|
||||
/* */
|
||||
|
||||
/* Absolute value macro */
|
||||
#define ABS(x) (x) < 0 ? -(x) : (x)
|
||||
/* */
|
||||
|
||||
/* 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_HEAD_U 'v' /* head when going up */
|
||||
#define SNAKE_HEAD_D '^' /* head when going down */
|
||||
#define SNAKE_HEAD_L '>' /* head when going left */
|
||||
#define SNAKE_HEAD_R '<' /* head when going right */
|
||||
#define FOOD '@' /* normal food */
|
||||
#define BOARD_CHAR '+' /* character at corners of border */
|
||||
#define SCREEN_WIDTH 30 /* the virtual screen width */
|
||||
#define SCREEN_HEIGHT 20 /* the virtual screen height */
|
||||
#define BOARD_CHAR '#' /* character at corners of border */
|
||||
#define SCREEN_WIDTH 40 /* the virtual screen width */
|
||||
#define SCREEN_HEIGHT 30 /* the virtual screen height */
|
||||
#define SPEED 100 /* speed of the game */
|
||||
/* */
|
||||
|
||||
|
|
Loading…
Reference in a new issue