stego.git
stego.c

/* stego - chess engine
* Copyright (C) 2025 ArcNyxx <me@arcnyxx.net>
* see LICENCE file for licensing information */
#include <ctype.h>
#include <curses.h>
#include "move.h"
#include "stego.h"
int
main(void)
{
board_t board, *bd = &board;
bd->king = bd->eking = 0b00010000;
bd->queen = bd->equeen = 0b00001000;
bd->rook = bd->erook = 0b10000001;
bd->bishop = bd->ebishop = 0b00100100;
bd->knight = bd->eknight = 0b01000010;
bd->pawn = bd->epawn = 0b11111111;
bd->epawn <<= 8, bd->pawn <<= 48;
bd->king <<= 56, bd->queen <<= 56, bd->rook <<= 56;
bd->bishop <<= 56, bd->knight <<= 56;
bd->enpassant = 64;
bd->wkcastle = bd->wqcastle = bd->bkcastle = bd->bqcastle = true;
bd->white = true;
initscr(); /* initialises curses */
noecho(); /* no echo characters */
nonl(); /* no output newline */
raw(); /* raw input mode */
curs_set(0); /* hide cursor */
if (has_colors()) {
start_color();
init_pair(1, COLOR_WHITE, COLOR_BLACK); /* regular */
init_pair(2, COLOR_BLACK, COLOR_WHITE); /* cursor */
}
int x = 0, y = 0;
int cur = 60, sel = -1; /* start on white king */
u64 possible;
bool run = true, state = false;
while (run) {
if (state != bd->white) {
for (int i = 0; i < 64; ++i)
bd->moves[i] = 0;
mv(bd);
state = bd->white;
}
if (sel == -1)
possible = bd->moves[cur];
int newx, newy;
getmaxyx(stdscr, newy, newx);
newx = (newx - 15) / 2, newy = (newy - 8) / 2;
if (newx != x || newy != y) {
clear();
x = newx, y = newy;
}
for (int i = 0; i < 64; ++i) {
int map = possible & (1ULL << i) ?
COLOR_PAIR(2) : COLOR_PAIR(1);
if (i == cur || i == sel)
map |= A_BOLD;
char letter = '.';
if ((1ULL << i) & (bd->king | bd->eking))
letter = 'k';
else if ((1ULL << i) & (bd->queen | bd->equeen))
letter = 'q';
else if ((1ULL << i) & (bd->rook | bd->erook))
letter = 'r';
else if ((1ULL << i) & (bd->bishop | bd->ebishop))
letter = 'b';
else if ((1ULL << i) & (bd->knight | bd->eknight))
letter = 'n';
else if ((1ULL << i) & (bd->pawn | bd->epawn))
letter = 'p';
u64 friend = bd->friend;
if (!bd->white)
friend = ~friend;
if (letter != '.' && ((1ULL << i) & friend))
letter = toupper(letter);
mvaddch(y, x, letter | map);
if (i % 8 == 7)
++y, x -= 14;
else
x += 2;
}
switch (getch()) {
default: break;
case 'h': if (cur % 8 != 0) cur -= 1; break;
case 'j': if (cur <= 55) cur += 8; break;
case 'k': if (cur >= 8) cur -= 8; break;
case 'l': if (cur % 8 != 7) cur += 1; break;
case 'q': run = false; break;
case ' ':
/* no selection yet */
if (sel == -1) {
if (possible) /* only select if has */
sel = cur; /* available moves */
/* selection made */
} else if (possible & (1ULL << cur)) {
/* make the move */
mk(bd, sel, cur);
sel = -1;
} else {
/* not a valid move */
sel = -1;
}
}
}
endwin();
}