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
|
/**
Copyright (c) Scott Gasch
Module Name:
testsearch.c
Abstract:
This is a test module to sanity check the search code. It
operates by generating a random legal chess position and
performing a two-ply search on the position. It is expected that
the search will terminate and return a legal move.
Author:
Scott Gasch ([email protected]) 2 Jan 2005
Revision History:
**/
#include "chess.h"
#ifdef TEST
#define TIME_LIMIT 200.0
void
SetMoveTimerForTestingSearch(void)
{
g_MoveTimer.uNodeCheckMask = 0x10000 - 1;
g_MoveTimer.dStartTime = SystemTimeStamp();
g_MoveTimer.bvFlags = 0;
g_MoveTimer.dSoftTimeLimit = g_MoveTimer.dStartTime + TIME_LIMIT;
g_MoveTimer.dHardTimeLimit = g_MoveTimer.dStartTime + TIME_LIMIT;
}
FLAG
TestSearch(void)
{
SEARCHER_THREAD_CONTEXT *ctx;
POSITION pos;
ULONG u;
GAME_RESULT result;
FLAG fPost = g_Options.fShouldPost;
FLAG fRet = FALSE;
ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT));
ASSERT(ctx);
g_Options.fShouldPost = FALSE;
Trace("Testing Search routine...\n");
for (u = 0; u < 20; u++)
{
GenerateRandomLegalPosition(&pos);
// Log the exact FEN before searching it -- a crash partway
// through this loop otherwise gives no way to reproduce which
// of the 20 random positions triggered it (this cost real
// debugging time chasing an intermittent failure whose
// position was never captured -- see board_representation/
// MOVEGEN_MIGRATION.md section 6b).
{
char *pszFen = PositionToFen(&pos);
Trace("TestSearch position %lu/20: %s\n", u + 1,
pszFen ? pszFen : "(PositionToFen failed)");
}
InitializeSearcherContext(&pos, ctx);
g_MoveTimer.bvFlags = 0;
g_Options.fPondering = FALSE;
g_Options.fThinking = TRUE;
g_Options.fSuccessfulPonder = FALSE;
MaintainDynamicMoveOrdering();
DirtyHashTable();
//
// TODO: Any preEval?
//
//
// Set a very long time limit on the search
//
SetMoveTimerForTestingSearch();
g_Options.uMaxDepth = 2;
//
// TODO: Set draw value
//
#if (PERF_COUNTERS && MP)
ClearHelperThreadIdleness();
#endif
result = Iterate(ctx);
//
// How long did that take?
//
if (SystemTimeStamp() - g_MoveTimer.dStartTime > TIME_LIMIT)
{
UtilPanic(TESTCASE_FAILURE,
NULL, "TestSearch", NULL, NULL,
__FILE__, __LINE__);
}
//
// Did we get a sane move?
//
if (RESULT_IN_PROGRESS == result.eResult)
{
if (FALSE == SanityCheckMove(&pos, ctx->mvRootMove))
{
UtilPanic(TESTCASE_FAILURE,
NULL, "TestSearch", NULL, NULL,
__FILE__, __LINE__);
}
}
#ifdef DEBUG
else if (RESULT_WHITE_WON == result.eResult)
{
ASSERT(InCheck(&pos, BLACK));
}
else if (RESULT_BLACK_WON == result.eResult)
{
ASSERT(InCheck(&pos, WHITE));
}
#endif
}
fRet = TRUE;
g_Options.fShouldPost = fPost;
SystemFreeMemory(ctx);
return(fRet);
}
#endif
|