00001
00002
00003 #ifndef _CHECKTABLEUTIL_H
00004 #define _CHECKTABLEUTIL_H
00005
00006 #include "osl/checkmate/checkHashRecord.h"
00007 #include "osl/hash/hashKey.h"
00008 #include <cassert>
00009 namespace osl
00010 {
00011 namespace hash
00012 {
00013 class HashKey;
00014 }
00015 namespace checkmate
00016 {
00017 struct CheckTableUtil
00018 {
00019 template <class Table>
00020 static
00021 void allocate(CheckHashRecord*& record, Table& table,
00022 const HashKey& key, PieceStand white_stand,
00023 const PathEncoding& path,
00024 CheckHashRecord *parent)
00025 {
00026 check_assert(record == 0);
00027 record = table.allocate(key, white_stand, path);
00028 if (! record->parent)
00029 {
00030 record->parent = parent;
00031 record->distance = parent->distance+1;
00032 }
00033 }
00034
00038 template <class Table>
00039 static
00040 void allocate(Move last_move, CheckHashRecord*& record, Table& table,
00041 const HashKey& key, const PathEncoding& path,
00042 CheckHashRecord *parent)
00043 {
00044 assert(parent);
00045 const PieceStand white_stand
00046 = parent->stand(WHITE).nextStand(WHITE, last_move);
00047 allocate(record, table, key, white_stand, path, parent);
00048 }
00049
00054 template <class Table>
00055 static
00056 void allocateNext(Move next_move,
00057 CheckHashRecord*& record, Table& table,
00058 const HashKey& key_before,
00059 const PathEncoding& path_before,
00060 CheckHashRecord *parent)
00061 {
00062 assert(parent);
00063 const PieceStand white_stand
00064 = parent->stand(WHITE).nextStand(WHITE, next_move);
00065 return allocate(record, table, key_before.newHashWithMove(next_move),
00066 white_stand,
00067 PathEncoding(path_before, next_move), parent);
00068 }
00070 template <Player P, class Table>
00071 static void registerImmediateCheckmateInDefense
00072 (const HashKey& key, const PathEncoding& path,
00073 CheckHashRecord *record, CheckMove& move,
00074 ProofDisproof pdp, Move check_move, PieceStand proof_pieces,
00075 Table& table);
00076 };
00077 }
00078 }
00079
00080 template <osl::Player P, class Table>
00081 void osl::checkmate::CheckTableUtil::
00082 registerImmediateCheckmateInDefense(const HashKey& key, const PathEncoding& path,
00083 CheckHashRecord *record, CheckMove& move,
00084 ProofDisproof pdp,
00085 Move check_move, PieceStand proof_pieces,
00086 Table& table)
00087 {
00088 assert(pdp.isCheckmateSuccess());
00089 const HashKey new_key = key.newHashWithMove(move.move);
00090 const PathEncoding new_path(path, move.move);
00091 if (! move.record)
00092 CheckTableUtil::allocate
00093 (move.move, move.record, table, new_key, new_path, record);
00094 if (! move.record->proofDisproof().isCheckmateSuccess())
00095 {
00096 if (move.record->moves.empty())
00097 {
00098 CheckMove best_move(check_move);
00099 best_move.flags.set(MoveFlags::ImmediateCheckmate);
00100 move.record->moves.setOne(best_move, table.listProvider());
00101 move.record->bestMove = &*(move.record->moves.begin());
00102 }
00103 else
00104 {
00105 CheckMove *attack = move.record->moves.find(check_move);
00106 assert(attack);
00107 move.record->bestMove = attack;
00108 move.record->bestMove->flags.set(MoveFlags::ImmediateCheckmate);
00109 move.record->bestMove->record = 0;
00110 }
00111 move.record->setProofPieces(proof_pieces);
00112 move.record->propagateCheckmate<P>(ProofDisproof::Checkmate());
00113 }
00114 record->addToSolvedInDefense(move, pdp);
00115 }
00116
00117 #endif
00118
00119
00120
00121