Assignment 5 – Backgammon Players
Due Wednesday 4/28 5:00pm for the testing deliverables and Friday 4/30 11:59pm for the code deliverables
1 A Player Interface
name : -> string
returns the player's name
start-game : color string -> void
informs the player a game has started, its color, and what its opponent’s name is
turn : board dice -> listof moves
asks the player to take a turn
end-game : board boolean -> void
informs the player that the game is over, what the final board was, and if it won
This interface very naturally wants to have sequence contracts (as discussed in Lecture 3). The sequence contract affect both the players and the callers of the players, and have these restrictions:
The player may assume that it will not see two start-game messages in a row without seeing an end-game message in between.
Also, the player may assume that it will not see any take-turn messages unless it has already seen a start-game message (and has not yet seen the matching end-game message).
Finally, the player must always return the same string from the name method.
The player may not, however, make any other assumptions. For example, it may not assume that an end-game message is preceded by a take-turn message that has a board state that is only one move different from the previous message, nor may it assume that two adjacent take-turn moves differ by exactly one backgammon move.
And if there is any contract violation (sequence or otherwise), communication with the player stops, so no more messages will be delivered.
For the rest of this assignment you will implement code that uses this interface and code that implements this interface. Use an object (if you language has those) or some kind of value that lets you write functions that consume and produce players.
2 A Random Player
Revisit the component you built for assignment 4. Continue to work on it until you’re getting all of the test cases passing.
Once you have a working rule checker, re-use it to implement a Backgammon player. Your player should implement the interface desctribed above. You should also enhance your implementation with code that enforces as many of the inteface’s cosntraints constraints as possible and produces appropriate errors if it discovers that the constraints are violated.
As for the strategy your player uses when it plays, that is up to you but a fine choice is a player that picks a random move.
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.
The test driver’s JSON specification builds on that in assignment 4. Here’s the input and output specification:
test-case-5 | ::= | [ board, color, dice ] |
turn | ::= | [ [ cpos, cpos ], ... ] |
test-case-5-result | ::= | turn |
Test Deliverables: In your team’s GitHub repository, create a directory "Deliverables/5/5.1/" and put five test cases named "input1.json", etc. The should contain JSON matching test-case-5. For the expected outputs, you need only include one of the possible legal moves your player may choose.
You will receive up to ten points for your tests, two points for each valid pair of input and output files.
Code Deliverables: In your team’s GitHub repository, create a directory "Deliverables/5/5.1/" and put a Makefile for the test driver for your team’s random player that generates the usual run executable. The oracle will not check to make sure that your player (or other students’ players) produces the move you expect; it will simply check that the move in the output file is a legal move.
You will receive up to twenty five points for your random player depending on how many tests its test driver passes.
3 A Bop-Happy Player
Implement a second player that follows that implements the same interface as the one described above but with a different strategy. You are welcome to choose the strategy but a good strategy is to think of assigning the board that results from every possible legal move a score (as a number), and then picking the board that has the highest score. A good scoring function is to take the difference between the distance that your checkers have before they get home (in total) and subtracting that same distance, but for your opponent.
Deliverables: In your team’s GitHub repository, create a directory "Deliverables/5/5.2/" and deposit there a Makefile for your test driver for the second player.
The test files from 5.1 will be used for both players.
You will receive up to twenty five points for your bob-happy player depending on how many tests its test driver passes.