Sunday, June 13, 2010

Dinoisland and pygame

Facebook has a series of puzzles they use to evaluate potential engineering employees or for the enjoyment of anyone curious. I've worked through quite a few of them and in the process learnt that I really need to brush up on my algorithms.

At the moment I'm working through Dinosaur Island which is an AI exercise which surprisingly is about dinosaurs on an island. You need to create an AI that pilots a species of dinosaur to prosperity on the island, either a herbivore dodging nasty carnivores to get at tasty foliage or a species of carnivores hunting down everything that moves. The environment is persistent and multiplayer so it's almost like a little Dino-MMO.

Interactions with the server are done via the Apache Thrift RPC framework, where each action that your dinosaur can take is an RPC method. Your dinosaur has a limited life span so after avoiding predators and starvation your dinosaur needs to reproduce (apparently asexually) to prolong the species. The species itself has a limited life expectancy after which an extinction event kills all your remaining dinosaurs ('rocks fall everybody dies'). Every action that your dinosaur takes costs calories (move, look, grow, reproduce) and takes a turn, you get calories by eating ('moving into') stuff. This is important because it means that during a turn your dinosaur can either look in a direction OR move in a direction.

I'm currently working on a species of herbivore I call 'Silliosaurus' which fairly naively hunts out the densest areas of foliage to eat while only spending a cursory amount of time avoiding predators. To 'win' your species needs to score 100,000 points (which I think you accumulate mostly by eating stuff) and there's a leaderboard. Currently Silliosaurus is averaging less than 10,000 point a run with a current best of 25,000 points or so. The main flaw seems to be that Silliosaurii move into a square expecting to eat something only to find it empty and sometimes expects to move into empty space and accidentally acquires a cornucopia of vegetation. This makes me think that there's a problem with how I process and store sight information but I haven't tracked it down yet.

In the process of debugging Silliosaurus I wanted to build a graphical representation of Dinoisland to help me visualise the behaviour of each Silliosaur. I ended up using pygame which is a python game development library the wraps SDL. Pygame is total overkill for my needs but turns out to be dead simple to use. In fact below is a slightly simplified sample of what it takes to draw the screen visible in the attached screenshot:

import pygame

screen = pygame.display.set_mode((800, 800))
pygame.display('Dinoisland: Silliosaurus')
plant = pygame.Surface((10,10))
dino = pygame.Surface((10,10))
bg = pygame.Surface((self.screen.get_size()))
plant.fill((0, 255, 0))
dino.fill((0, 0, 255))

screen.blit(bg, (0, 0))
for location in plantlist:
    screen.blit(plant, location)
for location in dinolist:
    screen.blit(dino, location)

So while Silliosaurus still wanders about lost and confused, occasionally starving to death or eaten by a Daisyysaurus, I have learnt a valuable lesson about how to create quick and easy graphics.

P.S Here's a link to the full sized screenshot

No comments:

Post a Comment