public override void Execute(BoardMove move)
        {
            var piece = BoardState.GetItem(move.From).Item as PawnEntity;

            piece.TwoStep = true;
            ActionProvider.Create((int)DefaultActions.MoveOnly, BoardState).Execute(move);
        }
        private static bool TryFindMove(IEnumerable <LocatedItem <ChessPieceEntity> > items, BoardLocation destination,
                                        StandardAlgebraicNotation san,
                                        out BoardMove findMoveTo)
        {
            findMoveTo = null;
            var locatedItems = items as LocatedItem <ChessPieceEntity>[] ?? items.ToArray();

            if (!locatedItems.Any())
            {
                return(true);
            }

            if (locatedItems.Count() == 1)
            {
                var item = locatedItems.Single();
                if (san.PromotionPiece.HasValue)
                {
                    findMoveTo = item.Paths.FlattenMoves().FindMove(item.Location, destination,
                                                                    ChessFactory.MoveExtraData(item.Item.Player, san.PromotionPiece.Value));
                }
                else
                {
                    findMoveTo = item.FindMoveTo(destination);
                }
                return(findMoveTo != null);
            }

            return(false);
        }
Exemple #3
0
        static void Main(string[] args)
        {
            AllianceScenario allianceScenario = AllianceScenario.GetRandomAllianceScenario();
            Board            board            = Board.GetInitialBoard();
            BoardMove        moves            = new BoardMove();

            moves.Add(board.GetMove("ber", "kie"));
            moves.Add(board.GetMove("bud", "rum"));
            moves.Add(board.GetMove("con", "bul"));
            moves.Add(board.GetMove("lvp", "edi"));
            moves.Add(board.GetMove("mar", "pie"));
            moves.Add(board.GetMove("mos", "stp"));
            moves.Add(board.GetMove("mun", "ruh"));
            moves.Add(board.GetMove("par", "gas"));
            moves.Add(board.GetMove("rom", "nap"));
            moves.Add(board.GetMove("ven", "tyr"));
            moves.Add(board.GetMove("vie", "tri"));
            moves.Add(board.GetMove("war", "sil"));
            moves.Add(board.GetMove("ank", "con"));
            moves.Add(board.GetMove("bre", "mao"));
            moves.Add(board.GetMove("edi", "nth"));
            moves.Add(board.GetMove("kie", "den"));
            moves.Add(board.GetMove("lon", "eng"));
            moves.Add(board.GetMove("nap", "tys"));
            moves.Add(board.GetMove("sev", "bla"));
            moves.Add(board.GetMove("stp_sc", "bot"));
            moves.Add(board.GetMove("tri", "alb"));
            moves.FillHolds(board);
            board.ApplyMoves(moves);
            board.EndTurn();


            moves.Clear();
            moves.Add(board.GetMove("bul", "gre"));
            moves.Add(board.GetMove("gas", "spa"));
            moves.Add(board.GetMove("kie", "hol"));
            moves.Add(board.GetMove("ruh", "bel"));
            moves.Add(board.GetMove("smy", "arm"));
            moves.Add(board.GetMove("stp", "nwy"));
            moves.Add(board.GetMove("tri", "ser"));
            moves.Add(board.GetMove("bot", "swe"));
            moves.Add(board.GetMove("con", "bul_ec"));
            moves.Add(board.GetMove("mao", "por"));
            moves.Add(board.GetMove("tys", "tun"));
            moves.FillHolds(board);
            board.ApplyMoves(moves);
            board.EndTurn();

            //var boardMoves = BoardFutures.GetAllBoardMovesWinter(board);
            var          probabilisticFuturesAlgorithm = new ProbabilisticFuturesAlgorithm();
            int          limit        = 20;
            List <Board> futureBoards = board.GetFutures(allianceScenario, probabilisticFuturesAlgorithm);

            while (futureBoards.Any() && limit > 0)
            {
                limit--;
                board        = futureBoards[0];
                futureBoards = board.GetFutures(allianceScenario, probabilisticFuturesAlgorithm);
            }
        }
        protected void SetupToEntity(BoardMove move, TestBoardEntity entity = null)
        {
            var locatedEntity = CreateItem(move, entity);

            RoBoardStateMock.Setup(m => m.GetItem(It.Is <BoardLocation>(l => move.To.Equals(l))))
            .Returns(locatedEntity);
        }
Exemple #5
0
        /// <summary>
        /// Performs a full play cycle.
        /// </summary>
        /// <param name="player">The player who is playing.</param>
        /// <returns>The desired move.</returns>
        public BoardMove Play(Player player)
        {
            int           index;
            UIFelliSquare pieceToMove;

            UIFelliSquare[] availableForSelection;
            BoardMove[]     possibleMoves;
            BoardMove       selectedMove = new BoardMove();

            while (true)
            {
                // Get all squares that have a piece belonging to the current
                // player and piece has possible moves.
                availableForSelection =
                    GetAllSquaresWithPiecesOfColor(player.PiecesColor);

                index = GetPlayerSelectSquare(availableForSelection);

                // If index < 0 that means the player hit escape in piece
                // selection...
                if (index < 0)
                {
                    // ...signaling desire to exit the game.
                    pieceToMove = null;
                    break;
                }

                pieceToMove = availableForSelection[index];

                // Get possible moves by the selected piece.
                possibleMoves = board.GetPossibleMoves(pieceToMove.Piece);

                // Get all possible destinations.
                availableForSelection = GetPossibleDestinations(possibleMoves);

                index = GetPlayerSelectSquare(availableForSelection);

                // If index < 0 that means the player hit escape in destination
                // selection...
                if (index < 0)
                {
                    pieceToMove.IsHovered = false;

                    // ...signaling desire to go back to piece selection.
                    continue;
                }

                selectedMove = possibleMoves[index];

                pieceToMove.IsHovered = false;
                availableForSelection[index].IsHovered = false;
                break;
            }

            // Returning BoardMove.Piece == null will signal an intention to
            // quit the game.
            return(new BoardMove(pieceToMove?.Piece,
                                 selectedMove.Destination,
                                 selectedMove.PieceEaten));
        }
        protected async Task OnBoardFieldClicked(Position position)
        {
            if (this.GameManager.IsGameReadyToPlay)
            {
                if (ChessBoardComponent.selectedPosition == null)
                {
                    var pieceAtPosition = GameManager.GetPieceForViewAtPosition(position);
                    if (pieceAtPosition != null)
                    {
                        if (pieceAtPosition.PieceColor == GameManager.ClientColor)
                        {
                            ChessBoardComponent.SelectPosition(position);
                            ChessBoardComponent.ShowMoves(GameManager.GetPieceMoveSetAtPosition(position).Select(x => position + x.Shift));
                        }
                    }
                }
                else
                {
                    var move = new BoardMove((Position)ChessBoardComponent.selectedPosition, position);
                    await GameManager.TryPerformMove(move);

                    ChessBoardComponent.UnSelectAll();
                }
            }
        }
Exemple #7
0
        public static IEnumerable <BoardMove> GetBoardMovesFallSpring(Board board, IEnumerable <MapNode> mapNodeSources)
        {
            if (board.Season is Winter)
            {
                throw new Exception($"Bad season {board.Season}");
            }
            List <UnitMove>             allUnitMoves     = board.GetUnitMoves();
            ILookup <MapNode, UnitMove> sourceNodeGroups = allUnitMoves.Where(um => mapNodeSources.Contains(um.Edge.Source)).ToLookup(um => um.Edge.Source);

            List <BoardMove> completedBoardMoves = new List <BoardMove>();
            int depth = 0;

            foreach (UnitMove move in sourceNodeGroups.First())
            {
                if (move.IsConvoy || move.IsDisband)
                {
                    continue;
                }
                BoardMove workingBoardMove = new BoardMove();
                workingBoardMove.Add(move);
                GetBoardMovesFallSpringRecursive(board, workingBoardMove, sourceNodeGroups, completedBoardMoves, depth + 1);
            }

            return(completedBoardMoves);
        }
Exemple #8
0
        private static void GetWinterBoardMovesDisbandsOnlyRecursive(Board originalBoard, BoardMove workingBoardMove, IEnumerable <UnitMove> availableMoves, HashSet <BoardMove> completedBoardMoves, PowersDictionary <int> buildDisbandCounts, int minMoves)
        {
            if (workingBoardMove.Count == minMoves)
            {
                completedBoardMoves.Add(workingBoardMove.Clone());
                return;
            }

            var    moveGrouping = availableMoves.ToLookup(um => um.Unit.Power);
            Powers power        = availableMoves.First().Unit.Power;
            IEnumerable <UnitMove> remainingMoves;

            foreach (UnitMove unitMove in moveGrouping[power])
            {
                if (workingBoardMove.Count(um => um.Unit.Power == power) == Math.Abs(buildDisbandCounts[power]))
                {
                    remainingMoves = availableMoves.Where(um => um.Unit.Power != power);
                }
                else
                {
                    remainingMoves = availableMoves.Where(um => um != unitMove);
                }
                BoardMove newBoardMove = workingBoardMove.Clone();
                newBoardMove.Add(unitMove);
                GetWinterBoardMovesDisbandsOnlyRecursive(originalBoard, newBoardMove, remainingMoves, completedBoardMoves, buildDisbandCounts, minMoves);
            }
        }
Exemple #9
0
        public void MateTest2()
        {
            var bod =
                "# ----  棋譜ファイル  ----\n" +
                "先手:先手\n" +
                "後手:後手\n" +
                "後手の持駒:歩三 \n" +
                "  9 8 7 6 5 4 3 2 1\n" +
                "+---------------------------+\n" +
                "|v香v桂 ・ ・ ・ ・ ・ ・ ・|一\n" +
                "| ・ ・ ・ ・ ・ ・ ・ ・ ・|二\n" +
                "|v玉v桂v歩 金 ・ ・ ・ ・ ・|三\n" +
                "| ・ ・ ・ ・ ・ ・ ・ ・ ・|四\n" +
                "| ・ 銀 ・ 歩 ・ ・ ・ ・ ・|五\n" +
                "| 玉 ・ 歩 ・ 歩 香 ・ ・ ・|六\n" +
                "| ・v金 銀 金 ・ ・ ・ ・ ・|七\n" +
                "| ・ ・v馬 銀 ・ ・ ・ ・ ・|八\n" +
                "| 香 ・ ・ ・ ・ ・ ・ ・ ・|九\n" +
                "+---------------------------+\n" +
                "先手の持駒:飛二 角 金 銀 桂二 香 歩十一 \n" +
                "手数=0\n" +
                "後手番\n";
            var board = BodBoard.Parse(bod);

            var move = BoardMove.CreateDrop(
                BWType.White,
                new Square(9, 5),
                PieceType.Hu);

            Assert.False(board.CanMove(move));
            Assert.False(board.DoMove(move));
        }
Exemple #10
0
        private static void GetWinterBoardMovesFullBuildsOnly(IEnumerable <UnitMove> availableMoves, List <BoardMove> buildBoardMoves, PowersDictionary <int> buildDisbandCounts)
        {
            var allPowersMoveCombos = new List <List <UnitMove> >();
            int powerCount          = 0;

            foreach (Powers currentPower in buildDisbandCounts.Where(kvp => kvp.Value > 0).Select(kvp => kvp.Key))
            {
                powerCount++;
                int buildMovesForPower  = buildDisbandCounts[currentPower];
                int territoryBuildCount = availableMoves.Where(um => um.Unit.Power == currentPower).GroupBy(um => um.Edge.Target.Territory).Count();
                int buildCount          = Math.Min(buildMovesForPower, territoryBuildCount);

                List <List <UnitMove> > singlePowerMoveCombos;
                Helpers.GetAllCombinations(availableMoves.Where(um => um.Unit.Power == currentPower).ToList(), buildCount, out singlePowerMoveCombos);
                singlePowerMoveCombos.RemoveAll(ul => ul.GroupBy(um => um.Edge.Target.Territory).Count() != buildCount);
                allPowersMoveCombos.AddRange(singlePowerMoveCombos);
            }
            var boardMoveLists = new List <List <List <UnitMove> > >();

            Helpers.GetAllCombinations(allPowersMoveCombos, powerCount, out boardMoveLists);
            boardMoveLists.RemoveAll(ll => ll.GroupBy(l2 => l2.First().Unit.Power).Count() < powerCount);
            foreach (List <List <UnitMove> > ll in boardMoveLists)
            {
                BoardMove workingBoardMove = new BoardMove();
                foreach (UnitMove move in ll.SelectMany(l => l))
                {
                    if (!workingBoardMove.CurrentlyAllowsWinter(move, buildDisbandCounts[move.Unit.Power]))
                    {
                        throw new Exception($"Bad combination when building winter board move: {move}.  {move.Unit.Power} allowed {buildDisbandCounts[move.Unit.Power]}");
                    }
                    workingBoardMove.Add(move);
                }
                buildBoardMoves.Add(workingBoardMove);
            }
        }
Exemple #11
0
        public void MateTest1()
        {
            var bod =
                "後手の持駒:角二 桂二 歩五 \n" +
                "  9 8 7 6 5 4 3 2 1\n" +
                "+---------------------------+\n" +
                "|v香 ・ ・ ・ ・ ・ ・ ・v香|一\n" +
                "| ・ ・ ・ ・ 銀 ・v金 ・ ・|二\n" +
                "| ・ ・ とv歩v歩 ・ ・v歩 ・|三\n" +
                "| ・ ・ ・ ・ ・ ・v歩 ・v歩|四\n" +
                "| 歩 ・ 銀 金 ・ 飛 ・ ・ ・|五\n" +
                "| ・ ・ 銀 歩 ・ 金 ・v玉 歩|六\n" +
                "| 玉 歩 桂 ・ ・ ・ ・ ・ ・|七\n" +
                "| ・ ・ 歩 ・ ・ 歩 金 ・ ・|八\n" +
                "| 香v飛 ・ ・ ・ 銀 ・ ・ 香|九\n" +
                "+---------------------------+\n" +
                "先手の持駒:桂 歩 \n" +
                "手数=130";
            var board = BodBoard.Parse(bod);

            var move = BoardMove.CreateDrop(
                BWType.Black,
                new Square(2, 7),
                PieceType.Hu);

            Assert.False(board.CanMove(move));
            Assert.False(board.DoMove(move));
        }
Exemple #12
0
        public void Should_return_false_when_wrong_piece_in_passing_location(string from, string to)
        {
            BoardLocation to1  = to.ToBoardLocation();
            var           move = new BoardMove(@from.ToBoardLocation(), to1, (int)DefaultActions.TakeOnly);

            Assert.False(_validator.ValidateMove(move, _boardState));
        }
Exemple #13
0
        public void Should_return_true_for_valid_take()
        {
            BoardLocation to   = "B7".ToBoardLocation();
            var           move = new BoardMove("A6".ToBoardLocation(), to, (int)ChessMoveTypes.TakeEnPassant);

            Assert.True(_validator.ValidateMove(move, _boardState));
        }
