Due date: 4/16 : MIDNIGHT
Squadron Scramble.com
Your boss has finally revealed your client's true goal: the construction
of a vastly popular web service (over TCP/IP, not HTTP) for running
automated Squadron Scramble competitions. Specifically, the client wishes
to deploy a Squadron Scramble administrator on port 8080 where automated
Squadron Scramble players can register and play a game.
Your Penultimate Task: [POINTS: 10] For this project you should
not modify the code for your administrator or player, except that
the administrator code should live up to all the tests run for the test
fests. Otherwise it has slim chances of running a complete
tournament. Because of the importance of this task, I have decided to
break it out and assign points separately. Naturally if your administrator
already lives up to all the tests in the test fest, you will receive those
10 points immediately.
Please understand this task also as a hint for establishing the robustness
of your player without getting credit for it.
Your Final Task: [POINTS: 50] Turn your game administrator from
Project 11 into an on-line administrator that serves
registration and game-playing requests on port 8080. Furthermore, turn
your best[*] game player into an on-line player that can register and play
a game of Squadron Scramble.
In order to create the communication among the game administrator and the
two to six players, you must use the remote proxy pattern instead. The
communication protocol for the remote proxy pattern is specified below. It
assumes a proxy player on the game administrator computer that
communicates with the proxy administrator on the player's computer. To get
started, the administrator computer should also run a server.
[*] The word "best" means most stable, least prone to crashing. In case
of a true competition you would want to turn your best-strategy player
into the one that is the most stable, least prone to crashes.
The Game Protocol
- Use case: a player registers with the administrator
To implement this protocol for a distributed setting, you should employ
the remote proxy pattern. Then the interchange looks like this:
SERVER CLIENT
=============================== WIRE ======================================
SomeOne
|
|
create() |
server remote-admin < ---------- |
create() | | |
admin <------------------ | | create() |
| | | player < ---- | = p
| | | | |
| | | | register(p) |
| | |<---------------- |
| | REGISTER(n) | | |
| | <------------------- | |
| create(n,..) | | | |
| remote-player <------ | = r | | |
| | | | | |
| register(r) | | | | |
| <--------------------- | | | |
| | . | | |
| | . | | |
| | . return: Boolean | | |
| ==========> | ==============================> | ===============> |
| | | |
QoS: 5 seconds for registration
Here CLIENT
and SERVER
are distinct processes
(possibly) running on distinct computers.
Once the server receives a message to start the game (see next use
case), it does not create a remote-player but returns false
to
the remote-admin
immediately.
- New use case: you starting a game:
SERVER CLIENT
=============================== WIRE ==============================
YOU server ... ... ...
| | admin
| START() | |
| ------------> | start() |
| | ------> |
| | <====== |
| <============ | |
| | |
START: choose an appropriate message format
Of course, it makes no sense to start a game unless enough players have
signed up for it. I suggest you display some information for each
registration message so that you know how many players are ready to play.
Hint: I recommend you use the start
method
on the client side to run a thread that listens to the TCP connection and
dispatches to the proper player method.
- Use case: the player receives the first hand of cards
SERVER CLIENT
============================ WIRE ===========================
admin remote-player remote-admin player
| | | |
| first-hand(h) | FIRST-HAND(h) | first-hand(h) |
| ------------> | --------------------> | -----------> |
| | | |
| <============ | <==================== | <=========== |
QoS: 5 seconds for handing over a hand
- Use case: a player receives the turn from admin
SERVER CLIENT
============================ WIRE ===========================
admin remote-player remote-admin player
| | | |
| create() | | |
| ----> turn | | |
| | | | |
| | | | |
| take(t) | | TAKE(t) | |
| ------------>| --------------------> | |
| | | | create() |
| | | p | -----> remote-turn
| | | | take(p)| |
| | | | -----------> |
| | | | | |
| | | | | |
. . . . . .
. . . . . .
. . . . . .
| | | | | |
| <====== |<== | <=================== | <===== |<=== |
QoS contract: a turn may not take more than 5 seconds
- Use case: the player requests the top-most card from the deck or some
cards from the stack:
SERVER CLIENT
=========================== WIRE =============================
admin turn remote-player remote-turn player
| | | | |
| | get(n) | GET(n) | get(n) |
| |<---------- |<-------------------- |<----- |
| | | | |
| | ========== | ==================> |=====> |
where
gafd() = get-a-card-from-deck()
| get-cards-from-stack(int)
QoS: NONE
- Use case: the player is informed that one of its bomber squadrons was
shot down
SERVER CLIENT
============================ WIRE ===========================
admin remote-player remote-admin player
| | | |
| inform(m) | INFORM(m) | inform(m) |
| -----------> | --------------------> | -----------> |
| | | |
| <=========== | <=================== | <=========== |
QoS: 5 seconds
- Use case: the player finds out that the game is over
You must equip your player with one more method: tend
. The
method is called when the game is over, with a string that represents the
result. (Why is this not needed for the end of a battle?)
;; player-tend: String -> Void
SERVER CLIENT
============================ WIRE ===========================
admin remote-player remote-admin player
| | | |
| tend(s) | TEND(m) | tend(m) |
| -----------> | --------------------> | -----------> |
| | | |
QoS: NONE. (The server does not expect an acknowledgment for this
method.)
The format of the external XML-encoded messages are available in
a separate file.