📄 boards.h
字号:
}
//we have an update from equal depth
switch(_vtype)
{
case notvalid:
//no value was stored here, so perform the update
_value=static_cast<signed char>(value);
//mark that we have an lower bound
_vtype=lowerbound;
break;
case lowerbound:
//if new bound is tighter then update
if(_value<value)
_value=static_cast<signed char>(value);
break;
case upperbound:
//if bounds collide then we have an exact value
if(_value==value)
_vtype=exact;
else
{
//owerwrite old entry
//TODO can I do somthing more here ???
_value=static_cast<signed char>(value);
//mark that we have an lower bound
_vtype=lowerbound;
}
break;
case exact:
//we have an exact value, do nothing
break;
};
}
/**
sets the depth of this position */
void SetDepth(unsigned int depth)
{
assert(depth>=0 && depth<=31);
_depth=static_cast<unsigned char>(depth);
}
/**
@return how deep was this position searched */
unsigned int GetDepth() const
{
return static_cast<unsigned int>(_depth);
}
/**
strips this entry of (almost) all info */
void Clean()
{
_depth=0;
_vtype=notvalid;
}
/**
@return true only if position has an exact value */
bool HasExact() const
{
return _vtype==exact;
}
/** translates: 10*10 ==> 8*8 */
static signed char Persil[10*10]; //TODO this doesn't quite belong here
/** translates: 8*8 ==> 10*10 */
static squareindex AntiPersil[8*8]; //TODO this doesn't quite belong here
//Friends will be friends...
friend class TranspositionTable;
};
//reset pack option
#pragma pack(pop)
/**
class Board, stores the board configuration */
class Board
{
//no privacy here neither
public:
/** 8 by 8 table surounded with sentinel values, to speedup
movegeneration. */
squarevalue table[10*10];
/**8x8 ought to be enough, but indexing would differ
altough I waist almost 2kb this way */
PreComp updatetable[10*10][5];
explicit Board();
/**in Othello it is posible that two or more moves are done
by one side if the other does not have any options. */
bool isblacksturn;
/** hash code */
unsigned int hash32;
/** number of empties on this board */
unsigned int empties;
/** number of blacks on this board */
unsigned int blacks;
/**
initializes the precomputed data */
void InitPrecomp();
/**
syncronize pattern indices with the current board state
this is an expensive method. */
void Syncronize();
#if !defined NDEBUG
//DEBUG
bool AssertIsInSync();
void DebugPrintBoard(int x);
#endif
/**
@return number of empty squares */
unsigned int CountEmpty() const
{
return empties;
}
/**
@return number of black discs */
unsigned int CountBlack() const
{
return blacks;
}
/**
@return number of white discs */
unsigned int CountWhite() const
{
return 64-empties-blacks;
}
/**
@return true only if this board is not infested with GUI
helper values */
bool IsClean() const;
/**
initalize the board with the start position */
void InitBoard();
//@{
/** pattern indeces, lines of length 8*/
int line1, line2, line3, line4, line5, line6, line7, line8; //@}
//@{
/** pattern indeces, colunms of length 8*/
int colA, colB, colC, colD, colE, colF, colG, colH; //@}
//@{
/** pattern indeces, diagonals of length 8 */
int diag8A1H, diag1A8H; //@}
//@{
/** pattern indeces, diagonals of length 7 */
int diag7A1G, diag2A8G, diag2H8B, diag7H1B; //@}
//@{
/** pattern indeces, diagonals of length 6 */
int diag6A1F, diag3A8F, diag3H8C, diag6H1C; //@}
//@{
/** pattern indeces, diagonals of length 5 */
int diag5A1E, diag4A8E, diag4H8D, diag5H1D; //@}
//@{
/** pattern indeces, diagonals of length 4 */
int diag4A1D, diag5A8D, diag5H8E, diag4H1E; //@}
//@{
/** pattern indeces, 2x4 corners */
int cornA1D2, cornA1B4, cornA8B5, cornA8D7,
cornH8E7, cornH8G5, cornH1G4, cornH1E2; //@}
//dummy, is this necessary?
int dummy;
// multiplications by powers of 3 to calcualte the pattern indeces.
int Mul4(int p1, int p2, int p3, int p4);
int Mul5(int p1, int p2, int p3, int p4, int p5);
int Mul6(int p1, int p2, int p3, int p4, int p5, int p6);
int Mul7(int p1, int p2, int p3, int p4, int p5, int p6, int p7);
int Mul8(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8);
int Diag3_1() const
{
return 3*(3*table[p31]+table[p22])+table[p13];
}
int Diag3_2() const
{
return 3*(3*table[p61]+table[p72])+table[p83];
}
int Diag3_3() const
{
return 3*(3*table[p38]+table[p27])+table[p16];
}
int Diag3_4() const
{
return 3*(3*table[p68]+table[p77])+table[p86];
}
/** the start up board */
static squarevalue sboard[10*10];
/** table to generate symetrics by the first diagonal */
static unsigned char sym_diag1[10*10];
/** table to generate symetrics by the second diagonal */
static unsigned char sym_diag2[10*10];
/** table to generate central symetrics */
static unsigned char sym_centr[10*10];
};
/**
Board representation in the book file, packed in 20 bytes
this is an actual entry into the Book. */
class BookBoard
{ //perhaps this should be an inner class of Book
private:
/**
only fields l and isblacksturn are initialized */
BookBoard& operator= (const Board& b);
/**
only fields l and isblacksturn are compared */
bool operator== (const BookBoard &bb)
{
return (!memcmp(l, bb.l, sizeof(l))) &&
bb.isblacksturn==isblacksturn;
}
/**
bitboard representation 00 means black,
01 means white, 10 means empty */
int l[4];
/** who's turn is it? */
unsigned char isblacksturn:1;
/** is this a valid entry? (see class Book) */
unsigned char isvalid:1;
/** best move in 0..63 format*/
unsigned char bmove:6;
/** for now trash */
unsigned char ischanged:1;
/** do we have an alternative (second best) move */
unsigned char isaltmovevalid:1;
/** the alternative move */
unsigned char altmove:6;
/** minmax value */
signed char value;
/** for now trash */
char trash;
//masks to extract board from bitboard representation
static int maskwhite[];
static int maskblack[];
static int maskempty[];
//I like friends
friend class Hasher;
friend class Book;
};
}
#endif //_BOARDS_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -