summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaume Delclòs Coll <cosa@cosarara.me>2024-05-08 13:04:44 +0000
committerJaume Delclòs Coll <cosa@cosarara.me>2024-05-08 13:04:44 +0000
commit700a054974068b7cc886e3d0a4701eddcbdc59cb (patch)
tree52bc8c31178c039b52ea7da669215870c1c41594
parent008781c1a510f764d6c99024faafb51534aebbaf (diff)
pretty notation
-rw-r--r--chess.c115
1 files changed, 75 insertions, 40 deletions
diff --git a/chess.c b/chess.c
index 2862fbd..b6c6671 100644
--- a/chess.c
+++ b/chess.c
@@ -6,6 +6,7 @@
#include <keyboard.h>
// Missing features
+// promotion
// display checkmate and stalemate
// arrows to go back and forward in history
// show moves better
@@ -126,8 +127,6 @@ typedef struct Move {
Piece piece;
Point src;
Point dst;
- int was_capture;
- MoveType type;
} Move;
Player
@@ -365,6 +364,56 @@ islegal(int board[8][8], Point src, Point dst, Move prev_move, CastleRights cr)
return move_type;
}
+// longest possible move would be something like Qa1xe4+,
+// so with null byte 8 characters is enough
+#define MOVE_STR_LEN 8
+void print_move(char* movestring, int board[8][8], Move move, Move prev_move, MoveType type, int was_capture, CastleRights cr) {
+ char capturestr[2] = "x";
+ char piece_id[3] = "";
+
+ if (!was_capture) {
+ capturestr[0] = 0;
+ }
+ if (move.piece == bP || move.piece == wP) {
+ if (was_capture) {
+ sprint(piece_id, "%c", 'A'+move.src.x);
+ }
+ } else {
+ // TODO: check the board and remove redundant info when possible
+ char src_file[2] = "";
+ char src_rank[2] = "";
+ int must_add_file = 0;
+ int must_add_rank = 0;
+ int others = 0;
+ // if other piece of the same type which could also go there
+ for (int x=0; x<8; x++) for (int y=0; y<8; y++) {
+ if (x == move.src.x && y == move.src.y || board[y][x] != move.piece) continue;
+ if (islegal(board, Pt(x, y), move.dst, prev_move, cr)) {
+ others = 1;
+ // if the rank is the same we must add the file, and vice versa
+ if (y == move.src.y) must_add_file = 1;
+ if (x == move.src.x) must_add_rank = 1;
+ }
+ }
+ if (others && !must_add_file && !must_add_rank) must_add_file = 1;
+ if (must_add_file) {
+ sprint(src_file, "%c", 'a'+move.src.x);
+ }
+ if (must_add_rank) {
+ sprint(src_rank, "%d", 8-move.src.y);
+ }
+ sprint(piece_id, "%c%s%s", PIECE_STR[move.piece][1], src_file, src_rank);
+ }
+ if (type == WhiteLongCastle || type == BlackLongCastle) {
+ sprint(movestring, "O-O-O");
+ } else if (type == WhiteShortCastle || type == BlackShortCastle) {
+ sprint(movestring, "O-O");
+ } else {
+ sprint(movestring, "%s%s%c%d", piece_id,
+ capturestr, 'a'+move.dst.x, 8-move.dst.y);
+ }
+}
+
void
threadmain(int, char **)
{
@@ -444,6 +493,7 @@ threadmain(int, char **)
memset(&cr, 0, sizeof(cr));
Move* history = calloc(MAX_MOVES, sizeof(Move));
+ char* movestrings = calloc(MAX_MOVES, MOVE_STR_LEN);
int move_num = 0;
// MAIN LOOP
@@ -496,36 +546,15 @@ threadmain(int, char **)
Point history_base = addpt(screen->r.min, Pt(50*8+25, 5));
for (int move = 0; move < move_num; move++) {
- char movestring[10];
- char capturestr[2] = "x";
- char piece_id[3] = "";
+ char fullstr[20];
char numstr[6] = "";
if (move % 2 == 0) {
sprint(numstr, "%d. ", move / 2 + 1);
}
- Move disp_move = history[move];
- if (!disp_move.was_capture) {
- capturestr[0] = 0;
- }
- if (disp_move.piece == bP || disp_move.piece == wP) {
- if (disp_move.was_capture) {
- sprint(piece_id, "%c", 'A'+disp_move.src.x);
- }
- } else {
- // TODO: check the board and remove redundant info when possible
- sprint(piece_id, "%c%c%d", PIECE_STR[disp_move.piece][1],
- 'A'+disp_move.src.x, 8-disp_move.dst.y);
- }
- if (disp_move.type == WhiteLongCastle || disp_move.type == BlackLongCastle) {
- sprint(movestring, "%sO-O-O", numstr);
- } else if (disp_move.type == WhiteShortCastle || disp_move.type == BlackShortCastle) {
- sprint(movestring, "%sO-O", numstr);
- } else {
- sprint(movestring, "%s%s%s%c%d", numstr, piece_id,
- capturestr, 'A'+disp_move.dst.x, 8-disp_move.dst.y);
- }
+ char* movestring = &movestrings[move*MOVE_STR_LEN];
+ sprint(fullstr, "%s%s", numstr, movestring);
Point end = string(screen, addpt(history_base, Pt(move & 1 ? 90 : 0, move / 2 * 20)),
- black, ZP, font, movestring);
+ black, ZP, font, fullstr);
}
flushimage(display, 1);
@@ -577,28 +606,34 @@ threadmain(int, char **)
selected = hovered; // select
} else if (src_piece && (move_type = islegal(board, selected, hovered, prev_move, cr))) {
// move
- prev_move.piece = src_piece;
- prev_move.src = selected;
- prev_move.dst = hovered;
- prev_move.was_capture = dst_piece;
- prev_move.type = move_type;
+ Move new_move;
+ new_move.piece = src_piece;
+ new_move.src = selected;
+ new_move.dst = hovered;
+ //int prev_board[8][8];
+ //int prev_move
+ //memcpy(prev_board, board, sizeof(int)*8*8);
+ if (move_num < MAX_MOVES) {
+ history[move_num] = new_move;
+ print_move(&movestrings[MOVE_STR_LEN*move_num], board,
+ new_move, prev_move, move_type, dst_piece, cr);
+ move_num++;
+ }
+
do_move(board, selected, hovered, move_type);
selected = Pt(-1, -1); // unselect
if (src_piece == bK) cr.bK_ever_moved = 1;
if (src_piece == wK) cr.wK_ever_moved = 1;
- if (eqpt(prev_move.src, Pt(0, 0)) || eqpt(prev_move.dst, Pt(0, 0)))
+ if (eqpt(new_move.src, Pt(0, 0)) || eqpt(new_move.dst, Pt(0, 0)))
cr.bRA_ever_moved = 1;
- if (eqpt(prev_move.src, Pt(0, 7)) || eqpt(prev_move.dst, Pt(0, 7)))
+ if (eqpt(new_move.src, Pt(0, 7)) || eqpt(new_move.dst, Pt(0, 7)))
cr.wRA_ever_moved = 1;
- if (eqpt(prev_move.src, Pt(7, 0)) || eqpt(prev_move.dst, Pt(7, 0)))
+ if (eqpt(new_move.src, Pt(7, 0)) || eqpt(new_move.dst, Pt(7, 0)))
cr.bRH_ever_moved = 1;
- if (eqpt(prev_move.src, Pt(7, 7)) || eqpt(prev_move.dst, Pt(7, 7)))
+ if (eqpt(new_move.src, Pt(7, 7)) || eqpt(new_move.dst, Pt(7, 7)))
cr.wRH_ever_moved = 1;
+ prev_move = new_move;
turn = !turn;
- if (move_num < MAX_MOVES) {
- history[move_num] = prev_move;
- move_num++;
- }
}
}
prev_click = click;