aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <aiden.woodruff@gmail.com>2019-09-18 22:53:41 -0500
committerAiden Woodruff <aiden.woodruff@gmail.com>2019-09-18 22:53:41 -0500
commitc94d23f56df06fdfdbdf01dd519aed53078f06c5 (patch)
treeabc5a25287550cfd84426fd2667f9f4245e5b230
parentf64ebb50da3a74b9060f1616d05b1e25e0503798 (diff)
downloadlife-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.txt9
-rw-r--r--src/board.c113
-rw-r--r--src/board.h23
-rw-r--r--src/test_board.c21
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
2include_directories(.) 2include_directories(.)
3add_executable(life life.c life.h updatemap.c updatemap.h menus.c menus.h) 3add_library(board board.c board.h)
4target_compile_features(board PUBLIC c_function_prototypes)
5if (UNIX)
6# target_link_libraries(board m)
7endif()
8add_executable(life life.c life.h board updatemap.c updatemap.h menus.c menus.h)
9add_executable(test_board test_board.c board)
4target_compile_features(life PUBLIC c_function_prototypes c_variadic_macros) 10target_compile_features(life PUBLIC c_function_prototypes c_variadic_macros)
11target_compile_features(test_board PRIVATE c_std_99)
5target_include_directories(life PRIVATE "${CURSES_INCLUDE_DIRS}") 12target_include_directories(life PRIVATE "${CURSES_INCLUDE_DIRS}")
6target_link_libraries(life "${CURSES_LIBRARIES}") 13target_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
8struct BOARD {
9 unsigned int* arr;
10 unsigned int arr_size;
11 unsigned int w;
12 unsigned int h;
13};
14
15BOARD 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
26BOARD 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
38BOARD 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
45void delboard(BOARD b) {
46 free(b->arr);
47 free(b);
48}
49
50unsigned 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
56unsigned 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}
72unsigned 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
81unsigned 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
86unsigned 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
102unsigned 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
110void 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
5struct BOARD;
6typedef struct BOARD* BOARD;
7
8BOARD newboard(unsigned int w, unsigned int h);
9BOARD dupboard(BOARD old);
10BOARD cpyboard(BOARD dest, BOARD src);
11void delboard(BOARD b);
12unsigned int board_getval(BOARD b, unsigned int x, unsigned int y);
13unsigned int board_setval(BOARD b, unsigned int x, unsigned int y, unsigned int val);
14unsigned 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)
17unsigned int board_getval_i(BOARD b, unsigned int i);
18unsigned int board_setval_i(BOARD b, unsigned int i, unsigned int val);
19unsigned int board_flip_i(BOARD b, unsigned int i);
20
21void 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
4int 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