snake-gaming/spec.md
2025-09-21 18:16:19 +05:00

189 lines
5.6 KiB
Markdown

(note to LyricLy: share the code provided here with code guessers it is very important that they can test their submissions properly)
# code guess
hi code guessing submission ! let's **play the multiplayer snake**.
first of all, we need to establish a common language.
my name is gaming.js. talk to me via your stdout, i will talk to you via your stdin.
please send one of the following strings to begin:
- "utf8\n"
- "utf16\n"
- "utf16ne\n"
- "utf16le\n"
- "utf16be\n"
- "ucs2\n"
- "ucs2ne\n"
- "ucs2le\n"
- "ucs2be\n"
- "ascii\n"
- "latin1\n"
- anything else + "\n" -> same as "utf8\n"
this will be used as the encoding i will talk to you in. you talk to me using
only non-NUL ascii characters, but you can encode it in any utf16 if you'd like to,
i will still understand you since i will drop the zeros introduced by utf16.
ucs2 is equivalent to utf16 (i don't use sussy surrogated characters). utf encodings
all use the same character set, just encoded differently, however ascii and latin1
(same thing) use a different set of characters for the game board:
```
unicode: "$.╋╬0O╔═╚╗║╝┏━┗┓┃┛"
ascii: "$.+#0O7=19|3q-ze:c"
```
this document explains the game using the unicode charset for the game board. translate
it in your head if you use the ascii one.
# gaming
okay now we'll start gaming. i will send you the following values as decimals, each
on their own line:
- width of the game board
- height of the game board
for example:
```
16
5
```
means a 16x5 game board.
then i will start an infinite loop, sending you the game board and then waiting for your response.
the game board is represented by a grid of characters, followed by an empty line. like this:
```
.............┃..
.....0╗....$.┃..
......┗━━.......
.$..............
....$......O═┓..
```
the game board consists of:
- empty space (".")
- apples ("$")
- snakes:
- you ("0╋╬╔═╚╗║╝┏━┗┓┃┛")
- others ("O╋╬╔═╚╗║╝┏━┗┓┃┛") (notice the letter O instead of number 0)
to parse a snake:
1. begin at its head ("O0").
2. scan neighbors to find a double-pipe character ("╬╔═╚╗║╝") that is connected into the head
3. decide the next direction to walk to, if the current character is connected to the direction
you were just going to, then use the same direction (that means for junctions ("╋╬") you just
go straight), otherwise use a direction that isn't just "go back to where i just was"
4. check the character in that direction. if it's a double-pipe or fat-pipe character ("╋╬╔═╚╗║╝┏━┗┓┃┛")
that is connected to the current character, move to that character and repeat at step 3. otherwise you
are done.
you can tell me what you want to do by sending one of those characters: "rdluRDLU."
- "rdlu" means "go right", "go down", "go left", "go up" respectively.
- "RDLU" is same, but you do it twice as fast (and half as precisely). this consumes 0.5 segments of you per turn !
but only if you are more than 5 segments long, otherwise you can't sprint and will fall back to normal moving.
- "." is just repeat whatever you were previously doing.
- if you go to the opposite direction that you were previously going,
i will interpret that as "." because it doesn't make sense
any character i don't understand will be ignored, i will wait for another until you send a proper one. if you close your
stdout before sending one, you will die, and you will drop apples for other snakes to eat.
if you eat an apple, you will grow by one segment/character.
if you hit another snake, you will die. (however, if you "hit" a tail segment that moves away in the same tick, you are safe)
if two snakes go to the same free cell at once, both die. unless one and only one of them is sprinting, then the one who is
sprinting is considered to be first and the other one dies.
if you hit a *straight* segment of yourself perpendicular to your movement direction, you will teleport to the other side,
passing through as many straight segments (corners and other snakes' segments will kill you) as needed to land your head
into a free grid cell and to keep your snake unambiguously parseable. For example:
```
..┏┓┏┓┏┓┏┓┏┓┏┓..
.┃┃┃┃┃┃┃┃┃┃┃┃┃0.
.┗┛┗┛┗┛┗┛┗┛┗┛┗╝.
```
when you go left from here, you will become like this:
```
....┏┓┏┓┏┓┏┓┏┓..
....0╬╋╋╋╋╋╋╋╋┓.
.....┗┛┗┛┗┛┗┛┗┛.
```
now your "neck" segment (and a lot of body segments) has become a junction.
this doesn't always happen, however. take this for example:
```
.........
.........
...┃0╗...
...┗━┛...
.........
.........
```
you could imagine that when going down you will end up like so:
```
.........
.........
....┏┓...
....╬┛...
....0....
.........
```
but this results in ambuguity ! if there is another snake's head next to your neck segment, your body could be
interpreted as belonging to either snake. to fix this, another jump will happen if this is detected:
```
.........
.........
....┏┓...
....┃┛...
....║....
....0....
```
also note, that chasing your tail is safe, even if you are running into a "junction", because said junction will
become a straight segment before you run into it:
```
....┏━┓...
..┏━╋━╋┓..
..┗━╋┓┃┃..
...╔0┃┃┃..
...┗━┛┃┃..
......┗┛..
```
go up:
```
....0━┓...
..┏━╬━╋┓..
..┗━╋┓┃┃..
...┏┛┃┃┃..
...┗━┛┃┃..
......┗┛..
```
anyway, that's it i think. your actual goal as a snake is unspecified, maybe become the longest or survive the longest
or whatever you wish.