}
void game_start() {
- printf("\e[?1049h");
+ printf("\e[?1049h\e[?25l]");
+ struct termios oldtio, newtio;
+ tcgetattr(STDIN_FILENO, &oldtio);
+ newtio = oldtio;
+ newtio.c_lflag &= ~(ICANON | ECHO);
+ tcsetattr(STDIN_FILENO, TCSANOW, &newtio);
board *b = new_board();
game_loop(b);
+ printf("\e[?1049l\e[?25h");
+ tcsetattr(STDIN_FILENO, TCSANOW, &oldtio);
print_score(b);
free_board(b);
- printf("\e[?1049l");
+}
+
+enum direction get_input()
+{
+ switch(fgetc(stdin)) {
+ case 'a':
+ return west;
+ case 's':
+ return south;
+ case 'w':
+ return north;
+ case 'd':
+ return east;
+ case 'q':
+ return quit;
+ default:
+ return get_input();
+ }
}
void game_loop(board *b) {
- char c[16];
- int d;
- bool r = true;
while(move_possible_any(b)) {
place_new_piece(b);
print_board(b);
- INPUT:
- printf("Make a move:\n");
- fgets(c, sizeof(c), stdin);
- switch(c[0]) {
- case 'a':
- d = west;
- break;
- case 's':
- d = south;
- break;
- case 'w':
- d = north;
- break;
- case 'd':
- d = east;
- break;
- case 'q':
- r = false;
+ while(true) {
+ enum direction d = get_input();
+
+ if (d == quit) {
+ return;
+ } else if(move_possible(b, d)) {
+ make_move(b, d);
break;
- default:
- printf("Invalid move: %c\n", c[0]);
- goto INPUT;
- }
- if(!r)
- return;
- if(!move_possible(b, d)) {
- printf("Move not possible: %c\n", c[0]);
- goto INPUT;
+ }
}
- make_move(b, d);
}
}
}
}
-void merge_west(board *b) {
+void merge_west(board *b) {
for(int i = 1; i < 4; ++i) {
for(int j = 0; j < 4; ++j) {
if(b->x[i][j] != 0 && b->x[i-1][j] == b->x[i][j]) {
}
}
-void print_sep() {
- printf("||--------------------------------------------------------------||\n");
+void center_print(uint n, int width)
+{
+ char s[20] = {'\0'};
+ int len;
+ sprintf(s, "%u", n);
+ len = strlen(s);
+ if (len >= width) {
+ printf("%s", s);
+ } else {
+ int remaining = width - len;
+ int spaces_right = remaining / 2;
+ int spaces_left = remaining - spaces_right;
+ printf("%*s%s%*s", spaces_left, "", s, spaces_right, "");
+ }
+}
+
+void print_sep(const char *left, const char *right, const char *cross, const char *line)
+{
+ printf("%s", left);
+ for(int i = 0; i < 4; i++) {
+ for(int j = 0; j < 6; j++)
+ printf("%s", line);
+ if(i == 3)
+ printf("%s", right);
+ else
+ printf("%s", cross);
+ }
+ printf("\n");
+}
+
+uint mylog2(uint n) {
+ uint i;
+
+ for (i = 0; ! (n & 1); i++)
+ n >>= 1;
+
+ return i;
}
void print_board_line(board *b, int l) {
- printf("||\t%u\t|\t%u\t|\t%u\t|\t%u\t||\n", b->x[0][l], b->x[1][l], b->x[2][l], b->x[3][l]);
- print_sep();
+ printf("\u2503");
+
+ for(int i = 0; i < 4; i++) {
+ uint n = b->x[i][l];
+
+ if(n == 0) {
+ printf(" ");
+ } else {
+ uint c = mylog2(n);
+
+ if (c > 6) {
+ c -= 6;
+ printf("\e[1m");
+ }
+
+ printf("\e[3%1um", c);
+ center_print(n, 6);
+ printf("\e[0m");
+ }
+
+ if(i == 3)
+ printf("\u2503");
+ else
+ printf("\u2502");
+ }
+
+ printf("\n");
+ print_sep("\u2503", "\u2503", "\u2502", " ");
+
+ if(l == 3)
+ print_sep("\u2517", "\u251B", "\u2537", "\u2501");
+ else
+ print_sep("\u2520", "\u2528", "\u253C", "\u2500");
}
void print_board(board *b) {
- printf("Score: %u\n", b->points);
- print_sep();
+ printf("\e[2J\e[0;0H");
+ printf("\e[1mScore: \e[0m%u\n", b->points);
+ print_sep("\u250F", "\u2513", "\u252F", "\u2501");
for(int i = 0; i < 4; ++i) {
print_board_line(b, i);
}
- printf("\n");
}
void print_score(board *b) {
- printf("Game Over\nScore:%u\n", b->points);
+ printf("\e[1m\e[91mGame Over\e[0m\n\e[1mScore: \e[0m%u\n", b->points);
}
void merge_test1() {