/
MyBot.cs
169 lines (151 loc) · 5.93 KB
/
MyBot.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
using System;
using System.Collections.Generic;
using System.Linq;
public class Move
{
public int SourcePlanet { get; set; }
public int DestPlanet { get; set; }
public int Turn { get; set; }
}
public class MyBot
{
private static int CurrentTurn = 0;
private static bool IsKamikazi = false;
// The DoTurn function is where your code goes. The PlanetWars object
// contains the state of the game, including information about all planets
// and fleets that currently exist. Inside this function, you issue orders
// using the pw.IssueOrder() function. For example, to send 10 ships from
// planet 3 to planet 8, you would say pw.IssueOrder(3, 8, 10).
//
// There is already a basic strategy in place here. You can use it as a
// starting point, or you can throw it out entirely and replace it with
// your own. Check out the tutorials and articles on the contest website at
// http://www.ai-contest.com/resources.
private static double GetScore(Planet source, Planet dest, PlanetWars pw)
{
// on the first turn, don't attack the enemy -- take as many neutral planets as possible
if (CurrentTurn == 0 && dest.Owner == 2)
return double.MaxValue;
double score = dest.NumShips / 1 + dest.GrowthRate;
if (dest.Owner != 0)
score = score * 1.1;
int distance = pw.Distance(source.PlanetID, dest.PlanetID);
score = score * (double)(distance / 2);
return score;
}
private static bool CanSend(Planet source, Planet dest, PlanetWars pw)
{
int fleetsHeaded = pw.MyFleets().Where(f => f.DestinationPlanet == dest.PlanetID).Sum(f => f.NumShips);
int destFleets = dest.NumShips;
int sourceFleets = source.NumShips;
return (destFleets < sourceFleets && fleetsHeaded < destFleets);
}
private static int AvailableFleets(Planet p, PlanetWars pw)
{
int available = p.NumShips - pw.EnemyFleets().Where(f => f.DestinationPlanet == p.PlanetID).Sum(f => f.NumShips);
return available;
}
private static int GetNumFleetsToSend(Planet source, Planet dest, PlanetWars pw)
{
int distance = pw.Distance(source.PlanetID, dest.PlanetID);
int inFlight = pw.MyFleets().Where(f => f.DestinationPlanet == dest.PlanetID && f.TurnsRemaining < distance)
.Sum(f => f.NumShips);
int shipsOnArrival = (dest.Owner == 0) ? dest.NumShips : dest.NumShips + (distance * dest.GrowthRate);
return (shipsOnArrival + 1) - inFlight;
}
public static void DoTurn(PlanetWars pw)
{
if (CurrentTurn == 0 && pw.Distance(pw.MyPlanets().First().PlanetID, pw.EnemyPlanets().First().PlanetID) <= 8)
IsKamikazi = true;
if (IsKamikazi)
{
foreach (var planet in pw.MyPlanets())
{
var enemy = pw.EnemyPlanets().FirstOrDefault();
int shipsHeaded = pw.Fleets().Where(f => f.DestinationPlanet == planet.PlanetID).Sum(f => f.NumShips);
if (enemy != null)
{
if (planet.NumShips - shipsHeaded - 1 > 0)
pw.IssueOrder(planet, enemy, planet.NumShips - shipsHeaded - 1);
}
else
{
foreach (int dest in pw.EnemyFleets().Select(f => f.DestinationPlanet).Distinct())
{
if (dest == planet.PlanetID)
break;
int headedTo = pw.EnemyFleets().Where(f => f.DestinationPlanet == dest).Sum(f => f.NumShips);
int numToSend = ( (planet.NumShips - shipsHeaded) > headedTo) ? headedTo + 1 : (planet.NumShips - shipsHeaded);
if (numToSend > 0)
pw.IssueOrder(planet, pw.GetPlanet(dest), numToSend);
}
}
}
}
else
{
foreach (var planet in pw.MyPlanets())
{
int available = AvailableFleets(planet, pw);
var enemy = pw.NotMyPlanets().Where(p => CanSend(planet, p, pw));
enemy = enemy.OrderBy(p => GetScore(planet, p, pw));
int skip = 0;
while (available > 0)
{
var bestEnemy = enemy.Skip(skip).FirstOrDefault();
skip++;
if (bestEnemy != null)
{
int numToSend = GetNumFleetsToSend(planet, bestEnemy, pw);
if (available > numToSend)
{
pw.IssueOrder(planet, bestEnemy, numToSend);
available = available - numToSend;
}
}
else
{
available = 0;
}
}
}
}
}
public static void Main()
{
string line = "";
string message = "";
int c;
try
{
while ((c = Console.Read()) >= 0)
{
switch (c)
{
case '\n':
if (line.Equals("go"))
{
PlanetWars pw = new PlanetWars(message);
DoTurn(pw);
pw.FinishTurn();
message = "";
CurrentTurn++;
}
else
{
message += line + "\n";
}
line = "";
break;
default:
line += (char)c;
break;
}
}
}
catch (Exception)
{
// Owned.
}
}
}