/* numEffectState.cc #include "osl/numEffectState.h" #include "osl/simpleState.tcc" #include "osl/move_classifier/moveAdaptor.h" #include "osl/move_classifier/safeMove.h" #include "osl/move_generator/allMoves.h" #include "osl/move_generator/move_action.h" #if (defined(__i386__) || defined(__x86_64__)) && !defined(OSL_NO_SSE) typedef __v2di v2di; const NumEffectState& st2) assert(st1.isConsistent(true)); if (!(st1.effects == st2.effects)) if (!(st1.pieces_onboard == st2.pieces_onboard)) if (!(st1.promoted == st2.promoted)) if (!(st1.pin_or_open == st2.pin_or_open)) if (!(st1.king_mobility == st2.king_mobility)) if (!(st1.king8infos == st2.king8infos)) return (static_cast(st1) } const osl::checkmate::King8Info osl:: { } template { #ifdef ALLOW_KING_ABSENCE return; king8infos[P]=King8Info::make(*this,kingSquare

()).uint64Value(); NumEffectState::NumEffectState(const SimpleState& st) { pieces_onboard[1].resetAll(); effects.effected_mask[0].resetAll(); effects.effected_changed_mask[0].resetAll(); for(int num=0;num<40;num++){ if (p.isOnBoard()){ if (p.isPromoted()) for(int i=0;i<2;i++){ if(hasEffectAt(pl,p.square())) effects.effected_mask[i].set(num); } } makePinOpen(BLACK); if(kingSquare().isOnBoard()) if(kingSquare().isOnBoard()) } NumEffectState::~NumEffectState() } const osl::Piece osl:: { return Piece::EMPTY(); if (pieces.any()) ppieces = pieces & promoted.getMask(); if (pieces.any()) return pieceOf(ppieces.bsf()+PtypeFuns::indexNum*32); pieces = effect.selectBit(); { pieces &= ~ppieces; return pieceOf(pieces.bsf()+PtypeFuns::indexNum*32); } effect.clearBit(); return pieceOf(king.bsf()+PtypeFuns::indexNum*32); const int index = 0; pieces = effect.getMask(index) & ~ppieces; return pieceOf(pieces.any() ? pieces.bsf() : ppieces.bsf()); if (Piece_Table.getPtypeOf(num) == Piece_Table.getPtypeOf(nump)) return pieceOf(std::min(num, nump)); NumEffectState::findThreatenedPiece(Player P) const assert(! inCheck(P)); PieceMask nolance = pieces; nolance.clearBit(); const int lance_index = PtypeFuns::indexNum; // 64bit: 0, 32bit: 1 mask_t all = nolance.getMask(i); mask_t notpromoted = all & ~promoted; pp = promoted.bsr() + i*32; } npp = notpromoted.bsr() + i*32; if (ret >= PtypeTraits::indexMin) } if (lance.any()) { if (plance.any()) return pieceOf(lance.bsr()+lance_index*32); if (ret >= 0) { return pieceOf(ret); return Piece::EMPTY(); NumEffectState::wasCheckEvasion(Move last_move) const if (! last_move.isNormal()) const Square from = last_move.from(), to = last_move.to(); if (last_move.isCapture() return true; } return hasEffectIf(last_move.capturePtypeO(), to, && !Board_Table.isBetweenSafe(from, to, const Piece piece = pieceOnBoard(to); return false; return true; return primDir(d) } void osl::NumEffectState::makeMove(Move move) assert(turn() == move.player()); makeMovePass(); } assert(isAlmostValidMove(move)); const Square to=move.to(); { } { if (captured != Piece::EMPTY()) doCaptureMove(from,to,captured,move.promoteMask()); else doSimpleMove(from,to,move.promoteMask()); } } void osl::NumEffectState:: { int num; CArray pin_or_open_backup; PieceMask promoted_backup; CArray effected_changed_mask_backup; mobility::MobilityTable mobilityTable; prologueSimple(Player2Type(), from, to, promoteMask, pin_or_open_backup, king_mobility_backup, } prologueSimple(Player2Type(), from, to, promoteMask, pin_or_open_backup, king_mobility_backup, } clearPawn(turn(),from); void osl::NumEffectState:: { PtypeO oldPtypeO, capturePtypeO, newPtypeO; mask_t num1Mask; KingMobility king_mobility_backup; CArray effected_mask_backup; CArray king8infos_backup; if(turn()==BLACK){ capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask, promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable); else{ capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask, promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable); const Ptype capturePtype=target.ptype(); clearPawn(alt(turn()),to); clearPawn(turn(),from); doDropMove(Square to,Ptype ptype) Piece oldPiece; int num, numIndex; CArray pin_or_open_backup; CArray effected_mask_backup; CArray king8infos_backup; if(turn()==BLACK){ pin_or_open_backup, king_mobility_backup, } prologueDrop(Player2Type(), to, ptype, oldPiece, num, ptypeO, numIndex, numMask, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable); if (ptype==PAWN) } template prologueSimple(Player2Type

, Square from, Square to, int promoteMask, PtypeO& oldPtypeO, PtypeO& new_ptypeo, KingMobility& king_mobility_backup, CArray& effected_mask_backup, CArray& king8infos_backup, { pin_or_open_backup = pin_or_open; effected_mask_backup = effects.effected_mask; king8infos_backup=king8infos; oldPiece=pieceAt(from); newPiece+=(to-from); new_ptypeo=newPiece.ptypeO(); setPieceOf(num,newPiece); effects.clearEffectedChanged(); // 自分自身がブロックしていたpromote?の延長 effects.effectedNumTable[num].clear(); effects.template doBlockAt(*this,to,num); effects.template doBlockAt(*this,from,num); makePinOpen(P); Direction lastD=UL; recalcPinOpen(from,lastD,P); } Direction lastD=UL; recalcPinOpen(from,lastD,alt(P)); } if (promoteMask) if(hasEffectAt(BLACK,to)) else if(hasEffectAt(WHITE,to)) else effects.effected_changed_mask[BLACK].set(num); { changed.set(from); if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare())) makeKing8Info(); || pin_or_open[WHITE]!=pin_or_open_backup[WHITE]) } epilogueSimple(Square from, Square to, Piece oldPiece, const CArray& pin_or_open_backup, const PieceMask& promoted_backup, const CArray& effected_changed_mask_backup, const MobilityTable & mobility_backup) setPieceOf(num,oldPiece); setBoard(from,oldPiece); effects.doBlockAt(*this,from,num); effects.doBlockAt(*this,to,num); effects.invalidateChangedEffects(); king_mobility = king_mobility_backup; effects.effected_mask = effected_mask_backup; effects.mobilityTable = mobility_backup; } template prologueDrop(Player2Type

, Square to, Ptype ptype, int& numIndex, mask_t& numMask, KingMobility& king_mobility_backup, CArray& effected_changed_mask_backup, MobilityTable &mobility_backup) king8infos_backup = king8infos; pin_or_open_backup = pin_or_open; effected_mask_backup = effects.effected_mask; #if OSL_WORDSIZE == 64 #elif OSL_WORDSIZE == 32 #endif standMask(P).getMask(numIndex) & Ptype_Table.getMaskLow(ptype); numMask=ownMochigoma.lowestBit(); num = numLow|(numIndex<<5); Piece newPiece=oldPiece; ptypeO=newPiece.ptypeO(); effects.clearChangedEffects(); effects.template doBlockAt(*this,to,num); setBoard(to,newPiece); stand_count[P][ptype-PTYPE_BASIC_MIN]--; { recalcPinOpen(to,lastD,P); { recalcPinOpen(to,lastD,alt(P)); if(hasEffectAt(BLACK,to)) else if (hasEffectAt(WHITE,to)) else effects.effected_changed_mask[BLACK].set(num); { changed.set(to); || pin_or_open[BLACK]!=pin_or_open_backup[BLACK]) if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare())) makeKing8Info(); } template epilogueDrop(Player2Type

, Square to, Ptype ptype, Piece oldPiece, const CArray& pin_or_open_backup, const CArray& effected_mask_backup, const CArray& king8infos_backup, { stand_count[P][ptype-PTYPE_BASIC_MIN]++; setBoard(to,Piece::EMPTY()); effects.template doBlockAt(*this,to,num); effects.effectedNumTable[num].clear(); pin_or_open = pin_or_open_backup; effects.effected_mask = effected_mask_backup; effects.mobilityTable = mobility_backup; } template prologueCapture(Player2Type

, Square from, Square to, Piece target, Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO, int& num1Index, mask_t& num1Mask, KingMobility& king_mobility_backup, CArray& effected_mask_backup, CArray& king8infos_backup, { pin_or_open_backup = pin_or_open; effected_mask_backup = effects.effected_mask; king8infos_backup = king8infos; num1=target.number(); num1Mask=PieceMask::numToMask(num1); standMask(P).xorMask(num1Index,num1Mask); Piece newPiece=oldPiece.promoteWithMask(promoteMask); num0=oldPiece.number(); setPieceOf(num1,target.captured()); oldPtypeO=oldPiece.ptypeO(); capturePtypeO=target.ptypeO(); effects.clearChangedEffects(); effects.setChangedPieces(effectSetAt(to)); effects.template doEffect(*this,oldPtypeO,from,num0); effects.template doBlockAt(*this,from,num0); effects.effectedNumTable[num1].clear(); effects.template doEffect(*this,new_ptypeo,to,num0); if (oldPtypeO == newPtypeO(P,KING)) else { pin_or_open[P].reset(num0); recalcPinOpen(from,lastD,P); } Direction lastD=UL; pin_or_open[alt(P)].reset(num1); // captured is not pin recalcPinOpen(to,lastD,alt(P)); promoted_backup = promoted; effects.effected_mask[BLACK].reset(num1); if (promoteMask) if(hasEffectAt(BLACK,to)) else if(hasEffectAt(WHITE,to)) else effects.effected_changed_mask[BLACK].set(num0); { changed.set(from); if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare())) makeKing8Info(); || pin_or_open[WHITE]!=pin_or_open_backup[WHITE]) } void osl::NumEffectState:: Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO, int num1Index, mask_t num1Mask, const KingMobility& king_mobility_backup, const CArray& effected_mask_backup, const CArray& king8infos_backup, { stand_count[P][unpromote(getPtype(capturePtypeO))-PTYPE_BASIC_MIN]--; effects.effectedNumTable[num1]=effects.effectedNumTable[num0]; setPieceOf(num0,oldPiece); effects.template doEffect(*this,newPtypeO,to,num0); setBoard(to,target); effects.template doEffect(*this,capturePtypeO,to,num1); effects.invalidateChangedEffects(); king_mobility = king_mobility_backup; effects.effected_mask = effected_mask_backup; effects.mobilityTable = mobility_backup; } bool osl::NumEffectState::isConsistent(bool showError) const if (!SimpleState::isConsistent(showError)) if (showError) return false; effect::NumSimpleEffectTable effects1(*this); { { std::cerr << *this; for(int x=9;x>0;x--) Square pos(x,y); { } for(int num=0;num<=39;num++){ Direction d=static_cast(i); std::cerr << "piece=" << pieceOf(num) << ",num=" << num << ",d=" << d << ",v1=" << effects.effectedNumTable[num][d] << ",v2=" << effects1.effectedNumTable[num][d] << std::endl; } std::cerr << effects.effectedNumTable << std::endl; return false; for (int z=0; z<2; ++z) { #ifdef ALLOW_KING_ABSENCE continue; #if 0 if (pin(p) != pin2) { std::cerr << "pin for " << p << " differs " << pin(p) << " " << pin2 << "\n"; } King8Info king8info2 = King8Info::make(alt(p), *this); if (showError) return false; } const Piece p = pieceOf(i); if (promoted.test(i) != p.isPromoted()) { std::cerr << "promoted differs " << p << " " << promoted << " " << promoted.test(i) << "\n"; } } } { const CArray changed_squares const BoardMask changed_all = changed_squares[BLACK] | changed_squares[WHITE]; for (int i=0; i(move); const Piece from_piece = this->pieceAt(from); if (! testValidityOtherThanEffect(move)) if(!hasEffectByPiece(from_piece,to)){ std::cerr << " No such move2 : " << move << std::endl; return false; return true; isAlmostValidMove(Move move,bool show_error) const{ show_error=false; if(show_error) else } #ifndef MINIMAL { for(int y=1;y<=9;y++){ for(int x=9;x>0;x--){ os << csa::show(pieceAt(pos)) << effectSetAt(pos); os << std::endl; // 持ち駒の表示 if (standMask(BLACK).test(num)){ << std::endl; else if (standMask(WHITE).test(num)){ << std::endl; } #endif osl::PieceMask osl::NumEffectState:: { if(target.isPieceStand()) return pins; makePinOpenDir

    (target,pins,mask,defense); makePinOpenDir(target,pins,mask,defense); makePinOpenDir(target,pins,mask,defense); makePinOpenDir(target,pins,mask,defense); return pins; makePinOpen(osl::Player defense) pin_or_open[defense]=makePinOpen(kingSquare(defense),defense); allEffectAt(Player attack, Ptype ptype, Square target) const switch (ptype) { return allEffectAt(attack, target); return allEffectAt(attack, target); return allEffectAt(attack, target); return allEffectAt(attack, target); return allEffectAt(attack, target); return allEffectAt(attack, target); return allEffectAt(attack, target); return allEffectAt(attack, target); assert(0); return mask_t(); { (*this).used_mask=src.used_mask; (*this).stand_mask=src.stand_mask; { v2di b20=*((v2di*)&src.board[20]); v2di b32=*((v2di*)&src.board[32]); v2di b40=*((v2di*)&src.board[40]); v2di b52=*((v2di*)&src.board[52]); *((v2di*)&(*this).board[20])=b20; *((v2di*)&(*this).board[32])=b32; *((v2di*)&(*this).board[40])=b40; *((v2di*)&(*this).board[52])=b52; v2di b64=*((v2di*)&src.board[64]); v2di b72=*((v2di*)&src.board[72]); v2di b80=*((v2di*)&src.board[80]); v2di b88=*((v2di*)&src.board[88]); v2di b96=*((v2di*)&src.board[96]); v2di b104=*((v2di*)&src.board[104]); *((v2di*)&(*this).board[68])=b68; *((v2di*)&(*this).board[84])=b84; *((v2di*)&(*this).board[100])=b100; v2di b116=*((v2di*)&src.board[116]); v2di b132=*((v2di*)&src.board[132]); v2di b148=*((v2di*)&src.board[148]); *((v2di*)&(*this).board[116])=b116; *((v2di*)&(*this).board[132])=b132; *((v2di*)&(*this).board[148])=b148; v2di p4=*((v2di*)&src.pieces[4]); v2di p12=*((v2di*)&src.pieces[12]); v2di p20=*((v2di*)&src.pieces[20]); v2di p28=*((v2di*)&src.pieces[28]); v2di p36=*((v2di*)&src.pieces[36]); *((v2di*)&(*this).pieces[4])=p4; *((v2di*)&(*this).pieces[12])=p12; *((v2di*)&(*this).pieces[20])=p20; *((v2di*)&(*this).pieces[28])=p28; *((v2di*)&(*this).pieces[36])=p36; #else for(int y=1;y<=9;y++) (*this).pieces=src.pieces; (*this).pawnMask=src.pawnMask; this->player_to_move=src.player_to_move; this->pieces_onboard=src.pieces_onboard; (*this).pin_or_open=src.pin_or_open; (*this).king8infos=src.king8infos; { } bool osl::NumEffectState::isSafeMove(Move move) const using namespace move_classifier; } { return PlayerMoveAdaptor::isMember(*this, move); bool osl::NumEffectState::isPawnDropCheckmate(Move move) const using namespace move_classifier; } { return PlayerMoveAdaptor::isMember(*this, move); { return ConditionAdaptor::isMember(*this, move); void osl::NumEffectState::generateAllUnsafe(MoveVector& out) const move_action::Store store(out); } { // 王手がかかっている時は防ぐ手のみを生成, 王手回避は不成も生成 } // そうでなければ全ての手を生成 GenerateAllMoves::generate(turn(), *this, all_moves); // 確認が必要 [&](Move m){ }); } void osl::NumEffectState::generateWithFullUnpromotions(MoveVector& moves) const generateLegal(moves); return; const Move move = moves[i]; moves.push_back(move.unpromote()); } findEffect(Player P, Square target, PieceVector& out) const effect_action::StorePiece store(&out); } namespace osl // explicit template instantiation template bool NumEffectState:: template bool NumEffectState:: template void NumEffectState::makeKing8Info(); template void NumEffectState:: PtypeO&, PtypeO&, CArray&, KingMobility&, CArray&, MobilityTable&); prologueSimple(Player2Type, Square, Square, int, Piece&, int&, PieceMask&, CArray&, CArray&, prologueCapture(Player2Type, Square, Square, Piece, int, Piece&, CArray&, KingMobility&, PieceMask&, CArray&, MobilityTable&); prologueCapture(Player2Type, Square, Square, Piece, int, Piece&, CArray&, KingMobility&, PieceMask&, CArray&, MobilityTable&); template void NumEffectState:: int&, mask_t&, CArray&, KingMobility&, CArray&, MobilityTable&); prologueDrop(Player2Type, Square, Ptype, Piece&, int&, PtypeO&, CArray&, CArray&, epilogueCapture(Player2Type, Square, Square, Piece, Piece, PtypeO, PtypeO, const KingMobility&, const PieceMask&, const CArray&, const MobilityTable&); epilogueCapture(Player2Type, Square, Square, Piece, Piece, PtypeO, PtypeO, const KingMobility&, const PieceMask&, const CArray&, const MobilityTable&); epilogueDrop(Player2Type, Square, Ptype, Piece, int, PtypeO, int, mask_t, const CArray&, const CArray&, const MobilityTable&); epilogueDrop(Player2Type, Square, Ptype, Piece, int, PtypeO, int, mask_t, const CArray&, const CArray&, const MobilityTable&); #ifndef DFPNSTATONE NumEffectState::safeCaptureNotByKing(Square, Piece) const; NumEffectState::safeCaptureNotByKing(Square, Piece) const; } /* ------------------------------------------------------------------------- */ // ;;; mode:c++ // ;;; End: */ #include "osl/numEffectState.tcc" #include "osl/bits/numSimpleEffect.tcc" #include "osl/move_classifier/check_.h" #include "osl/move_classifier/pawnDropCheckmate.h" #include "osl/move_generator/escape_.h" #include "osl/move_generator/effect_action.h" #include #include #endif bool osl::operator==(const NumEffectState& st1, { assert(st2.isConsistent(true)); return false; return false; return false; return false; return false; return false; == static_cast(st2)); NumEffectState::king8Info(Player king) const return King8Info(Iking8Info(king)); void osl::NumEffectState::makeKing8Info() const Player altP=alt(P); if (kingSquare

    ().isPieceStand()) #endif } osl:: : SimpleState(st),effects(st) pieces_onboard[0].resetAll(); promoted.resetAll(); effects.effected_mask[1].resetAll(); effects.effected_changed_mask[1].resetAll(); Piece p=pieceOf(num); pieces_onboard[p.owner()].set(num); promoted.set(num); Player pl=indexToPlayer(i); { effects.effected_changed_mask[i].set(num); } } makePinOpen(WHITE); makeKing8Info(); makeKing8Info(); osl:: { NumEffectState::selectCheapPiece(PieceMask effect) const if (! effect.any()) mask_t pieces = effect.selectBit(), ppieces; { pieces &= ~ppieces; return pieceOf(pieces.bsf()+PtypeFuns::indexNum*32); } if (pieces.any()) ppieces = pieces & promoted.getMask(); if (pieces.any()) return pieceOf(ppieces.bsf()+PtypeFuns::indexNum*32); mask_t king = effect.selectBit(); if (effect.none()) // depends on current piece numbers: , KE 18, GI 22, KI 26, , , KA 36, HI 38, ppieces = effect.getMask(index) & promoted.getMask(index); if (pieces.none() || ppieces.none()) const int num = pieces.bsf(), nump = ppieces.bsf(); return pieceOf(num); } const osl::Piece osl:: { PieceMask pieces = piecesOnBoard(P) & effectedMask(alt(P)); int pp=-1, npp=-1, ret=-1; for (int i=lance_index; i>=0; --i) { mask_t promoted = all & promotedPieces().getMask(i); if (promoted.any()) { notpromoted &= ~Ptype_Table.getMaskLow(Piece_Table.getPtypeOf(pp)); if (notpromoted.any()) ret = std::max(pp, npp); return pieceOf(ret); mask_t lance = pieces.selectBit(); mask_t plance = lance & promotedPieces().getMask(lance_index); return pieceOf(plance.bsr()+lance_index*32); } assert(Piece_Table.getPtypeOf(ret) == PAWN); } } bool osl:: { return false; if (last_move.ptype() == KING) { && hasEffectIf(last_move.capturePtypeO(), to, from)) return hasEffectAt(turn(), from); if (last_move.isCapture()) kingSquare(alt(turn()))) kingSquare(alt(turn()))); if (! pin(alt(turn())).test(piece.number())) if (last_move.isDrop() || last_move.oldPtype() == KNIGHT) const Direction d=pinnedDir(piece); !=primDirUnsafe(Board_Table.getShort8Unsafe(piece.owner(), from,to)); { if (move.isPass()) { return; const Square from=move.from(); if (from.isPieceStand()) doDropMove(to,move.ptype()); else const Piece captured = pieceOnBoard(to); { } { } changeTurn(); doSimpleMove(Square from, Square to, int promoteMask) Piece oldPiece; PtypeO oldPtypeO, newPtypeO; KingMobility king_mobility_backup; CArray effected_mask_backup; CArray king8infos_backup; if (turn()==BLACK){ oldPiece, num, oldPtypeO, newPtypeO, promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable); else{ oldPiece, num, oldPtypeO, newPtypeO, promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable); if (promoteMask!=0 && num < PtypeTraits::indexLimit) } doCaptureMove(Square from, Square to, Piece target, int promoteMask) Piece oldPiece; int num0, num1, num1Index; CArray pin_or_open_backup; PieceMask promoted_backup; CArray effected_changed_mask_backup; mobility::MobilityTable mobilityTable; prologueCapture(Player2Type(), from, to, target, promoteMask, oldPiece, oldPtypeO, pin_or_open_backup, king_mobility_backup, } prologueCapture(Player2Type(), from, to, target, promoteMask, oldPiece, oldPtypeO, pin_or_open_backup, king_mobility_backup, } if (capturePtype==PAWN) if (promoteMask!=0 && num0::indexLimit) } void osl::NumEffectState:: { PtypeO ptypeO; mask_t numMask; KingMobility king_mobility_backup; CArray effected_changed_mask_backup; mobility::MobilityTable mobilityTable; prologueDrop(Player2Type(), to, ptype, oldPiece, num, ptypeO, numIndex, numMask, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable); else{ pin_or_open_backup, king_mobility_backup, } setPawn(turn(),to); void osl::NumEffectState:: Piece& oldPiece, int& num, CArray& pin_or_open_backup, PieceMask& promoted_backup, CArray& effected_changed_mask_backup, MobilityTable &mobility_backup) mobility_backup = effects.mobilityTable; king_mobility_backup = king_mobility; effected_changed_mask_backup = effects.effected_changed_mask; Piece newPiece=oldPiece.promoteWithMask(promoteMask); num=oldPiece.number(); oldPtypeO=oldPiece.ptypeO(); // 自分自身の効きを外す effects.clearChangedEffects(); effects.template doEffect(*this,oldPtypeO,from,num); // あるいは自分自身のブロック setBoard(to,newPiece); setBoard(from,Piece::EMPTY()); effects.template doEffect(*this,new_ptypeo,to,num); if (oldPtypeO == newPtypeO(P,KING)) else { pin_or_open[P].reset(num); recalcPinOpen(to,lastD,P); { pin_or_open[alt(P)].reset(num); recalcPinOpen(to,lastD,alt(P)); promoted_backup = promoted; promoted.set(num); effects.effected_mask[BLACK].set(num); effects.effected_mask[BLACK].reset(num); effects.effected_mask[WHITE].set(num); effects.effected_mask[WHITE].reset(num); effects.effected_changed_mask[WHITE].set(num); BoardMask changed=changedEffects(BLACK)|changedEffects(WHITE); changed.set(to); || pin_or_open[BLACK]!=pin_or_open_backup[BLACK]) if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare())) makeKing8Info(); } void osl::NumEffectState:: int num, PtypeO oldPtypeO, PtypeO newPtypeO, const KingMobility& king_mobility_backup, const CArray& effected_mask_backup, const CArray& king8infos_backup, { effects.doEffect(*this,newPtypeO,to,num); effects.effectedNumTable[num].clear(); setBoard(to,Piece::EMPTY()); effects.doEffect(*this,oldPtypeO,from,num); pin_or_open = pin_or_open_backup; promoted = promoted_backup; effects.effected_changed_mask = effected_changed_mask_backup; king8infos = king8infos_backup; void osl::NumEffectState:: Piece& oldPiece, int& num, PtypeO& ptypeO, CArray& pin_or_open_backup, CArray& effected_mask_backup, CArray& king8infos_backup, { mobility_backup = effects.mobilityTable; king_mobility_backup = king_mobility; effected_changed_mask_backup = effects.effected_changed_mask; numIndex=0; numIndex=Ptype_Table.getIndex(ptype); const mask_t ownMochigoma= assert(ownMochigoma.any()); int numLow = ownMochigoma.bsf(); oldPiece=pieceOf(num); newPiece+=to-Square::STAND(); setPieceOf(num,newPiece); effects.clearEffectedChanged(); effects.template doEffect(*this,ptypeO,to,num); standMask(P).xorMask(numIndex,numMask); pieces_onboard[P].xorMask(numIndex,numMask); Direction lastD=UL; } Direction lastD=UL; } effects.effected_mask[BLACK].set(num); effects.effected_mask[BLACK].reset(num); effects.effected_mask[WHITE].set(num); effects.effected_mask[WHITE].reset(num); effects.effected_changed_mask[WHITE].set(num); BoardMask changed=changedEffects(BLACK)|changedEffects(WHITE); if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare())) makeKing8Info(); || pin_or_open[WHITE]!=pin_or_open_backup[WHITE]) } void osl::NumEffectState:: int num, PtypeO ptypeO, int numIndex, mask_t numMask, const KingMobility& king_mobility_backup, const CArray& effected_changed_mask_backup, const MobilityTable& mobility_backup) standMask(P).xorMask(numIndex,numMask); pieces_onboard[P].xorMask(numIndex,numMask); effects.template doEffect(*this,ptypeO,to,num); setPieceOf(num,oldPiece); effects.invalidateChangedEffects(); king_mobility = king_mobility_backup; effects.effected_changed_mask = effected_changed_mask_backup; king8infos = king8infos_backup; void osl::NumEffectState:: int promoteMask, PtypeO& new_ptypeo, int& num0, int& num1, CArray& pin_or_open_backup, PieceMask& promoted_backup, CArray& effected_changed_mask_backup, MobilityTable &mobility_backup) mobility_backup = effects.mobilityTable; king_mobility_backup = king_mobility; effected_changed_mask_backup = effects.effected_changed_mask; num1Index=PieceMask::numToIndex(num1); pieces_onboard[alt(P)].xorMask(num1Index,num1Mask); oldPiece=pieceAt(from); newPiece+=(to-from); setPieceOf(num0,newPiece); new_ptypeo=newPiece.ptypeO(); stand_count[P][unpromote(getPtype(capturePtypeO))-PTYPE_BASIC_MIN]++; effects.clearEffectedChanged(); effects.template doEffect(*this,capturePtypeO,to,num1); setBoard(from,Piece::EMPTY()); effects.effectedNumTable[num0]=effects.effectedNumTable[num1]; setBoard(to,newPiece); makePinOpen(P); Direction lastD=UL; pin_or_open[P].reset(num1); // captured is not pin recalcPinOpen(to,lastD,P); { pin_or_open[alt(P)].reset(num0); recalcPinOpen(from,lastD,alt(P)); } promoted.reset(num1); effects.effected_mask[WHITE].reset(num1); promoted.set(num0); effects.effected_mask[BLACK].set(num0); effects.effected_mask[BLACK].reset(num0); effects.effected_mask[WHITE].set(num0); effects.effected_mask[WHITE].reset(num0); effects.effected_changed_mask[WHITE].set(num0); BoardMask changed=changedEffects(BLACK)|changedEffects(WHITE); changed.set(to); || pin_or_open[BLACK]!=pin_or_open_backup[BLACK]) if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare())) makeKing8Info(); } template epilogueCapture(Player2Type

    , Square from, Square to, Piece target, PtypeO newPtypeO, int num0, int num1, const CArray& pin_or_open_backup, const PieceMask& promoted_backup, const CArray& effected_changed_mask_backup, const MobilityTable &mobility_backup) standMask(P).xorMask(num1Index,num1Mask); pieces_onboard[alt(P)].xorMask(num1Index,num1Mask); effects.effectedNumTable[num0].clear(); setPieceOf(num1,target); setBoard(from,oldPiece); effects.template doBlockAt(*this,from,num0); effects.template doEffect(*this,oldPtypeO,from,num0); pin_or_open = pin_or_open_backup; promoted = promoted_backup; effects.effected_changed_mask = effected_changed_mask_backup; king8infos = king8infos_backup; #ifndef MINIMAL { { std::cerr << "error before effect\n"; } if (!(effects1==effects)) if (showError) std::cerr << "Effect error 1" << std::endl; for(int y=1;y<=9;y++) { if (!(effects1.effectSetAt(pos)==effects.effectSetAt(pos))) std::cerr << pos << ",real=" << effects.effectSetAt(pos) << ",ideal=" << effects1.effectSetAt(pos) << std::endl; } for(int i=0;i<8;i++){ if(effects.effectedNumTable[num][d]!=effects1.effectedNumTable[num][d]){ } } } } const Player p = indexToPlayer(z); if (kingSquare(p).isPieceStand()) #endif const PieceMask pin2 = effect_util::Pin::make(*this, p); if (showError) return false; #endif if (King8Info(Iking8Info(p)).uint64Value() != king8info2.uint64Value()) { std::cerr << "king8info for " << p << " differs \n" << King8Info(Iking8Info(p)) << "\n" << king8info2 << "\n"; } for (int i=0; i each_effect, prev_effect; each_effect[i].clear(); } for (int y=1; y<=9; ++y) { for (int i=0; i #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE) #endif assert(move.isValid()); assert(this->turn() == move.player()); if (from.isPieceStand()) // 打つ手 const Square to=move.to(); return false; if (show_error) { } } } bool osl::NumEffectState:: #ifdef MINIMAL #endif return isAlmostValidMove(move); return isAlmostValidMove(move); void osl::NumEffectState::showEffect(std::ostream& os) const os<< static_cast(*this); os << 'P' << y; Square pos(x,y); } } for(int num=0;num(target,pins,mask,defense); makePinOpenDir(target,pins,mask,defense); makePinOpenDir

    (target,pins,mask,defense); makePinOpenDir(target,pins,mask,defense); } void osl::NumEffectState:: { } const osl::mask_t osl::NumEffectState:: { case PAWN: case PPAWN: case LANCE: case PLANCE: case KNIGHT: case PKNIGHT: case SILVER: case PSILVER: case GOLD: case BISHOP: case PBISHOP: case ROOK: case PROOK: case KING: default: } } void osl::NumEffectState::copyFrom(const NumEffectState& src) #ifndef MINIMAL #endif #if (defined(__i386__) || defined(__x86_64__)) && !defined(OSL_NO_SSE) v2di b16=*((v2di*)&src.board[16]); v2di b24=*((v2di*)&src.board[24]); v2di b36=*((v2di*)&src.board[36]); v2di b48=*((v2di*)&src.board[48]); v2di b56=*((v2di*)&src.board[56]); *((v2di*)&(*this).board[16])=b16; *((v2di*)&(*this).board[24])=b24; *((v2di*)&(*this).board[36])=b36; *((v2di*)&(*this).board[48])=b48; *((v2di*)&(*this).board[56])=b56; v2di b68=*((v2di*)&src.board[68]); v2di b84=*((v2di*)&src.board[84]); v2di b100=*((v2di*)&src.board[100]); *((v2di*)&(*this).board[64])=b64; *((v2di*)&(*this).board[72])=b72; *((v2di*)&(*this).board[80])=b80; *((v2di*)&(*this).board[88])=b88; *((v2di*)&(*this).board[96])=b96; *((v2di*)&(*this).board[104])=b104; v2di b112=*((v2di*)&src.board[112]); v2di b120=*((v2di*)&src.board[120]); v2di b128=*((v2di*)&src.board[128]); v2di b136=*((v2di*)&src.board[136]); v2di b144=*((v2di*)&src.board[144]); v2di b152=*((v2di*)&src.board[152]); *((v2di*)&(*this).board[112])=b112; *((v2di*)&(*this).board[120])=b120; *((v2di*)&(*this).board[128])=b128; *((v2di*)&(*this).board[136])=b136; *((v2di*)&(*this).board[144])=b144; *((v2di*)&(*this).board[152])=b152; v2di p0=*((v2di*)&src.pieces[0]); v2di p8=*((v2di*)&src.pieces[8]); v2di p16=*((v2di*)&src.pieces[16]); v2di p24=*((v2di*)&src.pieces[24]); v2di p32=*((v2di*)&src.pieces[32]); *((v2di*)&(*this).pieces[0])=p0; *((v2di*)&(*this).pieces[8])=p8; *((v2di*)&(*this).pieces[16])=p16; *((v2di*)&(*this).pieces[24])=p24; *((v2di*)&(*this).pieces[32])=p32; } for(int x=1;x<=9;x++) (*this).board[Square(x,y).index()]=src.board[Square(x,y).index()]; #endif this->stand_count = src.stand_count; effects.copyFrom(src.effects); (*this).promoted=src.promoted; (*this).king_mobility=src.king_mobility; } void osl::NumEffectState::copyFrom(const SimpleState& src) copyFrom(NumEffectState(src)); { return ConditionAdaptor::isMember(*this, move); bool osl::NumEffectState::isCheck(Move move) const using namespace move_classifier; } { return PlayerMoveAdaptor::isMember(*this, move); bool osl::NumEffectState::isDirectCheck(Move move) const using namespace move_classifier; } bool osl::NumEffectState::isOpenCheck(Move move) const using namespace move_classifier; } #ifndef MINIMAL { move_generator::AllMoves::generate(turn(), *this, store); void osl::NumEffectState::generateLegal(MoveVector& moves) const if (inCheck()) { GenerateEscapeKing::generate(*this, moves); else { MoveVector all_moves; // この指手は,玉の素抜きがあったり,打歩詰の可能性があるので std::copy_if(all_moves.begin(), all_moves.end(), std::back_inserter(moves), return this->isSafeMove(m) && ! this->isPawnDropCheckmate(m); } { if (inCheck()) for (int i=0, iend=moves.size(); i(Square, Square) const; hasEffectByWithRemove(Square, Square) const; template void NumEffectState::makeKing8Info(); prologueSimple(Player2Type, Square, Square, int, Piece&, int&, PieceMask&, CArray&, CArray&, template void NumEffectState:: PtypeO&, PtypeO&, CArray&, KingMobility&, CArray&, MobilityTable&); template void NumEffectState:: PtypeO&, PtypeO&, PtypeO&, int&, int&, int&, mask_t&, CArray&, CArray&, template void NumEffectState:: PtypeO&, PtypeO&, PtypeO&, int&, int&, int&, mask_t&, CArray&, CArray&, prologueDrop(Player2Type, Square, Ptype, Piece&, int&, PtypeO&, CArray&, CArray&, template void NumEffectState:: int&, mask_t&, CArray&, KingMobility&, CArray&, MobilityTable&); template void NumEffectState:: PtypeO, int, int, int, mask_t, const CArray&, const CArray&, const CArray&, template void NumEffectState:: PtypeO, int, int, int, mask_t, const CArray&, const CArray&, const CArray&, template void NumEffectState:: const CArray&, const KingMobility&, const CArray&, template void NumEffectState:: const CArray&, const KingMobility&, const CArray&, template Piece template Piece #endif // ;;; Local Variables: // ;;; c-basic-offset:2