LoopList wrote:In which line of the following code do you see the problem or bug? I simplified the code a bit.
Code: Select all
#include <stdio.h>
const int IS_ENPASSANT = 1 << 15;
struct move_info_c { int move, value; };
struct board_c { int piece_on[64]; } B;
inline int move_to(int move) { return move & 63; }
inline int move_from(int move) { return (move >> 6) & 63; }
inline int move_is_enpassant(int move) { return (move & IS_ENPASSANT) != 0; }
inline int make_enpassant(int from, int to) { return to | (from << 6) | IS_ENPASSANT; }
inline int piece_on_square(int square) { return B.piece_on[square]; }
inline int move_is_capture(int move) { return (piece_on_square(move_to(move)) != 6) || move_is_enpassant(move); }
inline int move_piece(int move) { return piece_on_square(move_from(move)); }
inline int move_piece_captured(int move) { return move_is_enpassant(move) ? 0 : piece_on_square(move_to(move)); }
inline int piece_value_midgame(int piece) {
int piece_value_mg[7] = {100, 300, 400, 500, 900, 1000, 0};
return piece_value_mg[piece];
}
void initialize() {
for (int square = 0; square < 64; square++) B.piece_on[square] = 6;
B.piece_on[28] = B.piece_on[29] = 0;
}
class sort_c {
public:
sort_c();
move_info_c * last_move, move_list[256];
};
sort_c::sort_c() {
move_list[0].move = make_enpassant(28, 21);
move_info_c * current = move_list;
int move = current->move, value = 0, temp = 0;
if (value < 0) current->value = value;
else if (move_is_capture(move)) {
temp = 50000 + piece_value_midgame(move_piece_captured(move)) - move_piece(move);
current->value = temp;
}
else current->value = 0;
printf_s("value...........%d\n", current->value);
printf_s("temp............%d\n", temp);
}
int main() {
initialize();
sort_c s;
return 0;
}
The following is essentially the same program as your already reduced version above:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
// change the following line into "typedef int uint;" if you are sure that
// the problem is not related to signedness
typedef unsigned int uint;
// change the following line into "typedef int MYBOOL;" if you are sure that
// the problem is not related to using int instead of bool
typedef bool MYBOOL;
void assertionFailure(char const * expr, char const * file, int line) {
fprintf(stderr, "ASSERTION FAILED: "%s" (%s, line %d)\n", file, line);
exit(1);
}
#define ASSERT(expr) if (!(expr)) assertionFailure(#expr, __FILE__, __LINE__)
const int IS_ENPASSANT = 1 << 15;
struct board_c { uint piece_on[64]; } B;
inline uint move_to(int move) {
return move & 63;
}
inline uint move_from(int move) {
return (move >> 6) & 63;
}
inline MYBOOL move_is_enpassant(int move) {
return (move & IS_ENPASSANT) != 0;
}
inline int make_enpassant(uint from, uint to) {
return to | (from << 6) | IS_ENPASSANT;
}
inline uint piece_on_square(uint square) {
ASSERT(square < 64);
return B.piece_on[square];
}
inline MYBOOL move_is_capture(int move) {
return (piece_on_square(move_to(move)) != 6) || move_is_enpassant(move);
}
inline uint move_piece(int move) {
return piece_on_square(move_from(move));
}
inline uint move_piece_captured(int move) {
return move_is_enpassant(move) ? 0 : piece_on_square(move_to(move));
}
inline int piece_value_midgame(uint piece) {
ASSERT(piece < 7);
int piece_value_mg[7] = {100, 300, 400, 500, 900, 1000, 0};
return piece_value_mg[piece];
}
int main() {
for (uint square = 0; square < 64; square++) B.piece_on[square] = 6;
B.piece_on[28] = B.piece_on[29] = 0;
int move = make_enpassant(28, 21);
ASSERT(move_is_enpassant(move));
int temp = 0;
if (move_is_capture(move)) {
temp = 50000
+ piece_value_midgame(move_piece_captured(move))
- move_piece(move);
}
printf_s("temp............%d\n", temp);
// pause, just to be able to see the output when running the program with "F5" in VisualStudio ...
printf("press return ...\n");
char line[80];
(void) fgets(line, sizeof(line), stdin);
return 0;
}
but with the following changes:
1. Removed the move_info_c structure, the move_list, and all code related to these data structures, assuming that the faulty behaviour is not related to that aspect but does already occur with a simple "int move" and no move list around it.
2. Removed other unused code: int value = 0, if (value < 0).
3. Removed class sort_c, putting the essential code directly into main().
4. Added few ASSERT's (here also used in release version).
5. Introduced usage of unsigned int and bool, in order to verify that the problem is not related to these aspects (you can roll back both easily, see code comments)
Does this program version still expose the problem with VS2010/x64 and the options you described? If it does: is there an ASSERT thrown, or just a wrong value printed? If it does not, you can try to add potentially "offending" parts of the program that have been removed so far, step by step, until the problem pops up again. Of special interest would be whether my assumption under no. 1 above holds.
At the moment I do not see any wrong implementation here, too, so a compiler bug would be the logical conclusion. But one point creates some doubt: why should that compiler bug pop up just for some chess program code using "en passant", where each chess programmer has already had a couple of ep bugs in his chess programmer lifetime?
Sven