diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 123 | ||||
| -rw-r--r-- | src/solve.c | 16 | ||||
| -rw-r--r-- | src/tower.c | 2 |
3 files changed, 86 insertions, 55 deletions
@@ -2,15 +2,18 @@ int main(int argc, char **argv) { + bool solve_arg = false; t_tower towers[3]; size_t disk_num = 3; - if (argc == 2) - if (sscanf(argv[1], "%lu", &disk_num) != 1) + if (argc >= 2) + if (sscanf(argv[1], "%lu", &disk_num) != 1 || disk_num > MAX_HEIGHT - 1) { fprintf(stderr, "%s: error: `%s` is not a valid number of disk", argv[0], argv[1]); return (1); } towers_init(towers, disk_num); + if (argc == 3 && strcmp(argv[2], "-s") == 0) + solve_arg = true; initscr(); noecho(); @@ -32,69 +35,81 @@ int main(int argc, char **argv) abort(); } - enum e_mode mode = MODE_SELECT_FROM; - int from_selection = 0; - int current = 0; - bool running = true; - while (running) + + if (!solve_arg) { - for (int i = 0; i < 3; i++) + enum e_mode mode = MODE_SELECT_FROM; + int from_selection = 0; + int current = 0; + bool running = true; + while (running) { - enum e_highlight highlight = HIGHLIGHT_NONE; - if (mode == MODE_SELECT_TO && i == from_selection) - highlight |= HIGHLIGHT_FROM; - if (i == current) - highlight |= HIGHLIGHT_CURRENT; - tower_put(&towers[i], wins[i], highlight); - } - - int c; - c = getch(); + for (int i = 0; i < 3; i++) + { + enum e_highlight highlight = HIGHLIGHT_NONE; + if (mode == MODE_SELECT_TO && i == from_selection) + highlight |= HIGHLIGHT_FROM; + if (i == current) + highlight |= HIGHLIGHT_CURRENT; + tower_put(&towers[i], wins[i], highlight); + } - switch (c) - { - case 'q': - running = false; - break; - case 'j': - case KEY_LEFT: - current--; + if (towers[0].len == 0 && + towers[1].len == 0) break; - case 'k': - case KEY_RIGHT: - current++; - break; - case '\n': - if (mode == MODE_SELECT_FROM) - { - if (towers[current].len == 0) - mvprintw(0, 0, "Tower %d is empty"); - else + + int c; + c = getch(); + + switch (c) + { + case 'q': + running = false; + break; + case 'j': + case KEY_LEFT: + current--; + break; + case 'k': + case KEY_RIGHT: + current++; + break; + case '\n': + if (mode == MODE_SELECT_FROM) { - from_selection = current; - mode = MODE_SELECT_TO; + if (towers[current].len == 0) + mvprintw(0, 0, "Tower %d is empty"); + else + { + from_selection = current; + mode = MODE_SELECT_TO; + } } - } - else if (mode == MODE_SELECT_TO) - { - if (!towers[current].len == 0 && - tower_peek(&towers[current]) < tower_peek(&towers[from_selection])) + else if (mode == MODE_SELECT_TO) { - mvprintw(0, 0, "Top disk of %d is smaller than top disk of %d", - current, from_selection); + if (!towers[current].len == 0 && + tower_peek(&towers[current]) < tower_peek(&towers[from_selection])) + { + mvprintw(0, 0, "Top disk of %d is smaller than top disk of %d", + current, from_selection); + } + else + towers_move(towers, from_selection, current); + mode = MODE_SELECT_FROM; } - else - towers_move(towers, from_selection, current); - mode = MODE_SELECT_FROM; - } - break; + break; + } + if (current < 0) + current = 2; + else if (current > 2) + current = 0; } - if (current < 0) - current = 2; - else if (current > 2) - current = 0; } + else + solve(towers, wins, disk_num, 0, 1, 2); + mvaddstr(0, 0, "FINISHED: press any key to quit"); + getch(); for (int i = 0; i < 3; i++) delwin(wins[3]); endwin(); diff --git a/src/solve.c b/src/solve.c new file mode 100644 index 0000000..d020dfd --- /dev/null +++ b/src/solve.c @@ -0,0 +1,16 @@ +#include "hanoi.h" + +void solve(t_tower towers[3], WINDOW *wins[3], + int n, int from, int via, int to) +{ + if (n == 0) + return; + solve(towers, wins, n - 1, from, to, via); + towers_move(towers, from, to); + + for (int i = 0; i < 3; i++) + tower_put(&towers[i], wins[i], HIGHLIGHT_NONE); + usleep(1000); + + solve(towers, wins, n - 1, via, from, to); +} diff --git a/src/tower.c b/src/tower.c index b31eaf7..914c0fb 100644 --- a/src/tower.c +++ b/src/tower.c @@ -1,4 +1,4 @@ -#include "tower.h" +#include "hanoi.h" static uint8_t st_tower_pop(t_tower *tower) { |
