Python

Python

> Programming

Since version 2.49, besides LeekScript, you can write your leeks' artificial intelligences on Leek Wars in Python (or in JavaScript / TypeScript). AIs run in a secure and deterministic environment, with access to the whole combat API of the game, and can fight AIs written in any other language.

Choosing the language

The language of an AI is determined by its file extension:

| Language | Extension | |----------|-----------| | LeekScript | (none) | | JavaScript | .js or .mjs | | TypeScript | .ts or .mts | | Python | .py |

You pick the language when creating a file ("New AI" button in the editor) or as the default language of your first AI when signing up. Renaming a file with a different extension changes its language.

Entry point: turn()

Each turn, the engine runs your AI. Two ways to write it:

Simple AI: write your code directly, it runs every turn:

Stateful AI: define a turn() function. The file body runs only once (declare your classes and persistent variables there), then turn() runs every turn:

The combat API

The game API is exposed in an object-oriented form, and keeps its camelCase names in Python: me.setWeapon(...), Fight.getNearestEnemy(). There is no global me variable: get your entity via Fight.me.

Unlike LeekScript, there are no global functions and no "flat" constants (getNearestEnemy(), WEAPON_PISTOL…): the whole API goes through the objects below.

Class tree

Entities returned by the API are typed: isinstance(enemy, Leek), isinstance(enemy, Bulb)

| Class | Main members | |-------|--------------| | Entity | life, maxLife, tp, mp, strength, agility, wisdom, resistance, science, magic, level, name, cell, weapon, weapons, chips, effects, states, summons, alive, dead, isAlly(), isEnemy(), distance(target) | | Me | everything from Entity, plus the actions: moveToward(target), moveAwayFrom(target), useWeapon(target), useChip(chip, target), setWeapon(weapon), say(message), summon(chip, cell, ai), canUseWeapon(target), weaponCell(target), chipCells(chip, target), weaponTargets(cell)… | | Cell | x, y, empty, obstacle, entity, distance(target), pathLength(target), lineOfSight(target), path(target) | | Weapon / Chip | cost, minRange, maxRange, area, launchType, maxUses, needsLos, features (plus cooldown and currentCooldown for Chip) | | Effect | type, value, caster, turns, critical, item, target | | Feature | type, minValue, maxValue, turns, targets |

Alongside the classes, four singletons:

| Singleton | Role | Main members | |-----------|------|--------------| | Fight | the fight | me, turn, getNearestEnemy(), getFarthestEnemy(), getEnemies(), getAliveEnemies(), getAllies(), getAlliedTurret()… | | Field | the field | cellFromXY(x, y), getObstacles(), distance(a, b), pathLength(a, b), lineOfSight(a, b), path(a, b) | | Registers | storage persisted between fights | get(key), set(key, value), delete(key), all() | | Debug | field visualization | mark(cells, color), markText(cells, text), show(cell), clearMarks(), pause() |

Constants

Constants are grouped by family, in two forms:

The editor's autocompletion (Weapon., Effect., Entity.Stat.…) lists all available members, with live type checking (Pyright).

Multiple files

Split your AI into modules with the classic Python import:

Only your own files are accessible. Module names follow the Python rules: no dashes, use underscores. Circular imports are not allowed.

The standard library

The Python 3.12 standard library is available: math, itertools, collections, heapq, functools, random… However, there are no external packages (pip), and modules accessing the system (files, network, processes) are unavailable.

Execution environment

See also