aboutsummaryrefslogtreecommitdiffhomepage
path: root/2048_renamed.c
diff options
context:
space:
mode:
Diffstat (limited to '2048_renamed.c')
-rw-r--r--2048_renamed.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/2048_renamed.c b/2048_renamed.c
new file mode 100644
index 0000000..c4d0d53
--- /dev/null
+++ b/2048_renamed.c
@@ -0,0 +1,201 @@
+#include <ncurses.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#define s(_) waddstr(W, _)
+#define c(_) waddch(W, _)
+#define f(f, _) wprintw(W, f, _)
+#define n c('\n')
+
+#define r(_, n) for (int _ = 0; _ < n; ++_)
+
+#define t(_) (G + y * ((x + S) % (S + 1) + _ * x) + (S + 1 - y) * i)
+
+WINDOW *W;
+char *M = "\0";
+int S, R, C, N, E, *L, *T, F[128], *G = F;
+
+void _() {
+ c('+');
+ r(i, 8 * S - 1) {
+ c('-');
+ }
+ c('+');
+ n;
+}
+
+void l() {
+ c('|');
+ r(i, S) {
+ r(j, 8) {
+ c(32);
+ }
+ c('\b');
+ c('|');
+ }
+ n;
+}
+
+void g() {
+ _();
+ r(i, S) {
+ l();
+
+ s("| ");
+ r(j, S) {
+ if (!*G) {
+ s(" | ");
+ } else if (*G >= 1024) {
+ f(" %2dk | ", *G / 1024);
+ } else {
+ f("%4d | ", *G);
+ }
+ ++G;
+ }
+ n;
+
+ l();
+
+ if (i < S - 1) {
+ c('|');
+ r(j, S) {
+ r(j, 8) {
+ c('-');
+ }
+ c('\b');
+ if (j < S - 1) {
+ c('+');
+ }
+ }
+ c('|');
+ n;
+ }
+ }
+ _();
+ G -= S * S;
+}
+
+int m(int x, int y, int d) {
+ C = 0;
+ r(i, S) {
+ E = 0;
+ L = 0;
+ r(j, S) {
+ T = t(j);
+ if (*T) {
+ if (L && *T == *L) {
+ if (d) {
+ *L *= 2;
+ *T = 0;
+ }
+ L = 0;
+ C = 1;
+ } else {
+ L = t(E);
+ if (d) {
+ *L = *T;
+ }
+ ++E;
+ }
+ }
+ }
+ for (; E < S; ++E) {
+ T = t(E);
+ C |= *T;
+ if (d) {
+ *T = 0;
+ }
+ }
+ }
+ return !C;
+}
+
+void p() {
+ E = 0;
+ r(i, S * S) {
+ if (!G[i]) {
+ ++E;
+ }
+ }
+ if (E == 0) {
+ return;
+ }
+ N = rand() % E;
+ r(i, S * S) {
+ if (!G[i] && --E == N) {
+ G[i] = rand() % 8 ? 2 : 4;
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ srand(time(0));
+
+ initscr();
+ cbreak();
+ noecho();
+ curs_set(0);
+ getmaxyx(stdscr, R, C);
+
+ S = argc > 1 ? (*argv[1] - '0') : 4;
+ if (S <= 1 || S > 8) {
+ M = "\1Invalid size given.\n";
+ goto q;
+ }
+
+ W = newwin(0, 0, (R - 4 * S) / 2, (C - 8 * S) / 2);
+ if (!W) {
+ M = "\1Terminal too small.\n";
+ goto q;
+ }
+
+ p();
+ p();
+
+ while (1) {
+ wclear(W);
+ g();
+ s(" h,j,k,l: move q: quit");
+ wrefresh(W);
+
+ switch (wgetch(W)) {
+ case 'q':
+ goto q;
+
+ case 'h':
+ m(1, 1, 1);
+ goto e;
+ case 'j':
+ m(-1, S, 1);
+ goto e;
+ case 'k':
+ m(1, S, 1);
+ goto e;
+ case 'l':
+ m(-1, 1, 1);
+ goto e;
+
+ e:
+ if (C) {
+ p();
+ }
+ if (m(1, 1, 0) & m(-1, 1, 0) & m(1, S, 0) & m(-1, S, 0)) {
+ M = "\0Game over.\n";
+ goto q;
+ }
+ usleep(2048 * 8);
+ break;
+ }
+ }
+
+q:
+ if (W) {
+ delwin(W);
+ }
+ endwin();
+
+ fputs(M + 1, stderr);
+ return *M;
+}