コード例 #1
0
ファイル: SupplyAdviser.cs プロジェクト: rhiensch/pwbot
        public override Moves Run(Planet supplyPlanet)
        {
            Moves moves = new Moves();

            if (supplyPlanet == null) return moves;

            Planets frontPlanets = Context.GetFrontPlanets();
            if (frontPlanets == null) return moves;
            if (frontPlanets.Count == 0) return moves;
            if (frontPlanets.IndexOf(supplyPlanet) != -1) return moves;

            IPathFinder pathFinder = new ClosestPathFinder(Context);
                //new DirectPathFinder(Context);
                //new DijkstraPathFinder(Context);
            Planet dest = pathFinder.FindNextPlanetInPath(supplyPlanet);
            if (dest != null)
            {
                int canSend = Context.CanSend(supplyPlanet);
                if (canSend == 0) return moves;

                Move move = new Move(supplyPlanet, dest, canSend);
                moves.Add(move);
            }
            return moves;
        }
コード例 #2
0
ファイル: MovesSet.cs プロジェクト: rhiensch/pwbot
        public MovesSet(IEnumerable<Move> movesSet, double score, string adviserName, PlanetWars context)
        {
            this.context = context;
            MaxDistance = Int32.MinValue;
            MinDistance = Int32.MaxValue;
            AverageDistance = 0;
            SummaryNumShips = 0;
            NumShipsByTurns = 0;

            moves = new Moves();
            foreach (Move move in movesSet)
            {
                AddMove(move);
            }

            Score = score;
            AdviserName = adviserName;
        }
コード例 #3
0
ファイル: DefendAdviser.cs プロジェクト: rhiensch/pwbot
        public override Moves Run(Planet planet)
        {
            Moves moves = new Moves();
            loseTurn = 0;

            //Planet planet = SelectPlanetForAdvise();
            if (planet == null) return moves;

            List<Step> saveSteps = Context.GetMyPlanetSaveSteps(planet);

            if (saveSteps.Count == 0) return moves;

            foreach (Step t in saveSteps)
            {
                Planets planetsCanHelp = Context.MyPlanetsWithinProximityToPlanet(planet, t.ToTurn);

                Comparer comparer = new Comparer(Context) {TargetPlanet = planet};
                planetsCanHelp.Sort(comparer.CompareDistanceToTargetPlanetLT);

                int sendedShipsNum = 0;
                foreach (Planet nearPlanet in planetsCanHelp)
                {
                    int canSend = Math.Min(t.NumShips - sendedShipsNum, Context.CanSendByPlanets(nearPlanet, planet));
                    if (canSend <= 0) continue;

                    int distance = Context.Distance(planet, nearPlanet);
                    Move move = new Move(nearPlanet.PlanetID(), planet.PlanetID(), canSend);
                    if (distance < t.ToTurn)
                    {
                        //delay move
                        move.TurnsBefore = t.ToTurn - distance;
                        //move = new Move(nearPlanet.PlanetID(), planet.PlanetID(), Context.CanSend(nearPlanet, move.TurnsBefore));
                    }
                    moves.Add(move);
                    sendedShipsNum += canSend;
                }
                if (sendedShipsNum < t.NumShips)
                {
                    loseTurn = t.NumShips;
                }
            }

            return moves;
        }
コード例 #4
0
ファイル: StealAdviser.cs プロジェクト: rhiensch/pwbot
        public override Moves Run(Planet stealPlanet)
        {
            Moves moves = new Moves();

            PlanetHolder planetHolder = Context.GetPlanetHolder(stealPlanet);
            List<PlanetOwnerSwitch> switches = planetHolder.GetOwnerSwitchesFromNeutralToEnemy();
            if (switches.Count == 0) return moves;

            Planet futurePlanet = null;
            int turn = 0;
            for (int i = 0; i < switches.Count; i++)
            {
                turn = switches[i].TurnsBefore + 1;
                futurePlanet = Context.PlanetFutureStatus(stealPlanet, turn);
                if (futurePlanet.Owner() != 1) break;
                futurePlanet = null;
            }
            if (futurePlanet == null) return moves;

            Planets myPlanets = Context.MyPlanetsWithinProximityToPlanet(stealPlanet, turn);
            if (myPlanets.Count == 0) return moves;

            int needToSend = futurePlanet.NumShips() + 1;
            //needToSend += Context.GetEnemyAid(stealPlanet, turn);

            foreach (Planet myPlanet in myPlanets)
            {
                int distance = Context.Distance(myPlanet, stealPlanet);
                int canSend = Context.CanSendByPlanets(myPlanet, stealPlanet);
                if (canSend == 0) continue;

                int send = Math.Min(canSend, needToSend);
                needToSend -= send;

                Move move = new Move(myPlanet, stealPlanet, send) {TurnsBefore = turn - distance};
                moves.Add(move);

                if (needToSend <= 0) return moves;
            }

            moves.Clear();
            return moves;
        }
