diff options
author | Jaume Delclòs Coll <cosa@cosarara.me> | 2024-05-08 13:04:44 +0000 |
---|---|---|
committer | Jaume Delclòs Coll <cosa@cosarara.me> | 2024-05-08 13:04:44 +0000 |
commit | 700a054974068b7cc886e3d0a4701eddcbdc59cb (patch) | |
tree | 52bc8c31178c039b52ea7da669215870c1c41594 | |
parent | 008781c1a510f764d6c99024faafb51534aebbaf (diff) |
pretty notation
-rw-r--r-- | chess.c | 115 |
1 files changed, 75 insertions, 40 deletions
@@ -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; |