mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 15:10:53 +00:00
194 lines
4.5 KiB
C
194 lines
4.5 KiB
C
/* radare2 - LGPL - Copyright 2008-2022 - pancake */
|
|
|
|
#include <r_cons.h>
|
|
|
|
typedef struct game_state_t {
|
|
ut8 twok_buf[4][4];
|
|
int score;
|
|
int moves;
|
|
} GameState;
|
|
|
|
|
|
static void twok_init(GameState *state) {
|
|
memset (state, 0, sizeof (GameState));
|
|
}
|
|
|
|
static void twok_add(GameState *state) {
|
|
int i, j;
|
|
while (true) {
|
|
i = r_num_rand (4);
|
|
j = r_num_rand (4);
|
|
if (!state->twok_buf[i][j]) {
|
|
state->twok_buf[i][j] = 1 + (r_num_rand (10) == 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool twok_fin(GameState *state) {
|
|
int i, j;
|
|
for (i = 0; i < 4; i++) {
|
|
for (j = 0; j < 4; j++) {
|
|
if (!state->twok_buf[i][j]) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < 4; i++) {
|
|
for (j = 0; j < 3; j++) {
|
|
if (state->twok_buf[i][j] == state->twok_buf[i][j + 1]) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < 3; i++) {
|
|
for (j = 0; j < 4; j++) {
|
|
if (state->twok_buf[i][j] == state->twok_buf[i + 1][j]) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static void twok_move(GameState *state, int u, int v) {
|
|
int i, j, k;
|
|
int nKI = 0, nKJ = 0, nIK = 0, nJK = 0;
|
|
int moved = 0;
|
|
for (k = 0; k < 4; k++) {
|
|
for (i = 0; i < 4; i++) {
|
|
for (j = i + 1; j < 4 && !state->twok_buf[nKJ = u ? k : v ? j : 3 - j][nJK = !u ? k : v ? j : 3 - j]; j++) {
|
|
;
|
|
}
|
|
if (j == 4) {
|
|
continue;
|
|
}
|
|
nKI = u? k: v? i: 3 - i;
|
|
nIK = !u? k: v? i: 3 - i;
|
|
if (!state->twok_buf[nKI][nIK]) {
|
|
state->twok_buf[nKI][nIK] = state->twok_buf[nKJ][nJK];
|
|
state->twok_buf[nKJ][nJK] = 0;
|
|
--i;
|
|
moved = 1;
|
|
} else if (state->twok_buf[nKI][nIK] == state->twok_buf[nKJ][nJK]) {
|
|
state->score += 1 << ++state->twok_buf[nKI][nIK];
|
|
state->twok_buf[nKJ][nJK] = 0;
|
|
moved = 1;
|
|
}
|
|
}
|
|
}
|
|
if (moved) {
|
|
twok_add (state);
|
|
state->moves++;
|
|
}
|
|
}
|
|
|
|
static void getval(GameState *state, bool color, char *val0, int i, int x) {
|
|
const char * colorarray[] = {
|
|
Color_WHITE,
|
|
Color_RED,
|
|
Color_GREEN,
|
|
Color_MAGENTA,
|
|
Color_YELLOW,
|
|
Color_CYAN,
|
|
Color_BLUE,
|
|
Color_GRAY
|
|
};
|
|
if (state->twok_buf[i][x]) {
|
|
if (color) {
|
|
snprintf (val0, 31, "%s%4d"Color_RESET, colorarray [state->twok_buf [i][x] % 8 ], 1 << state->twok_buf[i][x]);
|
|
} else {
|
|
snprintf (val0, 31, "%4d", 1 << state->twok_buf[i][x]);
|
|
}
|
|
} else {
|
|
strcpy (val0, " ");
|
|
}
|
|
}
|
|
|
|
static void twok_print(GameState *state, bool color) {
|
|
char val0[32];
|
|
char val1[32];
|
|
char val2[32];
|
|
char val3[32];
|
|
int i;
|
|
if (color) {
|
|
printf (Color_BBLUE" +------+------+------+------+\n");
|
|
} else {
|
|
printf (" +------+------+------+------+\n");
|
|
}
|
|
for (i = 0; i < 4; i++) {
|
|
getval (state, color, val0, i, 0);
|
|
getval (state, color, val1, i, 1);
|
|
getval (state, color, val2, i, 2);
|
|
getval (state, color, val3, i, 3);
|
|
if (color) {
|
|
printf (Color_BBLUE" | | | | |\n");
|
|
printf (" |"Color_RESET" %s "Color_BBLUE"|"Color_RESET" %s "
|
|
Color_BBLUE"|"Color_RESET" %s "Color_BBLUE"|"Color_RESET" %s "Color_BBLUE"|\n",
|
|
val0, val1, val2, val3);
|
|
printf (" | | | | |\n");
|
|
printf (" +------+------+------+------+\n"Color_RESET);
|
|
} else {
|
|
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",
|
|
state->twok_buf[i][0], state->twok_buf[i][1],
|
|
state->twok_buf[i][2], state->twok_buf[i][3]);
|
|
}
|
|
}
|
|
|
|
R_API void r_cons_2048(bool color) {
|
|
GameState state;
|
|
int ch;
|
|
r_cons_set_raw (1);
|
|
twok_init (&state);
|
|
twok_add (&state);
|
|
twok_add (&state);
|
|
while (twok_fin (&state)) {
|
|
r_cons_clear00 ();
|
|
if (color) {
|
|
r_cons_printf (Color_GREEN"[r2048]"Color_BYELLOW" score: %d moves: %d\n"Color_RESET, state.score, state.moves);
|
|
} else {
|
|
r_cons_printf ("[r2048] score: %d moves: %d\n", state.score, state.moves);
|
|
}
|
|
r_cons_flush ();
|
|
twok_print (&state, color);
|
|
ch = r_cons_readchar ();
|
|
ch = r_cons_arrow_to_hjkl (ch);
|
|
switch (ch) {
|
|
case 'h':
|
|
twok_move (&state, 1, 1);
|
|
break;
|
|
case 'j':
|
|
twok_move (&state, 0, 0);
|
|
break;
|
|
case 'k':
|
|
twok_move (&state, 0, 1);
|
|
break;
|
|
case 'l':
|
|
twok_move (&state, 1, 0);
|
|
break;
|
|
}
|
|
if (ch < 1 || ch == 'q') {
|
|
break;
|
|
}
|
|
}
|
|
r_cons_clear00 ();
|
|
r_cons_printf ("[r2048] score: %d\n", state.score);
|
|
r_cons_flush ();
|
|
twok_print (&state, color);
|
|
|
|
r_cons_printf ("\n [r2048.score] %d\n", state.score);
|
|
do {
|
|
ch = r_cons_any_key ("Press 'q' to quit.");
|
|
} while (ch != 'q' && ch >= 1);
|
|
r_cons_set_raw (0);
|
|
}
|