Contents

Cmput 455 Assignment 1

Due Sep 18, 11:55pm. Submit via eClass submission link on the main eClass course page.
Late submission (with 20% deduction) Sep 20, 11:55pm. Submit via separate eClass link for late submissions.

In this assignment, you implement a random player for the game Ninuki, one of the many Five in a Row games. You do this by modifying the assignment 1 starter code which is based on the Go0 program from class, but modified to make your job easier. The main steps are:

  1. Implement the rules of Ninuki, including creating a list of legal moves, detecting a win or a draw, and playing a move.
  2. Write a random Ninuki player based on the Go0 player in the starter code.
  3. Test your program on the public test cases, and on more tests of your own design.

Setup

  1. First, make sure you have completed your Activities up to and including 3c. In these activities you set up Python 3, NumPy, and GoGui 1.5.3, install and run the Go0 and Go1 programs, do the sample session with the Go1 program.
  2. Download and expand assignment1.tgz . Go to the directory assignment1, which contains:

Rules of Ninuki

Ninuki or Five in a Row is played on a Go board. The game starts with an empty board, and players Black and White alternate to place a stone of their color on a grid point. Black goes first. The goal of the game is be the first player to:

If neither player creates five in a row or captures 10 stones, then the game is a draw.

For more information on the game, you can see the GoMoku wikipedia page. Many variants of the rules are discussed on that page. Our variant of Ninuki is similar, but not quite identical to, the variants called Ninuki-renju and Pente.

Capturing Stones

A player can capture two opponent stones by "sandwiching" them between their own stones. For example, if X is to play and there is a pattern "XOO." in any direction on the board, then X can capture the two stones "OO" by playing on the empty point on the other side, resulting in the pattern "X..X". (Here, a dot denotes an empty point.)

It is possible that a single stone captures several pairs of opponent stones. For example, in the pattern "XOO.OOX", a move by X in the center captures four stones, leading to "X..X..X". More examples are given in the public test cases.

There is no "suicide". For example, if the pattern "XO.X" already exists on the board, then O can play to create "XOOX" and is not captured.

After stones have been captured, both players are free to play on those points again in the future.

Some Implementation Differences between Go and Ninuki

When implementing your solution based on the starter code, be aware of the commonalities and differences between the two games. The rules of Ninuki are simpler. Checking legality of moves is simpler, there is only one basic capturing pattern, no suicide, and no ko rule to deal with. However, finding out whether the game is over is more complex. In Go, this is defined by consecutive passes. In Ninuki, you need to check if a player has five in a row, or has captured enough stones.

GTP Commands

We will test your program using the GTP commands below. These commands are already implemented in the starter code, but the implementation either is for Go or is just a stub that returns "unknown" or similar. You only need to change or implement the commands as indicated below.

Public Test Cases

The public test cases are in file assignment1-public-tests.gtp in the assignment1 directory. Most tests currently fail, since the program does not implement those commands correctly yet. See Testing Procedure below for examples.

Note that our given test cases include only a small number of cases. For evaluation, we will use a more comprehensive set of tests.

Testing Procedure

All our tests will be on a Ninuki board of size 19x19 or smaller. As in assignment1-public-tests.gtp, test cases are written as text files containing a sequence of GTP commands. Test cases contain both unnumbered GTP commands to set up a position, and numbered GTP commands to do the tests. Each test is followed by the expected correct answer.

What to Submit

Submit a single tgz file called assignment1.tgz which contains exactly the following (and nothing else):

A single directory assignment1 which contains all the files in your solution, namely:

  1. All the files from the original assignment1 directory, but with the python code modified to solve the assignment.
  2. Your presubmission.log file.
  3. A file readme.txt which lists the names and student IDs of your team. List the designated submitter first.

Do Your Own Pre-submission Test

Follow the steps below on a standard Linux undergraduate machine, and create a text file presubmission.log that shows a copy of your command line presubmission testing.

  1. Make sure the content of your assignment1 folder is correct, then create your submission with a command like tar -cvzf assignment1.tgz assignment1
  2. Use the Linux script command to log your testing session
  3. Copy your assignment1.tgz into a new directory
  4. Unpack it
  5. Run gogui-regress with your program, using assignment1-public-tests.gtp as input
  6. Stop script logging here with the command exit
  7. Add file presubmission.log to your assignment1, and compress it again
  8. Use tar -tf for a final check of your assignment1.tgz contents. Use the checklist below
  9. If you see extra files included in your tgz file that do not belong:
  10. Fix any problems, then submit on eClass when you're ready

Marking

There will be total of 5 marks for this assignment.

Code that does not run, or just hardcodes the public tests case by case, will receive a mark of 0. If your code needs fixes, you need to submit a revised version before the late submission deadline. TA will not attempt to fix your code under any circumstances. Use the discussion forum or consult the teaching team in case of questions.

Details - Read Them All!

Details of the play command

Attempt to play a move of given color on the given coordinate. First check if the move is legal according to the rules of Ninuki. If yes, then play it and update the board according to the rules. If no, then output an error message and do not change the board. The format of an error message is:

illegal move: "copy of the input argument(s)" reason

The possible reasons for error messages are listed below. Check them in the order given and output the first error only:

In the starter code, this command is implemented for Go, not for Ninuki.

Details of the gogui-rules_legal_moves command

If the game is over, return an empty list. Otherwise, return a list of all empty points on the board in sorted order.

In the starter code, this command always returns an empty list.

The Go0/Go1 engine also implements a legal_moves command for the game of Go. You can just ignore that.

Details for the gogui-rules_final_result command

Here, one of the first three answers black, white, draw should only be given if the game is over. The fourth answer unknown should always be returned if this command is called for a board where the game is not over yet.

In the starter code, this command just returns unknown.

Details for end of game

There are three different cases which end the game. First, if a player creates a row of five or more stones, that player wins. Second, if a player captures a total of 10 or more stones, that player wins. Third, if the board is completely filled with stones, but no player has won, then the game is a draw. The gogui-rules_final_result command should output either the color of the winner, or draw.

The genmove command at the end of a game: Before the end of a game, genmove will play a random legal move and gives the move as its response. If the game is over because the opponent just won, the response of genmove should be:

resign

If the game is over because the board is full and it is a draw, the response should be

pass

This is the only circumstance in which pass should be generated. The reason for this specification is that we can more easily use the tools for Go in this way.

In the starter code, genmove is implemented for Go, not for Ninuki.


Last modified: Sep 1, 2023, Martin Müller