I have a CLI chess program that takes in input from user(eg: 'e2e4') and converts it into two bitmaps i.e., s_map and e_map.
The bitmaps are represented like 0x0000000000000000ULL;
where the rightmost bit represents h8, leftmost bit represent a1.
The algorithm I used
#ifdef _WIN32
#define CLR "cls"
#else
#define CLR "clear"
#endif
#define SQS 64
#define ROW 8
typedef struct {
uint64_t wp;
uint64_t wr;
uint64_t wn;
uint64_t wb;
uint64_t wq;
uint64_t wk;
uint64_t bp;
uint64_t br;
uint64_t bn;
uint64_t bb;
uint64_t bq;
uint64_t bk;
} PieceBitmaps;
typedef struct {
uint64_t s_map, e_map;
} Move;
typedef struct {
uint64_t s_map, e_map;
} Move;
int main(int argc, char * argv[]) {
char turn = 'W';
char winner = ' ';
PieceBitmaps pieces = init_bitmap();
Move input;
while (winner == ' ') {
system(CLR);
print_stuff(turn, &pieces);
do {
input = get_input();
printf("Hex: S-map: %x E-map: %x\n", input.s_map, input.e_map);
} while (1); // TODO: Validity functions go here.
turn = (turn == 'W') ? 'B' : 'W';
}
}
Move input_to_bitmap(char* input) {
Move mv;
mv.s_map = 0x8000000000000000ULL >> (((input[1] - '1') * ROW) + (tolower(input[0]) - 'a'));
mv.e_map = 0x8000000000000000ULL >> (((input[3] - '1') * ROW) + (tolower(input[2]) - 'a'));
return mv;
}
Move get_input() {
char input[5];
printf("Enter the move eg='e2e4' : ");
fgets(input, sizeof(input), stdin);
printf("%s\n", input);
if(strlen(input) == 4) while (getchar() != '\n'); // We clear the input buffer of garbage val to insure integrity for next iteration.
if (check_valid_input(input)) return (Move){0X0ULL, 0x0ULL};
return input_to_bitmap(input);
}
int check_valid_input(char* input) {
if (input[0] > 'h' || input[0] < 'a' || input[2] > 'h' || input[2] < 'a' ||
input[1] < '1' || input[1] > '8' || input[3] < '1' || input[3] > '8' || strlen(input) != 4) {
puts("Enter the move in a valid format.");
return 1;
}
return 0;
}
The >> index is correctly calculated but, the bit doesn't seem to shift for some particular squares like squares in rank1, rank2 and just show 0 for all of them, but are correctly shifted for other squares like h8, h7 etc.
The output looks like:
Enter the move eg='e2e4' : e2e4
e2e4
Hex: S-map: 0 E-map: 0
Enter the move eg='e2e4' : h8h7
h8h7
Hex: S-map: 1 E-map: 100
Enter the move eg='e2e4' : a1a4
a1a4
Hex: S-map: 0 E-map: 0
Enter the move eg='e2e4' : b1b4
b1b4
Hex: S-map: 0 E-map: 0
Enter the move eg='e2e4' : a2b4
a2b4
Hex: S-map: 0 E-map: 0
Enter the move eg='e2e4' :
Any feedback will be appreciated.
The problem isn't in the conversion, but in the output.
In the main
function, you use the following to print the converted values:
printf("Hex: S-map: %x E-map: %x\n", input.s_map, input.e_map);
The %x
format specifier expects an unsigned int
as its argument, but you are passing in a uint64_t
which is of a different size. Using the wrong format specifier invokes undefined behavior in your code.
You need to instead use the PRIx64
macro which generates the proper format specifier to print a uint64_t
in hex:
printf("Hex: S-map: %" PRIx64 " E-map: %" PRIx64 "\n", input.s_map, input.e_map);