summaryrefslogtreecommitdiff
path: root/2ls10.c
diff options
context:
space:
mode:
authorKatolaZ <katolaz@freaknet.org>2019-08-07 08:18:36 +0100
committerKatolaZ <katolaz@freaknet.org>2019-08-07 08:18:36 +0100
commit74eb7a909896551721df941a2988cfd2bcc3cb92 (patch)
treeed7ca87b73366f7cdba3dcff08eb2faf31a9642e /2ls10.c
initial commit
Diffstat (limited to '2ls10.c')
-rw-r--r--2ls10.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/2ls10.c b/2ls10.c
new file mode 100644
index 0000000..c3b0d70
--- /dev/null
+++ b/2ls10.c
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <termios.h>
+#include <unistd.h>
+
+int st[1<<7], lo, li, ls;
+int m, pt, n, pl, t;
+char nf;
+struct termios t1, t2;
+
+int cond (int j){
+ return t? j/n : j%n;
+}
+
+void clean(char *str){
+ if (str) printf("%s\n", str);
+ tcsetattr(0, TCSANOW, &t1);
+ exit(0);
+}
+
+int dash(int i){
+ return i?
+ putchar('-') + dash(i-1):0;
+ }
+
+int line(int i){
+ return putchar('+') + (i ?
+ dash(6)+ line(i-1):
+ putchar(10));
+}
+
+int valid_move(){
+ int i;
+ for (i=0; i<n*n - 1; i++){
+ if ((i%n < n-1 && st[i]==st[i+1]) || (i/n < n-1 && st[i] == st[i+n]))
+ return 1;
+ }
+ return 0;
+}
+
+void print_state(){
+ int i, j,v;
+ printf("\033[2J\033[1;1HScore: %d\n", pt);
+ line(n);
+ for (i=0; i<n; i++){
+ printf("|");
+ for(j=0; j<n; j++){
+ v=st[n*i+j];
+ if (v > 0)
+ printf("%5d |", 1<<v);
+ else printf(" |");
+ }
+ printf("\n");
+ }
+ line(n);
+}
+
+void set_rnd(){
+ int i;
+ while(nf){
+ i = rand();
+ if (!st[i%(n*n)]){
+ st[i%(n*n)] = 1 + (i%8==0);
+ if (! --nf) break;
+ return;
+ }
+ }
+ if (!valid_move()){
+ print_state();
+ clean("no more moves");
+ }
+}
+
+
+void shift(int j){
+ int num_empty=0;
+ do{
+ if (! st[j]) /* empty*/
+ num_empty -= li;
+ else if (num_empty){
+ st[j + num_empty] = st[j];
+ st[j] ^= st[j];
+ }
+ j += li;
+ } while (j >= 0 && cond(j) != ls);
+}
+
+void merge(int j){
+ do {
+ if (st[j] && st[j] == st[j-li]){
+ st[j-li] += 1;
+ if (st[j-li] == 11) pl ^= pl;
+ pt += 1<<st[j-li];
+ st[j] ^= st[j];
+ nf ++;
+ }
+ j += li;
+ } while( j>= 0 && cond(j) != ls);
+}
+
+void update(){
+ int i;
+ for(i =0; i<n; i++){
+ shift(m * i + lo);
+ merge(m * i + lo + li);
+ shift(m * i + lo);
+ }
+}
+
+int main(int argc, char *argv[]){
+ srand(time(NULL));
+ //srand(12345);
+ n = 4;
+ if (argc > 1) n = atoi(argv[1]);
+ nf = n * n;
+ tcgetattr(0, &t1);
+ t2 = t1;
+ t2.c_lflag &= ~(ICANON | ECHO);
+ tcsetattr(0, TCSANOW, &t2);
+ set_rnd();
+ pt = 0;
+ pl = 1;
+ while(pl){
+ //pr_st();
+ set_rnd();
+ print_state();
+ switch(getchar()){
+ case 'l':
+ lo = ls = n-1;
+ li = -1;
+ m = n;
+ t = 0;
+ break;
+ case 'h':
+ lo = ls = 0;
+ li = 1;
+ m = n;
+ t = 0;
+ break;
+ case 'j':
+ lo = n * (n-1);
+ li = -n;
+ ls = -1;
+ m = 1;
+ t=1;
+ break;
+ case 'k':
+ lo = 0;
+ li = ls = n;
+ m = 1;
+ t=1;
+ break;
+ case 'q':
+ clean("Thanks!");
+
+ }
+ update();
+
+ }
+ print_state();
+ clean("you won!");
+}