/// <summary> /// コンストラクタ /// </summary> public GLShogiElement() { AddPropertyChangedHandler("ViewSide", ViewSideUpdated); AddPropertyChangedHandler("EditMode", EditModeUpdated); Board = new Board(); ViewSide = BWType.Black; EditMode = EditMode.Normal; AutoPlayState = AutoPlayState.None; BlackPlayerName = "▲先手"; WhitePlayerName = "△後手"; BlackTime = TimeSpan.Zero; WhiteTime = TimeSpan.Zero; InManipulating = false; InitializeDraw(); }
/// <summary> /// コンストラクタ /// </summary> public KifuObject(KifuHeader header, Board startBoard, Exception error = null) { MoveList = new List<BoardMove>(); RootNode = new MoveNode(); Error = error; SetHeader(header); SetBoard(startBoard, false); }
/// <summary> /// 局面を設定し、局面に指し手がある場合はそれを指し手リストに追加します。 /// </summary> /// <remarks> /// <paramref name="isStartBoard"/>が真の場合は開始局面のみ /// (手を全く指していない=手数が0)しか受け入れません。 /// </remarks> public void SetBoard(Board board, bool isStartBoard) { if (board == null) { throw new ArgumentNullException("board"); } if (isStartBoard) { if (board.MoveCount > 0) { throw new ShogiException( "SetBoardには開始局面を設定してください。"); } StartBoard = board; } else { // 開始局面でなくてもよい場合は、指し手を別に取得します。 var moveList = new List<BoardMove>(); for (var move = board.Undo(); move != null; move = board.Undo()) { moveList.Insert(0, move); } StartBoard = board; SetMoveList(moveList); } }
/// <summary> /// KifMoveNodeからMoveNodeへ構造を変換します。 /// 結果は<paramref name="root"/>以下に設定されます。 /// </summary> private void ConvertToMoveNode(Board board, MoveNode root, List<Exception> errors) { for (var node = this; node != null; node = node.Variation) { var cloned = board.Clone(); // 指し手を実際に指してみます。 var bmove = node.MakeMove(cloned, errors); if (bmove == null) { continue; } var moveNode = new MoveNode { Move = bmove, MoveCount = node.MoveCount, Duration = node.Duration, Comment = node.Comment, }; // 次の指し手とその変化を変換します。 if (node.Next != null) { node.Next.ConvertToMoveNode(cloned, moveNode, errors); } root.AddNext(moveNode); } }
/// <summary> /// 局面識別子を実際の局面に直します。 /// </summary> public static Board ToBoard(this BoardType type) { var board = new Board(); switch (type) { case BoardType.NoHandicap: return board; case BoardType.HandicapKyo: board[1, 1] = null; break; case BoardType.HandicapRightKyo: board[9, 1] = null; break; case BoardType.HandicapKaku: board[2, 2] = null; break; case BoardType.HandicapHisya: board[8, 2] = null; break; case BoardType.HandicapHisyaKyo: board[1, 1] = null; board[8, 2] = null; break; case BoardType.Handicap2: board[2, 2] = null; board[8, 2] = null; break; case BoardType.Handicap3: board[9, 1] = null; goto case BoardType.Handicap2; case BoardType.Handicap4: board[1, 1] = null; board[9, 1] = null; goto case BoardType.Handicap2; case BoardType.Handicap5: board[8, 1] = null; goto case BoardType.Handicap4; case BoardType.HandicapLeft5: board[2, 1] = null; goto case BoardType.Handicap4; case BoardType.Handicap6: board[2, 1] = null; board[8, 1] = null; goto case BoardType.Handicap4; case BoardType.Handicap8: board[3, 1] = null; board[7, 1] = null; goto case BoardType.Handicap6; case BoardType.Handicap10: board[4, 1] = null; board[6, 1] = null; goto case BoardType.Handicap8; default: throw new ShogiException( type + ": BoardTypeの値が間違っています。"); } // 駒落ちの場合、最初に指すのは上手=後手となります。 board.Turn = BWType.White; return board; }
/// <summary> /// 共通コンストラクタ /// </summary> private AutoPlay(Board board) { UpdateEnumerator = GetUpdateEnumerator().GetEnumerator(); Board = board; Interval = DefaultInterval; BeginningInterval = TimeSpan.Zero; EndingInterval = TimeSpan.Zero; BackgroundFadeInterval = DefaultBackgroundFadeInterval; Position = TimeSpan.Zero; BasePosition = TimeSpan.Zero; IsWaitForLastMove = true; }
/// <summary> /// コンストラクタ /// </summary> public AutoPlay(Board board, AutoPlayType autoPlayType) : this(board) { if (autoPlayType != AutoPlayType.Undo && autoPlayType != AutoPlayType.Redo) { throw new ArgumentException( "アンドゥかリドゥを選択してください。", "autoPlayType"); } AutoPlayType = autoPlayType; this.maxMoveCount = (autoPlayType == AutoPlayType.Undo ? board.CanUndoCount : board.CanRedoCount); }
/// <summary> /// オブジェクトのコピーを作成します。 /// </summary> public Board Clone() { using (LazyLock()) { var cloned = new Board(false) { blackCapturedPieceBox = this.blackCapturedPieceBox.Clone(), whiteCapturedPieceBox = this.whiteCapturedPieceBox.Clone(), viewSide = this.viewSide, turn = this.turn, prevMovedSquare = ( this.prevMovedSquare != null ? this.prevMovedSquare.Clone() : null), moveList = this.moveList.Select(move => move.Clone()).ToList(), redoList = this.redoList.Select(move => move.Clone()).ToList(), }; // 各位置に駒を設定します。 for (var rank = 1; rank <= BoardSize; ++rank) { for (var file = 1; file <= BoardSize; ++file) { var square = new Square(file, rank); var piece = this[square]; cloned[square] = ( piece != null ? piece.Clone() : null); } } return cloned; } }
/// <summary> /// KifMoveNodeからMoveNodeへ構造を変換します。 /// </summary> public MoveNode ConvertToMoveNode(Board board, out Exception error) { var root = new MoveNode(); var errors = new List<Exception>(); ConvertToMoveNode(board, root, errors); error = ( !errors.Any() ? null : errors.Count() == 1 ? errors.FirstOrDefault() : new AggregateException(errors)); return root; }
/// <summary> /// オブジェクトの等値性を判定します。 /// </summary> public static bool BoardEquals(Board x, Board y) { var result = Util.PreEquals(x, y); if (result != null) { return result.Value; } return x.BoardEquals(y); }
/// <summary> /// オブジェクトの等値性を判定します。 /// </summary> public bool BoardEquals(Board other) { if ((object)other == null) { return false; } using (LazyLock()) using (other.LazyLock()) { for (var rank = 1; rank < BoardSize; ++rank) { for (var file = 1; file < BoardSize; ++file) { var square = new Square(file, rank); if (this[square] != other[square]) { return false; } } } if (!this.blackCapturedPieceBox.Equals(other.blackCapturedPieceBox) || !this.whiteCapturedPieceBox.Equals(other.whiteCapturedPieceBox)) { return false; } if (this.turn != other.turn) { return false; } /*if (this.prevMovedSquare != other.prevMovedSquare) { return false; }*/ //private List<BoardMove> moveList = new List<BoardMove>(); return true; } }
/// <summary> /// コンストラクタ /// </summary> public BoardPieceEventArgs(Board board, BoardMove move) { Board = board; Move = move; }
/// <summary> /// コンストラクタ /// </summary> public AutoPlay(Board board, bool isCloneBoard, AutoPlayType autoPlayType, int maxMoveCount = -1) : this(board, isCloneBoard) { if (autoPlayType != AutoPlayType.Undo && autoPlayType != AutoPlayType.Redo) { throw new ArgumentException( "アンドゥかリドゥを選択してください。", "autoPlayType"); } AutoPlayType = autoPlayType; MaxMoveCount = ( maxMoveCount >= 0 ? maxMoveCount : (autoPlayType == AutoPlayType.Undo ? board.CanUndoCount : board.CanRedoCount)); }
/// <summary> /// 共通コンストラクタ /// </summary> private AutoPlay(Board board, bool isCloneBoard) { if (board == null) { throw new ArgumentNullException("board"); } UpdateEnumeratorFactory = () => GetUpdateEnumerator(); StartBoard = board; Board = (isCloneBoard ? board.Clone() : board); IsCloneBoard = isCloneBoard; Interval = DefaultInterval; EffectFadeInterval = DefaultEffectFadeInterval; BeginningInterval = TimeSpan.Zero; EndingInterval = TimeSpan.Zero; Position = TimeSpan.Zero; BasePosition = TimeSpan.Zero; IsWaitForLastMove = true; }
/// <summary> /// コンストラクタ /// </summary> public KifuObject(KifuHeader header, Board startBoard, IEnumerable<BoardMove> moveList, Exception error = null) { Error = error; SetHeader(header); SetBoard(startBoard, true); SetMoveList(moveList); }
/// <summary> /// コンストラクタ /// </summary> public BoardPieceRoutedEventArgs(RoutedEvent ev, Board board, BoardMove move) : base(ev) { Board = board; Move = move; }
/// <summary> /// コンストラクタ /// </summary> public KifuObject(KifuHeader header, Board startBoard, MoveNode root, Exception error = null) { Error = error; SetHeader(header); SetBoard(startBoard, true); SetRootNode(root); }
/// <summary> /// コンストラクタ /// </summary> public ShogiUIElement3D() { Initialize(); BanBrush = DefaultBanBrush.Clone(); CapturedPieceBoxBrush = DefaultPieceBoxBrush.Clone(); PieceImage = DefaultPieceImage.Clone(); Board = new Board(); }
/// <summary> /// コンストラクタ /// </summary> public AutoPlay(Board board, IEnumerable<BoardMove> moveList) : this(board) { if (moveList == null) { throw new ArgumentNullException("moveList"); } AutoPlayType = AutoPlayType.Normal; this.moveList = new List<BoardMove>(moveList); this.maxMoveCount = moveList.Count(); }
/// <summary> /// 自動再生を開始します。 /// </summary> public void StartAutoPlay(AutoPlay autoPlay) { if (autoPlay == null) { return; } if (AutoPlayState == AutoPlayState.Playing) { return; } // this.autoPlayを変える前に局面を変更します。 // 局面変更時は自動再生を自動で止めるようになっているので、 // this.autoPlayフィールドを変更した後に局面を変えると、 // すぐに止まってしまいます。 this.oldBoard = Board; Board = autoPlay.Board; autoPlay.ShogiElement = this; this.autoPlay = autoPlay; AutoPlayState = AutoPlayState.Playing; }
/// <summary> /// KifMoveNodeからMoveNodeへ構造を変換します。 /// </summary> public MoveNode ConvertToMoveNode(Board board, KifMoveNode head, out Exception error) { var errors = new List<Exception>(); var root = new MoveNode { MoveCount = head.MoveCount, Duration = head.Duration, Comment = head.Comment, }; // これでrootの子要素に指し手ツリーが設定されます。 ConvertToMoveNode(board, root, errors); error = ( !errors.Any() ? null : errors.Count() == 1 ? errors.FirstOrDefault() : new AggregateException(errors)); return root; }
private void AutoPlay_Ended() { if (this.autoPlay == null) { return; } // コントロールは消去しておきます。 var autoPlay = this.autoPlay; this.autoPlay.ShogiElement = null; this.autoPlay = null; Board = this.oldBoard; this.oldBoard = null; AutoPlayState = AutoPlayState.None; // Boardが変更されるとAutoPlayはすべてクリアされます。 // Stopの中でBoardが変更されると少し面倒なことになるため、 // Stopメソッドはすべての状態が落ち着いた後に呼びます。 autoPlay.Stop(); }
/// <summary> /// このノードの手を実際に指してみて、着手可能か確認します。 /// </summary> private BoardMove MakeMove(Board board, List<Exception> errors) { var bmove = board.ConvertMove(Move, true); if (bmove == null || !bmove.Validate()) { errors.Add(new FileFormatException( LineNumber, string.Format( "{0}手目: 指し手が正しくありません。", MoveCount))); return null; } // 局面を進めます。 if (!board.DoMove(bmove)) { errors.Add(new FileFormatException( LineNumber, string.Format( "{0}手目の手を指すことができませんでした。", MoveCount))); return null; } return bmove; }
/// <summary> /// 局面から駒落ちなどの局面名を取得します。 /// </summary> public static BoardType GetBoardTypeFromBoard(Board board) { var list = EnumEx.GetValues<BoardType>() .Where(_ => _ != BoardType.None) .Where(_ => Board.BoardEquals(board, _.ToBoard())) .ToArray(); if (!list.Any()) { // 該当なし return BoardType.None; } return list.FirstOrDefault(); }