golImplementation of Conway's Game of Life writen in C |
git clone git://git.dimitrijedobrota.com/gol.git |
Log | Files | Refs | README | |
commit | 3db973191cc6ad64c2ddc07c303477c0c419c5f6 |
parent | f10581d443ba92b50564adbe45ad54eb2cdaba8d |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Tue, 31 May 2022 23:29:08 +0200 |
Display game hooks onto the new logic interface - Big performance improvement in game display - On-demand cursor and board redraw - Fix wrapping logic - Expand logic interface and reface existing one
Diffstat:M | include/display.h | | | ++++++----- |
M | include/logic.h | | | +++++++------ |
M | include/utils.h | | | ++++ |
M | src/display.c | | | ++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
M | src/logic.c | | | +++++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
M | src/main.c | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- |
6 files changed, 340 insertions(+), 202 deletions(-)
diff --git a/include/display.h b/include/display.h
@@ -1,7 +1,6 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include "logic.h"
#include "window.h"
extern window_T MAIN_w;
@@ -21,7 +20,6 @@ struct imenu_T {
};
extern int screen_offset_x, screen_offset_y;
extern int cursor_offset_x, cursor_offset_y;
int input(WINDOW *win, char *buffer, int size, input_f crit);
@@ -30,12 +28,15 @@ int display_stop(void);
void display_menu(window_T wind, char *name, struct menu_T *items, int size);
int display_imenu(window_T wind, struct imenu_T *items, int size);
void display_game(window_T wind, cell **mat, int h, int w, int ph, int pw);
void display_select(window_T wind, cell **mat, int w, int h);
void display_game(WINDOW *win, int h, int w, int ph, int pw, int redraw);
void display_select(window_T wind, int w, int h);
void display_status(window_T wind, unsigned long int generation, int gen_step,
int height, int wight, int play, int dt, int cursor_y,
int cursor_x);
int cursor_x, int expanded);
void display_cursor(WINDOW *win, int h, int w, int ph, int pw);
void handle_winch(int sig);
void display_state_set(int i, int j, int val);
#endif
diff --git a/include/logic.h b/include/logic.h
@@ -5,12 +5,13 @@ extern char *evolution_names[];
extern int evolution_cells[];
extern int evolution_size;
int logic_init(int w, int h, int isWrapping);
int evolution_init(int index);
int do_evolution(int steps);
int logic_free(void);
void toggleAt(int i, int j)
int logic_init(int w, int h, int isWrapping);
int evolution_init(int index);
int do_evolution(int steps);
int logic_free(void);
int toggleAt(int i, int j);
int getAt(int i, int j);
void deleteAt(int i, int j);
int getNext(int *row, int *col, int *value, int reset);
int getNext(int *row, int *col, int *value, int reset);
#endif
diff --git a/include/utils.h b/include/utils.h
@@ -22,4 +22,8 @@
handle_winch(10); \
}
#endif
#define MAX_SCREEN_H 512
#define MAX_SCREEN_W 1888
#endif
diff --git a/src/display.c b/src/display.c
@@ -12,13 +12,218 @@
#define center_horizontal(y, n) wcenter_horizontal(MAIN_W, y, n);
#define CHAR_BLANK " "
#define CHAR_CURSOR "<>"
#define CHAR_CIRCLE "\u26AB"
#define CHAR_SQUARE "\u2B1B"
#define CHAR_SQUARED "\u2B1C"
#define CHAR_CIRCLE_DOT "\u2299"
#define CHAR_ACTIVE CHAR_SQUARE
window_T MAIN_w = NULL;
#define y_at(y) (y + screen_offset_y + h) % h
#define x_at(x) (x + screen_offset_x + w) % w
#define for_each_cell(start_i, end_i, start_j, end_j) \
for (int i = start_i; i < end_i; i++) \
for (int j = start_j; j < end_j; j++)
#ifndef NO_UNICODE
#define print_cell(win, blank) \
if (val) \
waddstr(win, CHAR_ACTIVE); \
else \
waddstr(win, blank);
#else
#define print_cell(win, blank) waddstr(win, blank);
#endif
// expects val to to be set with value at cordinates
#define mvprint_cell(win, i, j, color_offset, blank) \
{ \
wmove(win, i + 1, j * 2 + 1); \
wattrset(win, COLOR_PAIR(val + color_offset)); \
print_cell(win, blank); \
}
#define print_cells(win, start_i, end_i, start_j, end_j, color_offset, blank) \
for (int i = start_i; i < end_i; i++) { \
wmove(win, i + 1, 1 + start_j * 2); \
for (int j = start_j; j < end_j; j++) { \
int val = getAt(y_at(i), x_at(j)); \
wattrset(win, COLOR_PAIR(val + color_offset)); \
print_cell(win, blank); \
} \
}
int screen_offset_x, screen_offset_y;
int cursor_offset_x, cursor_offset_y;
int get_screen_position(int value, int screen_offset, int screen_size,
int board_size) {
int overshoot = screen_offset + screen_size - board_size;
if (overshoot > 0) {
if (value < screen_offset && value > overshoot)
return -1;
if (value >= screen_offset) {
return value - screen_offset;
} else {
return value + screen_size - overshoot;
}
} else {
if (value < screen_offset || value > screen_offset + screen_size)
return -1;
return value - screen_offset;
}
}
void display_game(WINDOW *win, int h, int w, int ph, int pw, int redraw) {
werase(win);
wattrset(win, COLOR_PAIR(0));
box(win, ACS_VLINE, ACS_HLINE);
int row, col, val;
getNext(&row, &col, &val, 1);
while (getNext(&row, &col, &val, 0)) {
wattrset(win, COLOR_PAIR(val + 2));
if ((row = get_screen_position(row, screen_offset_y, ph, h)) == -1)
continue;
if ((col = get_screen_position(col, screen_offset_x, pw, w)) == -1)
continue;
mvprint_cell(win, row, col, 2, CHAR_BLANK);
}
wrefresh(win);
}
void display_cursor(WINDOW *win, int h, int w, int ph, int pw) {
static int prev_x = 0, prev_y = 0;
int val;
val = getAt(y_at(prev_y), x_at(prev_x));
mvprint_cell(win, prev_y, prev_x, 2, CHAR_BLANK);
val = getAt(y_at(cursor_offset_y), x_at(cursor_offset_x));
mvprint_cell(win, cursor_offset_y, cursor_offset_x, 5, CHAR_CURSOR);
wrefresh(win);
prev_y = cursor_offset_y;
prev_x = cursor_offset_x;
}
void display_select(window_T wind, int w, int h) {
int current_offset_y = cursor_offset_y;
int current_offset_x = cursor_offset_x;
redraw:;
int CLINES = LINES, CCOLS = COLS;
WINDOW *new = WINDOW_new(wind);
WINDOW *win = window_win(wind);
overlay(win, new);
wrefresh(new);
int ph = window_height(wind), pw = window_wight(wind) / 2;
nodelay(stdscr, 0);
while (TRUE) {
int start_i = MIN(cursor_offset_y, current_offset_y);
int end_i = MAX(cursor_offset_y, current_offset_y);
int start_j = MIN(cursor_offset_x, current_offset_x);
int end_j = MAX(cursor_offset_x, current_offset_x);
print_cells(new, start_i, end_i + 1, start_j, end_j + 1, 8, CHAR_BLANK);
wrefresh(new);
if (is_term_resized(CLINES, CCOLS)) {
flushinp();
delwin(new);
HANDLE_RESIZE;
ph = window_height(wind), pw = window_wight(wind) / 2;
display_game(win, w, h, ph, pw, 1);
goto redraw;
}
int c = getch();
switch (c) {
// offset selection
case 'w':
case 'W':
current_offset_y--;
break;
case 's':
case 'S':
current_offset_y++;
break;
case 'a':
case 'A':
current_offset_x--;
break;
case 'd':
case 'D':
current_offset_x++;
break;
// delete selection
case 'x':
case 'X':
for_each_cell(start_i, end_i + 1, start_j, end_j + 1)
deleteAt(y_at(i), x_at(j));
goto end;
// toggle selection
case 't':
case 'T':
for_each_cell(start_i, end_i + 1, start_j, end_j + 1)
toggleAt(y_at(i), x_at(j));
goto end;
// confirm and save slection
case '\n':
save_pattern();
goto end;
// quit
case 27:
case 'q':
case 'Q':
goto end;
defalut:
flushinp();
continue;
}
flushinp();
CLAMP(current_offset_y, 0, ph - 1);
CLAMP(current_offset_x, 0, pw - 1);
wclear(new);
overlay(win, new);
}
end:;
nodelay(stdscr, 1);
delwin(new);
return;
}
void display_status(window_T wind, unsigned long int gen, int gen_step,
int height, int wight, int play, int dt, int cursor_y,
int cursor_x, int expanded) {
WINDOW *win = window_win(wind);
wmove(win, 1, 1);
wprintw(win, " | %5s | ", play ? "play" : "pause");
wprintw(win, "Size: %dx%d | ", height, wight);
wprintw(win, "Generation: %10lu(+%d) | ", gen, gen_step);
wprintw(win, "dt: %4dms | ", dt);
wprintw(win, "Cursor: %4dx%-4d | ", cursor_y, cursor_x);
wprintw(win, "Expanded: %4d | ", expanded);
wrefresh(win);
}
int input(WINDOW *win, char *buffer, int size, input_f crit) {
int CLINES = LINES, CCOLS = COLS;
int ch, read = strlen(buffer);
@@ -167,135 +372,6 @@ redraw:;
}
}
#define y_at(y) (y + screen_offset_y + h) % h + 1
#define x_at(x) (x + screen_offset_x + w) % w + 1
#define at(y, x) mat[y_at(y)][x_at(x)]
#define at_offset(off) mat[y_at(off##_y)][x_at(off##_x)]
#ifndef NO_UNICODE
#define print_cell(win, k, l, blank) \
if (at(k, l)) \
waddstr(win, CHAR_CIRCLE); \
else \
waddstr(win, blank);
#else
#define print_cell(win, i, j, blank) waddstr(win, blank);
#endif
#define print_cells(win, start_i, end_i, start_j, end_j, color_offset, blank) \
for (int i = start_i; i < end_i; i++) { \
wmove(win, i + 1, 1 + start_j * 2); \
for (int j = start_j; j < end_j; j++) { \
wattrset(win, COLOR_PAIR((mat[y_at(i)][x_at(j)]) + color_offset)); \
print_cell(win, i, j, blank); \
} \
}
int screen_offset_x, screen_offset_y;
int cursor_offset_x, cursor_offset_y;
void display_game(window_T wind, cell **mat, int h, int w, int ph, int pw) {
WINDOW *win = window_win(wind);
#ifdef _WIN32
window_clear(wind);
#endif
print_cells(win, 0, ph, 0, pw, 2, CHAR_BLANK);
wmove(win, cursor_offset_y + 1, cursor_offset_x * 2 + 1);
wattrset(win, COLOR_PAIR(at_offset(cursor_offset) + 5));
print_cell(win, cursor_offset_y, cursor_offset_x, "<>");
wrefresh(win);
}
void display_select(window_T wind, cell **mat, int w, int h) {
int current_offset_y = cursor_offset_y;
int current_offset_x = cursor_offset_x;
redraw:;
int CLINES = LINES, CCOLS = COLS;
WINDOW *new = WINDOW_new(wind);
WINDOW *win = window_win(wind);
overlay(win, new);
wrefresh(new);
int ph = window_height(wind), pw = window_wight(wind) / 2;
nodelay(stdscr, 0);
while (TRUE) {
int start_i = MIN(cursor_offset_y, current_offset_y);
int end_i = MAX(cursor_offset_y, current_offset_y);
int start_j = MIN(cursor_offset_x, current_offset_x);
int end_j = MAX(cursor_offset_x, current_offset_x);
print_cells(new, start_i, end_i + 1, start_j, end_j + 1, 8, CHAR_BLANK);
wrefresh(new);
if (is_term_resized(CLINES, CCOLS)) {
flushinp();
delwin(new);
HANDLE_RESIZE;
ph = window_height(wind), pw = window_wight(wind) / 2;
display_game(wind, mat, w, h, ph, pw);
goto redraw;
}
int c = getch();
switch (c) {
// offset selection
case 'w':
case 'W':
current_offset_y--;
break;
case 's':
case 'S':
current_offset_y++;
break;
case 'a':
case 'A':
current_offset_x--;
break;
case 'd':
case 'D':
current_offset_x++;
break;
case '\n':
save_pattern();
// quit
case 27:
case 'q':
case 'Q':
nodelay(stdscr, 1);
delwin(new);
return;
defalut:
continue;
}
CLAMP(current_offset_y, 0, ph - 1);
CLAMP(current_offset_x, 0, pw - 1);
wclear(new);
overlay(win, new);
}
}
void display_status(window_T wind, unsigned long int gen, int gen_step,
int height, int wight, int play, int dt, int cursor_y,
int cursor_x) {
WINDOW *win = window_win(wind);
wmove(win, 1, 1);
wprintw(win, " | %5s | ", play ? "play" : "pause");
wprintw(win, "Size: %dx%d | ", height, wight);
wprintw(win, "Generation: %10lu(+%d) | ", gen, gen_step);
wprintw(win, "dt: %4dms | ", dt);
wprintw(win, "Cursor: %4dx%-4d | ", cursor_y, cursor_x);
wrefresh(win);
}
void curses_start(void) {
initscr();
window_settings(stdscr);
diff --git a/src/logic.c b/src/logic.c
@@ -20,11 +20,14 @@ int WIDTH, HEIGHT;
int cells_size;
int temp_size;
int counter;
int isExpanding;
char *evolution_names[] = {"Normal", "CoExsistance", "Predator", "Virus",
"Unknown"};
int evolution_cells[] = {2, 3, 3, 3, 3};
int evolution_size = 5;
int toggle_mod = 2;
static void (*evolve)(void);
static void (*addToCells)(int i, int j, int value);
@@ -78,28 +81,30 @@ void addToCellsWrap(int i, int j, int value) {
break;
}
for (int k = (i - 1 + HEIGHT) % HEIGHT; k <= (i + 1 + HEIGHT) % HEIGHT; k++) {
for (int l = (j - 1 + WIDTH) % WIDTH; l <= (j + 1 + WIDTH) % WIDTH; l++) {
for (int k = i - 1; k <= i + 1; k++) {
for (int l = j - 1; l <= j + 1; l++) {
int a = (k + HEIGHT) % HEIGHT;
int b = (l + WIDTH) % WIDTH;
for (int m = 0; m < temp_size; m++)
if (temp_cells[m].row == k && temp_cells[m].col == l) {
if (temp_cells[m].row == a && temp_cells[m].col == b) {
temp_cells[m].val += mod;
if (k == i && l == j) {
if (a == i && b == j) {
temp_cells[m].val -= mod;
temp_cells[m].val += value;
}
goto Kontinue;
}
if (k == i && l == j) {
if (a == i && b == j) {
temp_cells[temp_size].val = value;
temp_cells[temp_size].row = k;
temp_cells[temp_size].col = l;
temp_cells[temp_size].row = a;
temp_cells[temp_size].col = b;
temp_size++;
continue;
}
temp_cells[temp_size].val = mod;
temp_cells[temp_size].row = k;
temp_cells[temp_size].col = l;
temp_cells[temp_size].row = a;
temp_cells[temp_size].col = b;
temp_size++;
Kontinue:
continue;
@@ -302,6 +307,26 @@ static void (*evolution_modes[])() = {
static void (*addition_modes[])(int i, int j, int value) = {addToCellsNormal,
addToCellsWrap};
int shouldExpand(void) {
for (int i = 0; i < cells_size; i++) {
if (cells[i].row == 0 || cells[i].row == HEIGHT - 1 || cells[i].col == 0 ||
cells[i].col == WIDTH - 1) {
return 1;
}
}
return 0;
}
void expandMatrix(int size) {
WIDTH += 2 * size;
HEIGHT += 2 * size;
cells = realloc(cells, WIDTH * HEIGHT * sizeof(*cells));
for (int cellIndex = 0; cellIndex < cells_size; cellIndex++) {
cells[cellIndex].row += size;
cells[cellIndex].col += size;
}
}
int do_evolution(int steps) {
int times_resized = 0;
counter = 0;
@@ -310,8 +335,8 @@ int do_evolution(int steps) {
temp_size = 0;
temp_cells = calloc(temp_alloc, sizeof(*temp_cells));
if (!counter) {
if (shouldExpand()) {
expand_matrix(SIZE_TO_EXPAND);
if (isExpanding && shouldExpand()) {
expandMatrix(SIZE_TO_EXPAND);
times_resized++;
counter = SIZE_TO_EXPAND;
} else {
@@ -329,10 +354,9 @@ int do_evolution(int steps) {
int logic_init(int w, int h, int isWrapping) {
WIDTH = w;
HEIGHT = h;
addToCells = addition_modes[0];
if (isWrapping) {
addToCells = addition_modes[1];
}
addToCells = addition_modes[isWrapping];
isExpanding = !isWrapping;
cells = malloc(WIDTH * HEIGHT * sizeof(*cells));
return 1;
@@ -340,38 +364,19 @@ int logic_init(int w, int h, int isWrapping) {
int evolution_init(int index) {
evolve = evolution_modes[index];
toggle_mod = evolution_cells[index];
return 1;
}
int shouldExpand(void) {
for (int i = 0; i < cells_size; i++) {
if (cells[i].row == 0 || cells[i].row == HEIGHT - 1 || cells[i].col == 0 ||
cells[i].col == WIDTH - 1) {
return 1;
}
}
return 0;
}
void expand_matrix(int size) {
WIDTH += 2 * size;
HEIGHT += 2 * size;
cells = realloc(cells, WIDTH * HEIGHT * sizeof(*cells));
for (int cellIndex = 0; cellIndex < cells_size; cellIndex++) {
cells[cellIndex].row += size;
cells[cellIndex].col += size;
}
}
int logic_free(void) {
free(cells);
return 1;
}
void toggleAt(int i, int j) {
int toggleAt(int i, int j) {
for (int k = 0; k < cells_size; k++) {
if (cells[k].row == i && cells[k].col == j) {
cells[k].val = (cells[k].val + 1) % 3;
cells[k].val = (cells[k].val + 1) % toggle_mod;
if (cells[k].val == 0) {
for (int t = k + 1; t < cells_size; t++) {
cells[t - 1].val = cells[t].val;
@@ -379,14 +384,16 @@ void toggleAt(int i, int j) {
cells[t - 1].col = cells[t].col;
}
cells_size--;
return 0; // since the cell was deleted it's value is 0
}
return;
return cells[k].val; // only return value if it hasn't been deleted
}
}
cells[cells_size].val = 1;
cells[cells_size].row = i;
cells[cells_size].col = j;
cells_size++;
return 1;
}
void deleteAt(int i, int j) {
@@ -403,6 +410,13 @@ void deleteAt(int i, int j) {
}
}
int getAt(int i, int j) {
for (int k = 0; k < cells_size; k++)
if (cells[k].row == i && cells[k].col == j)
return cells[k].val;
return 0;
}
int getNext(int *row, int *col, int *value, int reset) {
static int index = 0;
if (reset) {
@@ -417,4 +431,5 @@ int getNext(int *row, int *col, int *value, int reset) {
*col = cells[index].col;
*value = cells[index].val;
index++;
}
\ No newline at end of file
return 1;
}
diff --git a/src/main.c b/src/main.c
@@ -21,7 +21,6 @@
#endif
extern window_T MAIN_w;
extern cell **mat;
extern char *evolution_names[];
extern int evolution_cells[];
extern int evolution_size;
@@ -32,15 +31,18 @@ int top_space = 5;
void load_pattern(void);
void save_pattern(void);
#define y_at(y) (y + screen_offset_y + h) % h + 1
#define x_at(x) (x + screen_offset_x + w) % w + 1
#define y_at(y) (y + screen_offset_y + h) % h
#define x_at(x) (x + screen_offset_x + w) % w
extern int screen_offset_x, screen_offset_y;
extern int cursor_offset_x, cursor_offset_y;
extern short int **mat;
void game(int h, int w, char *name, int ncells) {
unsigned long int gen = 0;
int gen_step = 1, play = 0, time_const = 100, time_step = 1;
int expanded;
window_T status_w, screen_w, game_w;
@@ -53,23 +55,56 @@ void game(int h, int w, char *name, int ncells) {
clock_t start_t, end_t = 0, total_t;
screen_offset_x = screen_offset_y = 0;
cursor_offset_y = window_height(game_w) / 2;
cursor_offset_x = window_wight(game_w) / 4;
redraw:;
int CLINES = LINES, CCOLS = COLS;
int ph = window_height(game_w), pw = window_wight(game_w) / 2;
int CLINES = LINES, CCOLS = COLS;
int ph = window_height(game_w), pw = window_wight(game_w) / 2;
WINDOW *game_W = window_win(game_w);
window_clear(menu_w);
window_clear(screen_w);
window_clear(status_w);
window_clear(game_w);
CLAMP(cursor_offset_y, 0, ph - 1);
CLAMP(cursor_offset_x, 0, pw - 1);
display_game(game_W, h, w, ph, pw, 1);
display_cursor(game_W, h, w, ph, pw);
int screen_change = 0;
int cursor_change = 0;
while (TRUE) {
start_t = clock();
display_status(status_w, gen, gen_step, h, w, play, time_const,
y_at(cursor_offset_y), x_at(cursor_offset_x));
display_game(game_w, mat, h, w, ph, pw);
if (play) {
do_evolution(gen_step);
expanded = do_evolution(gen_step);
screen_change = 1;
screen_offset_x += expanded;
screen_offset_y += expanded;
gen += gen_step;
}
display_status(status_w, gen, gen_step, h, w, play, time_const,
y_at(cursor_offset_y), x_at(cursor_offset_x), expanded);
if (play || screen_change) {
display_game(game_W, h, w, ph, pw, 0);
screen_change = 0;
cursor_change = 1;
}
if (cursor_change) {
display_cursor(game_W, h, w, ph, pw);
cursor_change = 0;
}
while ((total_t = (long int)(end_t - start_t)) < time_const * TIME_MOD) {
refresh();
int c = getch();
@@ -85,7 +120,9 @@ redraw:;
case 'l':
case 'L':
load_pattern();
window_set_title(screen_w, name);
window_set_title(menu_w, NULL);
goto redraw;
break;
@@ -119,37 +156,37 @@ redraw:;
case 'w':
case 'W':
cursor_offset_y--;
cursor_change = 1;
break;
case 's':
case 'S':
cursor_offset_y++;
cursor_change = 1;
break;
case 'a':
case 'A':
cursor_offset_x--;
cursor_change = 1;
break;
case 'd':
case 'D':
cursor_offset_x++;
cursor_change = 1;
break;
// toggle cell
case ' ':
mat[y_at(cursor_offset_y)][x_at(cursor_offset_x)] += 1;
mat[y_at(cursor_offset_y)][x_at(cursor_offset_x)] %= ncells;
toggleAt(y_at(cursor_offset_y), x_at(cursor_offset_x));
cursor_change = 1;
break;
// visual selection
case 'v':
case 'V':
display_select(game_w, mat, h, h);
display_select(game_w, h, h);
// clear up the screen afterwards
window_set_title(menu_w, NULL);
window_clear(menu_w);
window_clear(screen_w);
window_clear(status_w);
window_clear(game_w);
goto redraw;
break;
}
}
@@ -162,6 +199,7 @@ redraw:;
case KEY_HOME:
case KEY_LEFT:
screen_offset_x--;
screen_change = 1;
break;
case KEY_A3:
case KEY_C3:
@@ -169,6 +207,7 @@ redraw:;
case KEY_PPAGE:
case KEY_RIGHT:
screen_offset_x++;
screen_change = 1;
break;
}
@@ -179,6 +218,7 @@ redraw:;
case KEY_PPAGE:
case KEY_UP:
screen_offset_y--;
screen_change = 1;
break;
case KEY_C1:
case KEY_C3:
@@ -186,6 +226,7 @@ redraw:;
case KEY_END:
case KEY_NPAGE:
screen_offset_y++;
screen_change = 1;
}
screen_offset_x = (screen_offset_x + w) % w;
@@ -194,8 +235,8 @@ redraw:;
CLAMP(cursor_offset_y, 0, ph - 1);
CLAMP(cursor_offset_x, 0, pw - 1);
CLAMP(gen_step, 1, 10);
CLAMP(time_const, 1, 1000);
CLAMP(gen_step, 1, 100);
CLAMP(time_const, 0, 1000);
if (is_term_resized(CLINES, CCOLS)) {
flushinp();
@@ -210,8 +251,8 @@ redraw:;
void settings(char *pass, int index) {
struct imenu_T imenu_items[] = {
{ "Number of rows", 4, isdigit, NULL},
{"Number of columns", 4, isdigit, NULL},
{ "Number of rows", 6, isdigit, NULL},
{"Number of columns", 6, isdigit, NULL},
};
int imenu_items_s = sizeof(imenu_items) / sizeof(struct imenu_T);
@@ -223,7 +264,7 @@ void settings(char *pass, int index) {
if (!row || !column)
continue;
logic_init(column, row);
logic_init(column, row, 1);
evolution_init(index);
game(row, column, pass, evolution_cells[index]);