492 | Chapter 13: Symmetric Proxy Pattern
three moves has been selected, or if theMovebutton is clicked. To simplify matters,
allnameproperties are lowercase while thelabelproperties begin with an uppercase
letter. (e.g., Rock=label, rock=name). TheMovebutton is included to let the user
change her mind after selecting one of the three moves. By clicking the Move but-
ton, the player commits to the selected move by launching two methods,doMove( )
andlocalMove( ).
Dual moves
The function to actually make a move once its been selected by clicking the Move
button sends the move to the proxy usingdoMove( ),and stores it locally in a vari-
able withlocalMove( ). This is the heart of the Symmetric Proxy. The symmetry lies
in the fact that all moves are sent to both the local and proxy players.
The local move checks to be sure that the local player has not moved yet, and then
checks to see if the other side has moved. If the other side has moved, then the infor-
mation about the moves is turned over to theRefereeto determine and display the
outcome.
Now thedoMove( )is really nothing more than a call to the server-side script. It passes
the move to the server and does no more.
Proxy move
The onProxyMove( )method is the mirror image of thelocalMove( ). Because the
method is fired no matter which player moves, the algorithm in the method first filters
out the local move by splitting the string returned from the server into a move and a
player name. It looks at the player name, and if it’s the local’s name, it ignores it and
the move associated with it. (The move is handled by thelocalMove( )method.)
However, once the filtering has been completed, the algorithm is essentially the same
as the local move operation. Itdoesdisplay the fact that the opponent has moved by
displaying the name of the player butnotthe move. In this way, the application main-
tains the simultaneous nature of the play.
Referee object
The end game conditions are delegated to the Referee object. In this case, theReferee
object is theRPSsubclass contained within thetakeTurn( )method. By passing the
moves, output text field, and name of the array used to keep track of who took a turn
to the RPSobject’s moveComplete( ) template method, everything can be neatly
wrapped up. The single line,
rps.moveComplete(p1move,p2move,playerText,monitor);
takes advantage of the template method in theRefereeclass and launches the opera-
tions that make up the template method—doWinner( ), displayResults( ), and
resetGame( ).