Project 1 - Nim Server and Client

Client-Server Interfaces, Spring 2001


Table of Contents

Due Date

This assignment is due on Thursday, 12 April, no later than 2:00 p.m.

See the assignment turn-in page for instructions on turning in your assignment.

Background

Nim is a simple, two-player game involving a list of between 3 and 10 non-negative integers. Turns alternate between the two players. At each turn, a player selects one of the numbers in the list and subtracts a positive integer from it; the resulting value must be non-negative. Play ends when all numbers on the list are zero; the player reducing the last non-zero number to zero is the winner.

Here is an example game with three-number list; player A goes first.

24, 17, 3 Player A subtracts 6 from 24.
18, 17, 3 Player B subtracts 3 from 17.
18, 14, 3 Player A subtracts 5 from 18.
13, 14, 3 Player B subtracts 3 from 13.
10, 14, 3 Player A subtracts 5 from 14.
10, 9, 3 Player B subtracts 3 from 10.
7, 9, 3 Player A subtracts 5 from 9.
7, 4, 3 Player B subtracts 3 from 4.
7, 1, 3 Player A subtracts 5 from 7.
2, 1, 3 Player B takes the last row.
2, 1 Player A subtracts 1 from 2.
1, 1 Player B takes one of the two remaining rows.
1 Player A takes the remaining row and wins.

The Project

This project involves creating a Nim server and a Nim client. The Nim client plays Nim; the Nim server coordinates two Nim clients so they play a game together. The event diagram
example nim client-server
interaction
gives a general idea of the way in which clients and servers interact, as well as the names of the messages passed between the clients and the server.

Messages

Each message starts with a one-byte value giving the message type; the recognized message types are defined in /export/opt/cs-537/p1/nim.h. The structure of the rest of the message depends on the message type.

play_msg
A play message contains only the message type; it contains no other information.

turn_msg
A turn message contains the message type followed by one unsigned byte holding the size of the number list contained in the rest of the message. The number-list size must be positive. Following the list size is a sequence of n four-byte values, where n is the size of the number list. Each four-byte value holds one positive unsigned integer.

move_msg
A move message contains the message type followed by an unsigned byte holding a list index, followed by a four-byte sequence holding an unsigned integer. If the list index is l and the unsigned integer is i, the effect of a move message is to subtract i from the l-th number in the list. The list uses zero-origin indexing; that is, the first number in the list has index 0.

win_msg
A win message contains only the message type; it contains no other information.

lose_msg
A lose message contains only the message type; it contains no other information.

exit_msg
An exit message contains only the message type; it contains no other information.
All values are in network-byte order.

Client-Server Interaction

Clients and a server communicate using TCP. The client should support the -h and -p command-line options to specify the server's host IP address and port number. The server should support the -p command-line option to pick specific port numbers on which to listen. The server may also rely on a system selected port number, and may assume a default port number which is known to the client.

Once a client has connected to a server, it should send a play message to the server to indicate its willingness to play a game. A client cannot be included in a game until it sends a play message.

The server should start a game when it has two clients that have indicated a willingness to play. To start a game, the server randomly generates a positive list size, and then randomly generates numbers for the list. Once the list is generated, the server sends it to one of the two clients. If both clients are new, the server randomly picks one to start the game; otherwise, the server starts the game with the newer of the two clients.

When the server receives a move message, it adjusts the number list according to the information in the move message and sends the new list to the other client. To conserve network bandwidth, the server compresses out zero numbers in the list; that is, over the course of a game, the list will shrink in size.

The client that sends the move that empties the list wins the game and receives a win message from the server. The server sends a lose message to the other client and closes its connection. The winner remains connected to the server to face the next client. The winning client need not send another play message to start the next game.

A client may withdraw from the server by sending an exit message. If a game is in progress, the server declares the other client the winner, sending it a win message (this means a client may receive a win message before the game is over). A client that disconnects from the server without issuing a connect message is assumed to have exited.

Clients that connect to the server while a game is in progress are queued up at the server. When the current game ends, the server dequeues a client to start the next game; a client must have issued a play message before it can be dequeued for a game. A client may also issue an exit message while it's in the queue.

Error Interaction

If a server detects erroneous behavior from a client, the server disconnects from the client; if the client is involved in a game, the other client is declared the winner.

If a client detects erroneous behavior from the server, it should disconnect from the server, print an error message to std-err describing the problem, and exit.

Erroneous behavior includes receiving undefined messages, receiving incorrectly formatted messages, receiving messages with bad values, receiving messages out of expected order, failure to interact within a reasonable amount of time, and unexpected connection terminations.


This page last modified on 26 February 2001.