Compare commits
5 Commits
883aa91224
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| da36cbe79c | |||
| 874d0e0f18 | |||
| b7a043d261 | |||
| 78757a973f | |||
| f93ea56076 |
32
README.md
32
README.md
@@ -1,16 +1,36 @@
|
|||||||
# Sanke
|
# Sanke
|
||||||
A simple snake game in the terminal. No third party libraries needed.
|
A simple snake game in the terminal. No third party libraries needed.
|
||||||
|
|
||||||
## Demo
|
# Compiling
|
||||||
Click image for video
|
Run:
|
||||||
|
```sh
|
||||||
|
compile.sh release
|
||||||
|
```
|
||||||
|
to compile an optimized build. The script creates a directory called 'target' that contains the executable.
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=_coOVAW9qa4)
|
See:
|
||||||
|
```sh
|
||||||
|
compile.sh help
|
||||||
|
```
|
||||||
|
for more.
|
||||||
|
|
||||||
## How it works
|
# Running
|
||||||
|
Run:
|
||||||
|
```sh
|
||||||
|
sanke
|
||||||
|
```
|
||||||
|
to play with defaults settings.
|
||||||
|
|
||||||
|
See:
|
||||||
|
```sh
|
||||||
|
sanke --help
|
||||||
|
```
|
||||||
|
for setting game options.
|
||||||
|
|
||||||
|
# How it works
|
||||||
The program makes the terminal use non-canonical input and output by using termios. Then it updates and prints a 2D character array containing the board borders, snake, and food. Before terminating, the program restores canonical mode.
|
The program makes the terminal use non-canonical input and output by using termios. Then it updates and prints a 2D character array containing the board borders, snake, and food. Before terminating, the program restores canonical mode.
|
||||||
|
|
||||||
## Info
|
# Info
|
||||||
Only tested with the combination of
|
Only tested with the combination of
|
||||||
- GCC
|
- GCC
|
||||||
- Linux
|
- Linux
|
||||||
- x86 CPU
|
|
||||||
|
|||||||
13
compile.sh
13
compile.sh
@@ -6,6 +6,18 @@ if [ -v 1 ]; then
|
|||||||
arg=$1
|
arg=$1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $arg = "help" ]; then
|
||||||
|
echo "USAGE: compile.sh <option>"
|
||||||
|
echo ""
|
||||||
|
echo "Compiles debug build when called without an option."
|
||||||
|
echo "Options:"
|
||||||
|
echo " help : Show this help text."
|
||||||
|
echo " clean : Clean target directory."
|
||||||
|
echo " release: Build with optimizations."
|
||||||
|
echo " run : Build debug build and run."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $arg = "clean" ]; then
|
if [ $arg = "clean" ]; then
|
||||||
rm -rf ./target/*
|
rm -rf ./target/*
|
||||||
exit
|
exit
|
||||||
@@ -37,6 +49,5 @@ if [ $? -gt 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $arg = "run" ]; then
|
if [ $arg = "run" ]; then
|
||||||
echo
|
|
||||||
./target/sanke
|
./target/sanke
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "Board.h"
|
#include "Board.h"
|
||||||
#include "Snake.h"
|
#include "Snake.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#define MAT_INDEX(mat, w, i, j) (mat)[(j) + (w) * (i)]
|
#define MAT_INDEX(mat, w, i, j) (mat)[(j) + (w) * (i)]
|
||||||
|
|
||||||
@@ -16,6 +17,9 @@ Board board_alloc(const int width, const int height) {
|
|||||||
board.width_with_borders = board.width + 2;
|
board.width_with_borders = board.width + 2;
|
||||||
board.height_with_borders = board.height + 2;
|
board.height_with_borders = board.height + 2;
|
||||||
board.squares = (char*) malloc(sizeof(char) * board.width_with_borders * board.height_with_borders);
|
board.squares = (char*) malloc(sizeof(char) * board.width_with_borders * board.height_with_borders);
|
||||||
|
if (board.squares == NULL) {
|
||||||
|
mallocError("board.squares", __FILE__, "board_alloc");
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 1; i < board.height_with_borders; i++) {
|
for (size_t i = 1; i < board.height_with_borders; i++) {
|
||||||
for (size_t j = 1; j < board.width_with_borders; j++) {
|
for (size_t j = 1; j < board.width_with_borders; j++) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "Snake.h"
|
#include "Snake.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
extern const char snake_vis;
|
extern const char snake_vis;
|
||||||
|
|
||||||
@@ -31,6 +32,9 @@ Snake snake_alloc(
|
|||||||
snake.length = 1;
|
snake.length = 1;
|
||||||
snake.dir = init_dir;
|
snake.dir = init_dir;
|
||||||
snake.parts = (BoardPiece*) malloc(sizeof(BoardPiece) * snake.max_length);
|
snake.parts = (BoardPiece*) malloc(sizeof(BoardPiece) * snake.max_length);
|
||||||
|
if (snake.parts == NULL) {
|
||||||
|
mallocError("snake.parts", __FILE__, "snake_alloc");
|
||||||
|
}
|
||||||
snake.parts[0] = (BoardPiece) { .x = init_x, .y = init_y, .vis_char = '&' };
|
snake.parts[0] = (BoardPiece) { .x = init_x, .y = init_y, .vis_char = '&' };
|
||||||
|
|
||||||
return snake;
|
return snake;
|
||||||
|
|||||||
38
src/args.c
38
src/args.c
@@ -4,13 +4,31 @@
|
|||||||
|
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
static void handle_version() {
|
static void check_bounds(const char* arg_name, const int i, const int argc) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
printf("%s needs an argument. See: sanke --help\n", arg_name);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_version() {
|
||||||
printf("Sanke version %s\n", VERSION);
|
printf("Sanke version %s\n", VERSION);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_help() {
|
||||||
|
printf(
|
||||||
|
"USAGE: sanke <options>\n\n"
|
||||||
|
"Options:\n"
|
||||||
|
" --width, -w: Set the width (10 - 50) of the board. Default 15.\n"
|
||||||
|
" --height, -h: Set the height (10 - 50) of the board. Default 15.\n"
|
||||||
|
" --speed, -s: Set the speed (1 - 1000) of the game in squares per second. Default 7.\n"
|
||||||
|
" --help : Display this help text.\n"
|
||||||
|
);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
static void set_width(Arguments* args, char* width_str) {
|
static void set_width(Arguments* args, char* width_str) {
|
||||||
printf("width_str: %s\n", width_str);
|
|
||||||
int width = atoi(width_str);
|
int width = atoi(width_str);
|
||||||
if (width < 10) {
|
if (width < 10) {
|
||||||
printf("Width must be between 10 and 50. Was %d.\n", width);
|
printf("Width must be between 10 and 50. Was %d.\n", width);
|
||||||
@@ -23,7 +41,7 @@ static void set_width(Arguments* args, char* width_str) {
|
|||||||
static void set_height(Arguments* args, char* height_str) {
|
static void set_height(Arguments* args, char* height_str) {
|
||||||
int height = atoi(height_str);
|
int height = atoi(height_str);
|
||||||
if (height < 10) {
|
if (height < 10) {
|
||||||
printf("Width must be between 10 and 50. Was %d.\n", height);
|
printf("Width must be between 10 and 50. Was %s.\n", height_str);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +62,7 @@ Arguments cmd_args(int argc, char** argv) {
|
|||||||
Arguments args = {
|
Arguments args = {
|
||||||
.width = 15,
|
.width = 15,
|
||||||
.height = 15,
|
.height = 15,
|
||||||
.sleep_ms = 150
|
.sleep_ms = 150,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
@@ -53,13 +71,20 @@ Arguments cmd_args(int argc, char** argv) {
|
|||||||
|| strcmp(argv[i], "-v") == 0
|
|| strcmp(argv[i], "-v") == 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
handle_version();
|
show_version();
|
||||||
|
|
||||||
|
} else if (
|
||||||
|
strcmp(argv[i], "--help") == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
show_help();
|
||||||
|
|
||||||
} else if (
|
} else if (
|
||||||
strcmp(argv[i], "--width") == 0
|
strcmp(argv[i], "--width") == 0
|
||||||
|| strcmp(argv[i], "-w") == 0
|
|| strcmp(argv[i], "-w") == 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
check_bounds("width", i, argc);
|
||||||
set_width(&args, argv[i + 1]);
|
set_width(&args, argv[i + 1]);
|
||||||
|
|
||||||
} else if (
|
} else if (
|
||||||
@@ -67,6 +92,7 @@ Arguments cmd_args(int argc, char** argv) {
|
|||||||
|| strcmp(argv[i], "-h") == 0
|
|| strcmp(argv[i], "-h") == 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
check_bounds("height", i, argc);
|
||||||
set_height(&args, argv[i + 1]);
|
set_height(&args, argv[i + 1]);
|
||||||
|
|
||||||
} else if (
|
} else if (
|
||||||
@@ -74,7 +100,9 @@ Arguments cmd_args(int argc, char** argv) {
|
|||||||
|| strcmp(argv[i], "-s") == 0
|
|| strcmp(argv[i], "-s") == 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
check_bounds("speed", i, argc);
|
||||||
set_speed(&args, argv[i + 1]);
|
set_speed(&args, argv[i + 1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ int randomInt(const int start, const int end, const unsigned int seed) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make a general error logging function and macro
|
||||||
void mallocError(const char* varName, const char* fileName, const char* functionName) {
|
void mallocError(const char* varName, const char* fileName, const char* functionName) {
|
||||||
printf("Ran out of memory to allocate to %s in %s/%s\n", varName, fileName, functionName);
|
printf("Ran out of memory to allocate to %s in %s/%s\n", varName, fileName, functionName);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user