예제 #1
0
 public bool WasCheckedBefore(List <CheckedPosition> alreadyCheckedList, CheckedPosition currentCheck)
 {
     foreach (var info in alreadyCheckedList)
     {
         if (info.Position == currentCheck.Position)
         {
             if (info.IncomeDelta == null || info.IncomeDelta == currentCheck.IncomeDelta)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #2
0
        /// <summary>
        /// Возвращаем список всех полей, в которые можно попасть из исходного поля
        /// </summary>
        /// <param name="task"></param>
        /// <param name="source"></param>
        /// <param name="previos"></param>
        /// <returns></returns>
        public List <AvaliableMove> GetAllAvaliableMoves(GetAllAvaliableMovesTask task, TilePosition source, TilePosition previos)
        {
            Direction previosDirection;

            if (previos != null)
            {
                previosDirection = new Direction(previos, source);
            }
            else
            {
                previosDirection = new Direction(source, source);
            }

            var sourceTile = Map[source.Position];

            var  ourTeamId = task.TeamId;
            var  ourTeam   = Teams[ourTeamId];
            var  ourShip   = ourTeam.Ship;
            bool fromShip  = (ourShip.Position == source.Position);

            List <AvaliableMove> goodTargets = new List <AvaliableMove>();

            IEnumerable <TilePosition> positionsForCheck;

            if (sourceTile.Type.RequreImmediateMove()) //для клеток с редиректами запоминаем, что в текущую клетку уже не надо возвращаться
            {
                Position previosMoveDelta = null;
                if (sourceTile.Type == TileType.Ice)
                {
                    previosMoveDelta = previosDirection.GetDelta();
                }
                task.alreadyCheckedList.Add(new CheckedPosition(source, previosMoveDelta)); //запоминаем, что эту клетку просматривать уже не надо
            }

            //места всех возможных ходов
            positionsForCheck = GetAllTargetsForSubturn(source, previosDirection, ourTeam);

            foreach (var newPosition in positionsForCheck)
            {
                //проверяем, что на этой клетке
                var newPositionTile = Map[newPosition.Position];

                if (task.alreadyCheckedList.Count > 0 && previosDirection != null)
                {
                    Position        incomeDelta  = Position.GetDelta(previosDirection.To.Position, newPosition.Position);
                    CheckedPosition currentCheck = new CheckedPosition(newPosition, incomeDelta);

                    if (WasCheckedBefore(task.alreadyCheckedList, currentCheck)) //мы попали по рекурсии в ранее просмотренную клетку
                    {
                        if ((newPositionTile.Type == TileType.Airplane) && (Map.AirplaneUsed == false))
                        {
                            // даем возможность не использовать самолет сразу!
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                        }
                        continue;
                    }
                }

                //var newMove = new Move(new TilePosition(source), new TilePosition(newPosition), MoveType.Usual);

                switch (newPositionTile.Type)
                {
                case TileType.Water:
                    if (ourShip.Position == newPosition.Position)                                                                     //заходим на свой корабль
                    {
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition))); //всегда это можем сделать
                        if (task.NoCoinMoving == false && Map[task.FirstSource].Coins > 0)
                        {
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition, true))
                            {
                                MoveType = MoveType.WithCoin
                            });
                        }
                    }
                    else if (sourceTile.Type == TileType.Water)                                                                                  //из воды в воду
                    {
                        if (source.Position != ourShip.Position && GetPosibleSwimming(task.FirstSource.Position).Contains(newPosition.Position)) //пират плавает
                        {
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                        }
                        if (source.Position == ourShip.Position && GetShipPosibleNavaigations(task.FirstSource.Position).Contains(newPosition.Position))
                        {
                            //корабль плавает
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                        }
                    }
                    else     //с земли в воду мы можем попасть только если ранее попали на клетку, требующую действия
                    {
                        if (task.NoJumpToWater == false && sourceTile.Type.RequreImmediateMove())
                        {
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition))
                            {
                                WithJumpToWater = true
                            });
                            if (task.NoCoinMoving == false && Map[task.FirstSource].Coins > 0)
                            {
                                goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition))
                                {
                                    WithJumpToWater = true, MoveType = MoveType.WithCoin
                                });
                            }
                        }
                    }
                    break;

                case TileType.RespawnFort:
                    if (task.FirstSource == newPosition)
                    {
                        if (task.NoRespawn == false && ourTeam.Pirates.Count() < 3)
                        {
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition), new Respawn(ourTeam, newPosition.Position))
                            {
                                MoveType = MoveType.WithRespawn
                            });
                        }
                    }
                    else if (newPositionTile.OccupationTeamId.HasValue == false || newPositionTile.OccupationTeamId == ourTeamId)     //только если форт не занят
                    {
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                    }
                    break;

                case TileType.Fort:
                    if (task.NoFort == false && newPositionTile.OccupationTeamId.HasValue == false || newPositionTile.OccupationTeamId == ourTeamId)     //только если форт не занят
                    {
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                    }
                    break;

                case TileType.Canibal:
                    if (task.NoCanibal == false)
                    {
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                    }
                    break;


                case TileType.Trap:
                    if (task.NoTrap == false)
                    {
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                        if (task.NoCoinMoving == false && Map[task.FirstSource].Coins > 0 &&
                            (newPositionTile.OccupationTeamId == null || newPositionTile.OccupationTeamId == ourTeamId))
                        {
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition, true))
                            {
                                MoveType = MoveType.WithCoin
                            });
                        }
                    }
                    break;

                case TileType.Grass:
                case TileType.Chest1:
                case TileType.Chest2:
                case TileType.Chest3:
                case TileType.Chest4:
                case TileType.Chest5:
                case TileType.RumBarrel:
                case TileType.Spinning:
                    goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                    if (task.NoCoinMoving == false && Map[task.FirstSource].Coins > 0 &&
                        (newPositionTile.OccupationTeamId == null || newPositionTile.OccupationTeamId == ourTeamId))
                    {
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition, true))
                        {
                            MoveType = MoveType.WithCoin
                        });
                    }
                    break;

                case TileType.Unknown:
                    goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                    break;

                case TileType.Horse:
                case TileType.Arrow:
                case TileType.Balloon:
                case TileType.Ice:
                case TileType.Croc:
                case TileType.Cannon:
                    goodTargets.AddRange(GetAllAvaliableMoves(task, newPosition, source));
                    break;

                case TileType.Airplane:
                    if (Map.AirplaneUsed == false)
                    {
                        goodTargets.AddRange(GetAllAvaliableMoves(task, newPosition, source));
                    }
                    else
                    {
                        // если нет самолета, то клетка работает как трава!
                        goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition)));
                        if (task.NoCoinMoving == false && Map[task.FirstSource].Coins > 0 &&
                            (newPositionTile.OccupationTeamId == null || newPositionTile.OccupationTeamId == ourTeamId))
                        {
                            goodTargets.Add(new AvaliableMove(task.FirstSource, newPosition, new Moving(task.FirstSource, newPosition, true))
                            {
                                MoveType = MoveType.WithCoin
                            });
                        }
                    }
                    break;
                }
            }
            return(goodTargets);
        }