189 lines
5.6 KiB
Markdown
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.
|