CS680 Notes on Communication in 2-player Pong
From class Tuesday, Dec. 2
With hw7a, we will have the basic DB actions available:
// start a match, phase 1: determines whether caller is end A or end B
// and what the matchId is
public PongMatch startMatch1(double maxX, double maxY) throws ServiceException
// startMatch, phase 2: make sure 2 players are matched up
public PongMatch startMatch2(int matchId) throws ServiceException
// addMove: add a new move
public PongMove addMove(int matchId, int index, String end, double paddleY,
String status) throws ServiceException
// checkMove: check match row for increased moveCount
// return immediately if nothing to report, with null PongMove
// or pick up the new move if it's available and return it
// for ex., checkMove(1, 1), checks moveCount > 2, since index = 1 means 2 moves
// have already been done
public PongMove checkMove(int matchId, int indexSeen) throws ServiceException
These are all short actions, designed to fit in a single DB
transaction. We need to loop over startMatch2 actions until a second
player shows up (for player A only). We need to loop over checkMoves
until a new move shows up. We saw that form a useful bundle of actions
by doing an addMove followed by a loop of checkMoves, since these are
always needed in that order, except for the first checkMoves of B.
Therefore we can define longer/combo calls as follows:
PongMatch startMatch(int matchId, double maxX, double maxY)
if matchId == 0, then this is startMatch1 with significant maxX, maxY
if matchId > 0, then this loops over startMatch2 until it returns with playerCount == 2
PongMove getPutMove(int matchId, int index, String end, double paddleY, String status)
Except in the special case that status is "BLANK", do addMove. Then in
all cases, loop over checkMove until it returns a new move, and return
that move.
In order to force all get-move actions into this mold, we define a new
status value "BLANK" for B to use at first, when it doesn't have a real
move to report and is just waiting for the INIT move from A.
Note: The arguments to startMatch and getPutMove are of the form that
are easy to use with the Service layer of the hw7a solution. It
is possible to use PongMatch and PongMove type arguments, but that
means we have to create such objects above the service layer, which is
not recommended for simple Hibernate apps.
There are two executions of PlayGame, one starts a little after the
other, so there are two windows on the screen in the simple development
setup, with HSQLDB doing the communication. Both windows show the same
picture of the game, although there will be (hopefully small) time
differences due to communication delay.
Execution from PongGame perspective: each startMatch or getPutMatch is
done in a separate thread with a FutureTask<PongMatch> or
FutureTask<PongMove>, so that the UI can continue operating in
its own thread.
- First PongGame does startMatch with matchId = 0, finds out it's A, then startMatch with matchId > 0 to wait for player B.
- Second PongGame does startMatch with matchId = 0, finds out it's
B, then does getPutMove with "BLANK" and starts waiting for A's INIT
move.
- PongGame A then sees its second startMatch return, and start the ball (on the left). Then it calls getPutMove with INIT.
- B has been waiting for A's move, and now it returns. B starts the
ball (on the left). When B's player hits the ball, B does putGetMove
for it, and starts waiting for A's move.
- A has been waiting for B's move, and now it returns ...
See the sequence diagram.