コード例 #5
0
ファイル: AttackAdviser.cs プロジェクト: rhiensch/pwbot
		public override Moves Run(Planet targetPlanet)
		{
			Moves moves = new Moves();
			if (targetPlanet == null) return moves;

			Planets myPlanets = Context.MyPlanets();
			if (myPlanets.Count == 0) return moves;

			Comparer comparer = new Comparer(Context) {TargetPlanet = targetPlanet};
			myPlanets.Sort(comparer.CompareDistanceToTargetPlanetLT);

			PlanetHolder holder = Context.GetPlanetHolder(targetPlanet);

			foreach (Planet myPlanet in myPlanets)
			{
				int targetDistance = Context.Distance(myPlanet, targetPlanet);
				int myCanSend = Context.CanSendByPlanets(myPlanet, targetPlanet);
				if (myCanSend == 0) continue;

				Planet futurePlanet = Context.PlanetFutureStatus(targetPlanet, targetDistance);
				if (futurePlanet.Owner() != 2) continue;
				if (holder.IsNeutralToEnemySwith(targetDistance)) continue;

				int needToSend = 1 + futurePlanet.NumShips();
				if (Config.AttackSendMoreThanEnemyCanDefend)
					needToSend += Context.GetEnemyAid(targetPlanet, targetDistance);

				needToSend = moves.Aggregate(needToSend, (current, eachMove) => current - Context.CanSend(Context.GetPlanet(eachMove.SourceID)));

				if (needToSend <= 0) return moves;

				int canSend = Math.Min(needToSend, myCanSend);
				needToSend -= canSend;
				Move move = new Move(myPlanet, targetPlanet, canSend);
				moves.Add(move);

				if (needToSend <= 0) return moves;
			}

			return new Moves();
		}
コード例 #6
0
ファイル: DefendAdviser.cs プロジェクト: rhiensch/pwbot
        public override List<MovesSet> RunAll()
        {
            List<MovesSet> movesSet = new List<MovesSet>();
            Planets planetsForAdvise = Context.MyEndangeredPlanets();
            foreach (Planet planet in planetsForAdvise)
            {
                Moves moves = Run(planet);
                if (moves.Count <= 0) continue;
                MovesSet set = new MovesSet(moves, 0, GetAdviserName(), Context);
                //double score = enemyPlanet.GrowthRate() / Context.AverageMovesDistance(moves);
                double score = 2 * planet.GrowthRate() * (loseTurn > 0 ? loseTurn : Config.ScoreTurns) - set.NumShipsByTurns / set.AverageDistance;
                set.Score = score;

                if (loseTurn == 0)
                {
                    movesSet.Add(set);
                }
                else
                {
                    //todo delete bigger then target
                    Moves newMoves = new Moves();
                    foreach (Move move in set.GetMoves())
                    {
                        if (Context.GetPlanet(move.SourceID).NumShips() < Context.GetPlanet(move.DestinationID).NumShips())
                            newMoves.Add(new Move(move));
                    }
                    if (newMoves.Count > 0)
                    {
                        set = new MovesSet(newMoves, 0, GetAdviserName(), Context);
                        movesSet.Add(set);
                    }
                }
            }
            return movesSet;
        }
コード例 #7
0
ファイル: FirstMoveAdviser.cs プロジェクト: rhiensch/pwbot
        public MovesSet BruteForce(Planets planets, int canSend)
        {
            int scoreTurns = Config.ScoreTurns;//Context.Distance(myPlanet, enemyPlanet);

            int n = planets.Count;
            //int secondMoveCanSend = myPlanet.NumShips() - canSend + myPlanet.GrowthRate();
            int secondMoveCanSend = Math.Min(myPlanet.NumShips() - canSend + myPlanet.GrowthRate(), myPlanet.GrowthRate() * Context.Distance(myPlanet, enemyPlanet));

            List<MovesSet> sets = new List<MovesSet>();

            int size = (1 << n);
            for (int i = 0; i < size; i++)
            {
                if (CheckTimeFunc != null)
                    if (!CheckTimeFunc()) break;

                int ships = 0;
                int score = 0;
                int returners = 0;
                Moves moves = new Moves();
                Planets targetPlanets = new Planets(Config.MaxPlanets);
                for (int j = 0; j < n; j++)
                {
                    if (CheckTimeFunc != null)
                        if (!CheckTimeFunc()) break;

                    if ((i & (1 << j)) <= 0) continue;
                    Planet target = planets[j];
                    targetPlanets.Add(target);

                    int distance = Context.Distance(myPlanet, target);
                    int needShips = target.NumShips() + 1;

                    if (Context.Distance(myPlanet, target) >= Context.Distance(enemyPlanet, target))
                        needShips += 1;

                    if (myPlanet.NumShips() > canSend && enemyDistance > distance * 2)
                    {
                        //HowMany ships can return to myPlanet before enemy
                        returners += (enemyDistance - distance * 2) * myPlanet.GrowthRate();
                        if (returners > myPlanet.NumShips() - canSend) returners = myPlanet.NumShips() - canSend;
                    }

                    int growTurns = Math.Max(0, scoreTurns - Context.Distance(myPlanet.PlanetID(), target.PlanetID()));

                    score += growTurns * target.GrowthRate() - needShips;

                    ships += needShips;
                    if (ships > canSend + returners)
                    {
                        break;
                    }
                    moves.Add(
                        new Move(
                            myPlanet.PlanetID(),
                            target.PlanetID(),
                            needShips)
                        );
                }
                if (ships > canSend + returners) continue;

                //clear set
                MovesSet set = new MovesSet(moves, score, GetAdviserName(), Context);
                sets.Add(set);

                //sets with additional planet, divided for 2 turns
                int firstMoveCanSend = canSend + returners - ships;
                if (firstMoveCanSend < 0) firstMoveCanSend = 0;

                foreach (Planet additionalPlanet in planets)
                {
                    if (targetPlanets.Contains(additionalPlanet)) continue;

                    int needShips = additionalPlanet.NumShips() + 1;
                    if (Context.Distance(myPlanet, additionalPlanet) >= Context.Distance(enemyPlanet, additionalPlanet))
                        needShips += 1;

                    if (firstMoveCanSend + secondMoveCanSend < needShips) continue;
                    //this planet we can invade in another set: this set + this planet
                    if (firstMoveCanSend >= needShips) continue;

                    MovesSet additionalSet = new MovesSet(set, Context);
                    if (firstMoveCanSend > 0)
                        additionalSet.AddMove(new Move(myPlanet, additionalPlanet, firstMoveCanSend));

                    additionalSet.AddMove(new Move(myPlanet, additionalPlanet, needShips - firstMoveCanSend) { TurnsBefore = 1 });

                    int growTurns = Math.Max(0, scoreTurns - Context.Distance(myPlanet.PlanetID(), additionalPlanet.PlanetID()));
                    additionalSet.Score += (growTurns - 1) * additionalPlanet.GrowthRate() - needShips;

                    sets.Add(additionalSet);
                }

            }
            if (sets.Count == 0) return null;
            if (sets.Count > 1)
            {
                sets.Sort(new Comparer(null).CompareSetScoreGT);
            }
            /*foreach (MovesSet movesSet in sets)
            {
                Logger.Log("score: " + movesSet.Score + "  " + movesSet);
            }*/
            return sets[0];
        }
コード例 #8
0
ファイル: MyBot.cs プロジェクト: rhiensch/pwbot
		private void SelectAndMakeMoves()
		{
			if (setList == null) return;
			int n = setList.Count;

			if (n == 0) return;

			List<List<MovesSet>> sets = new List<List<MovesSet>>();

			int size = (1 << n);
			for (int i = 0; i < size; i++)
			{
				if (!CheckTime()) break;

				List<MovesSet> currentSetList = new List<MovesSet>();
				Moves totalMoves = new Moves();
				//int invadeNumber = Config.MaxInvades;

				for (int j = 0; j < n; j++)
				{
					if (!CheckTime()) break;

					if ((i & (1 << j)) <= 0) continue;

					MovesSet set = setList[j];

					//if (setList[j].AdviserName == "Invade") invadeNumber--;
					//if (invadeNumber < 0) break;

					currentSetList.Add(set);

					Moves moves = set.GetMoves();
					foreach (Move move in moves)
					{
						if (move.TurnsBefore > 0) continue;

						bool found = false;
						foreach (Move t in totalMoves)
						{
							if (t.SourceID != move.SourceID) continue;
							found = true;
							t.AddShips(move.NumShips);
							break;
						}
						if (!found)
						{
							totalMoves.Add(new Move(move));
						}
					}
				}
				bool isValid = totalMoves.All(totalMove => Context.IsValid(totalMove));
				/*if (!isValid)
					foreach (Move totalMove in totalMoves)
					{
						if (!Context.IsValid(totalMove))
						{
							Logger.Log("InValid: " + totalMove);
							break;
						}
					} */

				if (!isValid) continue;
				sets.Add(currentSetList);
			}

			setList.Clear();

			if (sets.Count > 1)
			{
				sets.Sort(new Comparer(null).CompareSetListScoreGT);
			}

			if (sets.Count > 0)
			{
				MakeMoves(sets[0]);
			}
		}
コード例 #9
0
ファイル: InvadeAdviser.cs プロジェクト: rhiensch/pwbot
		public override Moves Run(Planet targetPlanet)
		{
			Moves moves = new Moves();

			if (targetPlanet == null) return moves;

			Planets nearestPlanets = Context.GetClosestPlanetsToTargetBySectors(targetPlanet, Context.MyPlanets());
			//Context.MyPlanets();
			//MyPlanetsWithinProximityToPlanet(planet, Config.InvokeDistanceForInvade);););
			if (nearestPlanets.Count == 0) return moves;

			if (nearestPlanets.Count > 1)
			{
				Comparer comparer = new Comparer(Context) { TargetPlanet = targetPlanet };
				nearestPlanets.Sort(comparer.CompareDistanceToTargetPlanetLT);
			}

			foreach (Planet nearestPlanet in nearestPlanets)
			{
				int canSend = Context.CanSendByPlanets(nearestPlanet, targetPlanet);
				if (canSend == 0) continue;

				int distance = Context.Distance(targetPlanet, nearestPlanet);

				Planet futurePlanet = Context.PlanetFutureStatus(targetPlanet, distance);
				if (futurePlanet.Owner() == 2)//Error?
				{
#if LOG
					Logger.Log("InvadeAdvizer: Error?");
#endif
					moves.Clear();
					return moves;
				}

				int needToSend = futurePlanet.NumShips() + 1;
				if (Config.InvadeSendMoreThanEnemyCanDefend)
				{
					int extraTurns = (int)Math.Ceiling(targetPlanet.NumShips() / (double)targetPlanet.GrowthRate());
					if (Context.MyFutureProduction < Context.EnemyFutureProduction) extraTurns = 0;
					if ((Context.MyFutureProduction == Context.EnemyFutureProduction) &&
						(Context.MyTotalShipCount <= Context.EnemyTotalShipCount)) extraTurns = 0;
					needToSend += Context.GetEnemyAid(targetPlanet, distance + extraTurns);
				}
				
				needToSend = moves.Aggregate(needToSend, (current, eachMove) => current - Context.CanSendByPlanets(Context.GetPlanet(eachMove.SourceID), Context.GetPlanet(eachMove.DestinationID)));
				
				//delay closer moves
				/*foreach (Move eachMove in moves)
				{
					int moveDistance = Context.Distance(eachMove.DestinationID, eachMove.SourceID);
					int turns = distance - moveDistance;
					eachMove.TurnsBefore = turns;
					needToSend -= Context.CanSend(Context.GetPlanet(eachMove.SourceID), turns);
				}*/

				if (needToSend <= 0) return moves;

				canSend = Math.Min(needToSend, canSend);
				needToSend -= canSend;
				Move move = new Move(nearestPlanet, targetPlanet, canSend);
				moves.Add(move);

				if (needToSend <= 0) return moves;
			}

			moves.Clear();
			return moves;
		}
