[AI Code] Jungle Bots

Colten88··13 votes·1,045 views

I, for one, like to try out new strategies and unusual builds on the bots to get a feel for how they work out without needing to worry about the heaps of insults and accusations that tend to get thrown around by this game's overly competetive aspect (who also include those who yell at others to make up for their own shortcommings.)

Anyway, rant aside, I would like to see the bots use the jungle so as to better approximate a real match. Now, I don't work for Riot and I don't know the exact manner in which they coded the game, but I have attempted to write a bit of pseudo-code that would explain how the AI could work for a jungling bot.

I've broken my pseudo-code into a couple sections:

  • Actual jungling functions for clearing camps.

  • Ganking functions.

  • Champion-specific override functions (using Maokai Maokai as the example).

So, without further ado:

// New Variables float gankThreshold = 1.5; //Determined by difficulty. Higher difficulty adjusts this based on the success of previous ganks. float recallThreshold = 0.30; String jungleSide = "";

//=====General Jungle Functions===== void clearGolemSide() { jungleGolem(); jungleFrog(); jungleWolves(); if (me.blueTeam) checkUpperGanks(); else { checkDragon(); checkLowerGanks(); } } // ---------------------------------------------------------------------------------------------------- void clearLizardSide() { jungleLizard(); jungleBirds(); jungleMiniGolems(); if (me.blueTeam) { checkDragon(); checkLowerGanks(); } else checkUpperGanks(); } // ---------------------------------------------------------------------------------------------------- void checkRecall() checkRecall(0.0); // ---------------------------------------------------------------------------------------------------- void checkRecall(float travelTime) ( if ((me.health + me.healthRegen x travelTime)/me.healthMax < recallThreshold) recall(); ) // ---------------------------------------------------------------------------------------------------- void checkJungleCamp(JungleCamp camp) { if(camp.spawnTime <= travelTime(me.location, camp.center() +3 seconds) jungleCampClear(camp); } // ---------------------------------------------------------------------------------------------------- void checkDragon() { JungleCamp camp = Map.jungleCamp("Dragon", jungleSide); if(camp.spawnTime <= travelTime(me.location, camp.center() +10 seconds) { // I may want another if statement here to ensure that bots don't take on a dragon when under leveled or under fed. me.ping("Help", camp.center()); jungleDragonClear(); } }

//=====Jungle Camp Functions===== void jungleGolem() { checkJungleCamp(Map.jungleCamp("Golem", jungleSide); } void jungleFrog() { jungleCampClear(Map.jungleCamp("Frog", jungleSide); } void jungleWolves() { jungleCampClear(Map.jungleCamp("Wolves", jungleSide); } void jungleLizard() { checkJungleCamp(Map.jungleCamp("Lizard", jungleSide); } void jungleBirds() { jungleCampClear(Map.jungleCamp("Birds", jungleSide); } void jungleMiniGolems() { jungleCampClear(Map.jungleCamp("Mini Golems", jungleSide); } // ---------------------------------------------------------------------------------------------------- void jungleCampClear(JungleCamp camp) // Often overridden by champion-specific function. { checkRecall(travelTime(me.location, camp.center()));

int i =0;

me.attackMove(camp.center());
// Could then use me.attackMove(me.path(-me.attackRange)); to cause ranged junglers to stand back a bit.

while(i <3) // I&#039;m aware of the irony.
{
    if(camp.monster[i].name == "Big Golem" || camp.monster[i].name == "Big Lizard" || me.spell("smite").charges ==2) me.spell("smite", camp.monster[i]);
    me.attackRoutineNoUltimate(camp.monster[i]);
    ++i;
}

} // ---------------------------------------------------------------------------------------------------- void jungleDragonClear() // Often overridden by champion-specific function. { checkRecall(travelTime(me.location, camp.center()));

JungleCamp camp = Map.jungleCamp("Dragon", jungleSide);

me.attackMove(camp.center());

me.ping("Attack", camp.center());
me.spell("smite", camp.monster[0]);
me.attackRoutine(camp.monster[0]);

}

//=====Gank Functions===== void checkUpperGanks() { float top, mid;

top = gankability(top)
mid = gankability(mid)

if (top > mid) gankTop();
else gankMid();

} // ---------------------------------------------------------------------------------------------------- void checkLowerGanks() { float mid, bottom;

mid = gankability(mid)
bottom = gankability(bottom)

if (bottom > gankThreshold && bottom > mid) gankBottom();
else if (mid > gankThreshold) gankMid();

} // ---------------------------------------------------------------------------------------------------- float gankability(string lane) //Top, Mid, Bottom { int i =0; float gankability =0; Champion[] enemyChampion = Vision.getEnemyChampions(lane); Champion[] allyChampion = Vision.getAllyChampions(lane);

