00001
00002
00003 #include "osl/game_playing/historyToTable.h"
00004 #include "osl/game_playing/gameState.h"
00005 #include "osl/hash/hashKeyStack.h"
00006 #include "osl/repetitionCounter.h"
00007 #include "osl/search/simpleHashTable.h"
00008 #include "osl/search/simpleHashRecord.h"
00009 #include "osl/container/moveStack.h"
00010
00011 const int osl::game_playing::HistoryToTable::LIMIT
00012 = osl::search::SearchTable::HistorySpecialDepth;
00013
00014 void osl::game_playing::
00015 HistoryToTable::adjustDominance(const HashKey& key,
00016 search::SimpleHashTable& table,
00017 int black_win, int white_win,
00018 const Move& good_move)
00019 {
00020 const PieceStand black_stand = key.getPieceStand();
00021 const Player turn = key.turn();
00022 for (size_t i=0; i<PieceStand::order.size(); ++i)
00023 {
00024 const Ptype ptype = PieceStand::order[i];
00025 if (black_stand.get(ptype))
00026 {
00027
00028 PieceStand new_stand = black_stand;
00029 new_stand.sub(ptype);
00030 HashKey new_key = key;
00031 new_key.setPieceStand(new_stand);
00032 SimpleHashRecord *record = table.allocate(new_key, LIMIT);
00033 if (record)
00034 {
00035 const Move record_move = (turn == WHITE) ? good_move : Move::INVALID();
00036 record->setAbsoluteValue(record_move, white_win, LIMIT);
00037 record->qrecord.setHistoryValue(record_move, white_win);
00038 }
00039 }
00040 if (black_stand.canAdd(ptype))
00041 {
00042
00043
00044
00045
00046 PieceStand new_stand = black_stand;
00047 new_stand.add(ptype);
00048 HashKey new_key = key;
00049 new_key.setPieceStand(new_stand);
00050 SimpleHashRecord *record = table.allocate(new_key, LIMIT);
00051 if (record)
00052 {
00053 const Move record_move = (turn == BLACK) ? good_move : Move::INVALID();
00054 record->setAbsoluteValue(record_move, black_win, LIMIT);
00055 record->qrecord.setHistoryValue(record_move, black_win);
00056 }
00057 }
00058 }
00059 }
00060
00061 void osl::game_playing::
00062 HistoryToTable::adjustTable(const GameState& state, SimpleHashTable& table,
00063 int black_win, int draw, int white_win)
00064 {
00065 const RepetitionCounter& counter = state.counter();
00066
00067
00068 HashKeyStack history = state.hashHistory();
00069 MoveStack move_history = state.moveHistory();
00070 move_history.push(Move::INVALID());
00071 assert(move_history.size() == history.size());
00072
00073 HashKeyStack reverse_history;
00074 while (! history.empty())
00075 {
00076 const HashKey key = history.top();
00077 history.pop();
00078 assert(move_history.hasLastMove());
00079 const Move last_move = move_history.lastMove();
00080 move_history.pop();
00081
00082 if (key != state.state().getHash())
00083 reverse_history.push(key);
00084
00085
00086 adjustDominance(key, table, black_win, white_win, last_move);
00087 }
00088
00089 while (! reverse_history.empty())
00090 {
00091
00092 const HashKey key = reverse_history.top();
00093 reverse_history.pop();
00094
00095 SimpleHashRecord *record = table.allocate(key, LIMIT);
00096 const std::pair<Sennichite,int> result = counter.distanceToSennichite(key);
00097 if (result.first.isDraw())
00098 {
00099 record->setAbsoluteValue(Move::INVALID(), draw*result.second, LIMIT);
00100 record->qrecord.setHistoryValue(draw*result.second);
00101 }
00102 else
00103 {
00104 assert(result.first.hasWinner());
00105 const int value = (result.first.winner() == BLACK) ? black_win : white_win;
00106 record->setAbsoluteValue(Move::INVALID(), value, LIMIT);
00107 record->qrecord.setHistoryValue(value);
00108 }
00109 }
00110 }
00111
00112
00113
00114
00115
00116