Halite Gold, in less than twenty lines.

Can you write a top 20 Halite bot in less than 20 lines of code?

New Years Eve, I had some time free, so I started a halite bot from scratch. I wanted to write the simplest possible competent bot. To my surprise, the new bot got in the top 20. I was freaked out.

In fact, now with submissions closed the end of the Halite contest, there's a bot in the top 20 that is substantially similar to this.

How does it work?

It's silly, stupid, simple.

Here's a game map:

Score the map

We'll assign a score to all border squares.

We have a production multiplier, and a score multiplier. The constant at the end doesn't do anything - it's just to make the scores look nice to human eyes.

		map.borders.each do |site|
			site.score = site.production * 5 - (site.strength * 7 / 10) + 50
		end

Here are the border scores shown on the map.

	r.site_values(map) do
		map.sites_a.map{|s| [s, s.score] if s.score}
	end
7 10 -1
13 21 17
-3 32
-59 37
-51 38
-19 37
-11 28
5 30
10 15 14
7 5 0 -3
21 -4
30 0
31 45 12
45 47
48 51
44

Then move scores inwards.

We'll use a priority queue that lets us pop the next highest scoring site in the queue. For that site, we'll flow down a score to each unscored neighbor, and add that neighbor to the queue.

		pq = PQueue.new(map.border){ |a,b| a.score > b.score }			
		while site = pq.pop
			map.neighbors_with_directions_a(site).each do |ns, d|
				next if ns.owner != tag or ns.score
				ns.score = site.score - ns.production - 2
				ns.source_d = map.reverse_direction(d)
				pq.push ns
			end
		end

Here's the map, with our interior filled with scores.

	r.site_values(map) do
		map.sites_a.map{|s| [s, s.score] if s.score}
	end
7 10 -1
13 21 20 24 27 17
-3 15 19 24 28 31 32
-59 10 15 20 25 30 34 37
-51 8 13 19 25 31 35 38
-19 3 9 15 21 28 33 37
-11 -2 4 10 13 19 25 29 33 28
5 -2 3 10 16 18 16 21 25 29 30
10 3 10 17 23 24 19 15 20 24 14
7 8 16 24 30 30 5 0 -3
21 15 18 28 35 35 -4
30 25 22 33 40 39 0
31 36 31 39 45 43 12
45 40 40 46 47
48 44 51
44

Creating Movement

Pieces just flow "down" to higher score squares.

	r.site_values(map ) do
		map.sites_a.map{|s| [s, d_to_arrow(s.source_d)] if s.source_d }
	end

To allow for growth only move pieces bigger than some multiple of a site's production.

	r.site_values(map ) do
		map.sites_a.map{|s| [s, d_to_arrow(s.source_d)] if s.source_d and s.strength > 6 * s.production * 5 }
	end

Final tweaks

To lock in your gold level score, just add the following: