aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <aiden.woodruff@gmail.com>2018-07-29 19:58:41 -0500
committerAiden Woodruff <aiden.woodruff@gmail.com>2018-07-29 19:58:41 -0500
commit8635c9b7bb453846c0a712fca974a224bb219cb3 (patch)
treeba1f9c7f8c5203581ae82ffc9c1a718d485b1e47
parent3572c7e10cfc9021fba2843d5514ab1c2752e4a6 (diff)
downloadlife-8635c9b7bb453846c0a712fca974a224bb219cb3.tar.gz
life-8635c9b7bb453846c0a712fca974a224bb219cb3.tar.bz2
life-8635c9b7bb453846c0a712fca974a224bb219cb3.zip
Fancy rule setuplife-1.5.0
Removed rulestoint.py Used addstr instead of printw where applicable Moved help to menus.c Moved read_num to menus.c Version 1.5.0 Signed-off-by: Aiden Woodruff <aiden.woodruff@gmail.com>
-rw-r--r--ChangeLog39
-rw-r--r--NEWS3
l---------[-rw-r--r--]README7
-rw-r--r--README.md2
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac2
-rw-r--r--life-1.3.3.tar.gzbin115061 -> 0 bytes
-rw-r--r--life-1.4.1.tar.gzbin115242 -> 0 bytes
-rw-r--r--life-1.5.0.tar.gzbin0 -> 116064 bytes
-rw-r--r--life.c94
-rw-r--r--menus.c156
-rw-r--r--menus.h5
-rwxr-xr-xrulestoint.py17
-rw-r--r--updatemap.c22
14 files changed, 257 insertions, 110 deletions
diff --git a/ChangeLog b/ChangeLog
index 4f51942..8f78c16 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
12018-07-29 Aiden Woodruff <aiden.woodruff@gmail.com>
2
3 * NEWS: Added version 1.4.1 release date
4
5 * life.c (read_num): Moved to menus.c
6 Added has macro to test for bit
7 Set max width to COLS (from COLS-1)
8 board window is now whole screen
9 Set keypad to true only on board
10 Use foreach on erase at beginning of main while
11 Only set timeout for board window
12 Call fancy_rules function on C-R
13 Moved help section to menus.c (print_help)
14 Don't print lines on screen with wprintw, use mvwaddnstr
15 Use mvwchgat for current (x, y) highlighting
16 Only getch from board
17
18 * menus.c (print_copying_warranty): Don't capture width
19 Use waddstr
20 (read_num): Use getmaxx instead of COLS for width
21 (print_help): Use waddstr
22 Add C-R print
23 (fancy_rules): Function added, should only use one window
24
25 * menus.h: Add declarations
26
27 * rulestoint.py: Removed as function exists in main program
28
29 * README.md: Updated for removal of rulestoint.py
30
31 * README: Now symlink to README.md
32
33 * updatemap.c (update_map): Initialize intermap with strndup instead of malloc
34 Use has macro
35
36 * configure.ac: Updated version as life-1.5.0
37
38 Tarballed life-1.5.0.tar.gz
39
12018-07-19 Aiden Woodruff <aiden.woodruff@gmail.com> 402018-07-19 Aiden Woodruff <aiden.woodruff@gmail.com>
2 41
3 * life.c: Don't blindly accept commandline variables 42 * life.c: Don't blindly accept commandline variables
diff --git a/NEWS b/NEWS
index 36b08cc..7fa41ca 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
12018-07-28T15:34-05:00 Aiden Woodruff
2Version life-1.4.1 released
3
12018-07-25T00:39-05:00 Aiden Woodruff 42018-07-25T00:39-05:00 Aiden Woodruff
2Version life-1.4.0 released 5Version life-1.4.0 released
3 6
diff --git a/README b/README
index 5c11cfe..42061c0 100644..120000
--- a/README
+++ b/README
@@ -1,6 +1 @@
1# Life README.md \ No newline at end of file
2`life` runs arbitrary cellular automata models based off of a rule integer.
3
4To get a rule integer for a B/S rule string, use `rulestoint.py` with Python 3.
5
6It runs with ncurses, so make sure to install it (usually with `apt-get install ncurses-base` or the equivalent with yum) and the dev version if you intend to build it yourself.
diff --git a/README.md b/README.md
index 5c11cfe..73b545c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,4 @@
1# Life 1# Life
2`life` runs arbitrary cellular automata models based off of a rule integer. 2`life` runs arbitrary cellular automata models based off of a rule integer.
3 3
4To get a rule integer for a B/S rule string, use `rulestoint.py` with Python 3.
5
6It runs with ncurses, so make sure to install it (usually with `apt-get install ncurses-base` or the equivalent with yum) and the dev version if you intend to build it yourself. 4It runs with ncurses, so make sure to install it (usually with `apt-get install ncurses-base` or the equivalent with yum) and the dev version if you intend to build it yourself.
diff --git a/configure b/configure
index b3e29c7..4561da1 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
1#! /bin/sh 1#! /bin/sh
2# Guess values for system-dependent variables and create Makefiles. 2# Guess values for system-dependent variables and create Makefiles.
3# Generated by GNU Autoconf 2.69 for life 1.4.1. 3# Generated by GNU Autoconf 2.69 for life 1.5.0.
4# 4#
5# Report bugs to <aiden.woodruff@gmail.com>. 5# Report bugs to <aiden.woodruff@gmail.com>.
6# 6#
@@ -580,8 +580,8 @@ MAKEFLAGS=
580# Identity of this package. 580# Identity of this package.
581PACKAGE_NAME='life' 581PACKAGE_NAME='life'
582PACKAGE_TARNAME='life' 582PACKAGE_TARNAME='life'
583PACKAGE_VERSION='1.4.1' 583PACKAGE_VERSION='1.5.0'
584PACKAGE_STRING='life 1.4.1' 584PACKAGE_STRING='life 1.5.0'
585PACKAGE_BUGREPORT='aiden.woodruff@gmail.com' 585PACKAGE_BUGREPORT='aiden.woodruff@gmail.com'
586PACKAGE_URL='' 586PACKAGE_URL=''
587 587
@@ -1277,7 +1277,7 @@ if test "$ac_init_help" = "long"; then
1277 # Omit some internal or obsolete options to make the list less imposing. 1277 # Omit some internal or obsolete options to make the list less imposing.
1278 # This message is too long to be a string in the A/UX 3.1 sh. 1278 # This message is too long to be a string in the A/UX 3.1 sh.
1279 cat <<_ACEOF 1279 cat <<_ACEOF
1280\`configure' configures life 1.4.1 to adapt to many kinds of systems. 1280\`configure' configures life 1.5.0 to adapt to many kinds of systems.
1281 1281
1282Usage: $0 [OPTION]... [VAR=VALUE]... 1282Usage: $0 [OPTION]... [VAR=VALUE]...
1283 1283
@@ -1344,7 +1344,7 @@ fi
1344 1344
1345if test -n "$ac_init_help"; then 1345if test -n "$ac_init_help"; then
1346 case $ac_init_help in 1346 case $ac_init_help in
1347 short | recursive ) echo "Configuration of life 1.4.1:";; 1347 short | recursive ) echo "Configuration of life 1.5.0:";;
1348 esac 1348 esac
1349 cat <<\_ACEOF 1349 cat <<\_ACEOF
1350 1350
@@ -1435,7 +1435,7 @@ fi
1435test -n "$ac_init_help" && exit $ac_status 1435test -n "$ac_init_help" && exit $ac_status
1436if $ac_init_version; then 1436if $ac_init_version; then
1437 cat <<\_ACEOF 1437 cat <<\_ACEOF
1438life configure 1.4.1 1438life configure 1.5.0
1439generated by GNU Autoconf 2.69 1439generated by GNU Autoconf 2.69
1440 1440
1441Copyright (C) 2012 Free Software Foundation, Inc. 1441Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1804,7 +1804,7 @@ cat >config.log <<_ACEOF
1804This file contains any messages produced by compilers while 1804This file contains any messages produced by compilers while
1805running configure, to aid debugging if configure makes a mistake. 1805running configure, to aid debugging if configure makes a mistake.
1806 1806
1807It was created by life $as_me 1.4.1, which was 1807It was created by life $as_me 1.5.0, which was
1808generated by GNU Autoconf 2.69. Invocation command line was 1808generated by GNU Autoconf 2.69. Invocation command line was
1809 1809
1810 $ $0 $@ 1810 $ $0 $@
@@ -4306,7 +4306,7 @@ fi
4306 4306
4307# Define the identity of the package. 4307# Define the identity of the package.
4308 PACKAGE='life' 4308 PACKAGE='life'
4309 VERSION='1.4.1' 4309 VERSION='1.5.0'
4310 4310
4311 4311
4312cat >>confdefs.h <<_ACEOF 4312cat >>confdefs.h <<_ACEOF
@@ -5057,7 +5057,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
5057# report actual input values of CONFIG_FILES etc. instead of their 5057# report actual input values of CONFIG_FILES etc. instead of their
5058# values after options handling. 5058# values after options handling.
5059ac_log=" 5059ac_log="
5060This file was extended by life $as_me 1.4.1, which was 5060This file was extended by life $as_me 1.5.0, which was
5061generated by GNU Autoconf 2.69. Invocation command line was 5061generated by GNU Autoconf 2.69. Invocation command line was
5062 5062
5063 CONFIG_FILES = $CONFIG_FILES 5063 CONFIG_FILES = $CONFIG_FILES
@@ -5123,7 +5123,7 @@ _ACEOF
5123cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 5123cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
5124ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" 5124ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
5125ac_cs_version="\\ 5125ac_cs_version="\\
5126life config.status 1.4.1 5126life config.status 1.5.0
5127configured by $0, generated by GNU Autoconf 2.69, 5127configured by $0, generated by GNU Autoconf 2.69,
5128 with options \\"\$ac_cs_config\\" 5128 with options \\"\$ac_cs_config\\"
5129 5129
diff --git a/configure.ac b/configure.ac
index d84551c..e8776fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
2# Process this file with autoconf to produce a configure script. 2# Process this file with autoconf to produce a configure script.
3 3
4AC_PREREQ([2.69]) 4AC_PREREQ([2.69])
5AC_INIT([life], [1.4.1], [aiden.woodruff@gmail.com]) 5AC_INIT([life], [1.5.0], [aiden.woodruff@gmail.com])
6AC_CONFIG_SRCDIR([life.c]) 6AC_CONFIG_SRCDIR([life.c])
7AC_CONFIG_HEADERS([config.h]) 7AC_CONFIG_HEADERS([config.h])
8 8
diff --git a/life-1.3.3.tar.gz b/life-1.3.3.tar.gz
deleted file mode 100644
index 71b1dab..0000000
--- a/life-1.3.3.tar.gz
+++ /dev/null
Binary files differ
diff --git a/life-1.4.1.tar.gz b/life-1.4.1.tar.gz
deleted file mode 100644
index 5cd00aa..0000000
--- a/life-1.4.1.tar.gz
+++ /dev/null
Binary files differ
diff --git a/life-1.5.0.tar.gz b/life-1.5.0.tar.gz
new file mode 100644
index 0000000..b975fd9
--- /dev/null
+++ b/life-1.5.0.tar.gz
Binary files differ
diff --git a/life.c b/life.c
index 058fffc..2bf9733 100644
--- a/life.c
+++ b/life.c
@@ -21,35 +21,21 @@
21 21
22#ifndef stat_bar_print 22#ifndef stat_bar_print
23// Print text to status bar in the nice way, without erasing or refreshing 23// Print text to status bar in the nice way, without erasing or refreshing
24#define stat_bar_print(win,fmt,...) \ 24#define stat_bar_print(win, fmt,...) \
25 wprintw(win, fmt, ##__VA_ARGS__); \ 25 wprintw(win, fmt, ##__VA_ARGS__); \
26 for (int _i = getcurx(win); _i < COLS; _i++) waddch(win, ' '); 26 for (int _i = getcurx(win); _i < COLS; _i++) waddch(win, ' ');
27#endif 27#endif
28 28
29#ifndef foreach 29#ifndef foreach
30#define foreach(func,count,first,...) \ 30#define foreach(func, count, first,...) \
31 {typeof(first) things[] = {__VA_ARGS__}; \ 31 {typeof(first) things[] = {__VA_ARGS__}; \
32 func(first); \ 32 func(first); \
33 for (int _i = 0; _i < count - 1; _i++) func(things[_i]);} 33 for (int _i = 0; _i < count - 1; _i++) func(things[_i]);}
34#endif 34#endif
35 35
36int read_num (WINDOW * win, int min, int max) { 36#ifndef has
37 int ret = 0; 37#define has(var, bit) ((var & bit) == bit)
38 werase(win); 38#endif
39 char * text = (char*) malloc((size_t)(COLS + 1));
40 memset(text, 0, (size_t)(COLS + 1));
41 curs_set(1);
42 echo();
43 wgetnstr(win, text, (size_t)(COLS + 1));
44 ret = (int) strtol((const char *) text, NULL, 10);
45 if (!(ret >= min && ret <= max)) {
46 ret = 0;
47 }
48 noecho();
49 curs_set(0);
50 free(text);
51 return ret;
52}
53 39
54int main (int argc, char * argv[]) { 40int main (int argc, char * argv[]) {
55 unsigned int RULE = 0; 41 unsigned int RULE = 0;
@@ -58,7 +44,6 @@ int main (int argc, char * argv[]) {
58 initscr(); 44 initscr();
59 raw(); 45 raw();
60 curs_set(0); 46 curs_set(0);
61 keypad(stdscr, TRUE);
62 noecho(); 47 noecho();
63 RULE = args_info.ruleint_arg; 48 RULE = args_info.ruleint_arg;
64 srand(time(NULL)); 49 srand(time(NULL));
@@ -73,8 +58,8 @@ int main (int argc, char * argv[]) {
73 int livecell = '#'; 58 int livecell = '#';
74 int deadcell = '.'; 59 int deadcell = '.';
75 if (args_info.width_given) { 60 if (args_info.width_given) {
76 if (args_info.width_arg > COLS - 1) { 61 if (args_info.width_arg > COLS) {
77 width = COLS - 1; 62 width = COLS;
78 } else if (args_info.width_arg < 1) { 63 } else if (args_info.width_arg < 1) {
79 width = 1; 64 width = 1;
80 } else { 65 } else {
@@ -116,13 +101,14 @@ int main (int argc, char * argv[]) {
116 } 101 }
117 } 102 }
118 if (args_info.maximize_given) { 103 if (args_info.maximize_given) {
119 width = COLS - 1; 104 width = COLS;
120 height = LINES - 2; 105 height = LINES - 2;
121 } 106 }
122 cmdline_parser_free(&args_info); 107 cmdline_parser_free(&args_info);
123 WINDOW * board = newwin(height, width + 1, 0, 0); 108 WINDOW * board = newwin(LINES - 2, COLS, 0, 0);
124 WINDOW * stat_bar = newwin(1, 0, LINES - 2, 0); 109 WINDOW * stat_bar = newwin(1, 0, LINES - 2, 0);
125 WINDOW * entry = newwin(1, 0, LINES - 1, 0); 110 WINDOW * entry = newwin(1, 0, LINES - 1, 0);
111 keypad(board, TRUE);
126 wstandout(stat_bar); 112 wstandout(stat_bar);
127 char * map = NULL; 113 char * map = NULL;
128 map = malloc((height * width)+1); 114 map = malloc((height * width)+1);
@@ -131,10 +117,7 @@ int main (int argc, char * argv[]) {
131 int x = width/2; 117 int x = width/2;
132 int y = height/2; 118 int y = height/2;
133 while (ch != 'q') { 119 while (ch != 'q') {
134 erase(); 120 foreach(werase, 4, stdscr, board, stat_bar, entry);
135 werase(board);
136 werase(stat_bar);
137 werase(entry);
138 if (playing == FALSE) { 121 if (playing == FALSE) {
139 // Numpad and arrow directions 122 // Numpad and arrow directions
140 if (ch == KEY_UP) { 123 if (ch == KEY_UP) {
@@ -165,7 +148,7 @@ int main (int argc, char * argv[]) {
165 } 148 }
166 } else if (ch == '\n') { 149 } else if (ch == '\n') {
167 playing = TRUE; 150 playing = TRUE;
168 timeout(timeout_val); 151 wtimeout(board, timeout_val);
169 } else if (ch == 'c') { 152 } else if (ch == 'c') {
170 memset(map, deadcell, width*height); 153 memset(map, deadcell, width*height);
171 } else if (ch == 'r') { 154 } else if (ch == 'r') {
@@ -181,43 +164,37 @@ int main (int argc, char * argv[]) {
181 } 164 }
182 werase(stat_bar); 165 werase(stat_bar);
183 werase(entry); 166 werase(entry);
184 } else if (keyname(ch) == "^R") { 167 } else if (strcmp(keyname(ch), "^R") == 0) {
185 // Fancy rule selection 168 foreach(werase, 4, stdscr, board, stat_bar, entry);
186 // TODO (aiden.woodruff@gmail.com) Write 169 stat_bar_print(stat_bar, "Click Cancel to exit or Done to exit and save rule");
170 wrefresh(stat_bar);
171 int ruleint = fancy_rules(board, RULE, timeout_val);
172 if (ruleint != -1) {
173 RULE = ruleint;
174 }
187 } else if (ch == 'h') { 175 } else if (ch == 'h') {
188 timeout(-1); 176 wtimeout(board, -1);
189 erase(); 177 foreach(werase, 3, stdscr, board, stat_bar);
190 foreach(werase, 3, board, stat_bar, entry);
191 stat_bar_print(stat_bar, "Press any key to return"); 178 stat_bar_print(stat_bar, "Press any key to return");
192 printw("Arrow keys - Motion\n"); 179 print_help(board);
193 printw("Space - Flip cell (if it's alive, to dead, and vice versa)\n"); 180 foreach(wnoutrefresh, 3, stdscr, board, stat_bar);
194 printw("Enter - Pause/Play\n");
195 printw("\tN.B. - Many keys can only be used while paused.\n");
196 printw(", - Lower delay time\n");
197 printw(". - Increase delay time\n");
198 printw("R - Input a rule-int\n");
199 // TODO printw("Ctrl+R - Open the fancy rule menu\n");
200 printw("Ctrl+L - Redraw screen\n");
201 printw("W - Show warranty\n");
202 printw("V - Print version\n");
203 foreach(wnoutrefresh, 3, stdscr, entry, stat_bar);
204 doupdate(); 181 doupdate();
205 getch(); 182 getch();
206 timeout(timeout_val); 183 wtimeout(board, timeout_val);
207 } else if (ch == 'w') { 184 } else if (ch == 'w') {
208 timeout(-1); 185 wtimeout(board, -1);
209 foreach(werase, 4, stdscr, board, stat_bar, entry); 186 foreach(werase, 4, stdscr, board, stat_bar, entry);
210 stat_bar_print(stat_bar, "Press any key to return"); 187 stat_bar_print(stat_bar, "Press any key to return");
211 print_copying_warranty(stdscr); 188 print_copying_warranty(board);
212 foreach(wnoutrefresh, 3, stdscr, entry, stat_bar); 189 foreach(wnoutrefresh, 3, stdscr, entry, stat_bar);
213 doupdate(); 190 doupdate();
214 getch(); 191 getch();
215 timeout(timeout_val); 192 wtimeout(board, timeout_val);
216 } 193 }
217 } else { // ie PLAYING == TRUE 194 } else { // ie PLAYING == TRUE
218 if (ch == '\n') { 195 if (ch == '\n') {
219 playing = FALSE; 196 playing = FALSE;
220 timeout(-1); 197 wtimeout(board, -1);
221 } 198 }
222 } 199 }
223 200
@@ -230,16 +207,9 @@ int main (int argc, char * argv[]) {
230 foreach(wclear, 4, stdscr, entry, stat_bar, board); 207 foreach(wclear, 4, stdscr, entry, stat_bar, board);
231 } 208 }
232 for (int i = 0; i < height; ++i) { 209 for (int i = 0; i < height; ++i) {
233 if (i == y) { 210 mvwaddnstr(board, i, 0, map + (i * width), width);
234 wprintw(board, "%.*s", x, map + (y * width));
235 wstandout(board);
236 wprintw(board, "%.1s", map + (y * width) + x);
237 wstandend(board);
238 wprintw(board, "%.*s\n", width-(x+1), (map + (i * width) + x + 1));
239 } else {
240 wprintw(board, "%.*s\n", width, (map + (i * width)));
241 }
242 } 211 }
212 mvwchgat(board, y, x, 1, A_STANDOUT, COLOR_PAIR(0), NULL);
243 stat_bar_print(stat_bar, "(%d, %d)\t\tGeneration: %d\t\tDelay Time: %d", x, y, generation, delaymax); 213 stat_bar_print(stat_bar, "(%d, %d)\t\tGeneration: %d\t\tDelay Time: %d", x, y, generation, delaymax);
244 foreach(wnoutrefresh, 4, stdscr, board, entry, stat_bar); 214 foreach(wnoutrefresh, 4, stdscr, board, entry, stat_bar);
245 doupdate(); 215 doupdate();
@@ -251,7 +221,7 @@ int main (int argc, char * argv[]) {
251 update_map(map, width, height, livecell, deadcell, RULE); 221 update_map(map, width, height, livecell, deadcell, RULE);
252 } 222 }
253 } 223 }
254 ch = getch(); 224 ch = wgetch(board);
255 if (ch <= 'Z' && ch >= 'A') { 225 if (ch <= 'Z' && ch >= 'A') {
256 ch -= ('A' - 'a'); 226 ch -= ('A' - 'a');
257 } 227 }
diff --git a/menus.c b/menus.c
index 189a69b..e29e084 100644
--- a/menus.c
+++ b/menus.c
@@ -1,7 +1,159 @@
1#include "menus.h" 1#include "menus.h"
2 2
3#ifndef has
4#define has(var, bit) ((var & bit) == bit)
5#endif
6
3int print_copying_warranty (WINDOW * win) { 7int print_copying_warranty (WINDOW * win) {
4 int width = getmaxx(win);
5 const char * WARRANTY = " THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.\n EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.\n THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.\n SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION."; 8 const char * WARRANTY = " THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.\n EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.\n THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.\n SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.";
6 return wprintw(win, WARRANTY); 9 return waddstr(win, WARRANTY);
10}
11
12int print_help (WINDOW * win) {
13 if (waddstr(win, "Arrow keys - Motion\n") == OK &&
14 waddstr(win, "Space - Flip cell (if it's alive, to dead, and vice versa)\n") == OK &&
15 waddstr(win, "Enter - Pause/Play\n") == OK &&
16 waddstr(win, "\tN.B. - Many keys can only be used while paused.\n") == OK &&
17 waddstr(win, ", - Lower delay time\n") == OK &&
18 waddstr(win, ". - Increase delay time\n") == OK &&
19 waddstr(win, "R - Input a rule-int\n") == OK &&
20 waddstr(win, "Ctrl+R - Open the fancy rule menu\n") == OK &&
21 waddstr(win, "Ctrl+L - Redraw screen\n") == OK &&
22 waddstr(win, "W - Show warranty\n") == OK &&
23 waddstr(win, "V - Print version\n") == OK) {
24 return OK;
25 } else {
26 return ERR;
27 }
28}
29
30int read_num (WINDOW * win, int min, int max) {
31 int ret = 0;
32 werase(win);
33 int width = getmaxx(win);
34 char * text = (char*) malloc((size_t)(width + 1));
35 memset(text, 0, (size_t)(width + 1));
36 curs_set(1);
37 echo();
38 wgetnstr(win, text, (size_t)(width + 1));
39 ret = (int) strtol((const char *) text, NULL, 10);
40 if (!(ret >= min && ret <= max)) {
41 ret = 0;
42 }
43 noecho();
44 curs_set(0);
45 free(text);
46 return ret;
47}
48
49// Fancy rule menu, returns new rules or -1 on fail
50int fancy_rules (WINDOW * win, int ruleint, int speed) {
51 int done = FALSE;
52 int cursor = 0;
53 int ch = 0;
54 wtimeout(win, speed);
55 while (done == FALSE && ch != 'q') {
56 werase(win);
57 waddstr(win, "Press space to toggle buttons\n");
58 wprintw(win, "Rule int: %d\n", ruleint);
59 waddch(win, 'B');
60 for (int i = 0; i < 9; i++) {
61 if (cursor == i) {
62 wstandout(win);
63 }
64 waddch(win, has(ruleint, 1 << i) ? '1' : '0');
65 if (cursor == i) {
66 wstandend(win);
67 }
68 }
69 waddstr(win, "/S");
70 for (int i = 9; i < 18; i++) {
71 if (cursor == i) {
72 wstandout(win);
73 }
74 waddch(win, has(ruleint, 1 << i) ? '1' : '0');
75 if (cursor == i) {
76 wstandend(win);
77 }
78 }
79 waddstr(win, "\n");
80 if (cursor == 18) {
81 wstandout(win);
82 waddstr(win, "Cancel");
83 wstandend(win);
84 } else {
85 waddstr(win, "Cancel");
86 }
87 waddstr(win, " ");
88 if (cursor == 19) {
89 wstandout(win);
90 waddstr(win, "Default");
91 wstandend(win);
92 } else {
93 waddstr(win, "Default");
94 }
95 waddstr(win, " ");
96 if (cursor == 20) {
97 wstandout(win);
98 waddstr(win, "Done");
99 wstandend(win);
100 } else {
101 waddstr(win, "Done");
102 }
103 wrefresh(win);
104 if (ch == KEY_LEFT) {
105 if (cursor > 0 && cursor < 18) {
106 cursor--;
107 } else if (cursor > 18) {
108 cursor--;
109 }
110 } else if (ch == KEY_RIGHT) {
111 if (cursor < 17) {
112 cursor++;
113 } else if (cursor > 17 && cursor < 20) {
114 cursor++;
115 }
116 } else if (ch == KEY_UP || ch == KEY_DOWN) {
117 if (cursor > 17) {
118 switch (cursor) {
119 case 18:
120 cursor = 0;
121 break;
122 case 19:
123 cursor = 6;
124 break;
125 case 20:
126 cursor = 13;
127 break;
128 }
129 } else {
130 if (cursor > -1 && cursor < 6) {
131 cursor = 18;
132 } else if (cursor > 5 && cursor < 13) {
133 cursor = 19;
134 } else if (cursor > 12) {
135 cursor = 20;
136 }
137 }
138 } else if (ch == ' ' || ch == '\n') {
139 switch (cursor) {
140 case 18:
141 return -1;
142 break;
143 case 19:
144 ruleint = 6152;
145 break;
146 case 20:
147 return ruleint;
148 break;
149 default:
150 ruleint ^= 1 << cursor;
151 break;
152 }
153 }
154 if (done == FALSE) {
155 ch = wgetch(win);
156 }
157 }
158 ch = 0;
7} 159}
diff --git a/menus.h b/menus.h
index 567ae19..e507ad8 100644
--- a/menus.h
+++ b/menus.h
@@ -1,8 +1,13 @@
1#include <ncurses.h> 1#include <ncurses.h>
2#include <string.h>
3#include <stdlib.h>
2 4
3#ifndef LIFE_MENUS_H_ 5#ifndef LIFE_MENUS_H_
4#define LIFE_MENUS_H_ 6#define LIFE_MENUS_H_
5 7
6int print_copying_warranty (WINDOW * win); 8int print_copying_warranty (WINDOW * win);
9int print_help (WINDOW * win);
10int read_num (WINDOW * win, int min, int max);
11int fancy_rules (WINDOW * win, int ruleint, int speed);
7 12
8#endif // LIFE_MENUS_H_ 13#endif // LIFE_MENUS_H_
diff --git a/rulestoint.py b/rulestoint.py
deleted file mode 100755
index 342f01e..0000000
--- a/rulestoint.py
+++ /dev/null
@@ -1,17 +0,0 @@
1#!/usr/bin/python3
2rulestring = input("Rule String (B/S): ")
3bornstring = rulestring[rulestring.index('B')+1:rulestring.index('/')]
4survivestring = rulestring[rulestring.index('S')+1:]
5bornarr = [0]*9
6survivearr = [0] * 9
7ruleint = 0
8for i in range(len(bornstring)):
9 bornarr[int(bornstring[i])] = True
10for i in range(len(survivestring)):
11 survivearr[int(survivestring[i])] = True
12for i in range(9):
13 if (bornarr[i]):
14 ruleint |= 2**i
15 if (survivearr[i]):
16 ruleint |= 2**(i+9)
17print(ruleint)
diff --git a/updatemap.c b/updatemap.c
index d33b05a..fdf9769 100644
--- a/updatemap.c
+++ b/updatemap.c
@@ -1,13 +1,14 @@
1#include "updatemap.h" 1#include "updatemap.h"
2 2
3#ifndef has
4#define has(var, bit) ((var & bit) == bit)
5#endif
6
3char * update_map (char * base_map, const int width, const int height, char livecell, char deadcell, const unsigned int ruleint) { 7char * update_map (char * base_map, const int width, const int height, char livecell, char deadcell, const unsigned int ruleint) {
4 char * intermap = malloc((width * height)+1); 8 char * intermap = (char*) strndup(base_map, width * height);
5 memset(intermap, 0, (width*height)+1);
6 strcpy(intermap, base_map);
7 // Change intermap and stuff
8 for (int i = 0, x = 0, y = 0, surround = 0; i < width*height; i++, surround = 0) { 9 for (int i = 0, x = 0, y = 0, surround = 0; i < width*height; i++, surround = 0) {
9 x = i % width; 10 x = i % width;
10 y = (i - x)/width; 11 y = (i - x) / width;
11 /* 12 /*
12 Where i is the current cell: 13 Where i is the current cell:
13 A1 | A2 | A3 14 A1 | A2 | A3
@@ -31,25 +32,26 @@ char * update_map (char * base_map, const int width, const int height, char live
31 if (base_map[i+1-width] == livecell) surround++; // A3 32 if (base_map[i+1-width] == livecell) surround++; // A3
32 } 33 }
33 if (y < height - 1) { 34 if (y < height - 1) {
34 if (base_map[i+1+width] == livecell) surround++; // C3 35 if (base_map[i + 1 + width] == livecell) surround++; // C3
35 } 36 }
36 } 37 }
37 if (y > 0) { 38 if (y > 0) {
38 if (base_map[i-width] == livecell) surround++; 39 if (base_map[i - width] == livecell) surround++;
39 } 40 }
40 if (y < height - 1) { 41 if (y < height - 1) {
41 if (base_map[i+width] == livecell) surround++; 42 if (base_map[i + width] == livecell) surround++;
42 } 43 }
43 if (base_map[i] == deadcell) { 44 if (base_map[i] == deadcell) {
44 if ((ruleint & (1 << surround)) == (1 << surround)) { 45 if (has(ruleint, 1 << surround)) {
45 intermap[i] = livecell; 46 intermap[i] = livecell;
46 } 47 }
47 } else if (base_map[i] == livecell) { 48 } else if (base_map[i] == livecell) {
48 if ((ruleint & (1 << (surround + 9))) != (1 << (surround + 9))) { 49 if (has(ruleint, 1 << surround + 9)) {
49 intermap[i] = deadcell; 50 intermap[i] = deadcell;
50 } 51 }
51 } 52 }
52 } 53 }
54
53 // Rewrite map 55 // Rewrite map
54 strcpy(base_map, intermap); 56 strcpy(base_map, intermap);
55 free(intermap); 57 free(intermap);