// 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. public static void DoTurn(PlanetWars pw) { _spaceFile = new StreamWriter("C:\\Users\\Public\\Spacelist.txt", true); _openFile = new StreamWriter("C:\\Users\\Public\\Openlist.txt", true); _closedFile = new StreamWriter("C:\\Users\\Public\\Closedlist.txt", true); //bij iedere beurt wordt de root knoop opnieuw gelijk gezet aan de huidige (ongemuteerde) map state Mapstate root = new Mapstate(pw.MyPlanets(), pw.NumShips(1), pw.EnemyPlanets(), pw.NotMyPlanets(), pw.MyFleets(), pw.EnemyFleets(), new List<Strategyfleet>()); root = root.RootState(pw); List<Strategyfleet> ordersWillBe = strategize(root); //loop door de lijst van orders foreach (Strategyfleet move in ordersWillBe) { pw.IssueOrder(move.Bron, move.Doel, move.Sterkte); } _spaceFile.Close(); _openFile.Close(); _closedFile.Close(); //pw.IssueOrder(1, 2, 2000); //onmogelijke zet zodat we de boom op beurt 1 kunnen bekijken in de log file }
internal Mapstate DeepCopy(List<Planet> mPlaneten, int mijnAantalSchepen, List<Planet> vPlaneten, List<Planet> nmPlaneten, List<Fleet> mijnVloten, List<Fleet> vijandigeVloten, List<Strategyfleet> knoopStrategie) { mPlaneten = DeepCopyPlaneten(mPlaneten); vPlaneten = DeepCopyPlaneten(vPlaneten); nmPlaneten = DeepCopyPlaneten(nmPlaneten); knoopStrategie = DeepCopyStrategy(knoopStrategie); Mapstate deepCopyState = new Mapstate(mPlaneten, mijnAantalSchepen, vPlaneten, nmPlaneten, mijnVloten, vijandigeVloten, knoopStrategie); return deepCopyState; }
private static List<Mapstate> GenereerKnopen(Mapstate current, List<Mapstate> openlist) { int minimumStrength = 30; //minimale strength van een planeet List<Mapstate> kinderen = new List<Mapstate>(); current.MijnPlaneten = current.MijnPlaneten.OrderByDescending(o => o.Sterkte).ToList(); foreach (Planet myPlanet in current.MijnPlaneten) //voor elke planeet die ik bezit { foreach (Planet target in current.NietMijnPlaneten) //volor elke planeet die ik niet bezit { //hierdoor wordt iedere combiantie mogelijk van mijn planeten naar doelen if ( (myPlanet.Sterkte - minimumStrength > target.Sterkte) && !Zijnwehetaanhetaanvallen(current.MijnVloten, target.PlanetId()) && !Gaanwehetaanvallen(current.Knoopstrategie, target.PlanetId())) { /* * als mijn schepen op mijn planeet - de minimumale sterkte (bijvoorbeeld 100 - 30 = 70) * groter is dan het doel (100-30) > 50 ? ga dan door */ //nieuwe mapstate aanmaken Mapstate nieuweMapstate = current.DeepCopy(current.MijnPlaneten, current.MijnAantalSchepen, current.VijandigePlaneten, current.NietMijnPlaneten, current.MijnVloten, current.VijandigeVloten, current.Knoopstrategie); //muteer map state nieuweMapstate.StrategieToevoegen(myPlanet.PlanetId(), target.PlanetId(), target.Sterkte + 1); nieuweMapstate.MijnPlaneten = nieuweMapstate.MuteerMijnPlaneet(myPlanet, target.Sterkte); nieuweMapstate.NietMijnPlaneten = nieuweMapstate.MuteerDoelPlaneten(target); //nieuweMapstate.NietMijnPlaneten = muteerPlaneet(nieuweMapstate.NietMijnPlaneten, target.PlanetID()); //verwijdert de planeet uit het spel, let op! tel aantal strategievloten nieuweMapstate.MijnAantalSchepen -= target.NumShips() + 1; //gemuteerde knoop toevoegen kinderen.Add(nieuweMapstate); } } } return kinderen; }
private static List<Strategyfleet> strategize(Mapstate root) { int spaceCount, openCount, closedCount; //nog 0 mogelijke uitkomsten bekeken int numberResearched = 0; //maximaal 25 knopen bekijken om te voorkomen dat we door 100 miljoen miljard mogelijke uitkomsten gaan kijken int maxNumberResearched = 3000; //een lijst van map states, dit is onze boom waar we doorheen gaan kijken List<Mapstate> openlist = new List<Mapstate>(); //een lijst van map states, dit zijn de knopen die al nagekeken zijn of deze overeen komen met onze goalstate. //Als er geen goalstate gevonden is wordt een knoop uit deze lijst gehaald. List<Mapstate> closedlist = new List<Mapstate>(); //de lijst van mapstate knopen die worden toegevoegd aan de openlist List<Mapstate> kinderen = new List<Mapstate>(); //voordat we beginnen met de loop kijken we of de root knoop de oplossing is openlist.Add(root); //aan de lijst van map states wordt de root toegevoegd while (openlist.Count != 0 && numberResearched < maxNumberResearched) { //numberResearched zorgt ervoor dat we niet te vaak door de loop gaan (en honderduizenden knopen genereren/nakijken) numberResearched++; //de openlist is gesorteerd, Het eerste element in de openlist is de meest gunstige knoop om verder te bekijken Mapstate current = openlist.First(); //current variabele om in de boom te kijken //verwijder deze knoop uit de openlist openlist.RemoveAt(0); //controller of de knoop gebruikt kan worden om ons doel te bereiken if (Goal(current)) //TODO: goal test maken { openCount = openlist.Count; closedCount = closedlist.Count; spaceCount = openlist.Count + closedlist.Count + 1; _openFile.WriteLine(openCount); _closedFile.WriteLine(closedCount); _spaceFile.WriteLine(spaceCount); return current.Knoopstrategie; } //als de knoop niet gebruikt kan worden om de goalstate te realiseren wordt hij aan closedlist toegevoegd closedlist.Add(current); //genereer mapstate knopen van de huidige knoop kinderen = GenereerKnopen(current, openlist); //en voeg deze toe aan openlist openlist.AddRange(kinderen); //priorizeer lijst van mapstates op schepen openlist = openlist.OrderByDescending(o => o.Knoopstrategie.Count).ToList(); } //als de goal state niet gevonden wordt (het verslaan van de vijand) nemen we de best mogelijke oplossing //waarbij we in een aantal commandos zoveel mogelijk planeten veroveren met zo weinig mogelijk schepen openCount = openlist.Count; closedCount = closedlist.Count; spaceCount = openlist.Count + closedlist.Count + 1; _openFile.WriteLine(openCount); _closedFile.WriteLine(closedCount); _spaceFile.WriteLine(spaceCount); closedlist = closedlist.OrderByDescending(o => o.Knoopstrategie.Count) .ThenByDescending(o => o.MijnAantalSchepen) .ToList(); //De lijst van closedlist is gesorteerd, de meest gunstigste knoop staat vooraan Mapstate best = closedlist.First(); //uit deze knoop wordt de strategielijst gehaald return best.Knoopstrategie; }
//controlleren om met de huidige knoop de vijand verslagen kan worden private static bool Goal(Mapstate current) { if (current.VijandigePlaneten.Count(planet => planet.Owner() != 1) == 0) { return true; //zo ja, return deze knoop, vergeet de andere knopen! met deze aanval kan het potje misschien snel afgelopen zijn! } return false; }