44
13
This challenge has ended. To see the final scores of the competitors, click here
In this challenge, each submission is one bot. Each bot should be a Javascript function. Bots will fight to obtain the highest total worth in gold. Gold can be farmed, or earned from killing other bots, and is used to upgrade healing, attacking, shielding, and farming.
Objective:
Over a number of rounds containing up to 1000 turns (ends when only one bot is left), the bot with the highest total worth (the sum of all gold obtained) is the winner.
Turns:
In each turn, every bot which is alive (>0 HP) will be run once. It can return a move, which can be one of the following:
- Heal: Regains HP
- Attack: Removes HP from another bot
- Shield: Defends against later attacks
- Stun: Skips another bot's next turn
- Farm: Earns gold at the cost of HP
- Upgrade: Make certain moves better
All bots will return their move before any are executed, so a stun, heal, attack, shield, etc. will not affect any bots moving later in that turn. For example, if Bot A stuns Bot B, and Bot B is after Bot A in the turn order, Bot B will still move later in that same turn and the stun will occur on the next turn.
Combat, Farming, and Upgrading:
Each bot has a maximum HP of 100, and an assigned UID between 0 and 99. This UID changes after every round, and is how bots keep track of each other.
Healing is one of the simplest moves, adding an amount of HP determined by its level (starts at 5 HP). A bot cannot heal past 100 HP.
Attacking a bot by its UID is another possible move, with a base damage of 5 HP at level 0. Bots can also be stunned, skipping their next turn, which also uses UIDs.
Bots have additional shield HP, which has no limit. This shield HP will absorb damage from direct attacks from other bots, and is added by shielding. At level 0, shielding adds 5 shield HP.
Farming will earn 5 gold at level 0, at the cost of 2 HP. This 2 HP cannot be shielded. The only use for gold (beyond winning) is to upgrade moves. Healing, attacking, and shielding have a base value of 5 HP, and farming starts at 5 gold. Each of those moves have individual levels, which start at 0. These formulas will determine the value in HP or gold of a move, where L is the level:
- Healing:
L + 5
- Attacking:
1.25L + 5
- Shielding:
1.5L + 5
- Farming:
2L + 5
The cost of upgrading any move is the same for a certain level, and is determined by 2.5L² + 2.5L + 10
, where L is the current level. A bot can use the function cost(currentLevel)
as a shortcut to determine this.
Bots start with 25 gold, allowing them to quickly upgrade either two moves to level 1, or one move to level 2. This beginning gold does not count towards a bots total worth. Killing a bot gives you half of its total worth in gold, rounded up, and if two bots kill another in the same turn, they both get the reward.
Input/Output:
In order to communicate with the controller, the return value of the function is used to send move information. One of these should be returned:
- Heal:
heal()
- Attack:
attack(uid)
- Shield:
shield()
- Stun:
stun(uid)
- Farm:
farm()
- Upgrade:
upgrade("heal" / "attack" / "shield" / "farm")
To skip a turn (do nothing), return nothing, or return a falsy value.
To get the current turn number (starts at 1), use turn()
.
The arguments of your function will include information about your bot, UIDs of other bots, and between-turn storage. The first argument is an object with the following properties: uid
, hp
, gold
, and shield
. These are copies of your bot's current information. There is also an nested object levels
, with the level numbers of heal
, attack
, shield
, and farm
.
The second argument is a shuffled array of all alive bots other than yours, formatted as an object containing properties uid
, hp
(plus shield), worth
, and attack
(attack level). The third argument is an empty object which can be used for between-turn storage.
Example Bots:
This bot will farm until it can upgrade its attack to level 5, then attack a random bot each turn until it dies (or wins). Not very effective due to lack of healing/shielding.
function freeTestBotA(me, others, storage) {
if (me.levels.attack < 5) {
if (me.gold < cost(me.levels.attack))
return farm();
return upgrade("attack");
}
return attack(others[0].uid);
}
This bot has two modes: offensive and defensive. It will either stun a random bot or heal when in defensive mode, and it will either attack or shield when in offensive mode. It will attempt to upgrade its attacks whenever possible.
function freeTestBotB(me, others, storage) {
if (me.gold >= cost(me.levels.attack))
return upgrade("attack");
if (me.hp < 50)
if (Math.random() < 0.5)
return stun(others[0].uid);
else
return heal();
else
if (Math.random() < 0.5)
return attack(others[0].uid);
else
return shield();
}
Rules:
- Standard Loopholes forbidden
- Bots may not read, modify, or add any variables outside of their scope, may not attempt to cheat, and may not call any controller-defined or DOM functions
- Return value must be falsy, or one of the above function outputs
- Bots should not be designed to target a specific bot, but can be designed to take advantage of common strategies
- Bots may not attack themselves (discovered due to a comment by @Ness)
- Bots must be sufficiently different from any other bots that they can be reasonably considered separate entries
- Teaming is now not allowed
- Controller can be found here
- Chatroom
New Controller Debugging:
Using the file gold-battle-log.js
, you can set the value of the debug
property of a bot in botData
to 0 (no logging), 1 (log moves), or 2 (log moves, hp, gold, levels, etc.)
Challenge ends at 1700 UTC on Friday, August 9th
Comments are not for extended discussion; this conversation has been moved to chat.
– James – 2019-08-02T16:25:37.953Note: Please use the chatroom instead of commenting here! – Redwolf Programs – 2019-08-02T16:31:03.130
4
Created a gist with all bots. https://gist.github.com/Draco18s/2efbf95edcf98d6b1f264e26bbb669d1 I will endeavor to keep it updated (but if not it's a decent start).
– Draco18s no longer trusts SE – 2019-08-04T14:52:05.5404Auto-updating controller with bots included: https://www.redwolfprograms.com/koth – Redwolf Programs – 2019-08-07T15:36:41.097
4I'm voting to close this question because it's already de-facto closed to new answers ("This challenge has ended. To see the final scores ...") – pppery – 2019-09-03T20:29:13.907
3@pppery Could you not? I'd be fine with non-competitive answers, and the
[closed]
at the end is likely to make casual viewers skip over reading my challenge since they;d assume it's low quality or off-topic. – Redwolf Programs – 2019-09-04T03:11:13.823You are not permitted to override the sitewide policy that answers must be serious contenders. No newly-posted answer can be a serious contender given that it is "non-competiive" Given that, no valid new answer to this question can be posted. The [closed] status serves to enforce that already-present social restriction technically, not to drive away casual viewers. Also, even if I wanted to, I can't "not"; I already case a close vote when I made that comment and 3 other users have agreed with me in the review queue. – pppery – 2019-09-04T03:30:29.980
5@pppery I've never heard of a challenge being closed for being finished until today, and I'd argue the social restriction you want to enforce doesn't even exist. There's no need to close it, and I don't want it closed. To me, that seems like closing for the sake of closing, rather than for the good of the site. If someone wants to post an answer to an old question, they should be able to. There's no note after the serious contender rule saying it has to be a serious contender when it's posted; an answer can still be a serious contender for the challenge even if it's not a contender for winning – Redwolf Programs – 2019-09-04T03:35:48.950