Exemple #14
0
        public void BoardCloneTest()
        {
            Board board = Board.GetInitialBoard();
            Board clone = board.Clone();

            Assert.AreEqual(clone.OwnedSupplyCenters[Powers.Germany].Count, board.OwnedSupplyCenters[Powers.Germany].Count);

            BoardMove moves = new BoardMove();

            moves.Add(clone.GetMove("kie", "den"));
            moves.Add(clone.GetMove("ber", "kie"));
            moves.FillHolds(clone);
            clone.ApplyMoves(moves);
            clone.EndTurn();

            Assert.AreNotEqual(clone.Turn, board.Turn);

            moves.Clear();
            moves.Add(clone.GetMove("kie", "hol"));
            moves.FillHolds(clone);
            clone.ApplyMoves(moves);
            clone.EndTurn();

            Assert.AreNotEqual(clone.OwnedSupplyCenters[Powers.Germany].Count, board.OwnedSupplyCenters[Powers.Germany].Count);
        }
Exemple #15
0
        /// <summary>
        /// 駒の種類にかかわりなく、指定の位置に着手可能な指し手をすべて列挙します。
        /// </summary>
        public IEnumerable<BoardMove> ListupMoves(BWType bwType, Square dstSquare)
        {
            // 打てる駒をすべて列挙します。
            foreach (var pieceType in EnumEx.GetValues<PieceType>())
            {
                if (GetCapturedPieceCount(pieceType, bwType) <= 0)
                {
                    continue;
                }

                var move = new BoardMove()
                {
                    DstSquare = dstSquare,
                    DropPieceType = pieceType,
                    BWType = bwType,
                };

                // 駒打ちが可能なら、それも該当手となります。
                if (CanMove(move, MoveFlags.CheckOnly))
                {
                    yield return move;
                }
            }

            // 移動による指し手をすべて列挙します。
            foreach (var srcSquare in Board.AllSquares())
            {
                var moves = GetAvailableMove(bwType, srcSquare, dstSquare);

                foreach (var move in moves)
                {
                    yield return move;
                }
            }
        }
Exemple #16
0
        public void BuildUnitMoves()
        {
            Board     board = Board.GetInitialBoard();
            BoardMove moves = new BoardMove();

            moves.Add(board.GetMove("kie", "den"));
            moves.Add(board.GetMove("ber", "kie"));
            moves.FillHolds(board);
            board.ApplyMoves(moves);
            Assert.AreEqual(3, board.OwnedSupplyCenters[Powers.Germany].Count);
            board.EndTurn();

            Assert.AreEqual(3, board.OwnedSupplyCenters[Powers.Germany].Count);

            moves.Clear();
            moves.Add(board.GetMove("kie", "hol"));
            moves.FillHolds(board);
            board.ApplyMoves(moves);
            Assert.AreEqual(3, board.OwnedSupplyCenters[Powers.Germany].Count);
            board.EndTurn();

            Assert.AreEqual(5, board.OwnedSupplyCenters[Powers.Germany].Count);
            Assert.AreEqual(24, board.OwnedSupplyCenters.Where(kvp => kvp.Key != Powers.None).SelectMany(kvp => kvp.Value).Count());

            var unitMoves = board.GetUnitMoves();

            Assert.AreEqual(4, unitMoves.Count(um => um.IsBuild));
        }
Exemple #17
0
        /// <summary>
        /// <paramref name="srcSquare"/>の駒を<paramref name="dstSquare"/>
        /// に動かすことが可能な指し手をすべて列挙します。
        /// </summary>
        private IEnumerable<BoardMove> GetAvailableMove(BWType bwType,
                                                        Square srcSquare,
                                                        Square dstSquare)
        {
            var piece = this[srcSquare];
            if (piece == null || piece.BWType != bwType)
            {
                yield break;
            }

            var move = new BoardMove()
            {
                DstSquare = dstSquare,
                SrcSquare = srcSquare,
                MovePiece = piece.Piece,
                BWType = bwType,
            };

            // 成り駒でなければ、成る可能性があります。
            if (!piece.IsPromoted)
            {
                move.IsPromote = true;
                if (CanMove(move, MoveFlags.CheckOnly))
                {
                    // yield returnなのでCloneしないとまずい。
                    yield return move.Clone();
                }
            }

            move.IsPromote = false;
            if (CanMove(move, MoveFlags.CheckOnly))
            {
                yield return move;
            }
        }
        public void ClearAndAddHistoryItems(IEnumerable <HistoryItem.T> items)
        {
            Clear();
            foreach (HistoryItem.T item in items)
            {
                BoardMove.T move = item.Move;
                PieceTypes  pt   = PieceTypes.ptNone;
                if (move.Color.Equals(Piece.Colors.Black))
                {
                    pt = PieceTypes.ptBlack;
                }
                else if (move.Color.Equals(Piece.Colors.White))
                {
                    pt = PieceTypes.ptWhite;
                }

                MoveHistoryItem vm = new MoveHistoryItem(item.ID, pt,
                                                         Coord.toString(BoardMove.getSourceCoord(move)),
                                                         Coord.toString(BoardMove.getTargetCoord(move)),
                                                         BoardMove.getRemovedPiecesCount(move));

                Add(vm);
            }

            OnPropertyChanged("Count");
            OnCollectionChanged();
        }
        public Paths PathsFrom(BoardLocation location, int forPlayer)
        {
            var paths = new Paths();

            var playerIdx = (Colours)forPlayer;

            foreach (var dest in new[]
            {
                location.MoveRight(playerIdx, 2),
                location.MoveLeft(playerIdx, 2),
            })
            {
                if (dest != null)
                {
                    var side = dest.X > location.X
                            ? ChessMoveTypes.CastleKingSide
                            : ChessMoveTypes.CastleQueenSide;

                    paths.Add(new Path {
                        BoardMove.Create(location, dest, (int)side)
                    });
                }
            }

            return(paths);
        }
        public Paths PathsFrom(BoardLocation location, int forPlayer)
        {
            var paths = new Paths();

            var playerIdx = (Colours)forPlayer;

            foreach (var dest in new[]
            {
                location.KnightVerticalMove(playerIdx, true, true),
                location.KnightVerticalMove(playerIdx, true, false),
                location.KnightVerticalMove(playerIdx, false, true),
                location.KnightVerticalMove(playerIdx, false, false),

                location.KnightHorizontalMove(playerIdx, true, true),
                location.KnightHorizontalMove(playerIdx, true, false),
                location.KnightHorizontalMove(playerIdx, false, true),
                location.KnightHorizontalMove(playerIdx, false, false),
            })
            {
                if (dest != null)
                {
                    paths.Add(new Path {
                        BoardMove.Create(location, dest, (int)DefaultActions.MoveOrTake)
                    });
                }
            }

            return(paths);
        }
Exemple #21
0
 internal virtual void OnBoardMove(Location i_Source, Location i_Dest)
 {
     if (BoardMove != null)
     {
         BoardMove.Invoke(i_Source, i_Dest);
     }
 }
Exemple #22
0
        private List <MapNode> GetPath(Board board, MapNode source, BoardMove boardMove, List <KeyValuePair <MapNode, double> > orderedDistances, Func <MapNode, bool> predicate)
        {
            var allMoves = board.GetUnitMoves();

            foreach (MapNode currentTarget in orderedDistances.Select(kvp => kvp.Key)
                     .Where(predicate))
            {
                IEnumerable <UndirectedEdge <MapNode> > rawPath;
                if (!_predecessorObserver.TryGetPath(currentTarget, out rawPath))
                {
                    continue;
                }

                List <MapNode> path           = MakePathList(source, currentTarget, rawPath);
                MapNode        adjacentTarget = path[1];

                UnitMove unitMove = allMoves.FirstOrDefault(um => um.Edge.Target == adjacentTarget && um.Edge.Source == source);
                if (boardMove == null || boardMove.CurrentlyAllowsFallSpring(unitMove))
                {
                    return(path);
                }
            }

            // couldn't find anything
            return(null);
        }
Exemple #23
0
 public bool TryPerformMove(PieceColor color, BoardMove move)
 {
     if (GameState != GameState.Ended && game.CurrentPlayerColor == color && game.TryPerformMove(move))
     {
         GameState = GameState.InProgress;
         if (game.GameState == GameState.Ended)
         {
             blackTimer.Stop();
             whiteTimer.Stop();
             GameState = GameState.Ended;
             Winner    = game.GetWinner();
         }
         else
         {
             if (color == PieceColor.White)
             {
                 whiteTimer.HasMoved();
                 blackTimer.TryStart();
             }
             else if (color == PieceColor.Black)
             {
                 blackTimer.HasMoved();
                 whiteTimer.TryStart();
             }
         }
         return(true);
     }
     return(false);
 }
        private static IEnumerable <BoardLocation> CalcPathBetweenKingAndCastle(BoardMove move, Colours kingColour)
        {
            // TODO: This could be pulled out and tested in isolation indeed just be static lists
            var pathBetween = new List <BoardLocation>();

            BoardLocation KingSide(Colours c, int i)
            => c == Colours.White
                    ? move.From.MoveRight(c, i)
                    : move.From.MoveLeft(c, i);

            BoardLocation QueenSide(Colours c, int i)
            => c == Colours.White
                    ? move.From.MoveLeft(c, i)
                    : move.From.MoveRight(c, i);


            var kingOwner = kingColour;

            if (move.From.X < move.To.X)
            {
                pathBetween.Add(KingSide(kingOwner, 1));
                pathBetween.Add(KingSide(kingOwner, 2));
            }
            else
            {
                pathBetween.Add(QueenSide(kingOwner, 1));
                pathBetween.Add(QueenSide(kingOwner, 2));
            }

            pathBetween.RemoveAll(location => location == null);
            return(pathBetween);
        }
Exemple #25
0
        public void DisbandWinterUnitMoves()
        {
            Board     board = Board.GetInitialBoard();
            BoardMove moves = new BoardMove();

            moves.Add(board.GetMove("tri", "ven"));
            moves.Add(board.GetMove("ven", "pie"));
            moves.FillHolds(board);
            board.ApplyMoves(moves);
            board.EndTurn();


            moves.Clear();
            moves.FillHolds(board);
            board.ApplyMoves(moves);
            board.EndTurn();

            Assert.AreEqual(2, board.OwnedSupplyCenters[Powers.Italy].Count);
            Assert.AreEqual(4, board.OwnedSupplyCenters[Powers.Austria].Count);
            Assert.AreEqual(22, board.OwnedSupplyCenters.Where(kvp => kvp.Key != Powers.None).SelectMany(kvp => kvp.Value).Count());

            var unitMoves = board.GetUnitMoves();

            Assert.AreEqual(2, unitMoves.Count(um => um.IsBuild));
            Assert.AreEqual(3, unitMoves.Count(um => um.IsDisband));
        }
        public void Execute_can_castle_both_side(Colours colour, bool side)
        {
            int rank = colour == Colours.White ? 1 : 8;

            var king                = new KingEntity(colour);
            var kingStartFile       = King.StartPositionFor(colour).X;
            var kingDestinationFile = side ? ChessFile.G : ChessFile.C;
            var kingStartLoc        = $"{kingStartFile}{rank}".ToBoardLocation();
            var kingDestination     = $"{kingDestinationFile}{rank}".ToBoardLocation();

            var rook                = new RookEntity(colour);
            var rookStartFile       = side ? ChessFile.H : ChessFile.A;
            var rookDestinationFile = side ? ChessFile.F : ChessFile.D;
            var rookStart           = $"{rookStartFile}{rank}".ToBoardLocation();
            var rookDestination     = $"{rookDestinationFile}{rank}".ToBoardLocation();

            var actualKingMove = new BoardMove(kingStartLoc, kingDestination, (int)DefaultActions.MoveOnly);
            var actualRookMove = new BoardMove(rookStart, rookDestination, (int)DefaultActions.MoveOnly);

            SetupLocationReturn(kingStartLoc, king);
            SetupLocationReturn(rookStart, rook);
            SetupMockActionForMoveType((int)DefaultActions.MoveOnly);
            Action.Execute(actualKingMove);

            VerifyActionWasCreated((int)DefaultActions.MoveOnly);
            VerifyActionWasExecuted(actualKingMove);
            VerifyActionWasExecuted(actualRookMove);
        }
Exemple #27
0
 public async Task TryPerformMove(BoardMove move)
 {
     if (CanPerformMove(move))
     {
         await PerformMove(move);
     }
 }
Exemple #28
0
        public IEnumerable <BoardMove> GetBoardMovesFallSpring(Board board, AllianceScenario allianceScenario)
        {
            HashSet <BoardMove> completedBoardMoves = new HashSet <BoardMove>();

            if (board.Season is Winter)
            {
                throw new Exception($"Bad season {board.Season}");
            }
            foreach (var kvp in board.OccupiedMapNodes)
            {
                BoardMove      workingBoardMove = new BoardMove();
                List <MapNode> path;
                UnitMove       currentMove;
                if (_targeter.TryGetMoveTargetValidateWithBoardMove(board, kvp.Key, allianceScenario, workingBoardMove, out path, out currentMove))
                {
                    workingBoardMove.Add(currentMove);
                }
                else
                {
                    throw new Exception("Failed to add the very first move? Really!?");
                }
                GetFallSpringMovesRemaining(board, allianceScenario, _targeter, workingBoardMove, completedBoardMoves);
            }
            return(completedBoardMoves);
        }
Exemple #29
0
        public Paths PathsFrom(BoardLocation location, int forPlayer)
        {
            var paths     = new Paths();
            var playerIdx = (Colours)forPlayer;

            foreach (var dest in new[]
            {
                location.MoveForward(playerIdx),
                location.MoveForward(playerIdx)?.MoveRight(playerIdx),
                location.MoveRight(playerIdx),
                location.MoveBack(playerIdx)?.MoveRight(playerIdx),
                location.MoveBack(playerIdx),
                location.MoveBack(playerIdx)?.MoveLeft(playerIdx),
                location.MoveLeft(playerIdx),
                location.MoveLeft(playerIdx)?.MoveForward(playerIdx)
            })
            {
                if (dest != null)
                {
                    paths.Add(new Path {
                        BoardMove.Create(location, dest, (int)ChessMoveTypes.KingMove)
                    });
                }
            }

            return(paths);
        }
Exemple #30
0
        public void MoveBlackTest1()
        {
            var board = MakeBoard1(BWType.Black);

            var move = BoardMove.CreateMove(
                BWType.Black, new Square(8, 3), new Square(8, 2),
                new Piece(PieceType.Kyo, false), true);

            Assert.True(board.CanMove(move));

            // 駒が設定されてないと動けません。
            MethodUtil.SetPropertyValue(move, "MovePiece", new Piece());
            Assert.False(board.CanMove(move));
            MethodUtil.SetPropertyValue(move, "MovePiece", new Piece(PieceType.Kyo, false));

            // 84の駒は移動できません。
            MethodUtil.SetPropertyValue(move, "SrcSquare", new Square(8, 4));
            Assert.False(board.CanMove(move));
            MethodUtil.SetPropertyValue(move, "SrcSquare", new Square(8, 3));

            CanMoveTo(board, move, new List <Tuple <Square, bool> >
            {
                Tuple.Create(new Square(8, 2), false),
                Tuple.Create(new Square(8, 1), true),
            });
        }
Exemple #31
0
        public void white_left_castle_correct()
        {
            var game = new ClassicGame();

            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(1, 0), new Position(0, 2)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(2, 6), new Position(2, 4)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(2, 1), new Position(2, 3)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(3, 6), new Position(3, 4)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(3, 1), new Position(3, 3)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(1, 6), new Position(1, 4)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(2, 0), new Position(3, 1)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(0, 6), new Position(0, 4)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(3, 0), new Position(2, 1)));
            ChessAssert.IsMoveCorrect(game, new BoardMove(new Position(4, 6), new Position(4, 4)));
            /*-----------------------------------------------------------------------------------*/
            var castleMove = new BoardMove(new Position(4, 0), new Position(2, 0));
            var leftRook   = game.Board.GetPiece(new Position(0, 0));

            ChessAssert.IsMoveCorrect(game, castleMove);

            Assert.IsNull(game.Board.GetPiece(new Position(0, 0)));

            Assert.AreSame(leftRook, game.Board.GetPiece(new Position(3, 0)));
            Assert.AreEqual(leftRook.Position, new Position(3, 0));
        }
Exemple #32
0
        public void ShouldParseFromBoardMove(string @from, string to, DefaultActions moveType, string expectedSan)
        {
            var game = ChessFactory.NewChessGame();
            var move = BoardMove.Create(from.ToBoardLocation(), to.ToBoardLocation(), (int)moveType);

            Assert.That(StandardAlgebraicNotation.ParseFromGameMove(game.BoardState, move).ToNotation(), Is.EqualTo(expectedSan));
        }
Exemple #33
0
        /// <summary>
        /// 駒の各移動先に対して、その手が指せるのかどうかをチェックします。
        /// </summary>
        private void CanMoveTo(Board board, BoardMove move,
                               List<Tuple<Square, bool>> availables)
                               
        {
            for (var file = 1; file <= Board.BoardSize; ++file)
            {
                for (var rank = 1; rank <= Board.BoardSize; ++rank)
                {
                    var sq = new Square(file, rank);
                    var avail = availables.FirstOrDefault(_ => _.Item1 == sq);

                    move.DstSquare = sq;
                    if (avail != null)
                    {
                        if (avail.Item2)
                        {
                            // 成りが必須の場合
                            move.IsPromote = false;
                            Assert.False(board.CanMove(move));

                            move.IsPromote = true;
                            Assert.True(board.CanMove(move));
                        }
                        else
                        {
                            // 成りが必須でない場合
                            move.IsPromote = false;
                            Assert.True(board.CanMove(move));

                            move.IsPromote = true;
                            Assert.AreEqual(Board.CanPromote(move), board.CanMove(move));
                        }
                    }
                    else
                    {
                        // そもそも移動できる場所ではない
                        move.IsPromote = false;
                        Assert.False(board.CanMove(move));

                        move.IsPromote = true;
                        Assert.False(board.CanMove(move));
                    }
                }
            }
        }
Exemple #34
0
    /// <summary>
    /// Execute a board move, moving the piece, removing targeted pieces, and transforming the gamepiece.
    /// TODO: Let the gamerules handle this.
    /// </summary>
    /// <param name="move"></param>
    public void executeMove(BoardMove move)
    {
        //LocalPlayer.playerID;
        //Todo: Execute Move
        //BoardMove move = ..
        move.movingPiece.move(board.getSquare(move.destination));

        //Byebye
        foreach(BoardPiece byebyePiece in move.destroyedPieces)
        {
            DestroyImmediate(byebyePiece.gameObject);
        }

        //TODO: Transform

        //Next turn.  TODO: This should go away when it's implemented into the move.
        nextPlayerTurn();
    }
Exemple #35
0
        /// <summary>
        /// 1手指したときに呼ばれます。
        /// </summary>
        private void MoveDone(BoardMove move)
        {
            NotifyBoardChanging(move, false);

            Turn = Turn.Flip();
            PrevMovedSquare = move.DstSquare;

            this.moveList.Add(move);

            // リドゥスタックの更新を行います。
            var redoMove = this.redoList.LastOrDefault();
            if (redoMove != null && redoMove.Equals(move))
            {
                // 指し手がリドゥと同じなら手を一つ削るだけです。
                this.redoList.RemoveAt(this.redoList.Count - 1);
            }
            else
            {
                this.redoList.Clear();
            }

            // 局面の変化を通知します。
            NotifyBoardChanged(move, false);
        }
Exemple #36
0
        /// <summary>
        /// 駒を強制的に成る必要があるか調べます。
        /// </summary>
        public static bool IsPromoteForce(BoardMove move)
        {
            if (move == null)
            {
                throw new ArgumentNullException("move");
            }

            return IsPromoteForce(move.MovePiece, move.BWType, move.DstSquare);
        }
        /// <summary>
        /// 上、引、寄るの判定をします。
        /// </summary>
        private static bool CheckRankMoveType(BoardMove bm,
                                              Move referenceMove)
        {
            if (bm.ActionType == ActionType.Drop)
            {
                return false;
            }

            var fileMove = bm.DstSquare.File - bm.SrcSquare.File;
            var rankMove = bm.DstSquare.Rank - bm.SrcSquare.Rank;

            switch (referenceMove.RankMoveType)
            {
                case RankMoveType.Back:
                    return (bm.BWType == BWType.Black
                                ? (rankMove > 0)
                                : (rankMove < 0));
                case RankMoveType.Up:
                    return (bm.BWType == BWType.Black
                                ? (rankMove < 0)
                                : (rankMove > 0));
                case RankMoveType.Sideways:
                    return (fileMove != 0 && rankMove == 0);
            }

            return false;
        }
 /// <summary>
 /// 打つ、成る、成らず、などを判定します。
 /// </summary>
 /// <remarks>
 /// 駒が指定の場所に移動できない場合は自動的に打つが選ばれます。
 /// (盤上に飛車がないのに、"32飛車"のときなど)
 /// </remarks>
 private static bool CheckActionType(BoardMove bm,
                                     Move referenceMove, bool canMove)
 {
     if (referenceMove.ActionType == ActionType.None)
     {
         // 指し手一覧の中に移動できる駒があれば、
         // 「打」と指定しなければ打つと判定されません。
         if (canMove)
         {
             // 指定無しと成らずでおkとします。
             return (
                 bm.ActionType == ActionType.None ||
                 bm.ActionType == ActionType.Unpromote);
         }
         else
         {
             return (
                 bm.ActionType == ActionType.None ||
                 bm.ActionType == ActionType.Unpromote ||
                 bm.ActionType == ActionType.Drop);
         }
     }
     else if (referenceMove.ActionType == ActionType.Unpromote)
     {
         // 「不成」の場合は無と成らずでおkとします。
         return (
             bm.ActionType == ActionType.None ||
             bm.ActionType == ActionType.Unpromote);
     }
     
     return (bm.ActionType == referenceMove.ActionType);
 }
        /// <summary>
        /// 左、右、直の判定をします。
        /// </summary>
        private static bool CheckRelPosType(BoardMove bm,
                                            Move referenceMove,
                                            List<BoardMove> boardMoveList)
        {
            if (bm.ActionType == ActionType.Drop)
            {
                return false;
            }

            if (bm.MovePiece == Piece.Ryu || bm.MovePiece == Piece.Uma)
            {
                // 竜、馬の場合、「直」は使わずに「右左」のみを使用します。
                if (boardMoveList.Count() == 1)
                {
                    return (referenceMove.RelFileType == RelFileType.None);
                }
                else
                {
                    // 駒は二つしかないはずなので、相方に比べて自分が
                    // 左にあれば「左」、右にあれば「右」となっているか
                    // 判定します。
                    var other = (
                        ReferenceEquals(bm, boardMoveList[0])
                        ? boardMoveList[1]
                        : boardMoveList[0]);
                    var fileDif = bm.SrcSquare.File - other.SrcSquare.File;

                    switch (referenceMove.RelFileType)
                    {
                        case RelFileType.Left:
                            return (bm.BWType == BWType.Black
                                        ? (fileDif > 0)
                                        : (fileDif < 0));
                        case RelFileType.Right:
                            return (bm.BWType == BWType.Black
                                        ? (fileDif < 0)
                                        : (fileDif > 0));
                        case RelFileType.None:
                            return (fileDif == 0);
                    }
                }
            }
            else
            {
                var fileMove = bm.DstSquare.File - bm.SrcSquare.File;
                var rankMove = bm.DstSquare.Rank - bm.SrcSquare.Rank;

                switch (referenceMove.RelFileType)
                {
                    case RelFileType.Left:
                        return (bm.BWType == BWType.Black
                                    ? (fileMove < 0)
                                    : (fileMove > 0));
                    case RelFileType.Right:
                        return (bm.BWType == BWType.Black
                                    ? (fileMove > 0)
                                    : (fileMove < 0));
                    case RelFileType.Straight:
                        return (bm.BWType == BWType.Black
                                    ? (rankMove < 0)
                                    : (rankMove > 0)) &&
                               (fileMove == 0);
                }
            }

            return false;
        }
        /// <summary>
        /// 列で指し手をフィルターし、Moveに適切なRelPosTypeを設定します。
        /// </summary>
        private static List<BoardMove> FilterFile(Move move,
                                                  BoardMove referenceMove,
                                                  List<BoardMove> boardMoveList)
        {
            // 駒の移動前情報が必要です。
            var nextPos = referenceMove.DstSquare;
            var prevPos = referenceMove.SrcSquare;
            if (prevPos == null)
            {
                return null;
            }

            if ((move.Piece == Piece.Ryu || move.Piece == Piece.Uma) &&
                boardMoveList.Count() == 2)
            {
                // 馬と竜の場合は'直'ではなく、右と左しか使いません。
                var other = (
                    referenceMove == boardMoveList[0] ?
                    boardMoveList[1] : boardMoveList[0]);

                // 動かす前の駒が相方に比べて右にあるか左にあるか調べます。
                // 先手の場合は筋が小さい方が右です。
                var relFile = prevPos.File - other.SrcSquare.File;
                relFile *= (referenceMove.BWType == BWType.White ? -1 : +1);

                if (relFile == 0)
                {
                    return boardMoveList;
                }
                else if (relFile < 0)
                {
                    move.RelFileType = RelFileType.Right;
                }
                else
                {
                    move.RelFileType = RelFileType.Left;
                }

                return new List<BoardMove> { referenceMove };
            }
            else
            {
                // 黒から見ると正の場合は引く or 左へ移動(右)で
                // 負の場合は上がる or 右へ移動(左)です。
                var relFile = nextPos.File - prevPos.File;

                // 列の位置でフィルターします。
                var tmpMoveList = boardMoveList.Where(mv =>
                {
                    var rel = nextPos.File - mv.SrcSquare.File;
                    return (
                        relFile < 0 ? (rel < 0) :
                        relFile > 0 ? (rel > 0) :
                        (rel == 0));
                }).ToList();

                // 列情報でフィルターされた場合は、列の移動情報を付加します。
                if (tmpMoveList.Count() != boardMoveList.Count())
                {
                    var relFile2 = relFile * referenceMove.BWType.Sign();

                    if (relFile2 < 0)
                    {
                        move.RelFileType = RelFileType.Left;
                    }
                    else if (relFile2 > 0)
                    {
                        move.RelFileType = RelFileType.Right;
                    }
                    else
                    {
                        // 直の場合は、左右の動きはありません。
                        move.RankMoveType = RankMoveType.None;
                        move.RelFileType = RelFileType.Straight;
                    }
                }

                return tmpMoveList;
            }
        }
        /// <summary>
        /// 指し手が実際に着手可能か確認します。
        /// </summary>
        private bool CanMove(BoardMove move, MoveFlags flags = MoveFlags.DoMoveDefault)
        {
            var tmp = Board.Clone();

            // 成り・不成りの選択ダイアログを出す前に
            // 駒の移動ができるか調べておきます。
            // 失敗したら移動中だった駒は元の位置に戻されます。
            if (!tmp.DoMove(move, flags))
            {
                return false;
            }

            // 通常モードの場合、今指した側の玉が王手されていたら
            // その手は採用しません。(王手放置禁止)
            if (EditMode == EditMode.Normal &&
                tmp.IsChecked(tmp.Turn.Flip()))
            {
                return false;
            }

            return true;
        }
Exemple #42
0
        /// <summary>
        /// 駒を動かすか、または駒が動かせるか調べます。
        /// </summary>
        private bool CheckAndDoMove(BoardMove move, MoveFlags flags)
        {
            if (move == null || !move.Validate())
            {
                throw new ArgumentNullException("move");
            }

            using (LazyLock())
            {
                // 手番があわなければ失敗とします。
                if (EnumEx.HasFlag(flags, MoveFlags.CheckTurn))
                {
                    if (this.turn == BWType.None ||
                        this.turn != move.BWType)
                    {
                        return false;
                    }
                }

                if (move.ActionType == ActionType.Drop)
                {
                    return CheckAndDoDrop(move, flags);
                }
                else
                {
                    return CheckAndDoMoveOnly(move, flags);
                }
            }
        }
Exemple #43
0
        /// <summary>
        /// <paramref name="square"/>に<paramref name="pieceType"/>を打ち、
        /// なお王手されているか確認します。
        /// </summary>
        private bool IsDropAndChecked(BWType bwType, PieceType pieceType,
                                      Square square)
        {
            var piece = this[square];
            if (piece != null)
            {
                return true;
            }

            var move = new BoardMove()
            {
                DstSquare = square,
                DropPieceType = pieceType,
                BWType = bwType,
            };
            if (DoMove(move))
            {
                if (!IsChecked(bwType))
                {
                    Undo();
                    return false;
                }
                Undo();

                return true;
            }

            return true;
        }
Exemple #44
0
        /// <summary>
        /// 駒の移動のみの動作を調べるか実際にそれを行います。
        /// </summary>
        private bool CheckAndDoMoveOnly(BoardMove move, MoveFlags flags)
        {
            // 駒の移動元に自分の駒がなければダメ
            var srcPiece = this[move.SrcSquare];
            if (srcPiece == null || srcPiece.BWType != move.BWType)
            {
                return false;
            }

            // 駒の移動先に自分の駒があったらダメ
            var dstPiece = this[move.DstSquare];
            if (dstPiece != null && dstPiece.BWType == move.BWType)
            {
                return false;
            }

            // これはエラーだけど。。。w
            if (srcPiece.Piece != move.MovePiece)
            {
                return false;
            }

            // 各駒が動ける位置に移動するかどうか確認します。
            if (!CanMovePiece(move))
            {
                return false;
            }

            if (move.ActionType == ActionType.Promote)
            {
                // 成れない場合は帰ります。
                if (!CanPromote(move)) return false;
            }
            else
            {
                // 成らないといけない場合は帰ります。
                if (IsPromoteForce(move)) return false;
            }

            if (!EnumEx.HasFlag(flags, MoveFlags.CheckOnly))
            {
                var pieceType = srcPiece.PieceType;

                // 移動先に駒があれば、それを自分のものにします。
                if (dstPiece != null)
                {
                    IncCapturedPieceCount(dstPiece.PieceType, move.BWType);

                    // 取った駒を記憶しておきます。
                    move.TookPiece = dstPiece.Piece;
                }

                // 移動後の駒の成り/不成りを決定します。
                var promoted = (
                    srcPiece.IsPromoted ||
                    move.ActionType == ActionType.Promote);

                this[move.DstSquare] = new BoardPiece(
                    pieceType, promoted, move.BWType);

                // 移動前の位置からは駒をなくします。
                this[move.SrcSquare] = null;

                MoveDone(move);
            }

            return true;
        }
        /// <summary>
        /// 指し手をXX->YYの形式から、ZZ銀上などの形に変換します。
        /// </summary>
        /// <remarks>
        /// <paramref name="useSrcSquare"/>を真にすると、差し手の後に
        /// 古い位置の情報が付加されるようになります。(例: 32金(22))
        /// </remarks>
        public static Move ConvertMove(this Board board, BoardMove move,
                                       bool useSrcSquare)
        {
            if (board == null)
            {
                throw new ArgumentNullException("board");
            }

            if (move == null || !move.Validate())
            {
                throw new ArgumentNullException("move");
            }

            var fromPiece = (
                move.ActionType == ActionType.Drop ?
                new Piece(move.DropPieceType) :
                move.MovePiece);
            if (fromPiece == null)
            {
                return null;
            }

            // 駒の種類と最終位置から、あり得る指し手をすべて検索します。
            var boardMoveList = board.ListupMoves(
                fromPiece, move.BWType, move.DstSquare)
                .ToList();

            return FilterMove(
                board, boardMoveList, move, fromPiece, useSrcSquare);
        }
 /// <summary>
 /// 持ち駒の数を増やします。
 /// </summary>
 private void SetPiece(BWType bwType, BoardMove tmp)
 {
     // 駒位置が"00"の場合は持ち駒となります。
     if (tmp.DstSquare.File != 0)
     {
         this.board[tmp.DstSquare] = new BoardPiece(tmp.MovePiece, bwType);
     }
     else
     {
         this.board.IncCapturedPieceCount(tmp.MovePiece.PieceType, bwType);
     }
 }
Exemple #47
0
        public void MoveWhiteTest1()
        {
            var board = MakeBoard1(BWType.White);

            var move = new BoardMove
            {
                DstSquare = new Square(9, 8),
                SrcSquare = new Square(9, 7),
                MovePiece = new Piece(PieceType.Hu, false),
                IsPromote = true,
                BWType = BWType.White,
            };
            Assert.True(board.CanMove(move));

            // 84の駒は移動できません。
            move.SrcSquare = new Square(8, 4);
            Assert.False(board.CanMove(move));
            move.SrcSquare = new Square(9, 7);

            CanMoveTo(board, move, new List<Tuple<Square, bool>>
            {
                Tuple.Create(new Square(9, 8), false),
            });
        }
Exemple #48
0
        /// <summary>
        /// 駒打ちの動作が行えるか調べ、必要なら実行します。
        /// </summary>
        private bool CheckAndDoDrop(BoardMove move, MoveFlags flags)
        {
            if (GetCapturedPieceCount(move.DropPieceType, move.BWType) <= 0)
            {
                return false;
            }

            // 駒を打つ場所に駒があれば、当然失敗です。
            var piece = this[move.DstSquare];
            if (piece != null)
            {
                return false;
            }

            // 駒が置けるか確かめます。
            if (!CanDrop(move.BWType, move.DstSquare, move.DropPieceType))
            {
                return false;
            }

            if (!EnumEx.HasFlag(flags, MoveFlags.CheckOnly))
            {
                // 駒を盤面に置き、持ち駒から駒を減らします。
                this[move.DstSquare] = new BoardPiece(
                    move.DropPieceType, false, move.BWType);

                DecCapturedPieceCount(move.DropPieceType, move.BWType);

                MoveDone(move);
            }

            return true;
        }
Exemple #49
0
        public void MoveBlackTest1()
        {
            var board = MakeBoard1(BWType.Black);

            var move = new BoardMove
            {
                DstSquare = new Square(8, 2),
                SrcSquare = new Square(8, 3),
                MovePiece = new Piece(PieceType.Kyo, false),
                IsPromote = true,
                BWType = BWType.Black,
            };
            Assert.True(board.CanMove(move));

            // 駒が設定されてないと動けません。
            move.MovePiece = new Piece();
            Assert.False(board.CanMove(move));
            move.MovePiece = new Piece(PieceType.Kyo, false);

            // 84の駒は移動できません。
            move.SrcSquare = new Square(8, 4);
            Assert.False(board.CanMove(move));
            move.SrcSquare = new Square(8, 3);

            CanMoveTo(board, move, new List<Tuple<Square, bool>>
            {
                Tuple.Create(new Square(8, 2), false),
                Tuple.Create(new Square(8, 1), true),
            });
        }
Exemple #50
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 public BoardChangedEventArgs(BoardMove move, bool isUndo)
 {
     Move = move;
     IsUndo = isUndo;
 }
Exemple #51
0
        /// <summary>
        /// 実際に駒が動けるか確認します。
        /// </summary>
        private bool CanMovePiece(BoardMove move)
        {
            var relFile = move.DstSquare.File - move.SrcSquare.File;
            var relRank = move.DstSquare.Rank - move.SrcSquare.Rank;
            var piece = move.MovePiece;

            if (piece.IsPromoted)
            {
                // 成り駒が指定の場所に動けるか調べます。
                switch (piece.PieceType)
                {
                    case PieceType.Gyoku:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableGyoku);
                    case PieceType.Hisya:
                        if (CanMoveWithTable(move.BWType, relFile, relRank, MoveTableGyoku))
                        {
                            return true;
                        }
                        return CanMoveHisya(move.SrcSquare, relFile, relRank);
                    case PieceType.Kaku:
                        if (CanMoveWithTable(move.BWType, relFile, relRank, MoveTableGyoku))
                        {
                            return true;
                        }
                        return CanMoveKaku(move.SrcSquare, relFile, relRank);
                    case PieceType.Kin:
                    case PieceType.Gin:
                    case PieceType.Kei:
                    case PieceType.Kyo:
                    case PieceType.Hu:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableKin);
                }
            }
            else
            {
                // 成り駒以外の駒が指定の場所に動けるか調べます。
                switch (piece.PieceType)
                {
                    case PieceType.Gyoku:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableGyoku);
                    case PieceType.Hisya:
                        return CanMoveHisya(move.SrcSquare, relFile, relRank);
                    case PieceType.Kaku:
                        return CanMoveKaku(move.SrcSquare, relFile, relRank);
                    case PieceType.Kin:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableKin);
                    case PieceType.Gin:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableGin);
                    case PieceType.Kei:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableKei);
                    case PieceType.Kyo:
                        return CanMoveKyo(move.BWType, move.SrcSquare, relFile, relRank);
                    case PieceType.Hu:
                        return CanMoveWithTable(move.BWType, relFile, relRank, MoveTableHu);
                }
            }

            return false;
        }
Exemple #52
0
        /// <summary>
        /// <paramref name="srcSquare"/>の駒を<paramref name="dstSquare"/>
        /// に動かすことが可能な指し手を指してみて、なお王手されているか確認します。
        /// </summary>
        private bool IsMoveAndChecked(BWType bwType, Square srcSquare,
                                      Square dstSquare)
        {
            var piece = this[srcSquare];
            if (piece == null || piece.BWType != bwType)
            {
                return true;
            }

            var move = new BoardMove()
            {
                DstSquare = dstSquare,
                SrcSquare = srcSquare,
                MovePiece = piece.Piece,
                BWType = bwType,
            };

            // 成り駒でなければ、成る可能性があります。
            if (!piece.IsPromoted)
            {
                move.IsPromote = true;
                if (DoMove(move))
                {
                    if (!IsChecked(bwType))
                    {
                        Undo();
                        return false;
                    }
                    Undo();

                    return true;
                }
            }

            move.IsPromote = false;
            if (DoMove(move))
            {
                if (!IsChecked(bwType))
                {
                    Undo();
                    return false;
                }
                Undo();

                return true;
            }

            return true;
        }
Exemple #53
0
 public void playerPickedMove(BoardMove chosenMove)
 {
     gameManager.executeMove(chosenMove);
 }
Exemple #54
0
        /// <summary>
        /// undo操作を実行します。
        /// </summary>
        private void DoUndo(BoardMove move)
        {
            if (move.ActionType == ActionType.Drop)
            {
                // 駒打ちの場合は、その駒を駒台に戻します。
                this[move.DstSquare] = null;

                IncCapturedPieceCount(move.DropPieceType, move.BWType);
            }
            else
            {
                var movedPiece = this[move.DstSquare];

                // 駒を成った場合はそれを元に戻します。
                if (move.ActionType == ActionType.Promote)
                {
                    movedPiece.IsPromoted = false;
                }

                // 駒を取った場合は、その駒を元に戻します。
                if (move.TookPiece != null)
                {
                    this[move.DstSquare] = new BoardPiece(
                        move.TookPiece.Clone(),
                        move.BWType.Flip());

                    // 駒を取ったはずなので、その分を駒台から減らします。
                    DecCapturedPieceCount(
                        move.TookPiece.PieceType,
                        move.BWType);
                }
                else
                {
                    this[move.DstSquare] = null;
                }

                this[move.SrcSquare] = movedPiece;
            }

            Turn = Turn.Flip();
            PrevMovedSquare = (
                this.moveList.Any() ?
                this.moveList.Last().DstSquare :
                null);
        }
 /// <summary>
 /// コンストラクタ
 /// </summary>
 public BoardPieceRoutedEventArgs(RoutedEvent ev, Board board, BoardMove move)
     : base(ev)
 {
     Board = board;
     Move = move;
 }
Exemple #56
0
        /// <summary>
        /// その差し手を実際に実行します。
        /// </summary>
        public bool DoMove(BoardMove move, MoveFlags flags = MoveFlags.DoMoveDefault)
        {
            flags &= ~MoveFlags.CheckOnly;

            return CheckAndDoMove(move, flags);
        }
        /// <summary>
        /// 複数ある差し手の中から、適切なひとつの差し手を選択します。
        /// </summary>
        /// <remarks>
        /// <paramref name="referenceMove"/>にはXからYに移動したという情報
        /// しかないため、これを52金右などの指し手に変換します。
        /// </remarks>
        private static Move FilterMove(this Board board,
                                       List<BoardMove> boardMoveList,
                                       BoardMove referenceMove,
                                       Piece fromPiece,
                                       bool useSrcSquare)
        {
            if (!boardMoveList.Any())
            {
                return null;
            }

            var nextPos = referenceMove.DstSquare;
            var move = new Move()
            {
                BWType = referenceMove.BWType,
                Piece = fromPiece,
                File = nextPos.File,
                Rank = nextPos.Rank,
                ActionType = ( // '打', '不成'は消える可能性があります。
                    referenceMove.ActionType == ActionType.Promote ?
                    referenceMove.ActionType :
                    ActionType.None),
                SameAsOld = (board.PrevMovedSquare == nextPos),
            };

            // 移動元情報を使う場合は、これで終わりです。
            // (.kifファイルからの読み込み時は、駒の移動の場合は移動前情報がつき、
            //  駒打ちの場合は"打"が必ずつきます)
            if (useSrcSquare)
            {
                move.SrcSquare = referenceMove.SrcSquare;
                move.ActionType = referenceMove.ActionType;
                return move;
            }

            // 駒打ち、成り、不成りなどでフィルターします。
            var tmpMoveList = boardMoveList.Where(
                mv => mv.ActionType == referenceMove.ActionType)
                .ToList();
            if (tmpMoveList.Count() != boardMoveList.Count())
            {
                move.ActionType = referenceMove.ActionType;
            }
            if (tmpMoveList.Count() == 1)
            {
                return move;
            }

            // 段の位置でフィルターします。
            tmpMoveList = FilterRank(move, referenceMove, tmpMoveList);
            if (tmpMoveList.Count() == 1)
            {
                return move;
            }

            // 列の位置でフィルターします。
            tmpMoveList = FilterFile(move, referenceMove, tmpMoveList);
            if (tmpMoveList.Count() == 1)
            {
                return move;
            }

            // 不明。
            return null;
        }
Exemple #58
0
        /// <summary>
        /// 局面の変更を通知します。
        /// </summary>
        private void NotifyBoardChanged(BoardMove move, bool isUndo)
        {
            var handler = BoardChanged;

            if (handler != null)
            {
                Util.CallEvent(
                    () => handler(this, new BoardChangedEventArgs(move, isUndo)));
            }

            this.RaisePropertyChanged("MoveCount");
            this.RaisePropertyChanged("CanUndo");
            this.RaisePropertyChanged("CanRedo");
        }
        /// <summary>
        /// 実際に指し手を進めます。
        /// </summary>
        private void MakeMove(BoardMove move)
        {
            if (move == null || !move.Validate())
            {
                return;
            }

            BoardPieceChanging.SafeRaiseEvent(this,
                new BoardPieceEventArgs(Board.Clone(), move));
            Board.DoMove(move);
            BoardPieceChanged.SafeRaiseEvent(this,
                new BoardPieceEventArgs(Board.Clone(), move));
        }
        /// <summary>
        /// 段で指し手をフィルターし、Moveに適切なRankMoveTypeを設定します。
        /// </summary>
        private static List<BoardMove> FilterRank(Move move,
                                                  BoardMove referenceMove,
                                                  List<BoardMove> boardMoveList)
        {
            // 駒の移動前情報が必要です。
            var nextPos = referenceMove.DstSquare;
            var prevPos = referenceMove.SrcSquare;
            if (prevPos == null)
            {
                return null;
            }

            // 黒から見ると正の場合は引く or 左へ移動(右)で
            // 負の場合は上がる or 右へ移動(左)です。
            var relRank = nextPos.Rank - prevPos.Rank;

            // 段の位置でフィルターします。
            var tmpMoveList = boardMoveList.Where(mv =>
            {
                var rel = nextPos.Rank - mv.SrcSquare.Rank;
                if (relRank < 0)
                {
                    return (rel < 0);
                }
                else if (relRank > 0)
                {
                    return (rel > 0);
                }
                else
                {
                    return (rel == 0);
                }
            }).ToList();

            // 段情報でフィルターされた場合は、段の移動情報を付加します。
            if (tmpMoveList.Count() != boardMoveList.Count())
            {
                var relRank2 = relRank * referenceMove.BWType.Sign();

                if (relRank2 < 0)
                {
                    move.RankMoveType = RankMoveType.Up;
                }
                else if (relRank2 > 0)
                {
                    move.RankMoveType = RankMoveType.Back;
                }
                else
                {
                    move.RankMoveType = RankMoveType.Sideways;
                }
            }

            return tmpMoveList;
        }