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.
  1. First PongGame does startMatch with matchId = 0, finds out it's A, then startMatch with matchId > 0 to wait for player B.
  2. 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.
  3. PongGame A then sees its second startMatch return, and start the ball (on the left). Then it calls getPutMove with INIT.
  4. 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.
  5. A has been waiting for B's move, and now it returns ...
See the sequence diagram.