/usr/include/osl/effect/liberty8.h is in libosl-dev 0.6.0-3.1.
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 | /* liberty8.h
*/
#ifndef _LIBERTY8_H
#define _LIBERTY8_H
#include "osl/effect/liberty8Table.h"
#include "osl/direction.h"
#include "osl/piece.h"
#include "osl/ptypeList.h"
#include "osl/container/nearMask.h"
#include <boost/type_traits.hpp>
#include <iosfwd>
namespace osl
{
namespace effect
{
/**
* Liberty8で使われるHelper.
* Pは defense側
*/
template<typename Liberty,Player P,Ptype T>
class AddMaskAction{
Liberty & liberty;
NumEffectState const& state;
const Square target;
const NearMask nearMask;
public:
AddMaskAction(Liberty& l,NumEffectState const& s,Square t,NearMask n)
: liberty(l), state(s), target(t), nearMask(n)
{
}
void operator()(Piece p){
#if 1
const Square from=p.square();
const NearMask shortMask = Liberty8_Table.
getShortMask<PlayerTraits<P>::opponent>(p.ptype(), from, target);
liberty.andMask(shortMask);
if(PtypeFuns<T>::hasLongMove &&
(T!=LANCE || !p.isPromotedNotKingGold())){
LongEffect8 longEffect8=
Liberty8_Table.
getLongEffect<PlayerTraits<P>::opponent>(p.ptype(),
p.square(),
target);
Offset offset=longEffect8.getOffset();
if(offset.zero()) return;
// これが引き算で良いかどうかまだ気になる
if(state.isEmptyBetween(from,target-offset.blackOffset<P>())){
unsigned int nearMaskSpace=nearMask.spaceMask();
unsigned int mask0=longEffect8.getMask(0);
liberty.andMask(NearMask::makeDirect(~mask0));
if((mask0&nearMaskSpace)!=0){
unsigned int mask1=longEffect8.getMask(1);
liberty.andMask(NearMask::makeDirect(~mask1));
if( T!=BISHOP && (mask1&nearMaskSpace)!=0){
unsigned int mask2=longEffect8.getMask(2);
liberty.andMask(NearMask::makeDirect(~mask2));
}
}
}
}
if(T==ROOK){
LongEffect8 longEffect8=
Liberty8_Table.
getLongEffect2<PlayerTraits<P>::opponent>(p.square(),
target);
unsigned int mask0=longEffect8.getMask(0);
if(mask0==0) return;
unsigned int nearMaskSpace=nearMask.spaceMask();
liberty.andMask(NearMask::makeDirect(~mask0));
if((mask0&nearMaskSpace)==0) return;
unsigned int mask1=longEffect8.getMask(1);
liberty.andMask(NearMask::makeDirect(~mask1));
}
#else
/**
* 遅いけれどもほとんど動くバージョン
*/
for(int i=0;i<8;i++){
Direction dir=static_cast<Direction>(i);
Square to=target-Board_Table.getOffset<P>(dir);
if(to.isOnBoard() &&
state.hasEffectTo(p,to))
liberty.andMask(~(1<<i));
}
if(state.hasEffectTo(p,target)){
Direction longDirection=
Board_Table.getLongDirection<P>(target,p.square());
// 駒がある方向に長い利きをもっていて
// かつ逆方向に短い利きを持っていることはないので,
// これで良いことにする
if(Ptype_Table.getMoveMask(p.ptype())&dirToMask(longDirection)){
liberty.andMask(~(1<<longToShort(longDirection)));
}
}
#endif
}
};
/**
* 自分の駒があるマスの8近傍の敵の利きの状態を得る.
* \li Pからみて, Direction Dに敵の利きがある時に
* DirectionTraits<D>::mask のビットが立っている
* 特徴
* \li longと shortは区別しない
* \li 自分自身によってブロックされている場合は利きがあることにする
*/
template<Player P>
class Liberty8
{
/**
*/
NearMask mask;
template<Ptype T>
void addMaskPtype(NumEffectState const& state,Square target,NearMask nearMask){
typedef AddMaskAction<Liberty8<P>,P,T> action_t;
action_t action(*this,state,target,nearMask);
state.template
forEachOnBoard<PlayerTraits<P>::opponent,T,action_t>(action);
}
template<typename U>
void addMask(NumEffectState const& state,Square target,NearMask nearMask,U);
void addMask(NumEffectState const&, Square, NearMask, ptl::NullPtype){}
template<Ptype T,typename Tail>
void addMask(NumEffectState const& state,Square target,NearMask nearMask,ptl::PtypeList<T,Tail>){
addMaskPtype<T>(state,target,nearMask);
addMask(state,target,nearMask,Tail());
}
public:
Liberty8(NumEffectState const& state,Square target);
void andMask(NearMask m){
mask&=m;
}
NearMask getMask() const{
return mask;
}
/**
* 8 bit のテーブルを使って速く計算できるが
*/
int count() const{
int ret=0;
for (int i=0;i<8;i++)
if (mask.isSet(i))
ret++;
return ret;
}
};
template<Player P>
std::ostream& operator<<(std::ostream& os,Liberty8<P> const& liberty);
} // namespace effect
} // namespace osl
template<osl::Player P>
osl::effect::
Liberty8<P>::Liberty8(NumEffectState const& state, Square target)
{
/**
* targetには必ず P 側の駒があるべき
*/
assert(state.pieceAt(target).template isOnBoardByOwner<P>());
/**
* 10近傍の駒の有無を記録
* 本当は8近傍で良いのだが
*/
NearMask nearMask=NearMask::make<P>(state,target);
/**
* 下位8ビットのみで良い
* TODO: これの型は NearMask とは別であるべき?
*/
mask = NearMask::makeDirect(nearMask.uintValue() & 0xff);
addMask(state,target,nearMask,ptl::PtypeListIsBasic());
}
#endif /* _LIBERTY8_H */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
|