#include #include #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> 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) { cout << "\x1B[36m#\x1B[0m\x1B[D"; 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; }