コード例 #10
0
ファイル: MovesSet.cs プロジェクト: rhiensch/pwbot
 public Moves GetMoves()
 {
     Moves result = new Moves(moves);
     return result;
 }
コード例 #11
0
ファイル: AntiCrisisAdviser.cs プロジェクト: rhiensch/pwbot
        //From my strongest to closest suitable enemy
        public List<MovesSet> InvadeAction()
        {
            List<MovesSet> movesSet = new List<MovesSet>();

            Planets myPlanets = Context.MyStrongestPlanets(1);
            if (myPlanets.Count == 0) return movesSet;

            Planet myStrongestPlanet = myPlanets[0];

            int canSend = Context.CanSend(myStrongestPlanet);

            Planets targetFuturePlanets = new Planets(Config.MaxPlanets);
            targetFuturePlanets.AddRange(from eachPlanet in Context.Planets()
                                         where eachPlanet.GrowthRate() != 0
                                         let distance = Context.Distance(myStrongestPlanet, eachPlanet)
                                         select Context.PlanetFutureStatus(eachPlanet, distance)
                                         into futurePlanet where futurePlanet.Owner() == 0 && canSend > futurePlanet.NumShips() + 1 select futurePlanet);

            if (targetFuturePlanets.Count == 0) return movesSet;

            Comparer comparer = new Comparer(Context) { TargetPlanet = myStrongestPlanet };
            targetFuturePlanets.Sort(comparer.CompareDistanceToTargetPlanetLT);

            Moves moves = new Moves(1)
                          	{
                          		new Move(myStrongestPlanet, targetFuturePlanets[0],
                          		         Math.Min(canSend, targetFuturePlanets[0].NumShips() + 1))
                          	};
            movesSet.Add(new MovesSet(moves, 99999, GetAdviserName(), Context));

            return movesSet;
        }
コード例 #12
0
ファイル: AntiCrisisAdviser.cs プロジェクト: rhiensch/pwbot
        //From my strongest to closest suitable enemy
        public List<MovesSet> ReFrontAction()
        {
            List<MovesSet> movesSet = new List<MovesSet>();

            Planets frontPlanets = Context.GetFrontPlanets();
            if (frontPlanets == null) return movesSet;
            if (frontPlanets.Count < 2) return movesSet;

            Moves moves = new Moves(frontPlanets.Count - 1);

            frontPlanets.Sort(new Comparer(Context).CompareGrowsRateGT);
            Planet target = frontPlanets[0];
            foreach (Planet frontPlanet in frontPlanets)
            {
                if (frontPlanet.PlanetID() == target.PlanetID()) continue;
                moves.Add(new Move(frontPlanet, target, Context.CanSendSafe(frontPlanet)));
            }
            movesSet.Add(new MovesSet(moves, 9999, GetAdviserName(), Context));

            return movesSet;
        }
コード例 #13
0
ファイル: PlanetWars.cs プロジェクト: rhiensch/pwbot
		public int MaxMovesDistance(Moves moves)
		{
			if (moves.Count == 0) return 0;

			int maxDistance = 0;
			foreach (Move move in moves)
			{
				int distance = Distance(move.SourceID, move.DestinationID);
				if (maxDistance < distance) maxDistance = distance;
			}
			return maxDistance;
		}
コード例 #14
0
ファイル: PlanetWars.cs プロジェクト: rhiensch/pwbot
		public double AverageMovesDistance(Moves moves)
		{
			if (moves.Count == 0) return 0;

			double sumDistance = 0;
			foreach (Move move in moves)
			{
				sumDistance += Distance(move.SourceID, move.DestinationID);
			}
			return sumDistance/moves.Count;
		}