[AI Code] Jungle Bots

Colten88·8/29/2015, 4:53:47 PM·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 X8/29/2015, 5:40:56 PM2 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.

KatoDragon8/29/2015, 6:41:06 PM2 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.

XVI Jake IVX8/30/2015, 8:44:57 AM2 votes

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

Floooooooooooops8/31/2015, 6:57:03 AM2 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???

TurquoiseYoshi8/30/2015, 4:03:57 PM1 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.