static Action_SkBuff par4(arguments_t args, SkBuff b) { function_t f0 = GET_ARG_0(function_t, args); function_t f1 = GET_ARG_1(function_t, args); function_t f2 = GET_ARG_2(function_t, args); function_t f3 = GET_ARG_3(function_t, args); fanout_t fout = PFQ_CB(b.skb)->monad->fanout; Action_SkBuff a; a = EVAL_FUNCTION(f0, b); if (a.value.skb && !is_drop(PFQ_CB(a.value.skb)->monad->fanout)) return a; PFQ_CB(b.skb)->monad->fanout = fout; a = EVAL_FUNCTION(f1, b); if (a.value.skb && !is_drop(PFQ_CB(a.value.skb)->monad->fanout)) return a; PFQ_CB(b.skb)->monad->fanout = fout; a = EVAL_FUNCTION(f2, b); if (a.value.skb && !is_drop(PFQ_CB(a.value.skb)->monad->fanout)) return a; PFQ_CB(b.skb)->monad->fanout = fout; return EVAL_FUNCTION(f3, b); }
std::string to_usi_string(Move m) { std::stringstream ss; if (!is_ok(m)) { ss <<((m == MOVE_RESIGN) ? "resign" : (m == MOVE_WIN ) ? "win" : (m == MOVE_NULL ) ? "null" : (m == MOVE_NONE ) ? "none" : ""); } else if (is_drop(m)) { ss << Piece(move_from(m)); ss << '*'; ss << move_to(m); } else { ss << move_from(m); ss << move_to(m); if (is_promote(m)) ss << '+'; } return ss.str(); }
std::string pretty(Move m, Piece movedPieceType) { if (is_drop(m)) return (pretty(move_to(m)) + pretty2(movedPieceType) + (pretty_jp ? "打" : "*")); else return pretty(move_to(m)) + pretty2(movedPieceType) + (is_promote(m) ? (pretty_jp ? "成" : "+") : "") + "["+ pretty(move_from(m))+"]"; }
std::string pretty(Move m) { if (is_drop(m)) return (pretty(move_to(m)) + pretty2(Piece(move_from(m))) + (pretty_jp ? "打" : "*")); else return pretty(move_from(m)) + pretty(move_to(m)) + (is_promote(m) ? (pretty_jp ? "成" : "+") : ""); }
static ActionSkBuff par6(arguments_t args, SkBuff skb) { function_t f0 = GET_ARG_0(function_t, args); function_t f1 = GET_ARG_1(function_t, args); function_t f2 = GET_ARG_2(function_t, args); function_t f3 = GET_ARG_3(function_t, args); function_t f4 = GET_ARG_4(function_t, args); function_t f5 = GET_ARG_5(function_t, args); fanout_t fout = PFQ_CB(skb)->monad->fanout; ActionSkBuff a; a = EVAL_FUNCTION(f0, skb); if (a.skb && !is_drop(PFQ_CB(a.skb)->monad->fanout)) return a; PFQ_CB(skb)->monad->fanout = fout; a = EVAL_FUNCTION(f1, skb); if (a.skb && !is_drop(PFQ_CB(a.skb)->monad->fanout)) return a; PFQ_CB(skb)->monad->fanout = fout; a = EVAL_FUNCTION(f2, skb); if (a.skb && !is_drop(PFQ_CB(a.skb)->monad->fanout)) return a; PFQ_CB(skb)->monad->fanout = fout; a = EVAL_FUNCTION(f3, skb); if (a.skb && !is_drop(PFQ_CB(a.skb)->monad->fanout)) return a; PFQ_CB(skb)->monad->fanout = fout; a = EVAL_FUNCTION(f4, skb); if (a.skb && !is_drop(PFQ_CB(a.skb)->monad->fanout)) return a; PFQ_CB(skb)->monad->fanout = fout; return EVAL_FUNCTION(f5, skb); }
static Action_SkBuff inv(arguments_t args, SkBuff b) { function_t expr = GET_ARG(function_t, args); SkBuff nb = EVAL_FUNCTION(expr, b).value; if (!nb.skb || is_drop(PFQ_CB(nb.skb)->monad->fanout)) return Copy(nb); return Drop(nb); }
// 利きのある場所への取れない近接王手からの3手詰め Move Position::weak_mate_n_ply(int ply) const { // 1手詰めであるならこれを返す Move m = mate1ply(); if (m) return m; // 詰まない if (ply <= 1) return MOVE_NONE; Color us = side_to_move(); Color them = ~us; Bitboard around8 = kingEffect(king_square(them)); // const剥がし Position* This = ((Position*)this); StateInfo si; StateInfo si2; // 近接王手で味方の利きがあり、敵の利きのない場所を探す。 for (auto m : MoveList<CHECKS>(*this)) { // 近接王手で、この指し手による駒の移動先に敵の駒がない。 Square to = to_sq(m); if ((around8 & to) #ifndef LONG_EFFECT_LIBRARY // toに利きがあるかどうか。mが移動の指し手の場合、mの元の利きを取り除く必要がある。 && (is_drop(m) ? effected_to(us, to) : (attackers_to(us, to, pieces() ^ from_sq(m)) ^ from_sq(m))) // 敵玉の利きは必ずtoにあるのでそれを除いた利きがあるかどうか。 && (attackers_to(them,to,pieces()) ^ king_square(them)) #else && (is_drop(m) ? effected_to(us, to) : board_effect[us].effect(to) >= 2 || (long_effect.directions_of(us, from_sq(m)) & Effect8::directions_of(from_sq(m), to)) != 0) // 敵玉の利きがあるので2つ以上なければそれで良い。 && (board_effect[them].effect(to) <= 1) #endif ) { if (!legal(m)) continue; ASSERT_LV3(gives_check(m)); This->do_move(m,si,true); ASSERT_LV3(in_check()); // この局面ですべてのevasionを試す for (auto m2 : MoveList<EVASIONS>(*this)) { if (!legal(m2)) continue; // この指し手で逆王手になるなら、不詰めとして扱う if (gives_check(m2)) goto NEXT_CHECK; This->do_move(m2, si2, false); ASSERT_LV3(!in_check()); if (!weak_mate_n_ply(ply-2)) { // 詰んでないので、m2で詰みを逃れている。 This->undo_move(m2); goto NEXT_CHECK; } This->undo_move(m2); } // すべて詰んだ This->undo_move(m); // mによって3手で詰む。 return m; NEXT_CHECK:; This->undo_move(m); } } return MOVE_NONE; }