int Book::GetMoveAll( Shogi* pshogi, Moves& moves, TYPE type ){ /************************************************ 定跡手を列挙する。 ************************************************/ int i; int flag; list<BLIST>::iterator ib; list<MLIST>::iterator im; list<MLIST>* pmlist; uint64 hash = pshogi->GetHash(); MOVE mtemp; i = (int)( hash & BOOK_HASH_MASK ); // 局面が既にあるか調べる。 flag = 0; for( ib = blist[i].begin() ; ib != blist[i].end() ; ++ib ){ if( (*ib).hash == hash ){ flag = 1; break; } } if( flag == 0 ) return 0; // 指し手を列挙 pmlist = &(*ib).mlist; for( im = pmlist->begin() ; im != pmlist->end() ; ++im ){ mtemp.Import( (*im).mv ); if( pshogi->IsLegalMove( mtemp ) ){ switch( type ){ // 評価値を用いる場合 case TYPE_EVAL: mtemp.value = (*im).val; break; // 出現頻度を用いる場合 case TYPE_FREQ: default: mtemp.value = (*im).cnt * 100 / (*ib).cnt; break; } moves.Add( mtemp ); } } moves.Sort(); return moves.GetNumber(); }
Book& Book::operator+=( Book& book ){ /************************************************ 定跡データの併合 ************************************************/ list<BLIST>::iterator ib; list<MLIST>::iterator im; list<MLIST>* pmlist; unsigned h; MOVE mtemp; for( h = 0 ; h < BOOK_HASH_SIZE ; ++h ){ for( ib = book.blist[h].begin() ; ib != book.blist[h].end() ; ++ib ){ pmlist = &(*ib).mlist; for( im = pmlist->begin() ; im != pmlist->end() ; ++im ){ mtemp.Import( (*im).mv ); Add( (*ib).hash, mtemp, OVER_WRITE, (*im).cnt ); } } } return *(this); }
int Book::GetMove( Shogi* pshogi, MOVE& move, TYPE type ){ /************************************************ 定跡から指し手を探す。 ************************************************/ unsigned i; int flag; list<BLIST>::iterator ib; list<MLIST>::iterator im; int cnt; uint64 hash = pshogi->GetHash(); MOVE mtemp; i = (unsigned)( hash & BOOK_HASH_MASK ); // 局面が既にあるか調べる。 flag = 0; for( ib = blist[i].begin() ; ib != blist[i].end() ; ++ib ){ if( (*ib).hash == hash ){ flag = 1; break; } } if( flag == 0 ) return 0; // 指し手を決定 switch( type ){ // 評価値を用いる場合 case TYPE_EVAL: { list<MLIST>* pmlist = &(*ib).mlist; int vmax = (*pmlist->begin()).val - 1; for( im = pmlist->begin() ; im != pmlist->end() ; ++im ){ mtemp.Import( (*im).mv ); if( (*im).val > vmax && pshogi->IsLegalMove( mtemp ) ){ vmax = (*im).val; move = mtemp; } } return 1; } break; // 出現頻度を用いる場合 case TYPE_FREQ: default: list<MLIST>* pmlist = &(*ib).mlist; cnt = (int)( gen_rand32() % (*ib).cnt ); for( im = pmlist->begin() ; im != pmlist->end() ; ++im ){ cnt -= (*im).cnt; if( cnt < 0 ){ mtemp.Import( (*im).mv ); if( pshogi->IsLegalMove( mtemp ) ){ move = mtemp; return 1; } } } break; } return 0; }