effect5x3.cc
Go to the documentation of this file.
/* effect5x3.cc
*/
#include "osl/progress/effect5x3.h"
#include "osl/progress/effect5x3Table.h"
osl::progress::
Effect5x3::Effect5x3(const NumEffectState& state)
{
area_progresses[BLACK]=makeProgressArea(WHITE, state, state.kingSquare(BLACK));
area_progresses[WHITE]=makeProgressArea(BLACK, state, state.kingSquare(WHITE));
stand_progresses[WHITE]=makeProgressStand(BLACK, state);
stand_progresses[BLACK]=makeProgressStand(WHITE, state);
progresses[BLACK]=area_progresses[BLACK]+stand_progresses[BLACK];
progresses[WHITE]=area_progresses[WHITE]+stand_progresses[WHITE];
}
int osl::progress::
Effect5x3::makeProgressAll(Player defense, const NumEffectState& state,
Square king)
{
return makeProgressArea(alt(defense), state, king)
+ makeProgressStand(alt(defense), state);
}
int osl::progress::
Effect5x3::makeProgressArea(Player attack, const NumEffectState& state,
Square king)
{
const Square center = Centering5x3::adjustCenter(king);
const int min_x = center.x() - 2;
const int min_y = center.y() - 1;
// 利き
int sum_effect = 0;
for (int dx=0; dx<5; ++dx)
{
for (int dy=0; dy<3; ++dy)
{
const Square target(min_x+dx,min_y+dy);
sum_effect += state.countEffect(attack, target) *
Effect5x3_Table.getAttackEffect(attack,king,dx,dy);
}
}
return sum_effect / 2;
}
int osl::progress::
Effect5x3::makeProgressStand(Player attack, const NumEffectState& state)
{
// 持駒
int sum_pieces = 0;
sum_pieces += state.countPiecesOnStand<PAWN>(attack)*Effect5x3Table::StandPAWN;
sum_pieces += state.countPiecesOnStand<LANCE>(attack)*Effect5x3Table::StandLANCE;
sum_pieces += state.countPiecesOnStand<KNIGHT>(attack)*Effect5x3Table::StandKNIGHT;
sum_pieces += state.countPiecesOnStand<SILVER>(attack)*Effect5x3Table::StandSILVER;
sum_pieces += state.countPiecesOnStand<GOLD>(attack)*Effect5x3Table::StandGOLD;
sum_pieces += state.countPiecesOnStand<BISHOP>(attack)*Effect5x3Table::StandBISHOP;
sum_pieces += state.countPiecesOnStand<ROOK>(attack)*Effect5x3Table::StandROOK;
return sum_pieces;
}
void osl::progress::
Effect5x3::updateStand(int& old_stand, Move last_move)
{
if (last_move.isDrop()) {
const Ptype ptype = last_move.ptype();
old_stand -= Effect5x3_Table.piecesOnStand(ptype);
return;
}
const Ptype ptype = last_move.capturePtype();
if (ptype == PTYPE_EMPTY) {
return;
}
old_stand += Effect5x3_Table.piecesOnStand(unpromote(ptype));
}
void osl::progress::
Effect5x3::update(const NumEffectState& new_state, Move last_move)
{
const Player pl = last_move.player();
updateStand(stand_progresses[alt(pl)], last_move);
const Square kb = new_state.kingSquare<BLACK>(), kw = new_state.kingSquare<WHITE>();
BoardMask mb = new_state.changedEffects(BLACK), mw = new_state.changedEffects(WHITE);
bool king_move = last_move.ptype() == KING;
if ((king_move && new_state.turn() == BLACK) || mb.anyInRange(Board_Mask_Table5x3_Center.mask(kw)))
area_progresses[WHITE]=makeProgressArea(BLACK,new_state, kw);
if ((king_move && new_state.turn() == WHITE) || mw.anyInRange(Board_Mask_Table5x3_Center.mask(kb)))
area_progresses[BLACK]=makeProgressArea(WHITE,new_state, kb);
progresses[BLACK]=area_progresses[BLACK]+stand_progresses[BLACK];
progresses[WHITE]=area_progresses[WHITE]+stand_progresses[WHITE];
}
osl::progress::Effect5x3 osl::progress::
Effect5x3::expect(const NumEffectState&, Move move) const
{
Effect5x3 new_progress = *this;
if (move.capturePtype() != PTYPE_EMPTY) {
const Player alt_pl = alt(move.player());
int old = stand_progresses[alt_pl];
updateStand(new_progress.stand_progresses[alt_pl], move);
new_progress.progresses[alt_pl] += new_progress.stand_progresses[alt_pl] - old;
}
return new_progress;
}
/* ------------------------------------------------------------------------- */
osl::progress::
Effect5x3WithBonus::Effect5x3WithBonus(const NumEffectState& state) : Effect5x3(state)
{
progress_bonuses[BLACK]=makeProgressAreaBonus<WHITE>(state, state.kingSquare<BLACK>());
progress_bonuses[WHITE]=makeProgressAreaBonus<BLACK>(state, state.kingSquare<WHITE>());
effect_mask[BLACK] = makeEffectMask<BLACK>(state);
effect_mask[WHITE] = makeEffectMask<WHITE>(state);
updateProgressBonuses(state);
}
template <osl::Player Defense>
osl::PieceMask osl::progress::
Effect5x3WithBonus::makeEffectMask(const NumEffectState &state)
{
const Square king =
state.kingSquare<Defense>();
const Square center =
Centering5x3::adjustCenter(king);
const int min_x = center.x() - 2;
const int min_y = center.y() - 1;
PieceMask mask;
for (int dx = 0; dx < 5; ++dx)
{
for (int dy = 0; dy < 3; ++dy)
{
const Square target(min_x+dx, min_y+dy);
mask = mask | state.effectSetAt(target);
}
}
return mask;
}
inline
int osl::progress::
Effect5x3WithBonus::attackEffect3(const NumEffectState& state, Player attack, Square target)
{
const int a = state.countEffect(attack, target);
if (a <= 1)
return a;
if (state.countEffect(alt(attack), target) > 0
|| state.pieceAt(target).isOnBoardByOwner(attack))
return 1;
return 2;
}
namespace osl
{
namespace
{
template <Player P>
int countPawnLanceKnight(const NumEffectState& state, Square target)
{
// effect is max 2, pawn and lance cannot have the effect
// to a position at the same time so this is OK
const Square d = target+DirectionPlayerTraits<D,P>::offset();
const Piece pd = state.pieceAt(d);
// pawn and lance
int count = 0;
if (pd.ptypeO() == newPtypeO(P,PAWN))
++count;
else if (pd.ptypeO() == newPtypeO(P,LANCE))
++count;
else if (pd.isEmpty())
{
if (state.hasLongEffectAt<LANCE>(P, target))
++count;
}
else if (pd.isEdge())
return 0;
// knight
const Piece pdl = state.pieceAt(d+DirectionPlayerTraits<DL,P>::offset());
if (pdl.ptypeO() == newPtypeO(P,KNIGHT))
return count+1;
const Piece pdr = state.pieceAt(d+DirectionPlayerTraits<DR,P>::offset());
if (pdr.ptypeO() == newPtypeO(P,KNIGHT))
return count+1;
return count;
}
}
}
template <osl::Player Attack, bool AlwaysPromotable, bool AlwaysNotPromotable>
int osl::progress::
Effect5x3WithBonus::makeProgressAreaBonus(const NumEffectState& state, Square king,
Square center)
{
const int min_x = center.x() - 2;
const int min_y = center.y() - 1;
// 利き
int sum_effect = 0;
for (int dy = 0; dy < 3; ++dy)
{
const Square target(king.x(), min_y + dy);
int effect = attackEffect3(state, Attack, target) * 2;
if (effect > 0)
{
if (! AlwaysPromotable
&& (AlwaysNotPromotable || !target.canPromote<Attack>()) )
{
effect -= countPawnLanceKnight<Attack>(state, target);
assert(effect >= 0);
}
sum_effect += effect *
Effect5x3_Table.getAttackEffect(Attack, king, target.x() - min_x, dy) / 2;
}
}
for (int x = king.x() - 1; x >= min_x; --x)
{
int y_count = 0;
int sum = 0;
for (int dy = 0; dy < 3; ++dy)
{
const Square target(x, min_y + dy);
int effect = attackEffect3(state, Attack, target) * 2;
if (effect > 0)
{
if (! AlwaysPromotable
&& (AlwaysNotPromotable || !target.canPromote<Attack>()) )
{
if (king.x() - x > 1)
effect = 0;
else
effect -= countPawnLanceKnight<Attack>(state, target);
assert(effect >= 0);
}
sum += effect *
Effect5x3_Table.getAttackEffect(Attack, king, x - min_x, dy) / 2;
y_count++;
}
}
sum_effect += sum;
if (y_count == 3)
{
sum_effect += sum;
break;
}
}
for (int x = king.x() + 1; x < min_x + 5; ++x)
{
int y_count = 0;
int sum = 0;
for (int dy = 0; dy < 3; ++dy)
{
const Square target(x, min_y + dy);
int effect = attackEffect3(state, Attack, target) * 2;
if (effect > 0)
{
if (! AlwaysPromotable
&& (AlwaysNotPromotable || !target.canPromote<Attack>()) )
{
if (x - king.x() > 1)
effect = 0;
else
effect -= countPawnLanceKnight<Attack>(state, target);
assert(effect >= 0);
}
sum += effect *
Effect5x3_Table.getAttackEffect(Attack, king, x - min_x, dy) / 2;
y_count++;
}
}
sum_effect += sum;
if (y_count == 3)
{
sum_effect += sum;
break;
}
}
return sum_effect / 2;
}
template <osl::Player Attack>
int osl::progress::
Effect5x3WithBonus::makeProgressAreaBonus(const NumEffectState& state,
Square king)
{
const Square center = Centering5x3::adjustCenter(king);
const bool always_promotable = center.squareForBlack<Attack>().y() <= 2;
if (always_promotable)
return makeProgressAreaBonus<Attack,true,false>(state, king, center);
const bool always_notpromotable = center.squareForBlack<Attack>().y() >= 5;
if (always_notpromotable)
return makeProgressAreaBonus<Attack,false,true>(state, king, center);
return makeProgressAreaBonus<Attack,false,false>(state, king, center);
}
void osl::progress::
Effect5x3WithBonus::update(const NumEffectState& new_state, Move last_move)
{
Effect5x3::update(new_state, last_move);
const Square kb = new_state.kingSquare<BLACK>(), kw = new_state.kingSquare<WHITE>();
BoardMask mask = new_state.changedEffects();
mask.set(last_move.to()); mask.set(last_move.from());
const bool update_black = mask.anyInRange(Board_Mask_Table5x3_Center.mask(kb));
const bool update_white = mask.anyInRange(Board_Mask_Table5x3_Center.mask(kw));
if (update_black)
{
progress_bonuses[BLACK]=makeProgressAreaBonus<WHITE>(new_state,kb);
effect_mask[BLACK] = makeEffectMask<BLACK>(new_state);
}
if (update_white)
{
progress_bonuses[WHITE]=makeProgressAreaBonus<BLACK>(new_state,kw);
effect_mask[WHITE] = makeEffectMask<WHITE>(new_state);
}
updateProgressBonuses(new_state, update_black, update_white);
}
osl::progress::Effect5x3WithBonus osl::progress::
Effect5x3WithBonus::expect(const NumEffectState&, Move move) const
{
Effect5x3WithBonus new_progress = *this;
if (move.capturePtype() != PTYPE_EMPTY) {
const Player alt_pl = alt(move.player());
int old = stand_progresses[playerToIndex(alt_pl)];
new_progress.updateStand(alt_pl, move);
new_progress.progresses[playerToIndex(alt_pl)] += new_progress.stand_progresses[playerToIndex(alt_pl)] - old;
}
return new_progress;
}
void osl::progress::
Effect5x3WithBonus::updateProgressBonuses(const NumEffectState& state, bool update_black, bool update_white)
{
if (update_black && progress_bonuses[BLACK] != 0)
{
const int pieces = countEffectPieces(state, WHITE);
progress_bonuses[BLACK] =
std::min(pieces * pieces * 4,
progress_bonuses[BLACK]);
}
if (update_white && progress_bonuses[WHITE] != 0)
{
const int pieces = countEffectPieces(state, BLACK);
progress_bonuses[WHITE] =
std::min(pieces * pieces * 4,
progress_bonuses[WHITE]);
}
}
int osl::progress::
Effect5x3WithBonus::countEffectPieces(const NumEffectState &state, Player attack) const
{
PieceMask mask = effect5x3Mask(alt(attack));
mask = mask & state.piecesOnBoard(attack);
return mask.countBit();
}
/* ------------------------------------------------------------------------- */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
osl::Move
圧縮していない moveの表現 .
Definition basic_type.h:1052
osl::Move::ptype
Ptype ptype() const
Definition basic_type.h:1155
osl::Move::player
Player player() const
Definition basic_type.h:1195
osl::Move::isDrop
bool isDrop() const
Definition basic_type.h:1150
osl::Move::capturePtype
Ptype capturePtype() const
Definition basic_type.h:1180
osl::Move::to
const Square to() const
Definition basic_type.h:1132
osl::Move::from
const Square from() const
Definition basic_type.h:1125
osl::NumEffectState
利きを持つ局面
Definition numEffectState.h:34
osl::NumEffectState::effectSetAt
const NumBitmapEffect effectSetAt(Square sq) const
Definition numEffectState.h:258
osl::NumEffectState::changedEffects
const BoardMask changedEffects(Player pl) const
Definition numEffectState.h:144
osl::NumEffectState::countEffect
int countEffect(Player player, Square target) const
利きの数を数える.
Definition numEffectState.h:266
osl::NumEffectState::hasLongEffectAt
bool hasLongEffectAt(Player P, Square to) const
あるマスにPTYPEの長い利きがあるかどうか.
Definition numEffectState.h:346
osl::NumEffectState::piecesOnBoard
const PieceMask & piecesOnBoard(Player p) const
Definition numEffectState.h:63
osl::PieceMask
駒番号のビットセット.
Definition pieceMask.h:21
osl::Piece
駒.
Definition basic_type.h:788
osl::Piece::ptypeO
PtypeO ptypeO() const
Definition basic_type.h:824
osl::Piece::isEmpty
bool isEmpty() const
Definition basic_type.h:913
osl::Piece::isEdge
bool isEdge() const
Definition basic_type.h:919
osl::Piece::isOnBoardByOwner
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition basic_type.h:852
osl::SimpleState::turn
Player turn() const
Definition simpleState.h:220
osl::SimpleState::kingSquare
Square kingSquare() const
Definition simpleState.h:94
osl::SimpleState::countPiecesOnStand
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
Definition simpleState.h:182
osl::SimpleState::pieceAt
const Piece pieceAt(Square sq) const
Definition simpleState.h:167
osl::Square
Definition basic_type.h:532
osl::Square::y
int y() const
将棋としてのY座標を返す.
Definition basic_type.h:567
osl::Square::canPromote
bool canPromote() const
Definition basic_type.h:659
osl::Square::squareForBlack
const Square squareForBlack(Player player) const
Definition basic_type.h:598
osl::Square::x
int x() const
将棋としてのX座標を返す.
Definition basic_type.h:563
osl::container::BoardMask
11 x 12
Definition boardMask.h:21
osl::container::BoardMask::set
void set(unsigned int i)
Definition boardMask.h:40
osl::container::BoardMask::anyInRange
bool anyInRange(const BoardMask &mask) const
Definition boardMask.h:57
osl::container::PieceMask64::countBit
int countBit() const
Definition pieceMask64.h:78
osl::progress::Effect5x3Table::StandPAWN
@ StandPAWN
Definition effect5x3Table.h:39
osl::progress::Effect5x3Table::StandSILVER
@ StandSILVER
Definition effect5x3Table.h:42
osl::progress::Effect5x3Table::StandGOLD
@ StandGOLD
Definition effect5x3Table.h:43
osl::progress::Effect5x3Table::StandROOK
@ StandROOK
Definition effect5x3Table.h:45
osl::progress::Effect5x3Table::StandLANCE
@ StandLANCE
Definition effect5x3Table.h:40
osl::progress::Effect5x3Table::StandKNIGHT
@ StandKNIGHT
Definition effect5x3Table.h:41
osl::progress::Effect5x3Table::StandBISHOP
@ StandBISHOP
Definition effect5x3Table.h:44
effect5x3Table.h
effect5x3.h
osl::effect
Definition effectedNumTable.h:8
osl::progress::Effect5x3_Table
Effect5x3Table Effect5x3_Table
Definition effect5x3Table.cc:13
osl
Definition additionalEffect.h:6
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
osl::ROOK
@ ROOK
Definition basic_type.h:100
osl::BISHOP
@ BISHOP
Definition basic_type.h:99
osl::PAWN
@ PAWN
Definition basic_type.h:95
osl::KING
@ KING
Definition basic_type.h:93
osl::KNIGHT
@ KNIGHT
Definition basic_type.h:97
osl::PTYPE_EMPTY
@ PTYPE_EMPTY
Definition basic_type.h:85
osl::SILVER
@ SILVER
Definition basic_type.h:98
osl::GOLD
@ GOLD
Definition basic_type.h:94
osl::LANCE
@ LANCE
Definition basic_type.h:96
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に，promote前の型を返す． promoteしていない型の時はそのまま返す
Definition basic_type.h:157
osl::playerToIndex
constexpr int playerToIndex(Player player)
Definition basic_type.h:16
osl::Player
Player
Definition basic_type.h:8
osl::WHITE
@ WHITE
Definition basic_type.h:10
osl::BLACK
@ BLACK
Definition basic_type.h:9
osl::Board_Mask_Table5x3_Center
const BoardMaskTable5x3Center Board_Mask_Table5x3_Center
Definition tables.cc:121
osl::alt
constexpr Player alt(Player player)
Definition basic_type.h:13
osl::newPtypeO
PtypeO newPtypeO(Player player, Ptype ptype)
Definition basic_type.h:211
osl::Centering5x3::adjustCenter
static const Square adjustCenter(Square src)
Definition centering5x3.h:23
osl::DirectionPlayerTraits
Definition directionTraits.h:242
osl::progress::Effect5x3WithBonus
Definition effect5x3.h:89
osl::progress::Effect5x3WithBonus::countEffectPieces
int countEffectPieces(const NumEffectState &state, Player attack) const
Definition effect5x3.cc:364
osl::progress::Effect5x3WithBonus::updateStand
void updateStand(Player pl, Move m)
Definition effect5x3.h:113
osl::progress::Effect5x3WithBonus::Effect5x3WithBonus
Effect5x3WithBonus(const NumEffectState &state)
Definition effect5x3.cc:113
osl::progress::Effect5x3WithBonus::attackEffect3
static int attackEffect3(const NumEffectState &state, Player attack, Square target)
Definition effect5x3.cc:148
osl::progress::Effect5x3WithBonus::expect
Effect5x3WithBonus expect(const NumEffectState &state, Move move) const
Definition effect5x3.cc:332
osl::progress::Effect5x3WithBonus::makeProgressAreaBonus
static int makeProgressAreaBonus(const NumEffectState &state, Square king)
Definition effect5x3.cc:292
osl::progress::Effect5x3WithBonus::updateProgressBonuses
void updateProgressBonuses(const NumEffectState &state, bool black=true, bool white=true)
Definition effect5x3.cc:345
osl::progress::Effect5x3WithBonus::makeEffectMask
static PieceMask makeEffectMask(const NumEffectState &state)
osl::progress::Effect5x3WithBonus::update
void update(const NumEffectState &new_state, Move last_move)
Definition effect5x3.cc:307
osl::progress::Effect5x3WithBonus::effect_mask
CArray< PieceMask, 2 > effect_mask
Definition effect5x3.h:116
osl::progress::Effect5x3WithBonus::progress_bonuses
CArray< int, 2 > progress_bonuses
Definition effect5x3.h:115
osl::progress::Effect5x3WithBonus::effect5x3Mask
const PieceMask effect5x3Mask(Player p) const
Definition effect5x3.h:107
osl::progress::Effect5x3
玉の周囲5x3の領域の利きの数と持駒から計算した進行度.
Definition effect5x3.h:27
osl::progress::Effect5x3::makeProgressStand
static int makeProgressStand(Player attack, const NumEffectState &state)
Definition effect5x3.cc:50
osl::progress::Effect5x3::progresses
CArray< int, 2 > progresses
Definition effect5x3.h:71
osl::progress::Effect5x3::area_progresses
CArray< int, 2 > area_progresses
Definition effect5x3.h:71
osl::progress::Effect5x3::stand_progresses
CArray< int, 2 > stand_progresses
Definition effect5x3.h:71
osl::progress::Effect5x3::makeProgressArea
static int makeProgressArea(Player attack, const NumEffectState &state, Square king)
Definition effect5x3.cc:26
osl::progress::Effect5x3::update
void update(const NumEffectState &new_state, Move last_move)
Definition effect5x3.cc:80
osl::progress::Effect5x3::updateStand
static void updateStand(int &old_stand, Move last_move)
Definition effect5x3.cc:65
osl::progress::Effect5x3::Effect5x3
Effect5x3(const NumEffectState &state)
Definition effect5x3.cc:7
osl::progress::Effect5x3::expect
Effect5x3 expect(const NumEffectState &state, Move move) const
Definition effect5x3.cc:98
osl::progress::Effect5x3::makeProgressAll
static int makeProgressAll(Player defense, const NumEffectState &state, Square king)
Definition effect5x3.cc:18