aboutsummaryrefslogtreecommitdiff
path: root/apps/chess/chess.c
diff options
context:
space:
mode:
authorMarvin Borner2021-05-20 20:19:05 +0200
committerMarvin Borner2021-05-20 20:19:05 +0200
commit519a1de7d9fe809efc4077933fabbe93a8da9439 (patch)
treebe9d636e48036b42c8c6cc490b5f53db8b4f3a2e /apps/chess/chess.c
parent59de0af0cff96182d3e30ab453bc9763a6635947 (diff)
More generic makefile layout
Diffstat (limited to 'apps/chess/chess.c')
-rw-r--r--apps/chess/chess.c252
1 files changed, 0 insertions, 252 deletions
diff --git a/apps/chess/chess.c b/apps/chess/chess.c
deleted file mode 100644
index 94739ef..0000000
--- a/apps/chess/chess.c
+++ /dev/null
@@ -1,252 +0,0 @@
-// MIT License, Copyright (c) 2021 Marvin Borner
-// Ugly chess implementation to find the limits of libgui
-// Asserts are generally not needed but don't hurt either
-
-#include <assert.h>
-#include <libgui/gui.h>
-#include <print.h>
-
-// Config
-#define SIZE 8
-#define TILE 48
-#define WHITE_STARTS 1
-#define DARK_COLOR 0xff946f51
-#define LIGHT_COLOR 0xfff0d9b5
-#define START_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
-
-// Pieces
-#define NONE 0
-#define KING 1
-#define PAWN 2
-#define KNIGHT 3
-#define BISHOP 5
-#define ROOK 6
-#define QUEEN 7
-#define WHITE 8
-#define BLACK 16
-
-// Masks
-#define TYPE_MASK 7
-#define BLACK_MASK BLACK
-#define WHITE_MASK WHITE
-#define COLOR_MASK (WHITE_MASK | BLACK_MASK)
-
-// Macros
-#define COLOR(piece) (piece & COLOR_MASK)
-#define IS_COLOR(piece, color) (COLOR(piece) == color)
-#define TYPE(piece) (piece & TYPE_MASK)
-#define IS_ROOK_OR_QUEEN(piece) ((piece & 6) == 6)
-#define IS_BISHOP_OR_QUEEN(piece) ((piece & 5) == 5)
-#define IS_SLIDING_PIECE(piece) ((piece & 4) != 0)
-
-struct piece {
- u32 piece;
- u32 widget;
- char name[8];
- struct {
- u8 moved : 1;
- // idk
- } bits;
-};
-
-typedef struct piece board[SIZE][SIZE];
-
-static u32 win = 0; // Window
-static board tiles = { 0 }; // Matrix
-static vec2 selected = { -1, -1 }; // Selected tile
-
-static void load_image(struct piece *tile)
-{
- assert(gui_clear(win, tile->widget, GUI_LAYER_FG) == EOK);
-
- char icon[48] = { 0 };
- snprintf(icon, sizeof(icon), "/icons/chess-%s-%d.png", tile->name, TILE);
- enum gfx_filter filter = IS_COLOR(tile->piece, BLACK) ? GFX_FILTER_NONE : GFX_FILTER_INVERT;
-
- /* assert(gui_fill(win, tile->widget, GUI_LAYER_FG, 0) == EOK); */
- assert(gui_load_image_filter(win, tile->widget, GUI_LAYER_FG, vec2(0, 0), vec2(TILE, TILE),
- filter, icon) == EOK);
-}
-
-static void mouseclick(u32 widget_id, vec2 pos)
-{
- UNUSED(pos);
-
- vec2 clicked = vec2(0, 0);
- for (u32 x = 0; x < SIZE; x++)
- for (u32 y = 0; y < SIZE; y++)
- if (tiles[x][y].widget == widget_id)
- clicked = vec2(x, y);
-
- struct piece *clicked_piece = &tiles[clicked.x][clicked.y];
-
- if (vec2_eq(clicked, selected))
- return;
-
- if (selected.x != (u32)-1) {
- struct piece *selected_piece = &tiles[selected.x][selected.y];
-
- clicked_piece->piece = selected_piece->piece;
- selected_piece->piece = 0;
-
- strlcpy(clicked_piece->name, selected_piece->name, sizeof(clicked_piece->name));
- selected_piece->name[0] = '\0';
-
- assert(gui_clear(win, selected_piece->widget, GUI_LAYER_FG) == EOK);
- load_image(clicked_piece);
-
- assert(gui_redraw_window(win) == EOK);
-
- selected = vec2(-1, -1);
- } else if (clicked_piece->piece) {
- assert(gui_redraw_widget(win, clicked_piece->widget) == EOK);
- selected = clicked;
- }
-}
-
-static const char *resolve_name(u32 piece, char buf[8])
-{
- const char *name = NULL;
- switch (piece & TYPE_MASK) {
- case KING:
- name = "king";
- break;
- case PAWN:
- name = "pawn";
- break;
- case KNIGHT:
- name = "knight";
- break;
- case BISHOP:
- name = "bishop";
- break;
- case ROOK:
- name = "rook";
- break;
- case QUEEN:
- name = "queen";
- break;
- default:
- err(1, "Unknown piece %d\n", piece);
- }
-
- strlcpy(buf, name, 8);
-
- return buf;
-}
-
-static u32 fen_resolve_letter(char ch)
-{
- u32 piece = 0;
-
- switch (ch) {
- case 'k':
- piece = KING | BLACK;
- break;
- case 'K':
- piece = KING | WHITE;
- break;
- case 'p':
- piece = PAWN | BLACK;
- break;
- case 'P':
- piece = PAWN | WHITE;
- break;
- case 'n':
- piece = KNIGHT | BLACK;
- break;
- case 'N':
- piece = KNIGHT | WHITE;
- break;
- case 'b':
- piece = BISHOP | BLACK;
- break;
- case 'B':
- piece = BISHOP | WHITE;
- break;
- case 'r':
- piece = ROOK | BLACK;
- break;
- case 'R':
- piece = ROOK | WHITE;
- break;
- case 'q':
- piece = QUEEN | BLACK;
- break;
- case 'Q':
- piece = QUEEN | WHITE;
- break;
- default:
- err(1, "Invalid letter (%c)!\n", ch);
- }
-
- return piece;
-}
-
-// TODO: Add more than basic fen support
-static void fen_parse(const char *fen)
-{
- if (!fen || !*fen)
- return;
-
- u8 x = 0, y = 0;
- for (const char *p = fen; p && *p; p++) {
- if (*p == ' ')
- break;
-
- if (*p == '/') {
- x = 0;
- y++;
- continue;
- }
-
- if (*p >= '0' && *p <= '9')
- continue;
-
- u32 piece = fen_resolve_letter(*p);
-
- tiles[x][y].piece = piece;
- resolve_name(piece, tiles[x][y].name);
-
- x++;
- }
-}
-
-static void draw_board(void)
-{
- for (u8 x = 0; x < 8; x++) {
- for (u8 y = 0; y < 8; y++) {
- u32 widget =
- gui_new_widget(win, vec2(TILE, TILE), vec2(TILE * x, TILE * y));
- assert((signed)widget > 0);
-
- u8 colored = (x + y + 1) % 2 == 0;
-#if !WHITE_STARTS
- colored = !colored;
-#endif
- assert(gui_fill(win, widget, GUI_LAYER_BG,
- colored ? DARK_COLOR : LIGHT_COLOR) == EOK);
-
- struct piece *tile = &tiles[x][y];
- assert(gui_listen_widget(win, widget, GUI_LISTEN_MOUSECLICK,
- (u32)mouseclick) == EOK);
-
- tile->widget = widget;
-
- if (tile->piece)
- load_image(tile);
- }
- }
-
- assert(gui_redraw_window(win) == EOK);
-}
-
-int main(void)
-{
- assert(gui_new_window(&win) == EOK);
- fen_parse(START_FEN);
- draw_board();
-
- gui_loop();
- return 0;
-}