Skip to content

Instantly share code, notes, and snippets.

@sunzenshen
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sunzenshen/69162943e479c78cf86a to your computer and use it in GitHub Desktop.
Save sunzenshen/69162943e479c78cf86a to your computer and use it in GitHub Desktop.
CodeCombat Greed Competition Entry
// This code runs once per frame. Build units and command collectors!
// Destroy the enemy base within 180 seconds.
// Run over 4000 statements per call and chooseAction will run less often.
var base = this;
/////// 0. Determine which team is in play
// Ogres Team
var collectorType = 'peon';
var scoutType = 'munchkin';
var nobleType = 'ogre';
var casterType = 'shaman';
var flyerType = 'fangrider';
var titanType = 'brawler';
/*
// Humans Team
var collectorType = 'peasant';
var scoutType = 'soldier';
var nobleType = 'knight';
var casterType = 'librarian';
var flyerType = 'griffin-rider';
var titanType = 'captain';
*/
/////// 1. Command collectors to grab coins and gems. ///////
// You can only command collectors, not fighting units.
// You win by gathering gold more efficiently to make a larger army.
// Click on a unit to see its API.
var items = base.getItems();
var collectors = base.getByType(collectorType);
// At the time, I thought that collectors could only move toward an item,
// and not towards an xy coordinate.
var topLeft;
var topRight;
var lowLeft;
var lowRight;
for (var collectorIndex = 0; collectorIndex < collectors.length; collectorIndex++) {
var collector = collectors[collectorIndex];
var item = collector.getNearest(items);
var itemIndex = 0;
var itemCandidate;
// Figure out which items are in the 4 corners of the map.
// This was before I heard an XY coordinate could be used for movement.
if (collectorIndex === 0) {
for (itemIndex = 0; itemIndex < items.length; itemIndex++) {
itemCandidate = items[itemIndex];
topLeft = item.pos;
topRight = item.pos;
lowLeft = item.pos;
lowRight = item.pos;
if ((lowLeft.x > itemCandidate.pos.x) && (lowLeft.y > itemCandidate.pos.y)) {
lowLeft = itemCandidate.pos;
}
if ((topRight.x < itemCandidate.pos.x) && (topRight.y < itemCandidate.pos.y)) {
topRight = itemCandidate.pos;
}
if ((lowRight.x < itemCandidate.pos.x) && (lowRight.y > itemCandidate.pos.y)) {
lowRight = itemCandidate.pos;
}
if ((topLeft.x > itemCandidate.pos.x) && (topLeft.y < itemCandidate.pos.y)) {
topLeft = itemCandidate.pos;
}
}
}
// Determine if collectors are too close together.
var clusterDistance = 9999;
for (var collector2Index = 0; collector2Index < collectorIndex; collector2Index++) {
var collector2 = collectors[collector2Index];
if (clusterDistance > collector2.distance(collector)) {
clusterDistance = collector2.distance(collector);
}
}
if((clusterDistance < 50)) {
// If a collector is too close to another,
// then try to move to a pre-assigned quadrant.
if (collectorIndex === 0) {
base.command(collector, 'move', topLeft);
} else if (collectorIndex === 1) {
base.command(collector, 'move', lowRight);
} else if (collectorIndex === 2) {
base.command(collector, 'move', lowLeft);
} else if (collectorIndex === 3) {
base.command(collector, 'move', topRight);
}
} else if (collector.distance(item) > 10*item.bountyGold) {
// If current collector is not near any items,
// figure out which direction most of the items are.
var xWeight = 0;
var yWeight = 0;
for (itemIndex = 0; itemIndex < items.length; itemIndex++) {
itemCandidate = items[itemIndex];
if (collector.pos.x < itemCandidate.pos.x){
xWeight = xWeight + itemCandidate.bountyGold;
} else {
xWeight = xWeight - itemCandidate.bountyGold;
}
if (collector.pos.y < itemCandidate.pos.y){
yWeight = yWeight + itemCandidate.bountyGold;
} else {
yWeight = yWeight - itemCandidate.bountyGold;
}
}
// Then command the collector to move towards the direction with the most items.
if (xWeight > 0) {
if (yWeight > 0) {
base.command(collector, 'move', topRight);
} else { // yWeight <= 0
base.command(collector, 'move', lowRight);
}
} else { // xWeight <= 0
if (yWeight > 0) {
base.command(collector, 'move', topLeft);
} else { // yWeight <= 0
base.command(collector, 'move', lowLeft);
}
}
} else {
// Within a threshold based on item value, move the collector to the nearest item.
base.command(collector, 'move', item.pos);
}
}
/////// 2. Decide which unit to build this frame. ///////
// Collectors can gather gold; other units auto-attack the enemy base.
// You can only build one unit per frame, if you have enough gold.
var type;
if (base.built.length === 0) {
type = collectorType;
}
else {
if ((base.health < 300) ||
(base.gold > 100) ||
(base.getByType(scoutType).length > 1)) {
// I went with a set build order that is triggered on attack or economic threshold.
if(base.getByType(scoutType).length < 3) {
type = scoutType;
} else if(base.getByType(nobleType).length < 2) {
type = nobleType;
} else if(base.getByType(casterType).length < 1) {
type = casterType;
} else if(base.getByType(flyerType).length < 1) {
type = flyerType;
} else {
type = casterType;
}
} else if (base.getByType(collectorType).length < 2) {
type = collectorType;
} else if ((base.getByType(collectorType).length >= 2) &&
(base.getByType(scoutType).length < 1)) {
// Given a self-imposed max of 2 collectors,
// a light unit is sent to poke the enemy's defenses.
type = scoutType;
}
}
var toBuild = base.buildables[type];
if (type && (base.gold >= toBuild.goldCost)) {
base.build(type);
}
@sunzenshen
Copy link
Author

This was my entry for CodeCombat's Greed competition. Despite its half finished state, I ended up winning a free E-book from O'Reilly. My final rank on the Ogres team was #56 with 269 wins, 129 losses, and 9 ties.

Check out the "revisions" viewer for the original competition submission, as well as my updates since then.

Final ladder rankings:
http://codecombat.com/play/ladder/greed#winners

A writeup on approaches more skilled than mine:
http://blog.codecombat.com/a-31-trillion-390-billion-statement-programming-war-between-545-wizards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment