/usr/include/osl/checkmate/proofNumberTable.h is in libosl-dev 0.8.0-1.4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | /* proofNumberTable.h
*/
#ifndef OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
#define OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
#include "osl/checkmate/proofDisproof.h"
#include "osl/numEffectState.h"
#include "osl/bits/king8Info.h"
#include "osl/additionalEffect.h"
#include "osl/bits/boardTable.h"
namespace osl
{
namespace checkmate
{
class ProofNumberTable
{
public:
struct Liberty
{
/** 玉の自由度の予測値. 空王手の場合は 0 のことがある.*/
uint8_t liberty;
/** false の場合は必ず空き王手 */
bool has_effect;
explicit Liberty(uint8_t l=0, bool e=false) : liberty(l), has_effect(e)
{
}
};
private:
/** 一つの王手 -> Liberty:
* long なdirection は1マスあけた王手を意味する */
CArray2d<CArray<Liberty,DIRECTION_SIZE>,0x100u,PTYPE_SIZE> liberties;
/** 全ての有効drop -> 最小liberty.
* liberty 8bit + 有効drop 8bit + 最小値 -> ptype mask
*/
CArray2d<uint8_t,0x10000u,8> drop_liberty;
/** 龍や馬で王手をかけられる時のliberty: [liberty][move_mask] */
CArray2d<uint8_t,0x100u,0x100u> pmajor_liberty;
/** 王が1,2段目にいる時の移動王手によるliberty: [liberty][move_mask].
* それ以外でUに金類が移動できる場合もこれで良いか.
*/
CArray2d<uint8_t,0x100u,0x100u> promote_liberty;
/** それ以外の移動liberty: [liberty][move_mask] */
CArray2d<uint8_t,0x100u,0x100u> other_move_liberty;
public:
void init();
/**
* dir 方向からの王手をかけた時のlibertyの予想
*/
const Liberty countLiberty(Ptype ptype, Direction d, unsigned int liberty_mask) const
{
assert((d != UUL) && (d != UUR));
assert(liberty_mask <= 0xff);
return liberties[liberty_mask][ptype][d];
}
/**
* 8近傍へのdropまたは取れない移動後のlibertyの予測値を返す.
* 玉は取り返せる時でも取り返さない値.
* 桂馬は表をひく必要がないので呼び出し側で処理する.
* @return 空王手の場合は 0 のことがある.
*/
const Liberty countLibertyShortNotKnight(Player player, Square to, Ptype ptype,
Square king, King8Info info) const
{
assert(to.isNeighboring8(king));
assert(ptype != KNIGHT);
const unsigned int liberty_mask = info.liberty();
const Direction d =
(player == BLACK)
? Board_Table.getShort8<BLACK>(to, king)
: Board_Table.getShort8<WHITE>(to, king);
return countLiberty(ptype, d, liberty_mask);
}
const Liberty countLibertyLong(Player player, Square to, Ptype ptype,
Square king, King8Info info) const
{
assert(! to.isNeighboring8(king));
const unsigned int liberty_mask = info.liberty();
const Offset32 offset32(king,to);
const Offset offset = Board_Table.getShortOffsetNotKnight(offset32);
if (offset.zero())
return Liberty(0, false);
if (to + offset + offset != king) // 2マス以上遠く
{
if (isMajor(ptype))
ptype = unpromote(ptype);
else if (ptype != LANCE)
return Liberty(0, false);
}
const Direction d =
(player == BLACK)
? Board_Table.getLongDirection<BLACK>(offset32)
: Board_Table.getLongDirection<WHITE>(offset32);
assert(isLong(d));
return countLiberty(ptype, d, liberty_mask);
}
/**
* move は王手である必要がある
*/
int countLiberty(const NumEffectState& state, int liberty_count,
Move move, Square king, King8Info info) const
{
assert(liberty_count == misc::BitOp::countBit(info.liberty()));
const Player attack = move.player();
const Player defense = alt(attack);
const Square to = move.to();
const Ptype ptype = move.ptype();
if (ptype == KNIGHT)
return std::max(1,liberty_count + state.countEffect(defense, to));
const bool neighboring = to.isNeighboring8(king);
Liberty liberty = neighboring
? countLibertyShortNotKnight(attack, to, ptype, king, info)
: countLibertyLong(attack, to, ptype, king, info);
if (liberty.liberty == 0)
return std::max(liberty_count-1,1);
if (! neighboring && liberty.has_effect)
{
// TODO: 詰将棋と協調できるなら liberty.liberty <=
// liberty_count を保つように調整したい,が.
++liberty.liberty; // 合駒の分,もし両王手の場合は本来は不要
}
liberty.liberty += state.countEffect(defense, to);
if (move.isDrop())
{
if (neighboring)
{
if (state.countEffect(attack, to))
--liberty.liberty; // adjust king capture
}
assert(liberty.liberty);
return liberty.liberty;
}
// 移動: 銀のただすてなどは本当は利きをはずしたい
if (neighboring)
{
if (state.countEffect(attack, to) >= 2
|| effect_util::AdditionalEffect::hasEffect(state, to, attack))
--liberty.liberty; // adjust king capture
}
assert(liberty.liberty);
return liberty.liberty;
}
/** テスト用 */
int countLiberty(const NumEffectState& state, Move move) const;
/** drop のみ */
int
#ifdef __GNUC__
__attribute__ ((pure))
#endif
libertyAfterAllDrop(const NumEffectState& state) const;
int
#ifdef __GNUC__
__attribute__ ((pure))
#endif
libertyAfterAllDrop(const NumEffectState& state, Player attack,
King8Info info) const;
/** 移動 のみ */
int
#ifdef __GNUC__
__attribute__ ((pure))
#endif
libertyAfterAllMove(const NumEffectState& state) const;
int
#ifdef __GNUC__
__attribute__ ((pure))
#endif
libertyAfterAllMove(const NumEffectState& state, Player attack,
King8Info info, Square king) const;
/** 全て */
int
#ifdef __GNUC__
__attribute__ ((pure))
#endif
libertyAfterAllCheck(const NumEffectState& state) const;
int
#ifdef __GNUC__
__attribute__ ((pure))
#endif
disproofAfterAllCheck(const NumEffectState&, Player, King8Info) const;
/** 全て */
const ProofDisproof
#ifdef __GNUC__
__attribute__ ((pure))
#endif
attackEstimation(const NumEffectState& state) const;
const ProofDisproof
#ifdef __GNUC__
__attribute__ ((pure))
#endif
attackEstimation(const NumEffectState& state,
Player attack,
King8Info info, Square king) const;
};
// tables.ccに入れればconstにできる
extern ProofNumberTable Proof_Number_Table;
class EdgeTable
{
CArray2d<uint64_t, 2, Square::SIZE> edge_mask;
public:
void init();
/** liberty から盤の淵(xかyが1か9)を取り除く. libertyCount()==0になっても詰みとは限らない */
const King8Info
#ifdef __GNUC__
__attribute__ ((pure))
#endif
resetEdgeFromLiberty(Player king_player, Square king, King8Info info) const
{
uint64_t ret = info.uint64Value();
ret &= edge_mask[king_player][king.index()];
const uint64_t count = misc::BitOp::countBit((ret>>8)&0xffull);
ret |= count << 48;
return King8Info(ret);
}
};
extern EdgeTable Edge_Table;
}
}
#endif /* _CHECKMATE_IMMEDIATE_CHECKMATE_TABLE_H */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
|