-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.c
More file actions
140 lines (122 loc) · 3.18 KB
/
utils.c
File metadata and controls
140 lines (122 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "lib/utils.h"
#include "lib/board.h"
#include <stddef.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
int pi(char file, char rank) {
if (file < 'a' || file > 'h' || rank < '1' || rank > '8') return -1;
return (rank - '1') * 8 + (file - 'a');
}
void ip(int index, char *file, char *rank) {
*file = 'a' + (index % 8);
*rank = '1' + (index / 8);
}
int index_rank(int rank, int file) {
return (rank * 8) + file;
}
void print_move_eval(const char *label, int packed, int eval) {
int from = packed / 64;
int to = packed % 64;
char ff, fr, tf, tr;
ip(from, &ff, &fr);
ip(to, &tf, &tr);
printf("%s: %c%c -> %c%c (from=%d, to=%d), eval=%d\n", label, ff, fr, tf, tr, from, to, eval);
}
int uci_to_from_to(const char *uci, int *from, int *to) {
if (!uci)
return 0;
size_t len = strlen(uci);
if (len < 4)
return 0;
int ff = uci[0] - 'a';
int fr = uci[1] - '1';
int tf = uci[2] - 'a';
int tr = uci[3] - '1';
if (ff < 0 || ff > 7 || tf < 0 || tf > 7 || fr < 0 || fr > 7 || tr < 0 || tr > 7) {
return 0;
}
*from = fr * 8 + ff;
*to = tr * 8 + tf;
return 1;
}
void san_from_move(int pt, int from, int to, int capture, char *out, size_t out_size) { // make a san string from move
int file_from = from % 8;
int rank_from = from / 8;
int file_to = to % 8;
int rank_to = to / 8;
int idx = 0;
if (pt == KING && (file_to - file_from == 2 || file_from - file_to == 2)) { // castling
if (file_to > file_from) {
// O-O -> "OO"
out[idx++] = 'O';
out[idx++] = 'O';
} else {
// O-O-O -> "OOO"
out[idx++] = 'O';
out[idx++] = 'O';
out[idx++] = 'O';
}
out[idx] = '\0';
return;
}
if (pt == PAWN) {
if (capture) {
out[idx++] = 'a' + file_from; // dxe5 style
out[idx++] = 'x';
}
out[idx++] = 'a' + file_to;
out[idx++] = '1' + rank_to;
} else {
char pchar = '?';
switch (pt) {
case KNIGHT: pchar = 'N'; break;
case BISHOP: pchar = 'B'; break;
case ROOK: pchar = 'R'; break;
case QUEEN: pchar = 'Q'; break;
case KING: pchar = 'K'; break;
default: pchar = '?'; break;
}
out[idx++] = pchar;
if (capture) {
out[idx++] = 'x';
}
out[idx++] = 'a' + file_to;
out[idx++] = '1' + rank_to;
}
out[idx] = '\0';
}
int piece_char(char c) {
switch (c) {
case 'q': return QUEEN;
case 'r': return ROOK;
case 'b': return BISHOP;
case 'n': return KNIGHT;
default: return -1;
}
}
bool promotion_move(int side, int pt, int to) {
if (pt != PAWN)
return false;
int rank = to / 8;
return side ? (rank == 7) : (rank == 0); // white promotes ind 7, black, ind 0
}
int prompt_promotion(void) {
char line[64];
while (true) {
printf("Promote to (q/r/b/n): ");
if (!fgets(line, sizeof(line), stdin)) {
return QUEEN; // default to queen eof
}
for (int i = 0; line[i]; ++i) {
char c = line[i];
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
if (c >= 'A' && c <= 'Z') c = (char)(c - 'A' + 'a');
int p = piece_char(c);
if (p != -1) return p;
break;
}
printf("Invalid piece, q, r, b, or n.\n");
}
}