diff options
| author | Aiden Woodruff <aiden.woodruff@gmail.com> | 2018-07-27 19:58:26 -0500 |
|---|---|---|
| committer | Aiden Woodruff <aiden.woodruff@gmail.com> | 2018-07-27 19:58:26 -0500 |
| commit | 9ed4ac7700f77f3f1d5332798b85b5825504e19b (patch) | |
| tree | 256a2dbf22631b2f5353fdc92a9fe1ebd1673665 | |
| parent | e6e5d8be34441309876ff064a3d673a12161bc30 (diff) | |
| download | life-9ed4ac7700f77f3f1d5332798b85b5825504e19b.tar.gz life-9ed4ac7700f77f3f1d5332798b85b5825504e19b.tar.bz2 life-9ed4ac7700f77f3f1d5332798b85b5825504e19b.zip | |
Added bottom status bar and entry arealife-1.3.0
Fixed issue in update_map function
Moved update_map function to source file, with attached header
Added function to print warranty
Added multiple windows
Get screen size from LINES/COLS instead of getmaxyx macro
Added help key
Added foreach macro
Added macro to print onto status bar nicely
Removed unistd include
Change ruleint at runtime
Updated Makefile.am for new sources and headers
Signed-off-by: Aiden Woodruff <aiden.woodruff@gmail.com>
| -rw-r--r-- | ChangeLog | 34 | ||||
| -rw-r--r-- | Makefile.am | 4 | ||||
| -rw-r--r-- | Makefile.in | 37 | ||||
| -rw-r--r-- | life.c | 160 | ||||
| -rw-r--r-- | life.h | 2 | ||||
| -rw-r--r-- | menus.c | 7 | ||||
| -rw-r--r-- | menus.h | 8 | ||||
| -rw-r--r-- | updatemap.c | 57 | ||||
| -rw-r--r-- | updatemap.h | 62 |
9 files changed, 272 insertions, 99 deletions
| @@ -1,3 +1,37 @@ | |||
| 1 | 2018-07-17 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 2 | |||
| 3 | * update_map.c: File created | ||
| 4 | (update_map): Function moved from update_map.h | ||
| 5 | Fixed error with height | ||
| 6 | Use strcpy instead of memcpy | ||
| 7 | |||
| 8 | * update_map.h: Added #define guard | ||
| 9 | |||
| 10 | * menus.h: File added | ||
| 11 | |||
| 12 | * menus.c: File added | ||
| 13 | (print_copying_warranty): Print out warranty (part 15) to any window. | ||
| 14 | |||
| 15 | * life.h: Don't need unistd.h | ||
| 16 | Include menus.h | ||
| 17 | |||
| 18 | * life.c: Change uppercase characters to lowercase | ||
| 19 | Added stars on multiline boilerplate | ||
| 20 | Added windows for the stat bar and entry line | ||
| 21 | Get winsize from COLS and LINES instead of getmaxyx macro | ||
| 22 | Normal timeout variable added | ||
| 23 | TRUE and FALSE definitions removed | ||
| 24 | Added macro to pretty-print text onto status bar | ||
| 25 | Added macro to run function on list of items | ||
| 26 | Don't need to duplicate things that run when running is TRUE and when it's FALSE, ie ',' and '.' tests | ||
| 27 | Added runtime RULE change | ||
| 28 | Added help key | ||
| 29 | Added Warranty print key | ||
| 30 | Game is printed onto board WINDOW, not main screen | ||
| 31 | (read_num): Read a number from (usually) entry WINDOW | ||
| 32 | |||
| 33 | * Makefile.am: Added new sources and new headers | ||
| 34 | |||
| 1 | 2018-02-25 Aiden Woodruff <aiden.woodruff@gmail.com> | 35 | 2018-02-25 Aiden Woodruff <aiden.woodruff@gmail.com> |
| 2 | 36 | ||
| 3 | * README.md: File created. | 37 | * README.md: File created. |
diff --git a/Makefile.am b/Makefile.am index 1c79fa7..6f21a9e 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | AM_OPTIONS = gnu | 1 | AM_OPTIONS = gnu |
| 2 | bin_PROGRAMS = life | 2 | bin_PROGRAMS = life |
| 3 | life_SOURCES = life.c cmdline-life.c | 3 | life_SOURCES = life.c cmdline-life.c updatemap.c menus.c |
| 4 | life_CFLAGS = -I$(srcdir) | 4 | life_CFLAGS = -I$(srcdir) |
| 5 | include_HEADERS = life.h updatemap.h cmdline-life.h | 5 | include_HEADERS = life.h updatemap.h menus.h cmdline-life.h |
diff --git a/Makefile.in b/Makefile.in index a689ab4..ad31e4a 100644 --- a/Makefile.in +++ b/Makefile.in | |||
| @@ -103,7 +103,8 @@ CONFIG_CLEAN_FILES = | |||
| 103 | CONFIG_CLEAN_VPATH_FILES = | 103 | CONFIG_CLEAN_VPATH_FILES = |
| 104 | am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)" | 104 | am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)" |
| 105 | PROGRAMS = $(bin_PROGRAMS) | 105 | PROGRAMS = $(bin_PROGRAMS) |
| 106 | am_life_OBJECTS = life-life.$(OBJEXT) life-cmdline-life.$(OBJEXT) | 106 | am_life_OBJECTS = life-life.$(OBJEXT) life-cmdline-life.$(OBJEXT) \ |
| 107 | life-updatemap.$(OBJEXT) life-menus.$(OBJEXT) | ||
| 107 | life_OBJECTS = $(am_life_OBJECTS) | 108 | life_OBJECTS = $(am_life_OBJECTS) |
| 108 | life_LDADD = $(LDADD) | 109 | life_LDADD = $(LDADD) |
| 109 | life_LINK = $(CCLD) $(life_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ | 110 | life_LINK = $(CCLD) $(life_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ |
| @@ -306,9 +307,9 @@ top_build_prefix = @top_build_prefix@ | |||
| 306 | top_builddir = @top_builddir@ | 307 | top_builddir = @top_builddir@ |
| 307 | top_srcdir = @top_srcdir@ | 308 | top_srcdir = @top_srcdir@ |
| 308 | AM_OPTIONS = gnu | 309 | AM_OPTIONS = gnu |
| 309 | life_SOURCES = life.c cmdline-life.c | 310 | life_SOURCES = life.c cmdline-life.c updatemap.c menus.c |
| 310 | life_CFLAGS = -I$(srcdir) | 311 | life_CFLAGS = -I$(srcdir) |
| 311 | include_HEADERS = life.h updatemap.h cmdline-life.h | 312 | include_HEADERS = life.h updatemap.h menus.h cmdline-life.h |
| 312 | all: config.h | 313 | all: config.h |
| 313 | $(MAKE) $(AM_MAKEFLAGS) all-am | 314 | $(MAKE) $(AM_MAKEFLAGS) all-am |
| 314 | 315 | ||
| @@ -417,6 +418,8 @@ distclean-compile: | |||
| 417 | 418 | ||
| 418 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/life-cmdline-life.Po@am__quote@ | 419 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/life-cmdline-life.Po@am__quote@ |
| 419 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/life-life.Po@am__quote@ | 420 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/life-life.Po@am__quote@ |
| 421 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/life-menus.Po@am__quote@ | ||
| 422 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/life-updatemap.Po@am__quote@ | ||
| 420 | 423 | ||
| 421 | .c.o: | 424 | .c.o: |
| 422 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | 425 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
| @@ -459,6 +462,34 @@ life-cmdline-life.obj: cmdline-life.c | |||
| 459 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmdline-life.c' object='life-cmdline-life.obj' libtool=no @AMDEPBACKSLASH@ | 462 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmdline-life.c' object='life-cmdline-life.obj' libtool=no @AMDEPBACKSLASH@ |
| 460 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | 463 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
| 461 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -c -o life-cmdline-life.obj `if test -f 'cmdline-life.c'; then $(CYGPATH_W) 'cmdline-life.c'; else $(CYGPATH_W) '$(srcdir)/cmdline-life.c'; fi` | 464 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -c -o life-cmdline-life.obj `if test -f 'cmdline-life.c'; then $(CYGPATH_W) 'cmdline-life.c'; else $(CYGPATH_W) '$(srcdir)/cmdline-life.c'; fi` |
| 465 | |||
| 466 | life-updatemap.o: updatemap.c | ||
| 467 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -MT life-updatemap.o -MD -MP -MF $(DEPDIR)/life-updatemap.Tpo -c -o life-updatemap.o `test -f 'updatemap.c' || echo '$(srcdir)/'`updatemap.c | ||
| 468 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/life-updatemap.Tpo $(DEPDIR)/life-updatemap.Po | ||
| 469 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='updatemap.c' object='life-updatemap.o' libtool=no @AMDEPBACKSLASH@ | ||
| 470 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
| 471 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -c -o life-updatemap.o `test -f 'updatemap.c' || echo '$(srcdir)/'`updatemap.c | ||
| 472 | |||
| 473 | life-updatemap.obj: updatemap.c | ||
| 474 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -MT life-updatemap.obj -MD -MP -MF $(DEPDIR)/life-updatemap.Tpo -c -o life-updatemap.obj `if test -f 'updatemap.c'; then $(CYGPATH_W) 'updatemap.c'; else $(CYGPATH_W) '$(srcdir)/updatemap.c'; fi` | ||
| 475 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/life-updatemap.Tpo $(DEPDIR)/life-updatemap.Po | ||
| 476 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='updatemap.c' object='life-updatemap.obj' libtool=no @AMDEPBACKSLASH@ | ||
| 477 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
| 478 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -c -o life-updatemap.obj `if test -f 'updatemap.c'; then $(CYGPATH_W) 'updatemap.c'; else $(CYGPATH_W) '$(srcdir)/updatemap.c'; fi` | ||
| 479 | |||
| 480 | life-menus.o: menus.c | ||
| 481 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -MT life-menus.o -MD -MP -MF $(DEPDIR)/life-menus.Tpo -c -o life-menus.o `test -f 'menus.c' || echo '$(srcdir)/'`menus.c | ||
| 482 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/life-menus.Tpo $(DEPDIR)/life-menus.Po | ||
| 483 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='menus.c' object='life-menus.o' libtool=no @AMDEPBACKSLASH@ | ||
| 484 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
| 485 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -c -o life-menus.o `test -f 'menus.c' || echo '$(srcdir)/'`menus.c | ||
| 486 | |||
| 487 | life-menus.obj: menus.c | ||
| 488 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -MT life-menus.obj -MD -MP -MF $(DEPDIR)/life-menus.Tpo -c -o life-menus.obj `if test -f 'menus.c'; then $(CYGPATH_W) 'menus.c'; else $(CYGPATH_W) '$(srcdir)/menus.c'; fi` | ||
| 489 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/life-menus.Tpo $(DEPDIR)/life-menus.Po | ||
| 490 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='menus.c' object='life-menus.obj' libtool=no @AMDEPBACKSLASH@ | ||
| 491 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
| 492 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(life_CFLAGS) $(CFLAGS) -c -o life-menus.obj `if test -f 'menus.c'; then $(CYGPATH_W) 'menus.c'; else $(CYGPATH_W) '$(srcdir)/menus.c'; fi` | ||
| 462 | install-includeHEADERS: $(include_HEADERS) | 493 | install-includeHEADERS: $(include_HEADERS) |
| 463 | @$(NORMAL_INSTALL) | 494 | @$(NORMAL_INSTALL) |
| 464 | @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ | 495 | @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ |
| @@ -1,28 +1,58 @@ | |||
| 1 | /* | 1 | /* |
| 2 | An arbitrary cellular automata model using ncurses | ||
| 3 | Copyright (C) 2018 Aiden Woodruff | ||
| 4 | 2 | ||
| 5 | This program is free software: you can redistribute it and/or modify | 3 | * An arbitrary cellular automata model using ncurses |
| 6 | it under the terms of the GNU General Public License as published by | 4 | * Copyright (C) 2018 Aiden Woodruff |
| 7 | the Free Software Foundation, either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | 5 | ||
| 10 | This program is distributed in the hope that it will be useful, | 6 | * This program is free software: you can redistribute it and/or modify |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 7 | * it under the terms of the GNU General Public License as published by |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 8 | * the Free Software Foundation, either version 3 of the License, or |
| 13 | GNU General Public License for more details. | 9 | * (at your option) any later version. |
| 14 | 10 | ||
| 15 | You should have received a copy of the GNU General Public License | 11 | * This program is distributed in the hope that it will be useful, |
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | */ | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. | ||
| 15 | |||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | |||
| 19 | */ | ||
| 18 | #include "life.h" | 20 | #include "life.h" |
| 19 | 21 | ||
| 20 | // Declare TRUE and FALSE | 22 | #ifndef stat_bar_print |
| 21 | #ifndef TRUE | 23 | // Print text to status bar in the nice way, without erasing or refreshing |
| 22 | #define TRUE (1==1) | 24 | #define stat_bar_print(win,fmt,...) \ |
| 23 | #define FALSE (!TRUE) | 25 | wstandout(win); \ |
| 26 | wprintw(win, fmt, ##__VA_ARGS__); \ | ||
| 27 | for (int _i = getcurx(win); _i < COLS; _i++) waddch(win, ' '); \ | ||
| 28 | wstandend(stat_bar); | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #ifndef foreach | ||
| 32 | #define foreach(func,count,first,...) \ | ||
| 33 | {typeof(first) things[] = {__VA_ARGS__}; \ | ||
| 34 | func(first); \ | ||
| 35 | for (int _i = 0; _i < count - 1; _i++) func(things[_i]);} | ||
| 24 | #endif | 36 | #endif |
| 25 | 37 | ||
| 38 | int read_num (WINDOW * win, int min, int max) { | ||
| 39 | int ret = 0; | ||
| 40 | werase(win); | ||
| 41 | char * text = (char*) malloc((size_t)(COLS + 1)); | ||
| 42 | memset(text, 0, (size_t)(COLS + 1)); | ||
| 43 | curs_set(1); | ||
| 44 | echo(); | ||
| 45 | wgetnstr(win, text, (size_t)(COLS + 1)); | ||
| 46 | ret = (int) strtol((const char *) text, NULL, 10); | ||
| 47 | if (!(ret >= min && ret <= max)) { | ||
| 48 | ret = 0; | ||
| 49 | } | ||
| 50 | noecho(); | ||
| 51 | curs_set(0); | ||
| 52 | free(text); | ||
| 53 | return ret; | ||
| 54 | } | ||
| 55 | |||
| 26 | int main (int argc, char * argv[]) { | 56 | int main (int argc, char * argv[]) { |
| 27 | unsigned int RULE = 0; | 57 | unsigned int RULE = 0; |
| 28 | struct gengetopt_args_info args_info; | 58 | struct gengetopt_args_info args_info; |
| @@ -35,6 +65,7 @@ int main (int argc, char * argv[]) { | |||
| 35 | RULE = args_info.ruleint_arg; | 65 | RULE = args_info.ruleint_arg; |
| 36 | srand(time(NULL)); | 66 | srand(time(NULL)); |
| 37 | int ch = 0; | 67 | int ch = 0; |
| 68 | int timeout_val = 50; | ||
| 38 | int width = 36; | 69 | int width = 36; |
| 39 | int height = 18; | 70 | int height = 18; |
| 40 | int playing = 0; | 71 | int playing = 0; |
| @@ -63,11 +94,13 @@ int main (int argc, char * argv[]) { | |||
| 63 | } | 94 | } |
| 64 | } | 95 | } |
| 65 | if (args_info.maximize_given) { | 96 | if (args_info.maximize_given) { |
| 66 | getmaxyx(stdscr, height, width); | 97 | width = COLS - 1; |
| 67 | width -= 1; | 98 | height = LINES - 2; |
| 68 | height -= 2; | ||
| 69 | } | 99 | } |
| 70 | cmdline_parser_free(&args_info); | 100 | cmdline_parser_free(&args_info); |
| 101 | WINDOW * board = newwin(height, width + 1, 0, 0); | ||
| 102 | WINDOW * stat_bar = newwin(1, 0, LINES - 2, 0); | ||
| 103 | WINDOW * entry = newwin(1, 0, LINES - 1, 0); | ||
| 71 | char * map = NULL; | 104 | char * map = NULL; |
| 72 | map = malloc((height * width)+1); | 105 | map = malloc((height * width)+1); |
| 73 | memset(map, 0, height * width + 1); | 106 | memset(map, 0, height * width + 1); |
| @@ -76,7 +109,11 @@ int main (int argc, char * argv[]) { | |||
| 76 | int y = height/2; | 109 | int y = height/2; |
| 77 | while (ch != 'q') { | 110 | while (ch != 'q') { |
| 78 | erase(); | 111 | erase(); |
| 112 | werase(board); | ||
| 113 | werase(stat_bar); | ||
| 114 | werase(entry); | ||
| 79 | if (playing == FALSE) { | 115 | if (playing == FALSE) { |
| 116 | // Numpad and arrow directions | ||
| 80 | if (ch == KEY_UP) { | 117 | if (ch == KEY_UP) { |
| 81 | if (y > 0) y--; | 118 | if (y > 0) y--; |
| 82 | } else if (ch == KEY_DOWN) { | 119 | } else if (ch == KEY_DOWN) { |
| @@ -105,37 +142,81 @@ int main (int argc, char * argv[]) { | |||
| 105 | } | 142 | } |
| 106 | } else if (ch == '\n') { | 143 | } else if (ch == '\n') { |
| 107 | playing = TRUE; | 144 | playing = TRUE; |
| 108 | timeout(50); | 145 | timeout(timeout_val); |
| 109 | } else if (ch == 'c') { | 146 | } else if (ch == 'c') { |
| 110 | memset(map, deadcell, width*height); | 147 | memset(map, deadcell, width*height); |
| 111 | } else if (ch == ',') { | 148 | } else if (ch == 'r') { |
| 112 | delaymax -= (delaymax > 1 ? 1 : 0); | 149 | werase(stat_bar); |
| 113 | } else if (ch == '.') { | 150 | stat_bar_print(stat_bar, "Rule int - Current: %d - Default: 6152 - Max: 262143", RULE); |
| 114 | delaymax += (delaymax < 20 ? 1 : 0); | 151 | wrefresh(stat_bar); |
| 152 | { | ||
| 153 | int old_rule = RULE; | ||
| 154 | RULE = read_num(entry, 0, 262143); | ||
| 155 | if (RULE == 0) { | ||
| 156 | RULE = old_rule; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | werase(stat_bar); | ||
| 160 | werase(entry); | ||
| 161 | } else if (keyname(ch) == "^R") { | ||
| 162 | // Fancy rule selection | ||
| 163 | // TODO (aiden.woodruff@gmail.com) Write | ||
| 164 | } else if (ch == 'h') { | ||
| 165 | timeout(-1); | ||
| 166 | erase(); | ||
| 167 | foreach(werase, 3, board, stat_bar, entry); | ||
| 168 | stat_bar_print(stat_bar, "Press any key to return"); | ||
| 169 | printw("Arrow keys - Motion\n"); | ||
| 170 | printw("Space - Flip cell (if it's alive, to dead, and vice versa)\n"); | ||
| 171 | printw("Enter - Pause/Play\n"); | ||
| 172 | printw("\tN.B. - Many keys can only be used while paused.\n"); | ||
| 173 | printw(", - Lower delay time\n"); | ||
| 174 | printw(". - Increase delay time\n"); | ||
| 175 | printw("R - Input a rule-int\n"); | ||
| 176 | // TODO printw("Ctrl+R - Open the fancy rule menu\n"); | ||
| 177 | printw("W - Show warranty\n"); | ||
| 178 | printw("V - Print version\n"); | ||
| 179 | foreach(wnoutrefresh, 3, stdscr, entry, stat_bar); | ||
| 180 | doupdate(); | ||
| 181 | getch(); | ||
| 182 | timeout(timeout_val); | ||
| 183 | } else if (ch == 'w') { | ||
| 184 | timeout(-1); | ||
| 185 | foreach(werase, 4, stdscr, board, stat_bar, entry); | ||
| 186 | stat_bar_print(stat_bar, "Press any key to return"); | ||
| 187 | print_copying_warranty(stdscr); | ||
| 188 | foreach(wnoutrefresh, 3, stdscr, entry, stat_bar); | ||
| 189 | doupdate(); | ||
| 190 | getch(); | ||
| 191 | timeout(timeout_val); | ||
| 115 | } | 192 | } |
| 116 | } else { | 193 | } else { // ie PLAYING == TRUE |
| 117 | if (ch == '\n') { | 194 | if (ch == '\n') { |
| 118 | playing = FALSE; | 195 | playing = FALSE; |
| 119 | timeout(-1); | 196 | timeout(-1); |
| 120 | } else if (ch == ',') { | ||
| 121 | delaymax -= (delaymax > 1 ? 1 : 0); | ||
| 122 | } else if (ch == '.') { | ||
| 123 | delaymax += (delaymax < 20 ? 1 : 0); | ||
| 124 | } | 197 | } |
| 125 | } | 198 | } |
| 199 | |||
| 200 | // Commands that don't depend on state | ||
| 201 | if (ch == ',') { | ||
| 202 | delaymax -= (delaymax > 1 ? 1 : 0); | ||
| 203 | } else if (ch == '.') { | ||
| 204 | delaymax += (delaymax < 20 ? 1 : 0); | ||
| 205 | } | ||
| 126 | for (int i = 0; i < height; ++i) { | 206 | for (int i = 0; i < height; ++i) { |
| 127 | if (i == y) { | 207 | if (i == y) { |
| 128 | printw("%.*s", x, map + (y * width)); | 208 | wprintw(board, "%.*s", x, map + (y * width)); |
| 129 | standout(); | 209 | wstandout(board); |
| 130 | printw("%.1s", map + (y * width) + x); | 210 | wprintw(board, "%.1s", map + (y * width) + x); |
| 131 | standend(); | 211 | wstandend(board); |
| 132 | printw("%.*s\n", width-(x+1), (map + (i * width) + x + 1)); | 212 | wprintw(board, "%.*s\n", width-(x+1), (map + (i * width) + x + 1)); |
| 133 | } else { | 213 | } else { |
| 134 | printw("%.*s\n", width, (map + (i * width))); | 214 | wprintw(board, "%.*s\n", width, (map + (i * width))); |
| 135 | } | 215 | } |
| 136 | } | 216 | } |
| 137 | printw("(%d, %d)\t\tGeneration: %d\t\tDelay Time: %d\n", x, y, generation, delaymax); | 217 | stat_bar_print(stat_bar, "(%d, %d)\t\tGeneration: %d\t\tDelay Time: %d\n", x, y, generation, delaymax); |
| 138 | refresh(); | 218 | foreach(wnoutrefresh, 4, stdscr, board, entry, stat_bar); |
| 219 | doupdate(); | ||
| 139 | if (playing == TRUE) { | 220 | if (playing == TRUE) { |
| 140 | delay++; | 221 | delay++; |
| 141 | if (delay >= delaymax) { | 222 | if (delay >= delaymax) { |
| @@ -145,6 +226,9 @@ int main (int argc, char * argv[]) { | |||
| 145 | } | 226 | } |
| 146 | } | 227 | } |
| 147 | ch = getch(); | 228 | ch = getch(); |
| 229 | if (ch <= 'Z' && ch >= 'A') { | ||
| 230 | ch -= ('A' - 'a'); | ||
| 231 | } | ||
| 148 | } | 232 | } |
| 149 | endwin(); | 233 | endwin(); |
| 150 | free(map); | 234 | free(map); |
| @@ -3,7 +3,6 @@ | |||
| 3 | #include <string.h> | 3 | #include <string.h> |
| 4 | #include <stdio.h> | 4 | #include <stdio.h> |
| 5 | #include <time.h> | 5 | #include <time.h> |
| 6 | #include <unistd.h> | ||
| 7 | 6 | ||
| 8 | // Module Libraries | 7 | // Module Libraries |
| 9 | #include <ncurses.h> | 8 | #include <ncurses.h> |
| @@ -11,3 +10,4 @@ | |||
| 11 | // Project Libraries | 10 | // Project Libraries |
| 12 | #include "cmdline-life.h" | 11 | #include "cmdline-life.h" |
| 13 | #include "updatemap.h" | 12 | #include "updatemap.h" |
| 13 | #include "menus.h" | ||
| @@ -0,0 +1,7 @@ | |||
| 1 | #include "menus.h" | ||
| 2 | |||
| 3 | int 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."; | ||
| 6 | return wprintw(win, WARRANTY); | ||
| 7 | } | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include <ncurses.h> | ||
| 2 | |||
| 3 | #ifndef LIFE_MENUS_H_ | ||
| 4 | #define LIFE_MENUS_H_ | ||
| 5 | |||
| 6 | int print_copying_warranty (WINDOW * win); | ||
| 7 | |||
| 8 | #endif // LIFE_MENUS_H_ | ||
diff --git a/updatemap.c b/updatemap.c new file mode 100644 index 0000000..d33b05a --- /dev/null +++ b/updatemap.c | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | #include "updatemap.h" | ||
| 2 | |||
| 3 | char * 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); | ||
| 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 | x = i % width; | ||
| 10 | y = (i - x)/width; | ||
| 11 | /* | ||
| 12 | Where i is the current cell: | ||
| 13 | A1 | A2 | A3 | ||
| 14 | ----|----|---- | ||
| 15 | B1 | i | B3 | ||
| 16 | ----|----|---- | ||
| 17 | C1 | C2 | C3 | ||
| 18 | */ | ||
| 19 | if (x > 0) { | ||
| 20 | if (base_map[i-1] == livecell) surround++; // B1 | ||
| 21 | if (y > 0) { | ||
| 22 | if (base_map[i-width-1] == livecell) surround++; // A1 | ||
| 23 | } | ||
| 24 | if (y < height - 1) { | ||
| 25 | if (base_map[i-1+width] == livecell) surround++; // C1 | ||
| 26 | } | ||
| 27 | } | ||
| 28 | if (x < width - 1) { | ||
| 29 | if (base_map[i+1] == livecell) surround++; // B3 | ||
| 30 | if (y > 0) { | ||
| 31 | if (base_map[i+1-width] == livecell) surround++; // A3 | ||
| 32 | } | ||
| 33 | if (y < height - 1) { | ||
| 34 | if (base_map[i+1+width] == livecell) surround++; // C3 | ||
| 35 | } | ||
| 36 | } | ||
| 37 | if (y > 0) { | ||
| 38 | if (base_map[i-width] == livecell) surround++; | ||
| 39 | } | ||
| 40 | if (y < height - 1) { | ||
| 41 | if (base_map[i+width] == livecell) surround++; | ||
| 42 | } | ||
| 43 | if (base_map[i] == deadcell) { | ||
| 44 | if ((ruleint & (1 << surround)) == (1 << surround)) { | ||
| 45 | intermap[i] = livecell; | ||
| 46 | } | ||
| 47 | } else if (base_map[i] == livecell) { | ||
| 48 | if ((ruleint & (1 << (surround + 9))) != (1 << (surround + 9))) { | ||
| 49 | intermap[i] = deadcell; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | } | ||
| 53 | // Rewrite map | ||
| 54 | strcpy(base_map, intermap); | ||
| 55 | free(intermap); | ||
| 56 | return base_map; | ||
| 57 | } | ||
diff --git a/updatemap.h b/updatemap.h index 366213b..5c5bb8d 100644 --- a/updatemap.h +++ b/updatemap.h | |||
| @@ -1,56 +1,8 @@ | |||
| 1 | #include <stdlib.h> | 1 | #include <string.h> |
| 2 | 2 | ||
| 3 | char * update_map (char * base_map, const int width, const int height, char livecell, char deadcell, const unsigned int ruleint) { | 3 | #ifndef LIFE_UPDATEMAP_H_ |
| 4 | char * intermap = malloc((width * height)+1); | 4 | #define LIFE_UPDATEMAP_H_ |
| 5 | memcpy(intermap, base_map, (width*height)+1); | 5 | |
| 6 | // Change intermap and stuff | 6 | char * update_map (char * base_map, const int width, const int height, char livecell, char deadcell, const unsigned int ruleint); |
| 7 | for (int i = 0, x = 0, y = 0, surround = 0; i < width*height; i++, surround = 0) { | 7 | |
| 8 | x = i % width; | 8 | #endif // LIFE_UPDATEMAP_H_ |
| 9 | y = (i - x)/width; | ||
| 10 | /* | ||
| 11 | Where i is the current cell: | ||
| 12 | A1 | A2 | A3 | ||
| 13 | ----|----|---- | ||
| 14 | B1 | i | B3 | ||
| 15 | ----|----|---- | ||
| 16 | C1 | C2 | C3 | ||
| 17 | */ | ||
| 18 | if (x > 0) { | ||
| 19 | if (base_map[i-1] == livecell) surround++; // B1 | ||
| 20 | if (y > 0) { | ||
| 21 | if (base_map[i-width-1] == livecell) surround++; // A1 | ||
| 22 | } | ||
| 23 | if (y < height) { | ||
| 24 | if (base_map[i-1+width] == livecell) surround++; // C1 | ||
| 25 | } | ||
| 26 | } | ||
| 27 | if (x < width - 1) { | ||
| 28 | if (base_map[i+1] == livecell) surround++; // B3 | ||
| 29 | if (y > 0) { | ||
| 30 | if (base_map[i+1-width] == livecell) surround++; // A3 | ||
| 31 | } | ||
| 32 | if (y < height) { | ||
| 33 | if (base_map[i+1+width] == livecell) surround++; // C3 | ||
| 34 | } | ||
| 35 | } | ||
| 36 | if (y > 0) { | ||
| 37 | if (base_map[i-width] == livecell) surround++; | ||
| 38 | } | ||
| 39 | if (y < height) { | ||
| 40 | if (base_map[i+width] == livecell) surround++; | ||
| 41 | } | ||
| 42 | if (base_map[i] == deadcell) { | ||
| 43 | if ((ruleint & (1 << surround)) == (1 << surround)) { | ||
| 44 | intermap[i] = livecell; | ||
| 45 | } | ||
| 46 | } else if (base_map[i] == livecell) { | ||
| 47 | if ((ruleint & (1 << (surround + 9))) != (1 << (surround + 9))) { | ||
| 48 | intermap[i] = deadcell; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
| 52 | // Rewrite map | ||
| 53 | memcpy(base_map, intermap, (width*height)+1); | ||
| 54 | free(intermap); | ||
| 55 | return base_map; | ||
| 56 | } | ||
