radare2/libr/cons/2048.c
2014-03-31 16:39:16 +02:00

205 lines
4.0 KiB
C

#include <r_cons.h>
// TWOK is a C implemnetation of 2048 game
#define ut8 unsigned char
static ut8 twok_buf[4][4];
static int score =0;
static int moves =0;
#define INTERNAL static
INTERNAL void twok_init() {
int i, j;
score = 0;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
twok_buf[i][j] = 0;
}
INTERNAL void twok_add() {
int i, j, min = 1;
int holes = 0;
for (i=0;i<4;i++) {
for (j=0;j<4;j++) {
if (twok_buf[i][j] > 1) {
min = 2;
break;
}
}
}
for (i=0;i<4;i++)
for (j=0;j<4;j++)
if (!twok_buf[i][j]) {
holes = 1;
break;
}
if (holes)
for (;;) {
i = r_num_rand (4);
j = r_num_rand (4);
if (!twok_buf[i][j]) {
twok_buf[i][j] = r_num_rand (min)+1;
break;
}
}
}
INTERNAL int twok_fin() {
int i,j;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
if (!twok_buf[i][j])
return 1;
for (i=0;i<4;i++)
for (j=0;j<3;j++)
if (twok_buf[i][j] == twok_buf[i][j+1])
return 1;
for (i=0;i<3;i++)
for (j=0;j<4;j++)
if (twok_buf[i][j] == twok_buf[i+1][j])
return 1;
return 0;
}
INTERNAL void twok_move(int d) {
int i, j, k;
moves++;
if (d=='a') {
twok_add ();
} else
for (k=0;k<4;k++) {
switch (d) {
case 'h': // left
// for each row
for (i=0; i<4; i++) {
for (j=0; j<3; j++) {
if (twok_buf[i][j] == 0) {
twok_buf[i][j] = twok_buf[i][j+1];
twok_buf[i][j+1] = 0;
} else
if (twok_buf[i][j] == twok_buf[i][j+1]) {
twok_buf[i][j] ++;
score += (1<<twok_buf[i][j]);
twok_buf[i][j+1] = 0;
}
}
}
break;
case 'l': // right
for (i=0; i<4; i++) {
for (j=3; j>0; j--) {
if (twok_buf[i][j] == 0) {
twok_buf[i][j] = twok_buf[i][j-1];
twok_buf[i][j-1] = 0;
} else
if (twok_buf[i][j] == twok_buf[i][j-1]) {
twok_buf[i][j] ++;
score += (1<<twok_buf[i][j]);
twok_buf[i][j-1] = 0;
}
}
}
break;
case 'j': // down
// for each column
for (j=0; j<4; j++) {
for (i=3; i>0; i--) {
if (twok_buf[i][j] == 0) {
twok_buf[i][j] = twok_buf[i-1][j];
twok_buf[i-1][j] = 0;
} else
if (twok_buf[i][j] == twok_buf[i-1][j]) {
twok_buf[i][j] ++;
score += (1<<twok_buf[i][j]);
twok_buf[i-1][j] = 0;
}
}
}
break;
case 'k': // up
// for each column
for (j=0; j<4; j++) {
for (i=0; i<3; i++) {
if (twok_buf[i][j] == 0) {
twok_buf[i][j] = twok_buf[i+1][j];
twok_buf[i+1][j] = 0;
} else
if (twok_buf[i][j] == twok_buf[i+1][j]) {
twok_buf[i][j] ++;
score += (1<<twok_buf[i][j]);
twok_buf[i+1][j] = 0;
}
}
}
break;
}}
}
INTERNAL void twok_print() {
char val0[32];
char val1[32];
char val2[32];
char val3[32];
int i;
#define VAL(x) if (twok_buf[i][x]){\
sprintf(val##x,"%4d",1<<twok_buf[i][x]); \
} else strcpy(val##x, " ");
printf (" +------+------+------+------+\n");
for (i = 0; i<4; i++) {
VAL(0); VAL(1);
VAL(2); VAL(3);
printf (" | | | | |\n");
printf (" | %s | %s | %s | %s |\n",
val0,val1,val2,val3);
printf (" | | | | |\n");
printf (" +------+------+------+------+\n");
}
printf ("Hexboard: 'hjkl' and 'q'uit\n");
for (i = 0; i<4; i++)
printf (" %02x %02x %02x %02x\n",
twok_buf[i][0], twok_buf[i][1],
twok_buf[i][2], twok_buf[i][3]);
}
#if 0
int main() {
char buf[128];
twok_init();
twok_add();
// canonical stdin here
while (twok_fin()) {
twok_print();
if (!fgets (buf, sizeof (buf)-1, stdin))
break;
twok_move (buf[0]);
twok_add ();
}
printf ("score: %d\n", twok_score ());
return 0;
}
#endif
R_API void r_cons_2048() {
int ch;
r_cons_set_raw (1);
twok_init ();
twok_add ();
while (twok_fin()) {
r_cons_clear00();
r_cons_printf ("[r2048] score: %d moves: %d\n",
score, moves);
r_cons_flush ();
twok_print();
ch = r_cons_readchar ();
if (ch<1||ch =='q') break;
twok_move (ch);
twok_add ();
}
r_cons_clear00();
r_cons_printf ("[r2048] score: %d\n", score );
r_cons_flush ();
twok_print();
r_cons_printf ("\n [r2048.score] %d\n", score );
r_cons_any_key ();
r_cons_set_raw (0);
}