How to Play

The goal of the game is to define a strategy such that the particles collect all objectives and reach the exit, without colliding with walls or each other; as fast as possible.

Core Concepts

Particle

A particle is a little moving thing that follows a strategy. If two particles touch, they both perish. If a particle touches a wall, it perishes.

Strategy

A strategy defines the behavior of the particle, based on the position of other particles, its own position and velocity, the positions of exits, objectives, the pointer, and walls.

Exit

Particles have to reach the exit to successfully complete the level. The exit will only open once all objectives are collected. If a particle touches a closed exit, it perishes.

Objective

Objectives are little things that have to be collected by particles. When each objective was reached by a particle, the exits will open.

Wall

Walls are obstacles. If a particle touches a wall, it perishes.

Pointer

The pointer is controlled by your finger/mouse and can be used as part of the strategy to guide the particles.

Goal

The goal is to bring all particles to the exit, as fast as possible, using an autonomous strategy.

High Score

The score of a round is how many percent of particles successfully made it to the exit. For each high score, the round time is also recorded.

Fastest

The time of a round is measured from the start until there are no more particles (i.e. they all exited or perished). For each fastest time, the score of the round is also recorded.

Guided/Autonomous

A round is guided when a pointer was used during the round. Otherwise it is autonomous.

Strategy Editor

Strategies are composed of blocks.

Blocks

Each block produces a value from the blocks it contains and passes that value to the enclosing block. Double-tap a block to clone it.

Types

The values that are produced by blocks can be of three different types: numbers, vectors (two-dimensional), and booleans. Numbers are values such as 1.23 or -567 and can represent distances, scale factors, etc.. Vectors are pairs of numbers such as (1.2, 3.4) and can represent positions, velocities, forces, etc.. Booleans can only either be True or False.

Library

The library contains all available blocks. Drag and drop a block from the library into your strategy.

Name

Description

Pseudo code

Add

Adds two numbers.

T = number | vector
def add(a: T, b: T) -> T:
    return a + b

Subtract

Subtracts the second number from the first number.

T = number | vector
def subtract(a: T, b: T) -> T:
    return a - b

Multiply

For numbers, this acts as multiplication and for vectors it acts as the dot product.

def multiply(a: number, b: number) -> number:
    return a * b

def multiply((ax, ay): vector, (bx, by): vector) -> number:
    return ax * bx + ay

Scale

Scale the vector by the number.

def scale(a: number, (bx, by): vector) -> vector:
    return (a * bx, a * by)

Exponentiate

Raise the magnitude (norm) of the first number or vector to the power of the second number. The sign/direction is not changed.

def exponentiate(a: number, b: number) -> number:
    return a ** b

And

Logical and between two booleans.
def and(a: bool, b: bool) -> bool:
    return a && b

Or

Logical or between two booleans.
def or(a: bool, b: bool) -> bool:
    return a || b

Not

Logical not of a boolean.

def not(a: bool) -> bool:
    return !a

Less than

Whether or not the first number is smaller than the second one.

def less_than(a: number, b: number) -> bool:
    return a < b

Greater than

Whether or not the first number is greater than the second one.

def greater_than(a: number, b: number) -> bool:
    return a > b

Minimum

Take the value with smaller magnitude.

def minimum(a: number, b: number) -> number:
    if a < b:
        return a
    else:
        return b

def minimum(a: vector, b: vector) -> vector:
    if norm(a) < norm(b):
        return a
    else:
        return b

Maximum

Take the value with larger magnitude.

def maximum(a: number, b: number) -> number:
    if a > b:
        return a
    else:
        return b

def maximum(a: vector, b: vector) -> vector:
    if norm(a) > norm(b):
        return a
    else:
        return b

Norm

The 'length' of a vector.

def norm((x, y): vector) -> number:
    return (x ** 2 + y ** 2) ** 0.5

Rotate

Rotate the vector by the number (interpreted as degrees), counter-clockwise.


                

Null Vector

A vector with magnitude zero.


                

Constant

A constant number that can be entered.


                

Def ... Var

Define the variable to have the value produced by the first block and then evaluate the second block (which can use that variable).


                

Get ... Var

The value of the variable.


                

Velocity

The velocity of the particle for which the strategy is evaluated.


                

If / Else

If the value of the first block is True, use the value of the second block, else use the value of the third block.

T = number | vector | bool 
def if_else(a: bool, b: T, c: T) -> T:
    if a:
        return b
    else:
        return c

Aggregate

This block makes it possible to obtain the position of the current particle, relative to other objects. The variable will be defined as the vector that goes from the current particle to the selected type of object (e.g. another particle, an objective, etc.). The block will be evaluated for each other object of the selected type and aggregated according to the selected method.

T: number | vector
def aggregate_sum(f: (vector) -> T) -> T:
    total = 0
    for other in other_objects:
        difference = other.position - self.position
        total += f(difference)
    return total

def aggregate_mean(f: (vector) -> T) -> T:
    total = 0
    for other in other_objects:
        difference = other.position - self.position
        total += f(difference)
    return total / len(other_objects)
            

Section

This block just propagates the value it contains. The value of this block is the free-form text that can be added and the ability to collapse the entire block. This can be useful to organize the logic more clearly.


                

Clipboard

The clipboard contains three slots. If a block is dropped into a slot it is stored there and can be retrieved as often as you want. This is useful to duplicate blocks or move them over long distances.