Assignment 6 – A Remote Player
1 Design, Build and Test

Assignment 6 – A Remote Player

Due Wednesday 5/4 5:00pm for the testing deliverables and Friday 5/6 11:59pm for the code deliverables

Reminder: do not make copies of the code in your code base. Instead, share it and each assignment must refine and improve it.

1 Design, Build and Test

Implement a remote player adapter that, given any playing function, e.g., the one from from assignment 5 or a new one that you might implement later, plays a game using that function. It is essential that your remote player be parameterized over the playing function and not hard code it or have just a fixed list of playing functions it might use. One good strategy here is to encapsulate the playing function into an object with a method and then pass that object in to your player adapter, but in some languages just passing a function is easier or simpler and also fine. There must not be a fixed set of players that your networking code knows about. It must be possible to add a new player and reuse the networking code without modifying it.

Your adapter should read JSON inputs from a TCP/IP port whose details (IP and port number) are provided on stdin. That is, your program will not receive boards and other such information on stdin as you have been doing until now. Instead, it should expect a JSON value on stdin that will inform it how to connect over the network to the game. This is the format of the initial message, where number is a JSON number and string is a JSON string.

network-config

 ::= 

{ "host" : string, "port" : natural }

This restriction is to simplify using various JSON libraries, specifically to be sure we know where the end of the JSON value is before parsing begins.

In addition to the constraints required by the JSON specification, any JSON value that’s transmitted over the network may not have any newline characters in the object. Moreover, transmitted JSON values should be separated by a newline. That is, there there may be other whitespace between JSON values, but there must be at least one newline.

Once your player receives network-config on stdin, it should connect to the already-running server at the given network address. After connecting to the given host and port it should send a JSON string with its name. Once the server receives the name, it will send messages based on the request non-terminal and expect messages matching the response non-terminal. (See assignment 3 for the definitions of the game-state and player-state non-terminals.)

request

 ::= 

{ "game-state" : game-state, "player-state" : player-state }

 | 

{ "game-over" : [ [ string, integer ], ... ] }

response

 ::= 

player-state

 | 

"ack"

If the request contains a game state and a player state, the response must be a player state. If the request contains game over then the response must be "ack". The list in the game-over object tells your player the names of all of the players in the game and their scores. The server will close the connection after receiving the "ack".

Testing Deliverables: In your team’s GitHub repository, create a directory named “Deliverables/6/6.1/” and deposit five test cases there. The format for these test cases is identical to the format for assignment 5.1, but the test cases must be different to count.

You will receive up to ten points for your tests, two points for each valid pair of input and output files.

Code Deliverables: In the same “Deliverables/6/6.1” directory in your team’s GitHub, place a Makefile for your remote player adapter. As usual make should produce run. The run executable will then be supplied the networking information.

You will receive up to fifty points for your remote player adapter depending on how many tests its test driver passes.