public void Activate() { UnitController.GetInstance(); EnemyController.GetInstance(); FriendlyUnitPositionObserver.GetInstance(); MovementMaps.GetInstance(); BuildMap.GetInstance(); Metal.GetInstance().Init(); LosMap.GetInstance(); BuildPlanner.GetInstance(); BuildTable.GetInstance(); CommanderList.GetInstance(); Level1ConstructorList.GetInstance(); Level1FactoryList.GetInstance(); tankcontroller = new TankController(TankList.GetInstance().defbyid, BuildTable.GetInstance().UnitDefByName["armstump"]); tankcontroller.Activate(); helicoptercontroller = new TankController(HelicopterList.GetInstance().defbyid, BuildTable.GetInstance().UnitDefByName["armbrawl"]); helicoptercontroller.Activate(); new ScoutControllerRaider().Activate(); UnitController.GetInstance().LoadExistingUnits(); EnemyController.GetInstance().LoadExistingUnits(); CheckIdleUnits(); //BuildSolarCell(CommanderList.GetInstance().defbyid.Keys.GetEnumerator().Current); csai.UnitIdleEvent += new CSAI.UnitIdleHandler(csai_UnitIdleEvent); csai.TickEvent += new CSAI.TickHandler(csai_TickEvent); }
bool DoReclaim(int constructorid) { if (totalticks == 0) // check ticks first, beacuse metal shows as zero at start { return(false); } IUnitDef unitdef = UnitDefByUnitId[constructorid] as IUnitDef; Float3 mypos = aicallback.GetUnitPos(constructorid); MovementMaps movementmaps = MovementMaps.GetInstance(); int currentarea = movementmaps.GetArea(unitdef, mypos); //double nearestreclaimdistancesquared = 1000000; //Float3 nearestreclaimpos = null; double bestmetaldistanceratio = 0; int bestreclaimid = 0; int metalspace = (int)(aicallback.GetMetalStorage() - aicallback.GetMetal()); logfile.WriteLine("available space in metal storage: " + metalspace); int[] nearbyfeatures = aicallback.GetFeatures(mypos, maxreclaimradius); bool reclaimfound = false; foreach (int feature in nearbyfeatures) { IFeatureDef featuredef = aicallback.GetFeatureDef(feature); if (featuredef.metal > 0 && featuredef.metal <= metalspace) { Float3 thisfeaturepos = aicallback.GetFeaturePos(feature); double thisdistance = Math.Sqrt(Float3Helper.GetSquaredDistance(thisfeaturepos, mypos)); double thismetaldistanceratio = featuredef.metal / thisdistance; if (thismetaldistanceratio > bestmetaldistanceratio && movementmaps.GetArea(unitdef, thisfeaturepos) == currentarea) { logfile.WriteLine("Potential reclaim, distance = " + thisdistance + " metal = " + featuredef.metal + " ratio = " + thismetaldistanceratio); bestmetaldistanceratio = thismetaldistanceratio; bestreclaimid = feature; // nearestreclaimpo reclaimfound = true; } } } if (reclaimfound && (bestmetaldistanceratio > (1.0 / (100 * reclaimradiusperonehundredmetal)))) { Float3 reclaimpos = aicallback.GetFeaturePos(bestreclaimid); logfile.WriteLine("Reclaim found, pos " + reclaimpos.ToString()); if (csai.DebugOn) { aicallback.DrawUnit("ARMMEX", reclaimpos, 0.0f, 200, aicallback.GetMyAllyTeam(), true, true); } aicallback.GiveOrder(constructorid, new Command(Command.CMD_RECLAIM, new double[] { reclaimpos.x, reclaimpos.y, reclaimpos.z, 10 })); } else { logfile.WriteLine("No reclaim within parameters"); } return(reclaimfound); }
// note: need to check compatible area public Float3 GetNearestUnseen(Float3 currentpos, IUnitDef unitdef, int unseensmeansthismanyframes) { int currentunitarea = MovementMaps.GetInstance().GetArea(unitdef, currentpos); int losmapwidth = LastSeenFrameCount.GetUpperBound(0) + 1; int losmapheight = LastSeenFrameCount.GetUpperBound(0) + 1; int maxradius = Math.Max(losmapheight, losmapwidth); int unitlosradius = (int)unitdef.losRadius; // this is in map / 2 units, so it's ok Int2[] circlepoints = CreateCirclePoints(unitlosradius); int bestradius = 10000000; int bestarea = 0; Float3 bestpos = null; int unitmapx = (int)(currentpos.x / 16); int unitmapy = (int)(currentpos.y / 16); int thisframecount = aicallback.GetCurrentFrame(); // step around in unitlosradius / 2 steps for (int radius = unitlosradius * 2; radius <= maxradius; radius += unitlosradius / 2) { // calculate angle for a unitlosradius / 2 step at this radius. double anglestepradians = 2 * Math.Asin(unitlosradius / 2 / 2 / radius); for (double angleradians = 0; angleradians <= Math.PI * 2; angleradians += anglestepradians) { int unseenarea = 0; int searchmapx = unitmapx + (int)((double)radius * Math.Cos(angleradians)); int searchmapy = unitmapy + (int)((double)radius * Math.Sin(angleradians)); int thisareanumber = MovementMaps.GetInstance().GetArea(unitdef, new Float3(searchmapx * 16, 0, searchmapy * 16)); if (thisareanumber == currentunitarea) { if (csai.DebugOn) { DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 100, searchmapy * 16), unitlosradius); } foreach (Int2 point in circlepoints) { if (thisframecount - LastSeenFrameCount[searchmapx + point.x, searchmapx + point.y] > unseensmeansthismanyframes) { unseenarea++; } } if (unseenarea >= (circlepoints.GetUpperBound(0) + 1) * 8 / 10) { return(new Float3(searchmapx * 16, 0, searchmapy * 16)); } } } } return(null); }
void ExploreWith(int unitid) { bool destinationfound = false; Float3 currentpos = aicallback.GetUnitPos(unitid); MovementMaps movementmaps = MovementMaps.GetInstance(); IUnitDef unitdef = UnitDefListByDeployedId[unitid] as IUnitDef; int currentarea = movementmaps.GetArea(unitdef, currentpos); LosMap losmap = LosMap.GetInstance(); if (csai.DebugOn) { logfile.WriteLine("explorewith unit " + unitid + " " + unitdef.humanName + " area: " + currentarea); } /* * int numtriesleft = 30; // just try a few times then give up * // maybe there is a better way to do this? * while( !destinationfound ) * { * Float3 destination = GetRandomDestination(); * // logfile.WriteLine( "SpreadSearchWithSearchGrid attempt " + destination.ToString() ); * int mapx = (int)( destination.x / 16 ); * int mapy = (int)( destination.z / 16 ); * if( ( movementmaps.GetArea( unitdef, destination ) == currentarea && * losmap.LastSeenFrameCount[ mapx, mapy ] < recentmeansnumframes || numtriesleft <= 0 ) ) * { * logfile.WriteLine( "Looks good. Go. " + numtriesleft + " retriesleft" ); * if( csai.DebugOn ) * { * aicallback.CreateLineFigure( currentpos, destination,10,true,400,0); * aicallback.DrawUnit( "ARMFAV", destination, 0.0f, 400, aicallback.GetMyAllyTeam(), true, true); * } * aicallback.GiveOrder( unitid, new Command( Command.CMD_MOVE, destination.ToDoubleArray() ) ); * return; * } * numtriesleft--; * } */ // find nearest, area that hasnt had los recently //int maxradius = Math.Max( aicallback.GetMapWidth(), aicallback.GetMapHeight() ) / 2; //for( int radius = Float3 nextpoint = LosMap.GetInstance().GetNearestUnseen(currentpos, unitdef, 6000); if (nextpoint == null) { nextpoint = GetRandomDestination(); } aicallback.GiveOrder(unitid, new Command(Command.CMD_MOVE, nextpoint.ToDoubleArray())); }
// this is going to have to interact with all sorts of stuff in the future // for now keep it simple // for now we look for nearby buildings, then nearby enemy units with low speed, then anything public Float3 ChooseAttackPoint(Float3 ourpos) { bool gotbuilding = false; bool gotknownunit = false; double BestSquaredDistance = 100000000000; int bestid = 0; IUnitDef defforbestid = null; Float3 posforbestid = null; // logfile.WriteLine( "EnemySelector: checking mobile... " ); foreach (KeyValuePair <int, IUnitDef> kvp in enemycontroller.EnemyUnitDefByDeployedId) { int thisenemyid = kvp.Key; IUnitDef unitdef = kvp.Value; Float3 enemypos = aicallback.GetUnitPos(thisenemyid); //Float3 enemypos = EnemyMap.GetInstance(). // logfile.WriteLine( "Found building " + if (MovementMaps.GetInstance().GetArea(typicalunitdef, enemypos) == startarea) { if (Float3Helper.GetSquaredDistance(new Float3(0, 0, 0), enemypos) > 1) { double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, enemypos); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if (unitdef != null) { // logfile.WriteLine( "unitdef not null " + unitdef.humanName + " ismobile: " + unitdefhelp.IsMobile( unitdef ).ToString() ); // logfile.WriteLine( "gotbuilding = " + gotbuilding.ToString() ); if (gotbuilding) { if (!unitdefhelp.IsMobile(unitdef)) { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best building so far" ); bestid = thisenemyid; gotbuilding = true; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } else { if (unitdef.speed < maxenemyspeed) // if we already have building we dont care { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best known so far" ); bestid = thisenemyid; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } else // if unitdef unknown { // logfile.WriteLine( "gotknownunit = " + gotknownunit.ToString() ); if (!gotknownunit) // otherwise just ignore unknown units { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best unknown so far" ); bestid = thisenemyid; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } } } foreach (KeyValuePair <int, Float3> kvp in enemycontroller.EnemyStaticPosByDeployedId) { // logfile.WriteLine( "EnemySelector: checking static... " ); int thisenemyid = kvp.Key; Float3 enemypos = kvp.Value; double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, enemypos); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "EnemySelector: best distance so far" ); bestid = thisenemyid; gotbuilding = true; gotknownunit = true; posforbestid = enemypos; //defforbestid = unitdef; } } //if( enemycontroller.EnemyStaticPosByDeployedId.Contains( bestid ) ) // { // enemycontroller.EnemyStaticPosByDeployedId.Remove( bestid ); // } return(posforbestid); }
public void InitStartPos(Float3 startpos) { startarea = MovementMaps.GetInstance().GetArea(typicalunitdef, startpos); }
//int numOfUnits = 0; //IUnitDef[] unitList; //IUnitDef solarcollectordef; public void InitAI(IAICallback aicallback, int team) { Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); this.aicallback = aicallback; try{ this.Team = team; logfile = LogFile.GetInstance().Init(team); logfile.WriteLine("C# AI started v" + AIVersion + ", team " + team + " ref " + reference + " map " + aicallback.GetMapName() + " mod " + aicallback.GetModName()); if (File.Exists("AI/CSAI/debug.flg")) // if this file exists, activate debug mode; saves manually changing this for releases { logfile.WriteLine("Toggling debug on"); DebugOn = true; } if (DebugOn) { new Testing.RunTests().Go(); } InitCache(); PlayStyleManager.GetInstance(); LoadPlayStyles.Go(); metal = Metal.GetInstance(); CommanderController.GetInstance(); BuildTable.GetInstance(); UnitController.GetInstance(); EnemyController.GetInstance(); EnergyController.GetInstance(); MovementMaps.GetInstance(); BuildMap.GetInstance(); //FactoryController.GetInstance(); //RadarController.GetInstance(); //TankController.GetInstance(); //ScoutController.GetInstance(); //ConstructorController.GetInstance(); metal.Init(); BuildPlanner.GetInstance(); UnitController.GetInstance().LoadExistingUnits(); // need this if we're being reloaded in middle of a game, to get already existing units EnemyController.GetInstance().LoadExistingUnits(); StrategyController.GetInstance(); LoadStrategies.Go(); PlayStyleManager.GetInstance().ChoosePlayStyle("tankrush"); if (aicallback.GetModName().ToLower().IndexOf("aass") == 0 || aicallback.GetModName().ToLower().IndexOf("xtape") == 0) { aicallback.SendTextMsg("C# AI initialized v" + AIVersion + ", team " + team, 0); aicallback.SendTextMsg("Please say '.csai help' for available commands", 0); PlayStyleManager.GetInstance().ListPlayStyles(); //CommanderController.GetInstance().CommanderBuildPower(); } else { aicallback.SendTextMsg("Warning: CSAI needs AA2.23 or XTA7 to run correctly at this time", 0); logfile.WriteLine("*********************************************************"); logfile.WriteLine("*********************************************************"); logfile.WriteLine("**** ****"); logfile.WriteLine("**** Warning: CSAI needs AA2.23 or XTA7 to run correctly at this time ****"); logfile.WriteLine("**** ****"); logfile.WriteLine("*********************************************************"); logfile.WriteLine("*********************************************************"); } } catch (Exception e) { logfile.WriteLine("Exception: " + e.ToString()); aicallback.SendTextMsg("Exception: " + e.ToString(), 0); } }
public Float3 ClosestBuildSite(IUnitDef unitdef, Float3 approximatepos, int maxposradius, int mindistancemapunits) { // ok, so plan is we work our way out in a kindof spiral // we start in centre, and increase radius, and work around in a square at each radius, until we find something int centrex = (int)(approximatepos.x / 8); int centrey = (int)(approximatepos.z / 8); //int radius = 0; int radius = mindistancemapunits; int unitsizexwithmargin = unitdef.xsize + 2 * BuildMargin; int unitsizeywithmargin = unitdef.ysize + 2 * BuildMargin; if (unitdefhelp.IsFactory(unitdef)) { unitsizeywithmargin += 8; centrey += 4; } BuildMap buildmap = BuildMap.GetInstance(); MovementMaps movementmaps = MovementMaps.GetInstance(); // while( radius < mapwidth || radius < mapheight ) // hopefully we never get quite this far... while (radius < (maxposradius / 8)) { // logfile.WriteLine( "ClosestBuildSite radius " + radius ); for (int deltax = -radius; deltax <= radius; deltax++) { for (int deltay = -radius; deltay <= radius; deltay++) { if (deltax == radius || deltax == -radius || deltay == radius || deltay == -radius) // ignore the hollow centre of square { // logfile.WriteLine( "delta " + deltax + " " + deltay ); bool positionok = true; // go through each square in proposed site, check not build on for (int buildmapy = centrey - unitsizeywithmargin / 2; positionok && buildmapy < centrey + unitsizeywithmargin / 2; buildmapy++) { //string logline = ""; for (int buildmapx = centrex - unitsizexwithmargin / 2; positionok && buildmapx < centrex + unitsizexwithmargin / 2; buildmapx++) { int thisx = buildmapx + deltax; int thisy = buildmapy + deltay; if (thisx < 0 || thisy < 0 || thisx >= mapwidth || thisy >= mapwidth || !buildmap.SquareAvailable[thisx, thisy] || !movementmaps.vehiclemap[thisx / 2, thisy / 2]) { //logfile.WriteLine( "check square " + buildmapx + " " + buildmapy + " NOK" ); positionok = false; // logline += "*"; } else { // logline += "-"; } //logfile.WriteLine( "check square " + buildmapx + " " + buildmapy + "Ok" ); } // logfile.WriteLine( logline ); } // logfile.WriteLine(""); if (positionok) { return(new Float3((centrex + deltax) * 8, 0, (centrey + deltay) * 8)); } } } } radius++; } return(null); }
// note: need to check compatible area public Float3 GetNearestUnseen(Float3 currentpos, IUnitDef unitdef, int unseensmeansthismanyframes) { LosMap losmap = LosMap.GetInstance(); IAICallback aicallback = CSAI.GetInstance().aicallback; int mapwidth = aicallback.GetMapWidth(); int mapheight = aicallback.GetMapHeight(); int currentunitarea = MovementMaps.GetInstance().GetArea(unitdef, currentpos); int losmapwidth = losmap.LastSeenFrameCount.GetUpperBound(0) + 1; int losmapheight = losmap.LastSeenFrameCount.GetUpperBound(0) + 1; int maxradius = (int)Math.Sqrt(losmapheight * losmapheight + losmapwidth * losmapwidth); int unitlosradius = (int)unitdef.losRadius; // this is in map / 2 units, so it's ok Int2[] circlepoints = CreateCirclePoints(unitlosradius); int bestradius = 10000000; int bestarea = 0; Float3 bestpos = null; int unitmapx = (int)(currentpos.x / 16); int unitmapy = (int)(currentpos.y / 16); int thisframecount = aicallback.GetCurrentFrame(); // step around in unitlosradius steps for (int radiuslosunits = unitlosradius * 2; radiuslosunits <= maxradius; radiuslosunits += unitlosradius) { // calculate angle for a unitlosradius / 2 step at this radius. // DrawingUtils.DrawCircle(currentpos, radiuslosunits * 16); double anglestepradians = 2 * Math.Asin((double)unitlosradius / 2 / (double)radiuslosunits); //csai.DebugSay("anglestepradians: " + anglestepradians); //return null; for (double angleradians = 0; angleradians <= Math.PI * 2; angleradians += anglestepradians) { int unseenarea = 0; int searchmapx = unitmapx + (int)((double)radiuslosunits * Math.Cos(angleradians)); int searchmapy = unitmapy + (int)((double)radiuslosunits * Math.Sin(angleradians)); if (searchmapx >= 0 && searchmapy >= 0 && searchmapx < (mapwidth / 2) && searchmapy < (mapheight / 2)) { // if (csai.DebugOn) // { // int groupnumber = DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 50 + aicallback.GetElevation( searchmapx * 16, searchmapy * 16 ), searchmapy * 16), unitlosradius * 16); // aicallback.SetFigureColor(groupnumber, 1, 1, 0, 0.5); // } int thisareanumber = MovementMaps.GetInstance().GetArea(unitdef, new Float3(searchmapx * 16, 0, searchmapy * 16)); if (thisareanumber == currentunitarea) {// //if (csai.DebugOn) // { // int groupnumber = DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 100, searchmapy * 16), unitlosradius * 16); // aicallback.SetFigureColor(groupnumber, 1, 1, 0, 0.5); // } foreach (Int2 point in circlepoints) { int thismapx = searchmapx + point.x; int thismapy = searchmapy + point.y; if (thismapx >= 0 && thismapy >= 0 && thismapx < mapwidth / 2 && thismapy < mapheight / 2) { if (thisframecount - losmap.LastSeenFrameCount[thismapx, thismapy] > unseensmeansthismanyframes) { unseenarea++; } } } if (unseenarea >= (circlepoints.GetUpperBound(0) + 1) * 8 / 10) { int groupnumber = DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 100 * aicallback.GetElevation(searchmapx * 16, searchmapy * 16), searchmapy * 16), unitlosradius * 16); aicallback.SetFigureColor(groupnumber, 1, 0, 1, 0.5); return(new Float3(searchmapx * 16, 0, searchmapy * 16)); } // return new Float3(searchmapx * 16, 0, searchmapy * 16); // for debugging, remove later } } } } return(null); }