import deimos.ncurses; import std.string : toStringz; import core.stdc.locale; import std.format; import board; import spots; import std.stdio; void main() { setlocale(LC_CTYPE, ""); // ncurses locales are weird auto stdscr = initscr(); scope (exit) endwin(); cbreak(); // disables line buffering for input noecho(); // input doesn't display on-screen intrflush(stdscr, true); keypad(stdscr, true); // allows arrow keys to work scrollok(stdscr, true); // allows scrolling in up/down arrows nonl(); // "return" goes through input auto overlay = new OverlaySource(new RandomSource()); auto board = new Board(overlay); auto disp = new BoardDisplay(board, stdscr); disp.print(); int rocks = 0; disp.status = "0"; refresh(); outer: while (true) { auto c = getch(); switch (c) { case ',': case KEY_UP: disp.up(); break; case 'o': case KEY_DOWN: disp.down(); break; case 'e': case KEY_RIGHT: disp.right(); break; case 'a': case KEY_LEFT: disp.left(); break; case KEY_RESIZE: disp.getdims(); break; case ' ': if (overlay[disp.y, disp.x].isRock()) { overlay[disp.y, disp.x] = Spot(' '); rocks++; disp.status = format("%d", rocks); disp.print(); } else if (rocks > 0) { overlay[disp.y, disp.x] = Spot('*'); rocks--; disp.status = format("%d", rocks); disp.print(); } break; case 'q': break outer; case 's': auto filename = stdscr.readquery("Save:"); try { auto file = File(filename, "wb"); file.writefln!"%s %s"(disp.y, disp.x); file.writefln!"%d"(rocks); overlay.save(file); disp.print(); } catch (Exception e) { } break; case 'l': auto filename = stdscr.readquery("Load:"); try { import std.algorithm.iteration : splitter, map; import std.conv : to; import std.bigint; auto file = File(filename); auto coord = file.readln.splitter().map!(to!BigInt); disp.y = coord.front; coord.popFront; disp.x = coord.front; file.readf!"%d\n"(rocks); disp.status = format("%d", rocks); overlay.load(file); } catch (Exception e) { printw("exception!"); } disp.print(); break; default: continue; } } } string readquery(WINDOW* stdscr, string query) { import std.range : replicate; import std.conv : to; import std.array : appender; int height; int width; getmaxyx(stdscr, height, width); mvprintw(height, 0, toStringz(query ~ " ".replicate(width - query.length))); move(height, cast(int) query.length + 1); scrollok(stdscr, false); auto build = appender!(char[]); int p = cast(int) query.length + 1; while (auto ch = getch()) { if (ch == '\r' || ch == EOF) break; if (ch == '\b' || ch == KEY_BACKSPACE || ch == 127) { if (build[].length > 0) { p--; mvaddch(height, p, ' '); build.shrinkTo(build[].length - 1); move(height, p); } } else { build ~= cast(char) ch; addch(ch); p++; } } scrollok(stdscr, true); return cast(string) build[]; }