diff options
| author | Aiden Woodruff <aiden.woodruff@gmail.com> | 2019-09-18 22:53:41 -0500 |
|---|---|---|
| committer | Aiden Woodruff <aiden.woodruff@gmail.com> | 2019-09-18 22:53:41 -0500 |
| commit | c94d23f56df06fdfdbdf01dd519aed53078f06c5 (patch) | |
| tree | abc5a25287550cfd84426fd2667f9f4245e5b230 | |
| parent | f64ebb50da3a74b9060f1616d05b1e25e0503798 (diff) | |
| download | life-c94d23f56df06fdfdbdf01dd519aed53078f06c5.tar.gz life-c94d23f56df06fdfdbdf01dd519aed53078f06c5.tar.bz2 life-c94d23f56df06fdfdbdf01dd519aed53078f06c5.zip | |
Added board library to decrease size of boardmaps
Only allocate two maps, instead of another per generation
| -rw-r--r-- | src/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/board.c | 113 | ||||
| -rw-r--r-- | src/board.h | 23 | ||||
| -rw-r--r-- | src/test_board.c | 21 |
4 files changed, 165 insertions, 1 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3b216bf..47d993f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -1,6 +1,13 @@ | |||
| 1 | # Makefile stuff | 1 | # Makefile stuff |
| 2 | include_directories(.) | 2 | include_directories(.) |
| 3 | add_executable(life life.c life.h updatemap.c updatemap.h menus.c menus.h) | 3 | add_library(board board.c board.h) |
| 4 | target_compile_features(board PUBLIC c_function_prototypes) | ||
| 5 | if (UNIX) | ||
| 6 | # target_link_libraries(board m) | ||
| 7 | endif() | ||
| 8 | add_executable(life life.c life.h board updatemap.c updatemap.h menus.c menus.h) | ||
| 9 | add_executable(test_board test_board.c board) | ||
| 4 | target_compile_features(life PUBLIC c_function_prototypes c_variadic_macros) | 10 | target_compile_features(life PUBLIC c_function_prototypes c_variadic_macros) |
| 11 | target_compile_features(test_board PRIVATE c_std_99) | ||
| 5 | target_include_directories(life PRIVATE "${CURSES_INCLUDE_DIRS}") | 12 | target_include_directories(life PRIVATE "${CURSES_INCLUDE_DIRS}") |
| 6 | target_link_libraries(life "${CURSES_LIBRARIES}") | 13 | target_link_libraries(life "${CURSES_LIBRARIES}") |
diff --git a/src/board.c b/src/board.c new file mode 100644 index 0000000..c22aa0d --- /dev/null +++ b/src/board.c | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | #include <stdlib.h> | ||
| 2 | #include <assert.h> | ||
| 3 | #include <stdio.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | #include "board.h" | ||
| 7 | |||
| 8 | struct BOARD { | ||
| 9 | unsigned int* arr; | ||
| 10 | unsigned int arr_size; | ||
| 11 | unsigned int w; | ||
| 12 | unsigned int h; | ||
| 13 | }; | ||
| 14 | |||
| 15 | BOARD newboard(unsigned int w, unsigned int h) { | ||
| 16 | BOARD ret = (BOARD) malloc(sizeof(struct BOARD)); | ||
| 17 | ret->w = w; | ||
| 18 | ret->h = h; | ||
| 19 | // (a / b) + ((a % b) != 0) | ||
| 20 | unsigned int bits = sizeof(unsigned int) * 8; | ||
| 21 | ret->arr_size = w * h / bits + ((w * h) % bits != 0); | ||
| 22 | ret->arr = ( unsigned int*) calloc(ret->arr_size, sizeof(unsigned int)); | ||
| 23 | return ret; | ||
| 24 | } | ||
| 25 | |||
| 26 | BOARD dupboard (BOARD old) { | ||
| 27 | BOARD ret = (BOARD) malloc(sizeof(struct BOARD)); | ||
| 28 | ret->w = old->w; | ||
| 29 | ret->h = old->h; | ||
| 30 | ret->arr_size = old->arr_size; | ||
| 31 | ret->arr = ( unsigned int*) calloc(old->arr_size, sizeof(unsigned int)); | ||
| 32 | memcpy(ret->arr, old->arr, old->arr_size * sizeof(*old->arr)); | ||
| 33 | return ret; | ||
| 34 | } | ||
| 35 | |||
| 36 | // Copy boards of the same size | ||
| 37 | // For boards of differing sizes, just use dupboard | ||
| 38 | BOARD cpyboard (BOARD dest, BOARD src) { | ||
| 39 | assert(dest != NULL && dest->arr != NULL); | ||
| 40 | assert(src != NULL && src->arr != NULL); | ||
| 41 | memcpy(dest->arr, src->arr, src->arr_size * sizeof(*src->arr)); | ||
| 42 | return dest; | ||
| 43 | } | ||
| 44 | |||
| 45 | void delboard(BOARD b) { | ||
| 46 | free(b->arr); | ||
| 47 | free(b); | ||
| 48 | } | ||
| 49 | |||
| 50 | unsigned int board_getval(BOARD b, unsigned int x, unsigned int y) { | ||
| 51 | assert(("board_getval out of bounds", x < b->w && y < b->h)); | ||
| 52 | unsigned int n = b->w * y + x; | ||
| 53 | return (b->arr[n / sizeof(unsigned int) / 8] >> (n % (sizeof(unsigned int) * 8))) & 1; | ||
| 54 | } | ||
| 55 | |||
| 56 | unsigned int board_setval(BOARD b, unsigned int x, unsigned int y, unsigned int val) { | ||
| 57 | assert(("board_setval out of bounds", x < b->w && y < b->h)); | ||
| 58 | unsigned int n = b->w * y + x; | ||
| 59 | unsigned int retval = (b->arr[n / sizeof(unsigned int) / 8] >> (n % (sizeof(unsigned int) * 8))) & 1; | ||
| 60 | unsigned int pos = n % (sizeof(unsigned int) * 8); | ||
| 61 | switch (val) { | ||
| 62 | case 0: | ||
| 63 | b->arr[n / sizeof(unsigned int) / 8] &= ~(( unsigned int) (1 << pos)); | ||
| 64 | break; | ||
| 65 | case 1: | ||
| 66 | default: | ||
| 67 | b->arr[n / sizeof(unsigned int) / 8] |= 1 << pos; | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | return retval; | ||
| 71 | } | ||
| 72 | unsigned int board_flip(BOARD b, unsigned int x, unsigned int y) { | ||
| 73 | assert(("board_flip out of bounds", x < b->w && y < b->h)); | ||
| 74 | unsigned int n = b->w * y + x; | ||
| 75 | unsigned int retval = (b->arr[n / sizeof(unsigned int) / 8] >> (n % (sizeof(unsigned int) * 8))) & 1; | ||
| 76 | unsigned int pos = n % (sizeof(unsigned int) * 8); | ||
| 77 | b->arr[n / sizeof(unsigned int) / 8] ^= 1 << pos; | ||
| 78 | return retval; | ||
| 79 | } | ||
| 80 | |||
| 81 | unsigned int board_getval_i(BOARD b, unsigned int i) { | ||
| 82 | assert(("board_getval_i out of bounds", i < b->w * b->h)); | ||
| 83 | return (b->arr[i / sizeof(unsigned int) / 8] >> (i % (sizeof(unsigned int) * 8))) & 1; | ||
| 84 | } | ||
| 85 | |||
| 86 | unsigned int board_setval_i(BOARD b, unsigned int i, unsigned int val) { | ||
| 87 | assert(("board_setval_i out of bounds", i < b->w * b->h)); | ||
| 88 | unsigned int retval = (b->arr[i / sizeof(unsigned int) / 8] >> (i % (sizeof(unsigned int) * 8))) & 1; | ||
| 89 | unsigned int pos = i % (sizeof(unsigned int) * 8); | ||
| 90 | switch (val) { | ||
| 91 | case 0: | ||
| 92 | b->arr[i / sizeof(unsigned int) / 8] &= ~(( unsigned int) (1 << pos)); | ||
| 93 | break; | ||
| 94 | case 1: | ||
| 95 | default: | ||
| 96 | b->arr[i / sizeof(unsigned int) / 8] |= 1 << pos; | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | return retval; | ||
| 100 | } | ||
| 101 | |||
| 102 | unsigned int board_flip_i(BOARD b, unsigned int i) { | ||
| 103 | assert(("board_flip_i out of bounds", i < b->w * b->h)); | ||
| 104 | unsigned int retval = (b->arr[i / sizeof(unsigned int) / 8] >> (i % (sizeof(unsigned int) * 8))) & 1; | ||
| 105 | unsigned int pos = i % (sizeof(unsigned int) * 8); | ||
| 106 | b->arr[i / sizeof(unsigned int) / 8] ^= 1 << pos; | ||
| 107 | return retval; | ||
| 108 | } | ||
| 109 | |||
| 110 | void board_setall(BOARD b, unsigned int val) { | ||
| 111 | assert(b != NULL); | ||
| 112 | memset(b->arr, val == 0 ? 0 : 1, b->arr_size * sizeof(*b->arr)); | ||
| 113 | } \ No newline at end of file | ||
diff --git a/src/board.h b/src/board.h new file mode 100644 index 0000000..3b25c88 --- /dev/null +++ b/src/board.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #ifndef LIFE_BOARD_H_ | ||
| 2 | #define LIFE_BOARD_H_ | ||
| 3 | // Everything assumes there are 8 bits per byte | ||
| 4 | |||
| 5 | struct BOARD; | ||
| 6 | typedef struct BOARD* BOARD; | ||
| 7 | |||
| 8 | BOARD newboard(unsigned int w, unsigned int h); | ||
| 9 | BOARD dupboard(BOARD old); | ||
| 10 | BOARD cpyboard(BOARD dest, BOARD src); | ||
| 11 | void delboard(BOARD b); | ||
| 12 | unsigned int board_getval(BOARD b, unsigned int x, unsigned int y); | ||
| 13 | unsigned int board_setval(BOARD b, unsigned int x, unsigned int y, unsigned int val); | ||
| 14 | unsigned int board_flip (BOARD b, unsigned int x, unsigned int y); | ||
| 15 | |||
| 16 | // Variant of the regular functions which takes i instead of (x, y) | ||
| 17 | unsigned int board_getval_i(BOARD b, unsigned int i); | ||
| 18 | unsigned int board_setval_i(BOARD b, unsigned int i, unsigned int val); | ||
| 19 | unsigned int board_flip_i(BOARD b, unsigned int i); | ||
| 20 | |||
| 21 | void board_setall(BOARD b, unsigned int val); | ||
| 22 | |||
| 23 | #endif // LIFE_BOARD_H_ \ No newline at end of file | ||
diff --git a/src/test_board.c b/src/test_board.c new file mode 100644 index 0000000..e9a75bd --- /dev/null +++ b/src/test_board.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include "board.h" | ||
| 3 | |||
| 4 | int main () { | ||
| 5 | printf("sizeof(unsigned int): %d\n", sizeof(unsigned int)); | ||
| 6 | BOARD jim = newboard(10, 10); | ||
| 7 | for (unsigned int y = 0; y < 10; ++y) { | ||
| 8 | for (unsigned int x = 0; x < 10; ++x) | ||
| 9 | putchar(board_getval(jim, x, y) == 0 ? '.' : '#'); | ||
| 10 | putchar('\n'); | ||
| 11 | } | ||
| 12 | board_setval(jim, 0, 3, 1); | ||
| 13 | board_setval(jim, 4, 5, 1); | ||
| 14 | for (unsigned int y = 0; y < 10; ++y) { | ||
| 15 | for (unsigned int x = 0; x < 10; ++x) | ||
| 16 | putchar(board_getval(jim, x, y) == 0 ? '.' : '#'); | ||
| 17 | putchar('\n'); | ||
| 18 | } | ||
| 19 | delboard(jim); | ||
| 20 | return 0; | ||
| 21 | } \ No newline at end of file | ||
