summaryrefslogtreecommitdiff
path: root/src/user/ttt
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/ttt')
-rw-r--r--src/user/ttt/main.c271
1 files changed, 0 insertions, 271 deletions
diff --git a/src/user/ttt/main.c b/src/user/ttt/main.c
deleted file mode 100644
index 655bf8e..0000000
--- a/src/user/ttt/main.c
+++ /dev/null
@@ -1,271 +0,0 @@
-#include <pland/syscall.h>
-#include <popups/info.h>
-#include <knob/rand.h>
-
-#define SPACE_SIZE 20
-#define BORDER_SIZE 4
-#define WIDTH (SPACE_SIZE * 3 + BORDER_SIZE * 4)
-
-#define BG ((_pixel_t){.r = 0xd6, .g = 0xd6, .b = 0xd6})
-#define FG ((_pixel_t){.r = 0x33, .g = 0x33, .b = 0x33})
-#define XC ((_pixel_t){.r = 0x60, .g = 0x06, .b = 0x43})
-#define OC ((_pixel_t){.r = 0x2c, .g = 0x77, .b = 0x30})
-#define SL ((_pixel_t){.r = 0x9d, .g = 0x99, .b = 0xc2})
-
-static const bool x_pic[] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,
- 0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,
- 0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,
- 0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,
- 0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,
- 0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,
- 0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,
- 0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,
- 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-
-static const bool o_pic[] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
- 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
- 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
- 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-
-static const bool b_pic[] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-
-typedef enum {B, X, O} trit;
-
-static const bool *pics[] = {b_pic, x_pic, o_pic};
-static const _pixel_t colors[] = {FG, XC, OC};
-
-static _window_handle_t w;
-static _pixel_t pbuf[WIDTH * WIDTH];
-static trit board_state[9];
-static uint8_t cursor;
-static trit playing_as;
-static uint8_t filled_squares;
-
-__attribute__ ((__pure__))
-static bool is_win(uint8_t hint) {
- const uint8_t c = hint % 3;
- if ((board_state[c] == board_state[c + 3]) && (board_state[c] == board_state[c + 6]))
- return true;
- const uint8_t r = hint - c;
- if ((board_state[r] == board_state[r + 1]) && (board_state[r] == board_state[r + 2]))
- return true;
- return board_state[4] && (
- ((board_state[0] == board_state[4]) && (board_state[0] == board_state[8])) ||
- ((board_state[2] == board_state[4]) && (board_state[2] == board_state[6]))
- );
-}
-
-static void draw_rect(uint8_t y, uint8_t x, uint8_t h, uint8_t w, _pixel_t color) {
- for (uint8_t yy = y; yy < y + h; ++yy)
- for (uint8_t xx = x; xx < x + w; ++xx)
- pbuf[yy * WIDTH + xx] = color;
-}
-
-static void draw_spot(uint8_t n) {
- const _pixel_t bg_c = n == cursor ? SL : BG;
- const _pixel_t fg_c = colors[board_state[n]];
- const bool *const pic = pics[board_state[n]];
-
- const uint8_t ys = BORDER_SIZE + (n / 3) * (BORDER_SIZE + SPACE_SIZE);
- const uint8_t xs = BORDER_SIZE + (n % 3) * (BORDER_SIZE + SPACE_SIZE);
- for (uint8_t y = 0; y < SPACE_SIZE; ++y)
- for (uint8_t x = 0; x < SPACE_SIZE; ++x)
- pbuf[(ys + y) * WIDTH + xs + x] = pic[y * SPACE_SIZE + x] ? fg_c : bg_c;
-}
-
-static void ai_turn();
-
-static void reset_board() {
- cursor = 4;
- playing_as = gen_rand() % 2 + 1;
- filled_squares = 0;
- for (uint8_t i = 0; i < 9; ++i) {
- board_state[i] = B;
- draw_spot(i);
- }
-
- if (gen_rand() % 2)
- ai_turn();
-}
-
-static uint32_t start_time;
-
-static void on_win() {
- struct popup p;
- info_popupf(&p, "You win! Time: %us\nPress escape to play again.", FG, BG, _get_timestamp() - start_time);
- make_modal(&p);
- reset_board();
- _paint_window(w);
- start_time = _get_timestamp();
-}
-
-static void on_tie() {
- struct popup p;
- info_popupf(&p, "Tie! Time: %us\nPress escape to play again.", FG, BG, _get_timestamp() - start_time);
- make_modal(&p);
- reset_board();
- _paint_window(w);
- start_time = _get_timestamp();
-}
-
-static void ai_turn() {
- //super easy mode
- uint8_t n;
- do
- n = gen_rand() % 9;
- while (board_state[n]);
- board_state[n] = playing_as == O ? X : O;
- draw_spot(n);
- _paint_window(w);
- if (is_win(n)) {
- struct popup p;
- info_popupf(&p, "You lose. Time: %us\nPress escape to play again.", FG, BG, _get_timestamp() - start_time);
- make_modal(&p);
- reset_board();
- _paint_window(w);
- start_time = _get_timestamp();
- }
- else if (++filled_squares == 9)
- on_tie();
-}
-
-void main() {
- struct popup controls;
- info_popup(&controls,
- "Tic-Tac-Toe Controls:\n\n"
- "Arrow keys: move selection\n"
- "Spacebar: confirm selection\n"
- "Escape: quit\n\n"
- "Press escape to start.", FG, BG);
- make_modal(&controls);
-
- for (uint16_t i = 0; i < WIDTH * WIDTH; ++i)
- pbuf[i] = BG;
-
- draw_rect(SPACE_SIZE + BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, WIDTH - 2 * BORDER_SIZE, FG);
- draw_rect(BORDER_SIZE, SPACE_SIZE + BORDER_SIZE, WIDTH - 2 * BORDER_SIZE, BORDER_SIZE, FG);
- draw_rect(SPACE_SIZE * 2 + BORDER_SIZE * 2, BORDER_SIZE, BORDER_SIZE, WIDTH - 2 * BORDER_SIZE, FG);
- draw_rect(BORDER_SIZE, SPACE_SIZE * 2 + BORDER_SIZE * 2, WIDTH - 2 * BORDER_SIZE, BORDER_SIZE, FG);
-
- reset_board();
-
- w = _new_window(WIDTH, WIDTH, pbuf);
- start_time = _get_timestamp();
-
- while (1) {
- struct window_action wa;
- _get_win_action(w, &wa);
- if (!wa.action_type) {
- _wait_for_action();
- _yield_task();
- continue;
- }
-
- if (wa.action_type != KEY_DOWN)
- continue;
-
- switch (wa.as_key.key_id) {
- case KEY_UP_ARROW:
- if (cursor >= 3) {
- cursor -= 3;
- draw_spot(cursor + 3);
- draw_spot(cursor);
- _paint_window(w);
- }
- break;
- case KEY_DOWN_ARROW:
- if (cursor < 6) {
- cursor += 3;
- draw_spot(cursor - 3);
- draw_spot(cursor);
- _paint_window(w);
- }
- break;
- case KEY_LEFT_ARROW:
- if (cursor % 3) {
- --cursor;
- draw_spot(cursor + 1);
- draw_spot(cursor);
- _paint_window(w);
- }
- break;
- case KEY_RIGHT_ARROW:
- if (cursor % 3 != 2) {
- ++cursor;
- draw_spot(cursor - 1);
- draw_spot(cursor);
- _paint_window(w);
- }
- break;
- case KEY_ESCAPE:
- return;
- case KEY_SPACE:
- if (!board_state[cursor]) {
- board_state[cursor] = playing_as;
- draw_spot(cursor);
- _paint_window(w);
- if (is_win(cursor))
- on_win();
- else if (++filled_squares == 9)
- on_tie();
- else
- ai_turn();
- }
- break;
- default:
- break;
- }
- }
-} \ No newline at end of file