Algorithm

Pokemon Game Algorithm

This is a real take-home challenge I've encountered. It's not about finding the optimal algorithm — it's about demonstrating clean domain modeling, OOP pr...

10 Apr 2024

Pokemon Game Algorithm

This is a real take-home challenge I've encountered. It's not about finding the optimal algorithm — it's about demonstrating clean domain modeling, OOP principles, and testable code.

The challenge

Build a creature-collecting game. Think Pokemon, but simplified. A Collector moves around a world, finds nearby Creatures, and catches them.

Part 1: Domain modeling

Creatures have a family (flyer, swimmer, runner) and a species (Bird, Shark, Lion). Both Collectors and Creatures have a Position. A World holds references to all entities.

Typescript
type Family = "flyer" | "swimmer" | "runner";

interface Position {
    x: number;
    y: number;
}

class Creature {
    constructor(
        public name: string,
        public family: Family,
        public species: string,
        public position: Position
    ) {}
}

class Collector {
    public collection: Creature[] = [];

    constructor(
        public name: string,
        public position: Position
    ) {}
}

class World {
    public creatures: Creature[] = [];
    public collectors: Collector[] = [];
}

Part 2: Finding and catching

Define "nearby" however you want. I use Euclidean distance with a configurable radius. Catching picks a random nearby creature and moves it to the collector's collection.

Typescript
function distance(a: Position, b: Position): number {
    return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
}

function getNearbyCreatures(
    world: World,
    collector: Collector,
    radius: number
): Creature[] {
    return world.creatures.filter(
        (c) => distance(c.position, collector.position) <= radius
    );
}

function catchCreature(
    world: World,
    collector: Collector,
    radius: number
): Creature | null {
    const nearby = getNearbyCreatures(world, collector, radius);
    if (nearby.length === 0) return null;

    const target = nearby[Math.floor(Math.random() * nearby.length)];
    collector.collection.push(target);
    world.creatures = world.creatures.filter((c) => c !== target);
    return target;
}

What interviewers look for

This challenge tests design thinking, not algorithm knowledge. They want to see:

  • Clean abstractions that separate concerns
  • Meaningful names that communicate intent
  • Tests that cover edge cases (empty world, no nearby creatures, catching the last creature)
  • Code that's easy to extend (add new families, new behaviors)

Trade-offs

I kept Position as a simple {x, y} object. In a real game, you might want a grid-based system, hex coordinates, or a spatial index for efficient proximity queries. The random catch mechanic is simple but could be extended with probabilities based on creature rarity or distance.

Keep reading