tiny-soccersim-rust/README.md

191 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# tssr — Tiny Soccer Simulator Rust
A blazing-fast CLI that generates completely random soccer matches on the spot — or run scripted matches with the `.tsrc` (Tiny Soccer Sim Rust C) language.
## Build
```bash
cargo build --release
```
The binary will be at `target/release/tssr`.
## Usage
```bash
./tssr # random match (table output)
./tssr --json # random match (JSON output)
./tssr --script match.tsrc # scripted match (table output)
./tssr --script match.tsrc --json # scripted match (JSON output)
./tssr --help # show usage info
```
### Shebang
`.tsrc` scripts can be run directly with a shebang:
```tsrc
#!/usr/bin/env tssr
string home = "Team A";
string away = "Team B";
// ...
match(home, away);
```
```bash
chmod +x match.tsrc
./match.tsrc
```
## Output
### Table mode (default)
```
╔════════════════════════════════════════╗
║ TSSR MATCH RESULT ║
╠════════════════════════════════════════╣
║ Man Page City 2 - 1 Libre Pool║
╠════════════════════════════════════════╣
║ ║
║ Shots 10 8 ║
║ On Target 4 3 ║
║ Possession 55% 45% ║
║ ║
╠════════════════════════════════════════╣
║ Goals: ║
║ Man Page City: Marco Smith (23') ║
║ Man Page City: Leo Brown (67') ║
║ Libre Pool: Dan Garcia (45') ║
╚════════════════════════════════════════╝
```
### JSON mode (`--json`)
```json
{
"home": {
"team": "Man Page City",
"score": 2,
"shots": 10,
"shots_on_target": 4,
"possession": 55,
"scorers": [
{"player": "Marco Smith", "minute": 23},
{"player": "Leo Brown", "minute": 67}
]
},
"away": {
"team": "Libre Pool",
"score": 1,
"shots": 8,
"shots_on_target": 3,
"possession": 45,
"scorers": [
{"player": "Dan Garcia", "minute": 45}
]
}
}
```
## `.tsrc` Scripting Language
`.tsrc` (Tiny Soccer Sim Rust C) is a minimal C-like DSL for defining teams, players, and match events programmatically.
### Language Reference
```tsrc
// Declare a team variable
string var_name = "Team Name";
// Assign a player to a team (by variable or literal)
players["Player Name"] = var_name;
players["Player Name"] = "Team Name";
// Script a goal: minute (1-90), team (var or literal), player (literal)
goal(45, var_name, "Player Name");
goal(45, "Team Name", "Player Name");
// Select teams for the match (required)
match(var_home, var_away);
```
### Rules
- Variables must be declared with `string` before use
- `match()` directive is required — references variable names
- `players[]` references team names (values), not variable names — but variables are resolved automatically
- `goal()` arguments: `minute, team, player` — team can be variable or literal
- All semicolons are required
- `//` for single-line comments
- Strict validation: any inconsistency produces an error with a helpful message and exits immediately
### Validation Errors
The parser is strict — it will fail with a clear message if:
- A variable is used before being declared
- A variable is defined twice
- A player is added to a team that isn't in `match()`
- A player is added to the same team twice
- A goal references a player not on that team
- A goal references a team not in the match
- A goal minute is outside 1–90
- The same player scores at the same minute twice
- A match team has no players assigned
- `match()` references the same team for both home and away
### Scripted Goals
When `goal()` is used, the match becomes deterministic:
- Score is derived from the count of scripted goals per team
- Goal scorers and minutes are exactly as specified
- Shots and shots-on-target are floored at the goal count
- Possession remains randomized
Without `goal()`, everything is fully randomized.
## Team Names (Random Mode)
When no script is provided, teams are randomly selected from PES-style parodies referencing free software and open source:
- Man Page City, Libre Pool, ArsenAL, Shellsea, TomThumb FC
- Real Madread, BarcelON, BayErR, Door Mount, Inter Mission
- Man Unixited, A-JaX, CellTick, RanGERS, LaZIO, RomaAEM
- Port OS, BenFICA, Fine Node, AC M1Lan, PSGROOT
- Free BSD Athletic, Kernel Panic, Tor Valdes, Debian United
- Arch Lisbon, NixOS City, Fork Enoord, Branchand FC, Merge Conflict
## Stats Included
- Score
- Shots & shots on target
- Possession percentage
- Goal scorers with minute of goal
## Example Files
| File | Description |
|------|-------------|
| `scripted_match.tsrc` | GNU United vs BSD Athletic — 5 scripted goals with mixed variable/literal team references |
| `gnu-bsd-soccer.tsrc` | Variable-reference players, random goals |
| `test_match.tsrc` | Intentionally broken — demonstrates error handling |
## Testing
```bash
cargo test
```
13 integration tests cover:
- Goal validation (player on team, minute range, duplicates)
- Script validation (undefined variables, same team, missing match, no players)
- Happy paths (valid script, variable references, full scripted match)
## Performance
- Single runtime dependency (`rand`)
- `tempfile` is a dev-dependency only (for tests)
- Release profile uses LTO, single codegen unit, panic=abort, and symbol stripping
- Designed for sub-second cold compilation and instant execution
- Binary size: ~340KB stripped