# Racetrack

Racetrack is an awesome [minimalist](minimalism.md) [pen and paper](pen_and_paper.md) mathematical [game](game.md) in which one races a [car](car.md) through track with the goal to finish it as quickly as possible. For PC gaymers we could describe it as "an extremely suckless version of [Trackmania](trackmania.md)" for which you don't even need a computer. It is similar to other pen and paper games such as [paper football](paper_football.md). The basic idea is that of a car on a square grid that moves in steps -- in each step the player can adjust the car's current velocity a little bit (steer, accelerate, brake, ...) and so modify the velocity; the car must race to finish without crashing into walls, the tricky part is that one has to make predictions just like in real race, for example approaching a curve one must go to the right side of the road and brake a bit.

Racetrack is one of the best examples of what good games should look like, mainly because:

- It is extremely [suckless](suckless.md), it may be implemented and played with the use of a [computer](computer.md) but can also be played without it, i.e. it has practically no [dependencies](dependency.md). In theory it can only be played in one's brain, making it [brain software](brain_software.md).
- It is extremely [free](free_software.md) (as in freedom): firstly no one legally owns it and secondly its simplicity makes it free practically, anyone can play it and modify it regardless of where he lives, how much money he has, whether he has a computer -- even if one has no eyes or hands the game can still probably be played.
- It may easily be played by any number of players, even solo. If one plays alone, he simply tries to find the fastest solution for given track. If multiple players play, they compete who finds the best solution.
- It is [simple yet deep](easy_to_learn_hard_to_master.md), the rules are very simple but to find the optimal solution for given track may get very difficult, especially if the track is somewhat complex and employs e.g. a number of checkpoints that can be taken in any order. This is probably an [NP hard](np_hard.md) problem and finding a good solution may require a lot of experience, intuition, advanced programming techniques such as [machine learning](machine_learning.md) etc.
- It's not a mere game but a whole playground and "platform", for example it may be used to teach [vector](vector.md) mathematics, programming (path finding, heuristic search, [evolutionary programming](evolutionary_programming.md), ...), test machine learning algorithms etcetc.
- It can be very nicely implemented on computers, even on very simple ones such as [8bits](8bit.md), without bloat such as [floating point](float.md), and is friendly to e.g. implementing replays, artificial intelligence etc.
- The base version is extremely simple but may be extended greatly in various way, for example adding more rules or creating "rich" computer frontends; one may imagine e.g. a 3D frontend for the game with features such as bots, demo recording, different car skins, online multiplayer and leaderboards, track editor etc.
- ...

## Rules

There is no single rule set -- as no one owns the game, rules may be modified and adjusted, which is very good. However there exist core rules that basically make the game what it is -- let us describe those right now.

The game takes place on a 2D square grid (e.g. squared sheet of paper); the car can only ever occupy [integer](integer.md) coordinates, i.e. its position cannot be e.g. a fraction of a square (however if e.g. in some computer implementation the grid is dense enough, it may in theory practically give an impression of continuous space). (Some modifications may perhaps try to utilize different kinds of grids of more than two dimensions.)

The car has a [velocity](velocity.md) [vector](vector.md) which is initially [0,0] (i.e. the car is at rest). This vector can also only ever have integer components. The velocity vector is added to the car's position in each game step so that the car moves. For example car with position [3,2] and velocity [1,-1] will move to [4,1].

At each step the player can make a slight modification of the car's velocity, typically the player has to choose a vector from range [-1,-1] to [1,1] that's added to current velocity; in other words the player can modify current velocity by changing each of its two components by -1, 0 or 1. This makes for 9 possible choices at each game step, so the branching factor of the game is 9. This can be represented as racer steering, accelerating and braking. Of course modified version of the game may play around with this, e.g. an oil puddle may make player unable to modify velocity for one round etc.

Any specific track has a start (some versions of the game may just make player always start at [0,0]), finish (which may be a point, line, area etc.) and walls representing obstacles; modified versions of the game may also have other things such as checkpoints, items (nitro, time stop, ...) and other objects (jump ramps, oil puddles, teleports, ...). The player must race to the finish, usually without crashing into walls because a crash into wall means the car stops immediately (in some versions in may just mean the game ends). Implementation of walls and crashes may somewhat differ: in some versions walls are actually borders of "solid" areas to which the player must never enter, in other versions walls may be just lines the player must not touch or cross. In simple versions of the game walls are really line segments that go between given grid points (this is possible the more KISS variant as walls too are just defined with vectors and collision detection may be quite simple), more complex versions may allow non-integer coordinates for walls, curved walls etc. Walls may also be implemented just as "filled squares", i.e. just saying some grid points are solid and inaccessible. Crash usually means that a player would make such illegal move and so his current velocity is set to [0,0] as a consequence, but an advanced version may also make the player move as close to the crash point as possible to make the behavior closer to reality; however this may be very non-trivial to do while assuring the behavior can't be "abused". [Collision detection](collision_detection.md) can be implemented e.g. by checking if two lines intersect (if walls are just lines), or if a point belongs to given area (if walls are edges of areas), using [analytic geometry](analytic_geometry.md)).

The goal is basically always to finish the track in as few steps as possible.

TODO: example, pictures, ...

