aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-06-27 16:23:31 +0200
committerCharles <sircharlesaze@gmail.com>2020-06-27 16:23:31 +0200
commitb9c8bbac74bb828eeae033a54c1f25d1711cf66a (patch)
tree4483b62c30c9f9be46a9c1f699c4c6076f69a8e7
parente2c1a8b40787516b9f8f3697a73ac406eae05e6f (diff)
downloadhanoi-b9c8bbac74bb828eeae033a54c1f25d1711cf66a.tar.gz
hanoi-b9c8bbac74bb828eeae033a54c1f25d1711cf66a.tar.bz2
hanoi-b9c8bbac74bb828eeae033a54c1f25d1711cf66a.zip
Added tower display
-rw-r--r--inc/hanoi.h2
-rw-r--r--inc/tower.h35
-rw-r--r--src/main.c70
-rw-r--r--src/tower.c56
4 files changed, 161 insertions, 2 deletions
diff --git a/inc/hanoi.h b/inc/hanoi.h
index 7f93e21..6d71f11 100644
--- a/inc/hanoi.h
+++ b/inc/hanoi.h
@@ -3,4 +3,6 @@
# include <ncurses.h>
+# include "tower.h"
+
#endif
diff --git a/inc/tower.h b/inc/tower.h
new file mode 100644
index 0000000..88876f8
--- /dev/null
+++ b/inc/tower.h
@@ -0,0 +1,35 @@
+/* ************************************************************************** */
+/* */
+/* . */
+/* tower.h / \ */
+/* / \ */
+/* By: charles <charles.cabergs@gmail.com> /o o \ */
+/* / v \ */
+/* Created: 2020/06/27 14:06:50 by charles / _ \ */
+/* Updated: 2020/06/27 16:19:32 by charles '-----------' */
+/* */
+/* ************************************************************************** */
+
+#ifndef TOWER_H
+# define TOWER_H
+
+# include <stdlib.h>
+# include <stdint.h>
+# include <stddef.h>
+# include <string.h>
+
+# include <ncurses.h>
+
+# define MAX_HEIGHT 128
+
+typedef struct
+{
+ uint8_t data[MAX_HEIGHT];
+ size_t len;
+} t_tower;
+
+void towers_init(t_tower towers[3], size_t disk_num);
+void towers_move(t_tower towers[3], size_t from, size_t to);
+void tower_put(t_tower *tower, WINDOW *win, int highlight_level);
+
+#endif
diff --git a/src/main.c b/src/main.c
index 465b5ca..57b8179 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,10 +3,76 @@
int main()
{
initscr();
+ noecho();
+ cbreak();
- refresh();
- getch();
+ int width, height;
+ getmaxyx(stdscr, height, width);
+ (void)height;
+ int win_width = width / 3;
+
+ WINDOW *wins[3];
+ for (int i = 0; i < 3; i++)
+ {
+ refresh();
+ if ((wins[i] = newwin(0, win_width, 0, i * win_width)) == NULL)
+ abort();
+ box(wins[i], 0, 0);
+ /* wrefresh(wins[i]); */
+ }
+
+ t_tower towers[3];
+ towers_init(towers, 3);
+
+ int from_selection = 0;
+ int to_selection = 1;
+ bool mode_from = true;
+ bool running = true;
+ while (running)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ int highlight_level = 0;
+ if (i == from_selection)
+ highlight_level = 1;
+ tower_put(&towers[i], wins[i], highlight_level);
+ }
+
+ char c;
+ c = getch();
+
+ int selection = mode_from ? from_selection : to_selection;
+ switch (c)
+ {
+ case 'q':
+ running = false;
+ break;
+ case 'j':
+ selection--;
+ break;
+ case 'k':
+ selection++;
+ break;
+ case '\n':
+ if (mode_from)
+ from_selection = selection;
+ else
+ to_selection = selection;
+ if (!mode_from)
+ towers_move(towers, from_selection, to_selection);
+ mode_from = !mode_from;
+ break;
+ }
+ selection %= 3;
+ mvprintw(0, 0, "%d", selection);
+ refresh();
+ }
+
+ /* refresh(); */
+
+ for (int i = 0; i < 3; i++)
+ delwin(wins[3]);
endwin();
return 0;
}
diff --git a/src/tower.c b/src/tower.c
new file mode 100644
index 0000000..a92a201
--- /dev/null
+++ b/src/tower.c
@@ -0,0 +1,56 @@
+#include "tower.h"
+
+static uint8_t st_tower_pop(t_tower tower)
+{
+ if (tower.len == 0)
+ abort();
+ uint8_t top = tower.data[tower.len - 1];
+ tower.len--;
+ return top;
+}
+
+static void st_tower_push(t_tower tower, uint8_t top)
+{
+ if (tower.len == MAX_HEIGHT)
+ abort();
+ tower.data[tower.len] = top;
+ tower.len++;
+}
+
+void towers_init(t_tower towers[3], size_t disk_num)
+{
+ memset(towers[0].data, 0, sizeof(t_tower));
+ memset(towers[1].data, 0, sizeof(t_tower));
+ memset(towers[2].data, 0, sizeof(t_tower));
+ for (size_t i = 0; i < disk_num; i++)
+ towers[0].data[i] = disk_num - i;
+ towers[0].len = disk_num;
+ towers[1].len = 0;
+ towers[2].len = 0;
+}
+
+void towers_move(t_tower towers[3], size_t from, size_t to)
+{
+ if (from > 2 || to > 2)
+ abort();
+ st_tower_push(towers[to], st_tower_pop(towers[from]));
+}
+
+void tower_put(t_tower *tower, WINDOW *win, int highlight_level)
+{
+ int height, width;
+ getmaxyx(win, height, width);
+
+ if (highlight_level == 1)
+ wattron(win, A_BOLD);
+ mvwvline(win, 1, width / 2, '|', height - 2);
+
+ for (size_t i = 0; i < tower->len; i++)
+ {
+ int disk_width = tower->data[i] * 2 + 1;
+ mvwhline(win, height - i - 2, width / 2 - disk_width / 2, '#', disk_width);
+ }
+ if (highlight_level == 1)
+ wattroff(win, A_BOLD);
+ wrefresh(win);
+}