Lesson 6 - Shields
Introduction
Congratulations on making it this far! We've come a long way since Lesson 1 :) As a reward, your Dragons have been upgraded with a new ability: Shields. This will come in handy, because in this quest... enemy Dragons shoot back.In this Lesson, you will learn how to master your Dragon's Shields. If you succeed, you will be able to defeat two enemy Dragons with only one Dragon.
Shields
Dragons have health points and shield points. Shields absorb damage first, but when shields are gone, damage starts eating up health points. Shields can regenerate when a dragon is not taking damage. When a dragon has no more health points, it falls out of the sky and is out of the game.So, since shields regenerate, it is a good idea to manage your Dragon's shield energy. As much as possible, you want to absorb damage with your shields and save your health points.
Check shields
Your Dragon's shields can absorb quite a bit of damage. But they can only take so many hits before they run out of energy. So, you probably want to keep an eye on your shields so that you can get out of trouble before your shields fall.First, some info on shields:
- Every
unit
has attributes:unit.shields
andunit.maxShields
. unit.maxShields
is the maximum shield energy your Dragon can have. This number does not change.unit.shields
is the current shield energy of your Dragon. When the game starts, this number is the same asunit.maxShields
. When your Dragon takes damage,unit.shields
can drop to zero.
With these ingredients, we can make a new function to check if a Dragon's shield energy is low:
function isShieldEnergyLow(dragon)
{
if (dragon.maxShields == 0)
{
// this Dragon has no shields at all
return true;
}
// compute percent of shield energy remaining
var shieldPct = dragon.shields / dragon.maxShields * 100;
// if shield energy is less than 20%,
// say that shields are low
if (shieldPct < 20)
return true;
// shields are greater than 20%,
// say that shields are not low
return false;
}
Helper.computeRetreatPoint()
Now that we have a way to check if a Dragon's shield energy is low, what do we do if we notice a Dragon in trouble?
Yup, EVASIVE MANEUVERS! Retreat. Escape danger. Live to fight another day.
To do that, we can use the functon below:
Helper.computeRetreatPoint(unitPos, enemyPos)
- Pass this function your Dragon's position (
unitPos
) and an enemy Dragon's position (enemyPos
). It will then tell you where to move to fly away from the enemy. - You can then call
Game.moveTo()
to get your Dragon out of trouble.
Retreat if
Dragon has weak shields
Remember our friend if-else
from the last lesson? That's what we'll use to tell your Dragon to retreat... if
its shield energy is low.
We'll combine the two functions we just saw above:
if (isShieldEnergyLow(dragon))
{
var escapePos = Helper.computeRetreatPoint(dragon.pos, enemy.pos);
Game.moveTo(dragon.id, escapePos.x, escapePos.y);
}
Shield mastery
The trick to improving your Dragon's defense is to take advantage of your shields' regenerative powers. Find the balance between offense and defense. If you can keep escaping danger, your shields can keep regenerating to save your health points (which don't regenerate). And the more Dragons you keep alive, the better your chances of winning each game.Now let's update your Dragon A.I. code with everything we've learned in this lesson:
function isShieldEnergyLow(dragon)
{
if (dragon.maxShields == 0)
{
// this Dragon has no shields at all
return true;
}
// compute percent shield energy remaining
var shieldPct = dragon.shields / dragon.maxShields * 100;
// if shield energy is less than 20%,
// say that shields are low
if (shieldPct < 20)
return true;
// shields are greater than 20%,
// say that shields are not low
return false;
}
function run(state)
{
// get array of all my units
var myUnits = Helper.getMyUnits(state);
// get the first Dragon in the array
var dragon = myUnits[0];
// get first Dragon's ID
var dragonId = dragon.id;
// get this Dragon's closest enemy
var enemyFound = Helper.getClosestEnemy(state, dragon);
if (!enemyFound)
{
// yay! no more enemies -- nothing left to do.
// calling "return" stops this function from
// executing any other code below.
return;
}
// get enemy Dragon's ID
var enemy = enemyFound.unit;
var enemyId = enemy.id;
// ******** NEW! ********
// Choose offense or defense.
// Decide to move Dragon toward or away from enemy
if (isShieldEnergyLow(dragon))
{
// shield is low, retreat!
var escapePos = Helper.computeRetreatPoint(dragon.pos, enemy.pos);
Game.moveTo(dragon.id, escapePos.x, escapePos.y);
}
else
{
// move Dragon to enemy Dragon's position
// (but only if enemy is too far away)
if (enemyFound.dist > 350)
{
// move toward enemy -- it's more than 350 units away
Game.moveTo(dragonId, enemy.pos.x, enemy.pos.y);
}
}
// attack!
Game.attack(dragonId, enemyId);
}
Awesome, young master :) Your Dragon is getting powerful...
Cheatcode
Spoiler alert! Click to reveal full solution.
<!DOCTYPE html>
<html>
<body>
<div id="display">hello</div>
<script>
function isShieldEnergyLow(dragon)
{
if (dragon.maxShields == 0)
{
// this Dragon has no shields at all
return true;
}
// compute percent shield energy remaining
var shieldPct = dragon.shields / dragon.maxShields * 100;
// if shield energy is less than 20%,
// say that shields are low
if (shieldPct < 20)
return true;
// shields are greater than 20%,
// say that shields are not low
return false;
}
function run(state)
{
// get array of all my units
var myUnits = Helper.getMyUnits(state);
// get the first Dragon in the array
var dragon = myUnits[0];
// get first Dragon's ID
var dragonId = dragon.id;
// get this Dragon's closest enemy
var enemyFound = Helper.getClosestEnemy(state, dragon);
if (!enemyFound)
{
// yay! no more enemies -- nothing left to do.
// calling "return" stops this function from
// executing any other code below.
return;
}
// get enemy Dragon's ID
var enemy = enemyFound.unit;
var enemyId = enemy.id;
// ******** NEW! ********
// Choose offense or defense.
// Decide to move Dragon toward or away from enemy
if (isShieldEnergyLow(dragon))
{
// shield is low, retreat!
var escapePos = Helper.computeRetreatPoint(dragon.pos, enemy.pos);
Game.moveTo(dragon.id, escapePos.x, escapePos.y);
}
else
{
// move Dragon to enemy Dragon's position
// (but only if enemy is too far away)
if (enemyFound.dist > 350)
{
// move toward enemy -- it's more than 350 units away
Game.moveTo(dragonId, enemy.pos.x, enemy.pos.y);
}
}
// attack!
Game.attack(dragonId, enemyId);
}
Game.register(run);
</script>
</body>
</html>