Software Construction Assignment 8: Networking

Due: May 22, 2018 @ 10pm. Please include a README.txt that has both partners' names and email addresses.

This assignment has three goals:

  • build a parser and printer to be able to externalize your game's state in a common format,
  • be able to play over the network, and
  • try to find bugs in your solution to assignment 3 using random testing.
The first goal enables the latter two. Indeed, most of the work is in the first goal. Your handin for this assignment must produce code that runs on one of the tlab machines (more details below).

The tsuro.tar.gz and tsuro.zip archives have been updated with more programs (also described below).


Each interaction across the network consists of a pair of messages, one in each direction. The content of the messages is governed by the method type specifications in the Player interface. The sequence of the messages is governed by the sequence contract given in assignment 5.

  • When the server sends a get-name message, the response must be player-name.
  • When the server sends a initialize message, the response must be void.
  • When the server sends a place-pawn message, the response must be pawn-loc.
  • When the server sends a play-turn message, the response must be tile.
  • When the server sends a end-game message, the response must be void.

This is the specification for the data that passes over the network connection:

message
= get-name 
| player-name 
| initialize 
| void 
| place-pawn 
| pawn-loc 
| play-turn 
| tile 
| end-game 
get-name
= <get-name> </get-name>
player-name
= <player-name> str  </player-name>
initialize
= <initialize> color  list-of-color  </initialize>
place-pawn
= <place-pawn> board  </place-pawn>
play-turn
= <play-turn> board  set-of-tile  n  </play-turn>
board
= <board> tiles  pawns  </board>
end-game
= <end-game> board  set-of-color  </end-game>
list-of-splayer
= <list> splayer ... </list>
maybe-list-of-splayer
= <false> </false>
| <list> splayer  splayer ... </list>
splayer
= <splayer-dragon> color  set-of-tile  </splayer-dragon>
| <splayer-nodragon> color  set-of-tile  </splayer-nodragon>
list-of-tile
= <list> tile ... </list>
set-of-tile
= <set> tile ... </set>
tiles
= <map> <ent> xy  tile  </ent>... </map>
pawns
= <map> <ent> color  pawn-loc  </ent>... </map>
pawn-loc
= <pawn-loc> hv  n  n  </pawn-loc>
hv
= <h> </h>
| <v> </v>
xy
= <xy> <x> nat  </x> <y> nat  </y> </xy>
tile
= <tile> connect  connect  connect  connect  </tile>
connect
= <connect> n  n  </connect>
list-of-color
= <list> color ... </list>
set-of-color
= <set> color ... </set>
color
= <color> blue </color>
| <color> red </color>
| <color> green </color>
| <color> orange </color>
| <color> sienna </color>
| <color> hotpink </color>
| <color> darkgreen </color>
| <color> purple </color>
n
= <n> nat  </n>
void
= <void> </void>
str
= a sequence of characters 
nat
= 0
| 1
| 2
|...

Things in the purple fixed width font are literal characters that pass across the network, things in green italics refer to other parts of the specification, and things in orange boldface are meta notation about the spec. The ellipses that appear inside tags indicate repetitions: the element just before the ellipses can appear any number of times (including zero times). The ellipses in the nat non-terminal indicates that all natural numbers are okay.

Each message must be terminated by a newline character and there must not be any other newlines in messages. Whitespace is otherwise insignificant, except that it separates tokens.

The indices for the tile locations start with (0,0) in the upper-left. If the first coordinate gets larger, that means that tile location refers to a position to the right, and if the second coordinate gets larger that means that the tile location refers to a position lower down. Accordingly, the lower-left corner is (5,5). Note that these tiles never include the dragon tile; they include only tiles that may be played on the board.

Each pawn location refers to a place on the edge of a tile and each has three components. The first component indicates if the location is on a horizontal or a vertical edge. The second component indicates which edge it is, counting from 0 to 6. 0 means the upper or leftmost edge of the board and 6 means either the lower or rightmost edge. If the pawn location is a horizontal location, a 1 means that it pawn location is on the bottom edge of the first row of tiles, which is also the top edge of the second row tiles. Similarly, 1 in a vertical pawn location means either the right edge of the leftmost column of tiles, which is also the left edge of the second leftmost row of tiles. The last component refers to the spot along the tile. Each tile has two places a pawn might be, so those values range from 0 to 11.

The numbers inside the tile that indicate connections are the same numbers as you see in assignment 3. For example, here is the last tile in that list and its XML representation.
<tile><connect><n>0</n><n>5</n></connect><connect><n>1</n><n>3</n></connect><connect><n>2</n><n>6</n></connect><connect><n>4</n><n>7</n></connect></tile>

The parser normalizes the tiles, first sorting the connections so the smaller number comes first and then sorting each of the connections by the lower number. For example,

<tile>
 <connect><n>4</n><n>2</n></connect>
 <connect><n>1</n><n>3</n></connect>
 <connect><n>5</n><n>7</n></connect>
 <connect><n>0</n><n>6</n></connect></tile>
is converted to
<tile>
 <connect><n>0</n><n>6</n></connect>
 <connect><n>1</n><n>3</n></connect>
 <connect><n>2</n><n>4</n></connect>
 <connect><n>5</n><n>7</n></connect></tile>
before it is used further. Accordingly, some parsing failures will be printed in terms of the normalized versions of the files, not their original tiles.


Here are two example boards with their XML representations next to them:

<board><map><ent><xy><x>0</x><y>0</y></xy><tile><connect><n>0</n><n>1</n></connect><connect><n>2</n><n>4</n></connect><connect><n>3</n><n>6</n></connect><connect><n>5</n><n>7</n></connect></tile></ent></map><map><ent><color>red</color><pawn-loc><v></v><n>1</n><n>1</n></pawn-loc></ent></map></board>


<board><map><ent><xy><x>2</x><y>2</y></xy><tile><connect><n>0</n><n>4</n></connect><connect><n>1</n><n>5</n></connect><connect><n>2</n><n>6</n></connect><connect><n>3</n><n>7</n></connect></tile></ent><ent><xy><x>0</x><y>0</y></xy><tile><connect><n>0</n><n>1</n></connect><connect><n>2</n><n>3</n></connect><connect><n>4</n><n>5</n></connect><connect><n>6</n><n>7</n></connect></tile></ent><ent><xy><x>1</x><y>1</y></xy><tile><connect><n>0</n><n>2</n></connect><connect><n>1</n><n>4</n></connect><connect><n>3</n><n>7</n></connect><connect><n>5</n><n>6</n></connect></tile></ent><ent><xy><x>2</x><y>0</y></xy><tile><connect><n>0</n><n>1</n></connect><connect><n>2</n><n>6</n></connect><connect><n>3</n><n>7</n></connect><connect><n>4</n><n>5</n></connect></tile></ent><ent><xy><x>0</x><y>2</y></xy><tile><connect><n>0</n><n>6</n></connect><connect><n>1</n><n>5</n></connect><connect><n>2</n><n>4</n></connect><connect><n>3</n><n>7</n></connect></tile></ent><ent><xy><x>2</x><y>1</y></xy><tile><connect><n>0</n><n>2</n></connect><connect><n>1</n><n>6</n></connect><connect><n>3</n><n>7</n></connect><connect><n>4</n><n>5</n></connect></tile></ent><ent><xy><x>3</x><y>0</y></xy><tile><connect><n>0</n><n>1</n></connect><connect><n>2</n><n>7</n></connect><connect><n>3</n><n>4</n></connect><connect><n>5</n><n>6</n></connect></tile></ent><ent><xy><x>1</x><y>0</y></xy><tile><connect><n>0</n><n>5</n></connect><connect><n>1</n><n>4</n></connect><connect><n>2</n><n>7</n></connect><connect><n>3</n><n>6</n></connect></tile></ent><ent><xy><x>0</x><y>1</y></xy><tile><connect><n>0</n><n>1</n></connect><connect><n>2</n><n>4</n></connect><connect><n>3</n><n>6</n></connect><connect><n>5</n><n>7</n></connect></tile></ent><ent><xy><x>1</x><y>2</y></xy><tile><connect><n>0</n><n>4</n></connect><connect><n>1</n><n>7</n></connect><connect><n>2</n><n>3</n></connect><connect><n>5</n><n>6</n></connect></tile></ent></map><map><ent><color>blue</color><pawn-loc><v></v><n>0</n><n>2</n></pawn-loc></ent><ent><color>orange</color><pawn-loc><h></h><n>3</n><n>3</n></pawn-loc></ent><ent><color>green</color><pawn-loc><h></h><n>3</n><n>2</n></pawn-loc></ent><ent><color>red</color><pawn-loc><h></h><n>3</n><n>1</n></pawn-loc></ent><ent><color>sienna</color><pawn-loc><v></v><n>3</n><n>3</n></pawn-loc></ent></map></board>


To test your implementation against mine using random testing, run ./test-play-a-turn play-a-turn from the shell, where test-play-a-turn is from me and play-a-turn is a binary or shell script that you produce. It must accept, on its stdin, the arguments to the the play-a-turn function described in assignment 3 and it must produce the results given there, but in the format described above.

More precisely, expect the following XML expressions, one after each other (separated by newlines):

  • list-of-tile
  • list-of-splayer
  • list-of-splayer
  • board
  • tile
The program must read them, convert them to your representation of those objects, call your play-a-turn function, and then convert it's results into the following XML expressions, printing them on stdout (also separated by newlines):
  • list-of-tile
  • list-of-splayer
  • list-of-splayer
  • board
  • maybe-list-of-splayer

Your git repository handin for this assignment must include a Makefile, such that running make at the top-level of your git checkin on a t-lab machine produces a play-a-turn binary that works as described in the previous paragraph. We will be running your code using this method. The Racket binary needed to run test-play-a-turn is installed in /home/softare/racket/bin/racket on the t-lab machines. If you cannot meet this requirement for some reason, please get in touch.

In addition, you will find a program visualize that accepts various different things to draw on its stdin and then either draws them in a window or saves them in .png files. Use visualize -h for more information.


Overall Hints First, develop the programs that can translate method calls into text messages and text messages into method calls (test the parsing!). Second, wire in your existing code and test each half independently by simulating messages from the other half for simple interactions. Finally, wire everything together and play some games.

Parsing Hints There are two options for parsing. First, find a XML parser for your language of choice and use it (beware of heavyweight libraries). Second, you can write your own parser. The protocol only calls for a simple subset of the XML language. There are no dtds required. There are no attributes in the tags. Whitespace is only significant as a delimiter (and inside a name). All of this should make rolling your own special-purpose parser much easier.

Be sure to organize your parser as a separate library, so when you find bugs it will be easy to add test cases.



Software Construction