-
Notifications
You must be signed in to change notification settings - Fork 3
Remote control
Brutal Maze provides a INET (i.e. IPv4), STREAM (i.e. TCP) socket server which
can be enabled in the config file or by adding the --server
CLI flag. After
binding to the given host and port, it will wait for a client to connect. Then,
in each cycle of the loop, the server will send current details of each object
(hero, walls, enemies and bullets), wait for the client to process the data and
return instruction for the hero to follow. Since there is no EOT (End of
Transfer) on a socket, messages sent and received between server and client
must must be strictly formated as explained below.
First, the game will export its data to a byte sequence (which in this case, is simply a ASCII string without null-termination) of the length l. Before sending the data to the client, the server would send the number l padded to 8 digits.
Below is the meta structure of the data:
<Map height (nh)> <Number of enemies (ne)> <Number of bullets (nb)> <Score>
<nh lines describing visible part of the maze>
<One line describing the hero>
<ne lines describing ne enemies>
<nb lines describing nb bullets>
Visible part of the maze with the width nw and the height nh will be
exported as a bit (0
and 1
) map of nh lines and nw columns. For
example, the bit map and the picture below show the same part of a maze:
To avoid floating point number in later description of other objects, each
cell represent by a number 0
or 1
will have the width (and height) of
100, which means the top left corner of the top left cell will have the
coordinates of (0, 0), and the bottom right vertex of the bottom right cell
will have the coordinates of (nw*100, nh*100).
6 properties of the hero are exported in one line, separated by 1 space, in the following order:
- Hero's color indicating the current HP of the hero, as shown in in the later section.
- X-coordinate, which will be in the range [0, nw * 100], casted to an integer.
- Y-coordinate, which will be in the range [0, nh * 100], casted to an integer. Note that the y-axis points up-side-down instead of pointing upward.
- Angle of the direction the hero is pointing to in degrees, casted to a nonnegative integer (from 0 to 360). Same note as above (the unit circle figure might help you understand this easier).
-
Flag showing if the hero can strike an attack,
0
for no and1
for yes. -
Flag showing if the hero can heal,
0
for no and1
for yes.
Each enemy exports these properties:
- Color indicating the type and current HP of the enemy, as shown in the table below.
- X-coordinate, which will be in the range [0, nw * 100], casted to an integer.
- Y-coordinate, which will be in the range [0, nh * 100], casted to an integer.
- Angle of the direction the hero is pointing to in degrees, casted to a nonnegative integer (from 0 to 360).
To shorten the data, each color (in the Tango palette) is encoded to a
lowercase letter or number 0
. Different shades of a same color indicating
different HP of the characters.
HP | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|
Butter | ||||||
Orange | ||||||
Chocolate | ||||||
Chameleon | ||||||
Sky Blue | ||||||
Plum | ||||||
Scarlet Red | ||||||
Aluminium |
Bullets also export 4 properties like enemies:
-
Color indicating the type and potential damage of the bullet (from 0.0 to
1.0), encoded similarly to characters', except that Aluminium bullets only
have 4 colors
v
,w
,x
and0
. - X-coordinate, which will be in the range [0, nw * 100], casted to an integer.
- Y-coordinate, which will be in the range [0, nh * 100], casted to an integer.
- Angle of the bullet's flying direction in degrees, casted to a nonnegative integer (from 0 to 360).
Above snapshot of the game is exported as:
19 9 3 998
0000000000000000000000011
0001111100000111111111111
0001111100000111111111111
0001111100000111111111111
0001111100000111111111111
0001111100000111111111111
0001111100000000000000000
0001111100000000000000000
0001111100000000000000000
0001111100000000000000000
0001111100000000000000000
0001111100000111110000011
0001111100000111110000011
0001111100000111110000001
0001111100000111100000011
0001111100000111110000011
0001111100000111110000000
0001111100000111110000000
0001111100000111110000000
v 1208 837 87 1 1
g 1878 1033 45
d 1778 1283 122
d 1678 1383 203
s 1478 693 45
g 1778 1083 18
s 1378 783 45
g 1778 983 104
g 1898 783 45
d 1778 883 45
f 1201 507 209
i 1275 605 194
h 1470 817 208
Every loop, the server receives no more than 8 characters in this format:
<Movement> <Angle> <Attack>
. Again, these values need to be specially
encoded.
This is the most awkward one. As we can all imagine, there are 9 different
directions for the hero to move. If we represent them as two-dimensional
vector, at least 3 characters will be needed to describe such a simple thing,
e.g. 1 0
for m = (1, 0), and in the worst-case scenario m = (-1, -1), we will
need to use 5: -1 -1
. 40 bits used to carry a 4-bit piece of data, freaking
insane, right? So instead, we decided to slightly encode it like this:
Direction | Left | Nil | Right |
---|---|---|---|
Up | 0 | 1 | 2 |
Nil | 3 | 4 | 5 |
Down | 6 | 7 | 8 |
Direction to point to hero to, might be useful to aim or to perform close-range attack manually. This value should also be converted to degrees and cast to a nonnegative integer.
Attack acan be either of the three values:
- Do nothing
- Long-range attack
- Close-range attack
Simple, huh? Though be aware that this won't have any effect if the hero cannot strike an attack yet (as described in above section about Server output).
- Create INET, STREAMing socket s
- Connect s to the address
host:port
which the server is binded to - Receive length l of data
- If l > 0, close s and quit
- Receive the data
- Process the data
- Send instruction for the hero to the server and go back to step 3