/// <summary> /// 駒の移動 盤面編集 /// </summary> /// <param name="from"></param> /// <param name="to"></param> public void move_piece_for_edit(SquareHand from, SquareHand to) { var pos = gameServer.Position; // 何にせよ、移動、もしくは交換をする。 // → 交換をする実装、不評なので、将棋所・ShogiGUIに倣い、手駒に移動させる。 var from_pc = pos.PieceOn(from); var from_pt = from_pc.PieceType(); var from_pr = from_pc.RawPieceType(); var to_pc = pos.PieceOn(to); var to_pr = to_pc.RawPieceType(); // 移動元と移動先が同じなら何もする必要はない。 if (from == to) { // このケースを除外しておかないと、toの駒を手駒に移動させる処理などで // from == toだと手駒が増えることになる。 // しかし、駒を掴んでいる状態が変化するのでこのときだけ再描画は必要。 Dirty = true; } else if (to.IsBoardPiece()) { if (from.IsBoardPiece()) { // -- 盤上と盤上の駒 #if false // 2駒交換する実装 → 不評なので手駒に移動させることに変更。 // fromとtoの升の駒を交換する。 // fromに駒があることは確定している。toに駒があろうがなかろうが良い。 BoardEditCommand(raw => { raw.board[(int)from] = to_pc; raw.board[(int)to] = from_pc; }); #endif #if true // toのほうが手駒に移動する実装 BoardEditCommand(raw => { raw.board[(int)from] = Piece.NO_PIECE; raw.board[(int)to] = from_pc; if (to_pr != Piece.NO_PIECE && to_pr != Piece.KING) { // 移動元の駒のcolorの手駒に移動させる。玉は、(欠落するので)勝手に駒箱に移動する。 raw.hands[(int)from_pc.PieceColor()].Add(to_pr); } }); #endif } else if (from.IsHandPiece()) { // -- 手駒を盤面に BoardEditCommand(raw => { #if false // 駒箱に移動する実装 → 不評なので手駒になるように変更 raw.hands[(int)from.PieceColor()].Sub(from_pt); raw.board[(int)to] = from_pc; // このtoの位置にもし駒があったとしたら、それは駒箱に移動する。 // (その駒が欠落するので..) #endif #if true // toのほうが手駒に移動する実装 raw.hands[(int)from.PieceColor()].Sub(from_pt); raw.board[(int)to] = from_pc; if (to_pr != Piece.NO_PIECE && to_pr != Piece.KING) { // 移動元の駒のcolorの手駒に移動させる。玉は、(欠落するので)勝手に駒箱に移動する。 raw.hands[(int)from.PieceColor()].Add(to_pr); } #endif }); } else if (from.IsPieceBoxPiece()) { // -- 駒箱の駒を盤面に // toにあった駒は駒箱に戻ってくるが、これは仕方がない。 BoardEditCommand(raw => raw.board[(int)to] = from_pc); } } else if (to.IsHandPiece()) { if (from.IsBoardPiece()) { // -- 盤上の駒を手駒に移動させる。 // 手駒に出来る駒種でなければキャンセル if (from_pt == Piece.KING) { return; } BoardEditCommand(raw => { raw.board[(int)from] = Piece.NO_PIECE; raw.hands[(int)to.PieceColor()].Add(from_pr); }); } else if (from.IsHandPiece()) { // -- 手駒を手駒に。手番が違うならこれは合法。 if (from.PieceColor() != to.PieceColor()) { BoardEditCommand(raw => { // 同種の駒が駒台から駒台に移動するので、to_prは関係ない。 raw.hands[(int)from.PieceColor()].Sub(from_pr); raw.hands[(int)to.PieceColor()].Add(from_pr); }); } else { // 手駒を同じ駒台に移動させることは出来ないし、 // 選び直しているのでは? if (to_pr != Piece.NO_PIECE) { pick_up_for_edit(to); return; } } } else if (from.IsPieceBoxPiece()) { // -- 駒箱の駒を手駒に // 玉は移動手駒に出来ない if (from_pt != Piece.KING) { BoardEditCommand(raw => raw.hands[(int)to.PieceColor()].Add(from_pr)); } } } else if (to.IsPieceBoxPiece()) { if (from.IsBoardPiece()) { // -- 盤上の駒を駒箱に BoardEditCommand(raw => raw.board[(int)from] = Piece.NO_PIECE); } else if (from.IsHandPiece()) { // -- 駒台の駒を駒箱に BoardEditCommand(raw => raw.hands[(int)from.PieceColor()].Sub(from_pr)); } else if (from.IsPieceBoxPiece()) { // 駒箱の駒を移動させることは出来ないし、 // 選び直しているのでは? if (to_pr != Piece.NO_PIECE) { pick_up_for_edit(to); return; } } } }
/// <summary> /// [UI thread] : 盤面のsqの升(手駒も含む)がクリックされた /// </summary> /// <param name="sq"></param> public void OnBoardClick(SquareHand sq) { var pos = gameServer.Position; var state = viewState; var pc = pos.PieceOn(sq); //Console.WriteLine(sq.Pretty()); if (gameServer.InTheBoardEdit) { // -- 盤面編集中 switch (state.state) { case GameScreenControlViewStateEnum.Normal: { // 盤面編集中はどの駒でも掴める if (pc != Piece.NO_PIECE) { pick_up_for_edit(sq); } break; } case GameScreenControlViewStateEnum.PiecePickedUp: { // 盤面編集中はどの駒でも掴める state.picked_to = sq; move_piece_for_edit(state.picked_from, state.picked_to); break; } } } else { // -- 対局中、もしくは、対局終了後である。 switch (state.state) { case GameScreenControlViewStateEnum.Normal: { // 掴んだのが自分の駒であるか if (pc != Piece.NO_PIECE && pc.PieceColor() == pos.sideToMove && !sq.IsPieceBoxPiece()) { pick_up(sq); // sqの駒を掴んで行き先の候補の升情報を更新する } break; } case GameScreenControlViewStateEnum.PiecePickedUp: { // 次の4つのケースが考えられる // 1.駒を掴んでいる状態なので移動先のクリック // 2.自駒を再度掴んだ(掴んでいたのをキャンセルする) // 3.別の自分の駒を掴んだ(掴み直し) // 4.無縁の升をクリックした(掴んでいたのをキャンセルする) // 1. 駒の移動 // いま掴んでいる駒の移動できる先であるのか。 var bb = state.picked_piece_legalmovesto; if (sq.IsBoardPiece() && bb.IsSet((Square)sq)) { state.picked_to = sq; move_piece(state.picked_from, state.picked_to); } // 2. 掴んでいた駒の再クリック else if (sq == state.picked_from) { StateReset(); } // 3. 別の駒のクリック else if (pc != Piece.NO_PIECE && pc.PieceColor() == pos.sideToMove && !sq.IsPieceBoxPiece()) { pick_up(sq); } // 4. 掴む動作のキャンセル else { StateReset(); } break; } case GameScreenControlViewStateEnum.PromoteDialog: { // PromoteDialogを出していたのであれば、 switch (state.promote_dialog_selection) { case PromoteDialogSelectionEnum.NO_SELECT: break; // 無視 case PromoteDialogSelectionEnum.CANCEL: // キャンセルするので移動の駒の選択可能状態に戻してやる。 StateReset(); break; // 成り・不成を選んでクリックしたのでそれに応じた移動を行う。 case PromoteDialogSelectionEnum.UNPROMOTE: case PromoteDialogSelectionEnum.PROMOTE: var m = Util.MakeMove(state.picked_from, state.picked_to, state.promote_dialog_selection == PromoteDialogSelectionEnum.PROMOTE); DoMoveCommand(m); break; } break; } } } }
/// <summary> /// 駒の移動 盤面編集 /// </summary> /// <param name="from"></param> /// <param name="to"></param> public void move_piece_for_edit(SquareHand from, SquareHand to) { var pos = gameServer.Position; // 何にせよ、移動、もしくは交換をする。 var from_pc = pos.PieceOn(from); var from_pt = from_pc.PieceType(); var from_pr = from_pc.RawPieceType(); var to_pc = pos.PieceOn(to); var to_pr = to_pc.RawPieceType(); if (to.IsBoardPiece()) { if (from.IsBoardPiece()) { // -- 盤上と盤上の駒 // fromとtoの升の駒を交換する。 // fromに駒があることは確定している。toに駒があろうがなかろうが良い。 BoardEditCommand(raw => { raw.board[(int)from] = to_pc; raw.board[(int)to] = from_pc; }); } else if (from.IsHandPiece()) { // -- 手駒を盤面に BoardEditCommand(raw => { raw.hands[(int)from.PieceColor()].Sub(from_pt); raw.board[(int)to] = from_pc; // このtoの位置にもし駒があったとしたら、それは駒箱に移動する。 // (その駒が欠落するので..) }); } else if (from.IsPieceBoxPiece()) { // -- 駒箱の駒を盤面に BoardEditCommand(raw => raw.board[(int)to] = from_pc); } } else if (to.IsHandPiece()) { if (from.IsBoardPiece()) { // -- 盤上の駒を手駒に移動させる。 // 手駒に出来る駒種でなければキャンセル if (from_pt == Piece.KING) { return; } BoardEditCommand(raw => { raw.board[(int)from] = Piece.NO_PIECE; raw.hands[(int)to.PieceColor()].Add(from_pr); }); } else if (from.IsHandPiece()) { // -- 手駒を手駒に。手番が違うならこれは合法。 if (from.PieceColor() != to.PieceColor()) { BoardEditCommand(raw => { // 同種の駒が駒台から駒台に移動するので、to_prは関係ない。 raw.hands[(int)from.PieceColor()].Sub(from_pr); raw.hands[(int)to.PieceColor()].Add(from_pr); }); } else { // 手駒を同じ駒台に移動させることは出来ないし、 // 選び直しているのでは? if (to_pr != Piece.NO_PIECE) { pick_up_for_edit(to); return; } } } else if (from.IsPieceBoxPiece()) { // -- 駒箱の駒を手駒に // 玉は移動手駒に出来ない if (from_pt != Piece.KING) { BoardEditCommand(raw => raw.hands[(int)to.PieceColor()].Add(from_pr)); } } } else if (to.IsPieceBoxPiece()) { if (from.IsBoardPiece()) { // -- 盤上の駒を駒箱に BoardEditCommand(raw => raw.board[(int)from] = Piece.NO_PIECE); } else if (from.IsHandPiece()) { // -- 駒台の駒を駒箱に BoardEditCommand(raw => raw.hands[(int)from.PieceColor()].Sub(from_pr)); } else if (from.IsPieceBoxPiece()) { // 駒箱の駒を移動させることは出来ないし、 // 選び直しているのでは? if (to_pr != Piece.NO_PIECE) { pick_up_for_edit(to); return; } } } StateReset(); }