See the assignment turn-in page (last modified on 9 February 2004) for instructions on turning in your assignment.
The board is n-by-n, where n > 2. Each square is identified with a pair of positive integers (x, y), 0 <= x < n with (0, 0) in the lower left corner. x increases to the right; y increases going up.
The game starts with some number of knights randomly scattered around the board; unlike regular chess, a square can hold more than one knight. Knights move as they do in chess: two squares straight then one to the right or left. However, any move that would place the knight further from the barn than it was before the move is illegal.
Distance is measured using the Manhattan distance; the Manhattan distance between two squares is the number of squares traversed (exclusive of the initial and final squares) by moving first horizontally (or vertically) and then vertically (or horizontally). For example, the two squares A and B
are at Manhattan distance 3 + 2 = 5 from each other. Notice that the pivot square (the square in which the movement direction changes from horizontal to vertical or vice versa) is counted twice.
Using the Manhattan distnace admits a larger number of legal moves
than is allowed by Conway.
The distance measured is from a knight's position to the back of the barn at (0, n - 1).
The two players alternate turns. At each turn, a player moves all knights not yet in the barn; once a knight reaches the barn, it may be removed from the board. Each knight not yet in the barn is moved exactly once per turn. Unlike chess, a square may hold more than one knight. The loser is the player who moves the last uncorraled knight into the barn.
/export/home/class/cs-537/p1b/corral.h
. The
structure of the rest of the message depends on the message tag.
where
error
- The error message tag.
'~'
(ASCII value 126 decimal) inclusive. Characters outside this range
are invalid.
where
game
- The game message tag.
where
lose
- The lose message tag.
where
move
- The move message tag.
where
play
- The play message tag.
where
quit
- The quit message tag.
where
win
- The win message tag.
gives a general idea of the way in which clients and servers interact. More specifically, the interaction between client and server can be broken up into three phases: set-up, play, and shut-down.
Upon receiving a play message from the connecting client, the server pairs the playing client with a waiting client and starts a game of Corral between the two clients. If there is no waiting client, the playing client becomes the waiting client. A waiting client may wait an arbitrarily long time.
Note that the server can have at most one waiting client, but can have an arbitrary number of clients that are connected but are still missing their play messages.
The playing client receiving a move message from the server has somewhere around 10 seconds to respond with a move message. The playing client can reset the 10 second clock by sending a move message with n equal to zero back to the server; the client then has another 30 seconds or so to send another move message.
When the server receives a non-empty move message from the client, it adjusts the board according to the moves given in the move message. If the game is over, the server shuts the game down; otherwise, it sends a move message to the other client in the game.
When the server receives an empty move message, it resets its move-response time-out clock for that game. A client can send at most 10 consecutive empty move messages during its turn. If the client fails to send any moves after 10 consecutive empty move messages, the server should disconnect the client and declare the other playing client the winner.
A client may withdraw from the server at any time by sending a quit 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). If a client disconnects from the server without sending an quit message, the servers should behave as if it had received a quit from the disconnected client.
The receiver of an error message should assume the connection over which the message arrived has been closed (this means the receiver should not try to send an error message back when it receives a faulty error message). The receiver should print the error message (if any) to std-err and close the connection. What happens next depends on the receiver; a client should probably halt, a server should clean-up the connection and continue.
Error messages can be sent at any time, even at times when no error has been detected by the sender. The receiver's response to an error message, however, should always be as described in the previous paragraph.
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.
The client should support the -h
and -p
command-line options to
specify the server's host IP address and listening-port number, respectively.
The server should support the -p
command-line option to pick specific
listening-port number.
The client should implement an automated Corral player so it can play the game without input from the user. The client should not prompt the user for moves (you can add this as an option as you want, but the client's default behavior should be to generate moves automatically by itself). And remember, the objective of this project is to learn about client-server computing, not to implement winning algorithms for Corral. Having the client generate random moves is good enough.
The server should handle as many simultaneous games as possible. The maximum number of simultaneous games your sever should be able to handle depends, in part, on your implementation, but certainly the maximum number of open file descriptors allowed per process is one reasonable upper limit.
The choice of implementation language is up to you. However, you should make sure that whatever you chose is available on the cslab machines, which is where I'm going to test your code. It would also be nice, but not required, that your system also run on rockhopper.
clnt
. The srvr target
should build the Corral server; the name of the executable should be srvr
.
When you test or turn-in your project, the turn-in script runs (among other things) the following three commands:
$ make clean $ make clnt $ make srvr
You should make sure this works correctly.
There's an example makefile you can use in the assignment directory. If anybody feels the need to use ant or some other build mechanism, they should get in touch with me (essentially, what I'll tell you to put it in a makefile, but we'll have to work that out together).
This page last modified on 25 February 2004.