summaryrefslogtreecommitdiff
path: root/ui.cpp
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2019-02-13 23:32:08 +0100
committerTom Smeding <tom.smeding@gmail.com>2019-02-13 23:32:08 +0100
commitbc598375da7b9a20a35e958afb61dcd690d3d7b7 (patch)
tree764398251e30ae68920e53aa256d7e30b4cf55a0 /ui.cpp
parent6175cb1c53772cc92d91a39a254c38bdf8f64905 (diff)
Play interactively against AI
Diffstat (limited to 'ui.cpp')
-rw-r--r--ui.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/ui.cpp b/ui.cpp
new file mode 100644
index 0000000..82b9158
--- /dev/null
+++ b/ui.cpp
@@ -0,0 +1,109 @@
+#include <sstream>
+#include <vector>
+#include "ui.h"
+#include "termio/termio.h"
+
+using namespace std;
+
+
+static void cursorMove(int dx, int dy) {
+ if (dx < 0) cout << "\x1B[" << -dx << "D";
+ if (dx > 0) cout << "\x1B[" << dx << "C";
+ if (dy < 0) cout << "\x1B[" << -dy << "A";
+ if (dy > 0) cout << "\x1B[" << dy << "B";
+ cout << flush;
+}
+
+int UI::getMove(const Board &bd) {
+ Bounds bounds = bd.computeBounds();
+ const int l = bounds.left;
+ const int t = bounds.top;
+ const int w = bounds.right - bounds.left + 1;
+ const int h = bounds.bottom - bounds.top + 1;
+
+ const auto toIdx = [l, t](int x, int y) {
+ return BSZ * (t + y) + l + x;
+ };
+
+ // -1: edge, 0: open, 1...: stones
+ vector<vector<int>> cells(h);
+ for (int y = 0; y < h; y++) {
+ cells[y].resize(w);
+ for (int x = 0; x < w; x++) {
+ int idx = toIdx(x, y);
+ cells[y][x] = bd[idx];
+ if (cells[y][x] == 0 && bd.checkEdge(idx)) {
+ cells[y][x] = -1;
+ }
+ }
+ }
+
+ for (int y = 0; y < h; y++) {
+ if (y != 0) cout << endl;
+ for (int x = 0; x < w; x++) {
+ if (x != 0) cout << ' ';
+ if (cells[y][x] == -1) cout << EDGE_STR;
+ else if (cells[y][x] == 0) cout << OPEN_STR;
+ else cout << Stone(cells[y][x]);
+ }
+ }
+
+ cout << flush;
+
+ cursorMove(-2 * w - 1, -h + 1);
+ int curx = 0, cury = 0;
+ const auto cursorXY = [&curx, &cury](int x, int y) {
+ cursorMove(2 * (x - curx), y - cury);
+ curx = x; cury = y;
+ };
+ const auto cursorDXDY = [w, h, &curx, &cury, &cursorXY](int dx, int dy) {
+ int newx = curx + dx, newy = cury + dy;
+ newx = max(0, min(w - 1, newx));
+ newy = max(0, min(h - 1, newy));
+ cursorXY(newx, newy);
+ };
+
+ bool quit = false;
+
+ initkeyboard(false);
+
+ while (true) {
+ int key = tgetkey();
+ bool done = false;
+ switch (key) {
+ case KEY_LEFT: cursorDXDY(-1, 0); break;
+ case KEY_RIGHT: cursorDXDY(1, 0); break;
+ case KEY_UP: cursorDXDY(0, -1); break;
+ case KEY_DOWN: cursorDXDY(0, 1); break;
+
+ case KEY_LF:
+ case KEY_CR:
+ if (cells[cury][curx] == -1) done = true;
+ else bel();
+ break;
+
+ case 'q':
+ quit = true;
+ done = true;
+ break;
+
+ default:
+ bel();
+ break;
+ }
+ if (done) break;
+ }
+
+ endkeyboard();
+
+ int retidx = toIdx(curx, cury);
+
+ cursorXY(0, h - 1);
+ cout << endl << endl;
+
+ if (quit) {
+ exit(0);
+ }
+
+ return retidx;
+}