while(enemyChampion[i] != null)
{
         gankability -= enemyChampion[i].healthPercent() x enemyChampion[i].goldSpent(); //Should I use goldEarned() as a measure of skill or goldSpent() as a measure of power?
         ++i;
}
i =0;
while(allyChampion[i] != null)
{
         gankability += allyChampion[i].healthPercent() x allyChampion[i].goldSpent();
         ++i;
}
gankability += my.healthPercent() x my.goldSpent();
return gankability;

}

//=====Champion Specific Functions===== void junglerInitialize(float gankSkill, float survivability) { gankThreshold = gankSkill; recallThreshold = survivability;

if(me.blueTeam) jungleSide = "Blue Team";
else jungleSide = "Red Team";

} // ---------------------------------------------------------------------------------------------------- void junglerEarlyRoutine() // BlueFirst { void clearGolemSide(); void clearLizardSide(); } // OR void junglerEarlyRoutine() // RedFirst { void clearLizardSide(); void clearGolemSide(); } // ---------------------------------------------------------------------------------------------------- void jungleCampClear(JungleCamp camp) // Maokai override { checkRecall(travelTime(me.location, camp.center()));

int i =0;

me.attackMove(camp.center());

// Maokai pre-sapling
while(camp.spawnTime > me.ability("e").cooldownTime() && camp.spawnTime < 30) me.ability(e, camp.center());

while(i <3)
{
    if(camp.monster[i].name == "Big Golem" || camp.monster[i].name == "Big Lizard" || me.spell("smite").charges ==2) me.spell("smite", camp.monster[i]);
    me.attackRoutineNoUltimate(camp.monster[i]);
    /*while(camp.monster[i] <> null)
    {
        me.ability("e", camp.monster[i]);
        me.ability("w", camp.monster[i]);
        me.ability("q", camp.monster[i]);
        me.autoAttack(camp.monster[i]);
    }*/
    ++i;
}

} // ---------------------------------------------------------------------------------------------------- void jungleDragonClear() // Maokai override { checkRecall(travelTime(me.location, camp.center()));

JungleCamp camp = Map.jungleCamp("Dragon", jungleSide);

me.attackMove(camp.center());

// Maokai pre-sapling
while(camp.spawnTime > me.ability("e").cooldownTime() && camp.spawnTime < 30) me.ability(e, camp.center());

me.ping("Attack", camp.center());
me.spell("smite", camp.monster[0]);
me.attackRoutine(camp.monster[0]);

}

// End of Code

PS. Sorry about the lack of indentation, I'm not sure how to force indentation. I've put the function names in bold to help distinguish them and I've included separating lines between the larger functions.

9 Comments

Archon X2 votes

I'm going to be honest, I'd only support this for 'advanced' bots. Jungling is extremely complicated for new players. When I was new a few years ago I actually lost a few games against intermediate bots that were running 2 top, so them having a jungler that would gank would possibly make the mode too difficult for those who are not smurfs/bored level 30 people.

Valderis Vandala1 votes

Or just add a third difficulty level, only bots on that level use jungle, problem solved.

Archon X1 votes

It would be a fourth, don't forget intro bots. And yeah I would support it if it was separate from intermediate, in my opinion jungle bots are too advanced for genuine noobs.

Valderis Vandala1 votes

To be honest I doubt jungle bots would be more difficult to fight. I think they might be ridiculously more easy to fight.

There is only so much Riot can do with its AI, everything it does is very easy to abuse, I suspect that jungler IA will be exceptionally easy to abuse due to them having to fight the jungle monsters and being susceptible to counter jungling. A Jungler can fall off in power immensely compared to laners with little hope for recovery if the AI can't account for it.

I suspect it's too much of a pain in the ass to code to be considered worth while for Riot. Doesn't chance that we should keep bothering them about it because it is ridicules that this game doesn't even have proper AI that actually plays the full game.

KatoDragon2 votes

I would like to say that they really haven't fixed the bugs of the intermediate bots yet (they don't flash, teleport). This isn't a bad code, but I think the jungle is really complicated season 5. (Choosing smites, what to smite, 2 charges of smite, where to gank, how to gank) It's just too much. And riot's just focusing on Champion updates right now. Nothing on bots.

Archon X2 votes

you know an interesting thing about intermediate bots is that playing as Jinx they dodge every single W with perfect precision, but walk into E like they don't even see it.

XVI Jake IVX2 votes

Im guessing you spent quiet alot of time on this good job!

Floooooooooooops2 votes

Guys lets take a minute to honor this wonderful man for actually writing script for a game. That. Is. Awesome. and this is coming from someone who understands how difficult coding can sometimes be(I take IT as an elective). Also why aren't you working at Riot yet???

TurquoiseYoshi1 votes

As somebody who just took an intro programming class, I'm really impressed by this. Also, I would only put this as an option in Intermediate bots. Intro and Beginner are too low-level.

More from Maps & Modes

More by Colten88