Ejemplo n.º 1
0
 protected bool Equals(TilePosition other)
 {
     return(Position.Equals(other.Position) && Level == other.Level);
 }
Ejemplo n.º 2
0
 public Pirate(int teamId, TilePosition position)
 {
     Id       = Guid.NewGuid();
     TeamId   = teamId;
     Position = position;
 }
Ejemplo n.º 3
0
 public AvaliableMove(TilePosition source, TilePosition target, params IGameAction[] actions)
 {
     Source     = source;
     Target     = target;
     ActionList = new GameActionList(actions);
 }
Ejemplo n.º 4
0
 public Move(TilePosition from, TilePosition to, MoveType type = MoveType.Usual)
     : base(from, to)
 {
     Type = type;
 }
Ejemplo n.º 5
0
 public TileLevel(TilePosition position)
 {
     Position = position;
 }
Ejemplo n.º 6
0
 public TileLevel this[TilePosition pos]
 {
     get { return(Tiles[pos.Position.X, pos.Position.Y].Levels[pos.Level]); }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Возвращаем все позиции, в которые в принципе достижимы из заданной клетки за один подход
        /// (не проверяется, допустим ли такой ход)
        /// </summary>
        /// <param name="source"></param>
        /// <param name="previosMove"></param>
        /// <returns></returns>
        public List <TilePosition> GetAllTargetsForSubturn(TilePosition source, Direction previosMove, Team ourTeam)
        {
            var sourceTile = Map[source.Position];
            var ourShip    = ourTeam.Ship;

            IEnumerable <TilePosition> rez;

            switch (sourceTile.Type)
            {
            case TileType.Horse:
                rez = GetHorseDeltas(source.Position)
                      .Select(x => IncomeTilePosition(x));
                break;

            case TileType.Cannon:
                rez = new [] { IncomeTilePosition(GetCannonFly(sourceTile.CannonDirection, source.Position)) };
                break;

            case TileType.Arrow:
                rez = GetArrowsDeltas(sourceTile.ArrowsCode, source.Position)
                      .Select(x => IncomeTilePosition(x));
                break;

            case TileType.Balloon:
                rez = Teams.Select(x => x.Ship.Position)
                      .Select(x => IncomeTilePosition(x));   //на корабль
                break;

            case TileType.Airplane:
                if (Map.AirplaneUsed == false)
                {
                    var shipTargets = Teams.Select(x => x.Ship.Position)
                                      .Select(x => IncomeTilePosition(x)); //на корабль
                    var airplaneTargets = AllTiles(x => x.Type != TileType.Water &&
                                                   x.Type.RequreImmediateMove() == false &&
                                                   x.Type != TileType.Airplane)
                                          .Select(x => x.Position)
                                          .Select(x => IncomeTilePosition(x));
                    rez = shipTargets.Concat(airplaneTargets);
                    if (previosMove.From != source)
                    {
                        rez = rez.Concat(new [] { source });  //ход "остаемся на месте"
                    }
                }
                else
                {
                    rez = GetNearDeltas(source.Position)
                          .Where(x => IsValidMapPosition(x))
                          .Where(x => Map[x].Type != TileType.Water || x == ourShip.Position)
                          .Select(x => IncomeTilePosition(x));
                }
                break;

            case TileType.Croc:
                rez = new[] { previosMove.From };   //возвращаемся назад
                break;

            case TileType.Ice:
                if (Map[previosMove.From.Position].Type == TileType.Horse)
                {
                    //повторяем ход лошади
                    rez = GetHorseDeltas(source.Position)
                          .Select(x => IncomeTilePosition(x));
                }
                else     //повторяем предыдущий ход
                {
                    //TODO - проверка на использование самолета на предыдущем ходу - тогда мы должны повторить ход самолета
                    var      previosDelta = previosMove.GetDelta();
                    Position target       = Position.AddDelta(source.Position, previosDelta);
                    rez = new[] { target }.Select(x => IncomeTilePosition(x));
                }
                break;

            case TileType.RespawnFort:
                rez = GetNearDeltas(source.Position)
                      .Where(x => IsValidMapPosition(x))
                      .Where(x => Map[x].Type != TileType.Water || x == ourShip.Position)
                      .Select(x => IncomeTilePosition(x))
                      .Concat(new[] { source });
                break;

            case TileType.Spinning:
                if (source.Level == 0)
                {
                    rez = GetNearDeltas(source.Position)
                          .Where(x => IsValidMapPosition(x))
                          .Where(x => Map[x].Type != TileType.Water || x == ourShip.Position)
                          .Select(x => IncomeTilePosition(x));
                }
                else
                {
                    rez = new[] { new TilePosition(source.Position, source.Level - 1) };
                }
                break;

            case TileType.Water:
                if (source.Position == ourShip.Position)     //с своего корабля
                {
                    rez = GetShipPosibleNavaigations(source.Position)
                          .Concat(new[] { GetShipLanding(source.Position) })
                          .Select(x => IncomeTilePosition(x));
                }
                else     //пират плавает в воде
                {
                    rez = GetPosibleSwimming(source.Position)
                          .Select(x => IncomeTilePosition(x));
                }
                break;

            default:
                rez = GetNearDeltas(source.Position)
                      .Where(x => IsValidMapPosition(x))
                      .Where(x => Map[x].Type != TileType.Water || x == ourShip.Position)
                      .Select(x => IncomeTilePosition(x));
                break;
            }
            return(rez.Where(x => IsValidMapPosition(x.Position)).ToList());
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
0
        private void Step(TilePosition target, Pirate pirate, Ship ship, Team team)
        {
            //var moves = _availableMoves;
            //var actions = _actions;

            Tile targetTile = Board.Map[target.Position];

            var  source     = pirate.Position.Position;
            Tile sourceTile = Board.Map[source];

            bool onShip = (ship.Position == pirate.Position.Position);

            Direction direction = new Direction(pirate.Position, target);

            switch (targetTile.Type)
            {
            case TileType.Unknown:
            {
                // exploration
                if (onShip)
                {
                    if (CanLanding(pirate, target))
                    {
                        // landing
                        AddMoveAndActions(new Move(pirate.Position.Position, target),
                                          GameActionList.Create(
                                              new Explore(target, pirate, direction),
                                              new Landing(pirate, ship),
                                              new Moving(pirate, target)));
                    }
                }
                else
                {
                    AddMoveAndActions(new Move(pirate.Position.Position, target),
                                      GameActionList.Create(
                                          new Explore(target, pirate, direction),
                                          new Moving(pirate, target)));
                }

                break;
            }

            case TileType.Water:
            {
                if (target == ship.Position)     //на свой корабль
                {
                    if (sourceTile.Coins > 0)
                    {
                        // shipping with coins
                        AddMoveAndActions(new Move(pirate.Position.Position, target, MoveType.WithCoin),
                                          GameActionList.Create(
                                              new TakeCoinToShip(pirate, ship),
                                              new Shipping(pirate, ship)));
                    }

                    // shipping without coins
                    AddMoveAndActions(new Move(pirate.Position.Position, target),
                                      GameActionList.Create(
                                          //new DropCoin(pirate),
                                          new Shipping(pirate, ship)));
                }
                else if (pirate.Position.Position == ship.Position)     //двигаем корабль
                {
                    if (((ship.Position.X == 0 || ship.Position.X == Board.Size - 1) &&
                         (target.Y <= 1 || target.Y >= Board.Size - 2))
                        ||
                        ((ship.Position.Y == 0 || ship.Position.Y == Board.Size - 1) &&
                         (target.X <= 1 || target.X >= Board.Size - 2)))
                    {
                        break;     // enemy water territories
                    }

                    // navigation
                    AddMoveAndActions(new Move(pirate.Position.Position, target),
                                      GameActionList.Create(
                                          new Navigation(ship, target)));
                }
                else if (Board.Teams.Where(x => x.Id != CurrentTeamId).Select(x => x.Ship.Position).Contains(target))
                {
                    //столкновение с чужим кораблем
                    AddMoveAndActions(new Move(pirate.Position.Position, target),
                                      GameActionList.Create(
                                          new Dying(pirate)));
                }
                else     //падение пирата в воду и плавание в воде
                {
                    AddMoveAndActions(new Move(pirate.Position.Position, target),
                                      GameActionList.Create(
                                          new Moving(pirate, target)));
                }
                break;
            }

            case TileType.Chest1:
            case TileType.Chest2:
            case TileType.Chest3:
            case TileType.Chest4:
            case TileType.Chest5:
            case TileType.Grass:
            case TileType.Fort:
            case TileType.RespawnFort:
            case TileType.RumBarrel:
            case TileType.Canibal:
            case TileType.Spinning:
            case TileType.Trap:
            {
                var  attack       = targetTile.OccupationTeamId.HasValue && targetTile.OccupationTeamId.Value != pirate.TeamId;
                bool targetIsFort = targetTile.Type.IsFort();

                //Respawn
                if (targetTile.Type == TileType.RespawnFort && sourceTile.Type == TileType.RespawnFort)
                {
                    if (team.Pirates.Count() < 3)
                    {
                        AddMoveAndActions(new Move(pirate.Position.Position, target, MoveType.WithRespawn),
                                          GameActionList.Create(
                                              new Respawn(team, target)));
                    }
                }

                if (attack)
                {
                    if (targetIsFort == false)
                    {
                        // attack
                        if (onShip)
                        {
                            if (CanLanding(pirate, target))
                            {
                                AddMoveAndActions(new Move(pirate.Position.Position, target),
                                                  GameActionList.Create(
                                                      new Attack(target),
                                                      new Landing(pirate, ship),
                                                      new Moving(pirate, target)));
                            }
                        }
                        else
                        {
                            AddMoveAndActions(new Move(pirate.Position.Position, target),
                                              GameActionList.Create(
                                                  new Attack(target),
                                                  new Moving(pirate, target)));
                        }
                    }
                }
                else
                {
                    if (onShip)
                    {
                        if (CanLanding(pirate, target))
                        {
                            AddMoveAndActions(new Move(pirate.Position.Position, target),
                                              GameActionList.Create(
                                                  new Landing(pirate, ship),
                                                  new Moving(pirate, target)));
                        }
                    }
                    else
                    {
                        AddMoveAndActions(new Move(pirate.Position.Position, target),
                                          GameActionList.Create(
                                              new Moving(pirate, target)));

                        if (sourceTile.Coins > 0 && targetIsFort == false)
                        {
                            AddMoveAndActions(new Move(pirate.Position.Position, target, MoveType.WithCoin),
                                              GameActionList.Create(
                                                  new Moving(pirate, target, true)));
                        }
                    }
                }
                break;
            }
            }
        }