Assignment 5 – GO:   two dumb players
1 Design, Build and Test
2 Extend, Build and Test

Assignment 5 – GO: two dumb players

Due Friday 10/25 11:59pm for the tests and Tuesday 10/29 11:59pm for the final deliverables

1 Design, Build and Test

Revisit the component you built for assignment 4. If it doesn’t provide an operation that checks whether a history of boards is legal, modify the component accordingly to provide it. In particular, such an operation should consumes a stone and a list of 1 to 3 boards and check if the boards form a sequence that is consistent with the rules of the game from assignment 4 ending at a board where the given stone is allowed to make a move.

Once you have the modified rule checker, re-use it to implement a GO player. It is up to you to decide what specific interface your component should implement and how. At the very least, your components should provide a way for other parts of the game to (i) obtain the name of the player, (ii) notify the player to start playing a game given stones of some color; (iii) to ask the player to produce a legal move given some information about the recent and current state of the game; and (iv) inform the player that the game is over and which players won.

As usual, your code should come with a clear description of the interface you pick that includes an account of all operations the component is supposed to provide and all their constraints. You should also enhance your implementations with code that enforces as many of these constraints as possible and produces appropriate errors if it discovers that the constraints are violated.

If, while implementing the player, you realize that your board and rule checker component do not provide all the operations you need, feel free to revisit their design and implementation. However, do record these changes so that we can discuss them during the code walks.

After you implement the player, wrap it in a test driver that reads JSON from STDIN and outputs JSON to stdout like in the previous assignments.

In particular the test driver should read from STDIN JSON values of the form:

["register"] or ["receive-stones",Stone] or ["make-a-move",Boards]

where

Stone and Boards are the same as for assignment 4.

When the test driver consumes:

a ["register"], it should reply with the name "no name" of the player as a JSON string;

a ["receive-stones",Stone], it should return nothing but it should set the internal state of the registered player to start a game playing as the player with the given Stone;

a ["make-a-move",Boards], if the given Boards are consistent with the rules of the game it should reply with Point where the Point corresponds to a legal placement for the player’ s Stone taking into account Boards and selecting anong the legal placements the one with the smallest column index and (secondarily) the smallest row index or with "pass" if no such move exists, otherwise it should reply with "This history makes no sense!".The strategy is pretty dumb but, after all, this is not an AI course. Instead of building effective players, we will focus on code organization and clarity.

Your test driver should output its replies to STDOUT for a sequence of the above JSON values as a JSON array. The sequence should start with a ["register"] followed by a ["receive-stones",Stone] followed by a series ["make-a-move",Boards]. The sequence of the ["make-a-move",Boards] inputs does not need to correspond to an actual game.

Deliverables: In your team’s dev GitHub repository, create a directory "Deliverables/5/5.1/" and deposit there a Makefile for your test driver. In your team’s testing GitHub repository, create a directory "5/5.1/" and deposit there five input files for the test driver with at least five inputs each and their expected output files. Name your player "no name" and the input files "input1", "input2", etc. and the corresponding output files "output1", "output2", etc.

2 Extend, Build and Test

Implement another player similar to the one described above but with a different dumb strategy. This time your driver should prioritize capturing the opponent’s stones. In particular, the strategy should have a parameter n that denotes the length of the sequence of moves of your player within which capture is possible independently of the moves of the opponent. That is, if n is equal to 3, the strategy should give priority to moves of the player that are at the beginning of a sequence of moves that leads to a capture of the opponent’s stones within 3 moves no matter how the opponent plays. Among these moves, the strategy should select the one with the smallest column and row as described in the first task of the assignment. If no such move exists, the strategy should select one move from all legal moves as described in the first task of the assignment.

Deliverables: In your team’s dev GitHub repository, create a directory "Deliverables/5/5.2/" and deposit there a Makefile for your test driver for a player where n is 1. In your team’s testing GitHub repository, create a directory "5/5.2/" and deposit there five input files for the test driver with at least five inputs each and their expected output files. Name the input files "input1", "input2", etc. and the corresponding output files "output1", "output2", etc.