aboutsummaryrefslogtreecommitdiffhomepage
path: root/2048_clean.c
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-24 10:27:59 +0900
committernsfisis <nsfisis@gmail.com>2025-08-24 13:34:43 +0900
commit60613d00bbd7ad3541670d26dc27073810c53c29 (patch)
tree70c251ecffe7b98bae9117c7191c50f49267a358 /2048_clean.c
parent307dd4110d0dd2e1246288394f8a2b46a2e55add (diff)
download2048.c-60613d00bbd7ad3541670d26dc27073810c53c29.tar.gz
2048.c-60613d00bbd7ad3541670d26dc27073810c53c29.tar.zst
2048.c-60613d00bbd7ad3541670d26dc27073810c53c29.zip
rewrite without using ncursesHEADmain
Diffstat (limited to '2048_clean.c')
-rw-r--r--2048_clean.c111
1 files changed, 70 insertions, 41 deletions
diff --git a/2048_clean.c b/2048_clean.c
index ac58325..79a474b 100644
--- a/2048_clean.c
+++ b/2048_clean.c
@@ -1,24 +1,69 @@
-#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
+#include <termios.h>
#include <time.h>
#include <unistd.h>
-#define waddstr_(text) waddstr(main_window, text)
-#define waddch_(ch) waddch(main_window, ch)
-#define wprintw_(format, data) wprintw(main_window, format, data)
-#define newline waddch_('\n')
+#define waddstr_(text) printf("%s", text)
+#define waddch_(ch) putchar(ch)
+#define wprintw_(format, data) printf(format, data)
+#define newline printf("\r\n")
#define repeat(i, n) for (int i = 0; i < n; ++i)
#define get_tile_at(k) (grid + y * ((x + size) % (size + 1) + k * x) + (size + 1 - y) * i)
-WINDOW *main_window;
-char *message = "\0";
-int size, num_rows, num_columns, new_tile_pos, num_empty_slots, changed, last_empty_tile_index, *last_non_empty_tile,
- *this_tile, grid_buf[128], *grid = grid_buf;
+#define CLEAR_SCREEN "\033[2J\033[H"
+#define HIDE_CURSOR "\033[?25l"
+#define SHOW_CURSOR "\033[?25h"
-void draw_frame_1() {
+int size, new_tile_pos, num_empty_slots, changed, last_empty_tile_index, *last_non_empty_tile, *this_tile,
+ grid_buf[128], *grid = grid_buf, did_restore_from_alt_buffer, did_disable_raw_mode;
+
+void restore_from_alt_buffer(void) {
+ if (did_restore_from_alt_buffer++)
+ return;
+ printf("\033[?1049l");
+}
+
+void switch_to_alt_buffer(void) {
+ atexit(restore_from_alt_buffer);
+ printf("\033[?1049h");
+}
+
+struct termios original_termios;
+
+void disable_raw_mode(void) {
+ if (did_disable_raw_mode++)
+ return;
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &original_termios);
+ printf(SHOW_CURSOR);
+}
+
+void enable_raw_mode(void) {
+ tcgetattr(STDIN_FILENO, &original_termios);
+ atexit(disable_raw_mode);
+
+ struct termios raw = original_termios;
+ raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+ raw.c_oflag &= ~(OPOST);
+ raw.c_cflag |= (CS8);
+ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+ raw.c_cc[VMIN] = 0;
+ raw.c_cc[VTIME] = 1;
+
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+ printf(HIDE_CURSOR);
+}
+
+char get_key(void) {
+ char c;
+ while (read(STDIN_FILENO, &c, 1) != 1)
+ ;
+ return c;
+}
+
+void draw_frame_1(void) {
waddch_('+');
repeat(i, 8 * size - 1) {
waddch_('-');
@@ -27,19 +72,18 @@ void draw_frame_1() {
newline;
}
-void draw_frame_2() {
+void draw_frame_2(void) {
waddch_('|');
repeat(i, size) {
- repeat(j, 8) {
+ repeat(j, 7) {
waddch_(32);
}
- waddch_('\b');
waddch_('|');
}
newline;
}
-void show_grid() {
+void show_grid(void) {
draw_frame_1();
repeat(i, size) {
draw_frame_2();
@@ -62,10 +106,9 @@ void show_grid() {
if (i < size - 1) {
waddch_('|');
repeat(j, size) {
- repeat(j, 8) {
+ repeat(j, 7) {
waddch_('-');
}
- waddch_('\b');
if (j < size - 1) {
waddch_('+');
}
@@ -113,7 +156,7 @@ int move_grid(int x, int y, int do_change) {
return !changed;
}
-void put_new_tile() {
+void put_new_tile(void) {
num_empty_slots = 0;
repeat(i, size * size) {
if (!grid[i]) {
@@ -134,34 +177,25 @@ void put_new_tile() {
int main(int argc, char **argv) {
srand(time(0));
- initscr();
- cbreak();
- noecho();
- curs_set(0);
- getmaxyx(stdscr, num_rows, num_columns);
+ switch_to_alt_buffer();
+ enable_raw_mode();
size = argc > 1 ? (*argv[1] - '0') : 4;
if (size <= 1 || size > 8) {
- message = "\1Invalid size given.\n";
- goto quit;
- }
-
- main_window = newwin(0, 0, (num_rows - 4 * size) / 2, (num_columns - 8 * size) / 2);
- if (!main_window) {
- message = "\1Terminal too small.\n";
- goto quit;
+ fputs("invalid board size\n", stderr);
+ return 1;
}
put_new_tile();
put_new_tile();
while (1) {
- wclear(main_window);
+ printf(CLEAR_SCREEN);
show_grid();
waddstr_(" h,j,k,l: move q: quit");
- wrefresh(main_window);
+ fflush(stdout);
- switch (wgetch(main_window)) {
+ switch (get_key()) {
case 'q':
goto quit;
@@ -183,7 +217,6 @@ int main(int argc, char **argv) {
put_new_tile();
}
if (move_grid(1, 1, 0) & move_grid(-1, 1, 0) & move_grid(1, size, 0) & move_grid(-1, size, 0)) {
- message = "\0Game over.\n";
goto quit;
}
usleep(2048 * 8);
@@ -192,11 +225,7 @@ int main(int argc, char **argv) {
}
quit:
- if (main_window) {
- delwin(main_window);
- }
- endwin();
-
- fputs(message + 1, stderr);
- return *message;
+ disable_raw_mode();
+ restore_from_alt_buffer();
+ printf(CLEAR_SCREEN);
}