⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 752-756.html

📁 java game programming e-book
💻 HTML
字号:
<HTML>
<HEAD>
<META name=vsisbn content="1571690433"><META name=vstitle content="Black Art of Java Game Programming"><META name=vsauthor content="Joel Fan"><META name=vsimprint content="Sams"><META name=vspublisher content="Macmillan Computer Publishing"><META name=vspubdate content="11/01/96"><META name=vscategory content="Web and Software Development: Programming, Scripting, and Markup Languages: Java"><TITLE>Black Art of Java Game Programming:The Internet MahJong Server</TITLE>
<!-- HEADER --><STYLE type="text/css">  <!-- A:hover  { 	color : Red; } --></STYLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><script><!--function displayWindow(url, width, height) {         var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes');	if (Win) {		Win.focus();	}}//--></script><SCRIPT><!--function popUp(url) {        var Win = window.open(url,"displayWindow",'width=400,height=300,resizable=1,scrollbars=yes');	if (Win) {		Win.focus();	}}//--></SCRIPT><script language="JavaScript1.2"><!--function checkForQuery(fm) {  /* get the query value */  var i = escape(fm.query.value);  if (i == "") {      alert('Please enter a search word or phrase');      return false;  }                  /* query is blank, dont run the .jsp file */  else return true;  /* execute the .jsp file */}//--></script></HEAD><BODY> 
<TABLE border=0 cellspacing=0 cellpadding=0>
<tr>
<td width=75 valign=top>
<img src="../1571690433.gif" width=60 height=73 alt="Black Art of Java Game Programming" border="1">
</td>
<td align="left">
    <font face="arial, helvetica" size="-1" color="#336633"><b>Black Art of Java Game Programming</b></font>
    <br>
    <font face="arial, helvetica" size="-1"><i>by Joel Fan</i>
    <br>
    Sams,&nbsp;Macmillan Computer Publishing
    <br>
    <b>ISBN:</b>&nbsp;1571690433<b>&nbsp;&nbsp;&nbsp;Pub Date:</b>&nbsp;11/01/96</font>&nbsp;&nbsp;
</td>
</tr>
</table>
<P>

<!--ISBN=1571690433//-->
<!--TITLE=Black Art of Java Game Programming//-->
<!--AUTHOR=Joel Fan//-->
<!--AUTHOR=Eric Ries//-->
<!--AUTHOR=Calin Tenitchi//-->
<!--PUBLISHER=Macmillan Computer Publishing//-->
<!--IMPRINT=Sams//-->
<!--CHAPTER=18//-->
<!--PAGES=752-756//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="749-752.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="756-759.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading32"></A><FONT COLOR="#000077">A Client-Server Model for MahJong</FONT></H4>
<P>There are several models for client-server applications. I propose to use a simple one: The server handles everything about game play. The client keeps information locally, but doesn&#146;t do any decision-making. When the user takes an action, the client simply forwards it to the server for further scrutiny; when the server responds, the client updates the GUI components to restrict the user&#146;s future actions. Another possible model is to let the client deal with the user&#146;s actions locally, and only inform the server when a legal play is made. I prefer the former, because it is consistent, less prone to synchronization problems, copes well with future changes in the game structure, and keeps &#147;hackers&#148; from running a modified client program and getting unfair advantage.
</P>
<P>This approach also makes the client extremely simple. For each user action, it just sends a packet to the server, and the setup to wait for the response, which it displays graphically. For playing MahJong, it suffices to use the TileWindow class to update tiles and enable/disable MahJong related buttons. They are easy to write, so I won&#146;t give any code examples here.</P>
<P>I define only one type of client-to-server packet for MahJong games: CP_PLAY. It contains an action and a reference tile. Table 18-4 shows the kind of information this packet type carries.</P>
<TABLE WIDTH="100%"><CAPTION ALIGN=LEFT><B>Table 18-4</B> CP_PLAY fields and values
<TR>
<TH COLSPAN="3"><HR>
<TR>
<TH WIDTH="30%" ALIGN="LEFT">Action
<TH WIDTH="35%" ALIGN="LEFT" VALIGN="BOTTOM">Uses tile?
<TH WIDTH="35%" ALIGN="LEFT" VALIGN="BOTTOM">Description
<TR>
<TD COLSPAN="3"><HR>
<TR>
<TD>PASS = 0
<TD>no
<TD>Acknowledgement only.
<TR>
<TD>DRAW = 1
<TD>no
<TD>Bid to draw a new tile.
<TR>
<TD VALIGN="TOP">CONN_UP = 2
<TD VALIGN="TOP">no
<TD>Bid to make a chow, with two higher tiles.
<TR>
<TD VALIGN="TOP">CONN_MD = 3
<TD VALIGN="TOP">no
<TD>Bid to make a chow, with two sandwiching tiles.
<TR>
<TD VALIGN="TOP">CONN_DN = 4
<TD VALIGN="TOP">no
<TD>Bid to make a chow, with two lower tiles.
<TR>
<TD>TRIP = 5
<TD>no
<TD>Bid to make a pong.
<TR>
<TD>QUAD = 6
<TD>no
<TD>Bid to make a gong.
<TR>
<TD>DISCARD = 7
<TD>yes
<TD>Make a discard.
<TR>
<TD VALIGN="TOP">FOUR = 8
<TD VALIGN="TOP">yes
<TD>Make a gong with a concealed tile.
<TR>
<TD>WIN = 9
<TD>no
<TD>Claim to win the game.
<TR>
<TD COLSPAN="3"><HR>
</TABLE>
<P>From the server&#146;s point of view, a MahJong table is a finite-state machine. It has a status plus a set of variables. Figure 18-5 shows how a table reacts to game plays.
</P>
<P><A NAME="Fig5"></A><A HREF="javascript:displayWindow('images/18-05.jpg',598,701 )"><IMG SRC="images/18-05t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/18-05.jpg',598,701)"><FONT COLOR="#000077"><B>Figure 18-5</B></FONT></A>&nbsp;&nbsp;MahJong as a finite-state machine</P>
<P>Accordingly, the following field variables should be added to the Table class:
</P>
<!-- CODE //-->
<PRE>
  // constants for Table.status:
  public static final int IDLE = 0;      // no game in progress
  public static final int DISCARD = 1;   // someone&#146;s turn to discard
  public static final int AUCTION = 2;   // tile discarded, bid for it
  public static final int FOURTH = 3;    // gong with a 4th tile
  public int status = IDLE;              // table status
  public int turn = -1;                  // seat of player having turn
  public int dealer = -1;                // seat of dealer
  public byte active = 0;                // discarded tile
  public byte[] actions =                // plays made by the players
  &#123; -1, -1, -1, -1 &#125;;
public byte[] action_masks =           // acceptable plays
  &#123; 1, 1, 1, 1 &#125;;
Hand stockpile = new Hand(144);        // stockpile to draw tiles from
Hand[] pri_hands = new Hand[4];        // concealed hands
Hand[] pub_hands = new Hand[4];        // revealed hands
Hand[] semi_pubs = new Hand[4];        // concealed gongs
Hand[] out_tiles = new Hand[4];        // previously discarded tiles
Hand[] winning = new Hand[4];          // mahjong pattern
</PRE>
<!-- END CODE //-->
<P>A player&#146;s hand could be stored in the Player class, but I chose to think of it as belonging to that player&#146;s seat rather than the player himself. This way, if a player leaves the table, someone else can take his seat and continue the game with his hand.
</P>
<P>The server needs to send the clients various types of packets. They typically contain the game state or each player&#146;s hand. These packets are summarized in Table 18-5.</P>
<TABLE WIDTH="100%"><CAPTION ALIGN=LEFT><B>Table 18-5</B> MahJong-related server packets
<TR>
<TH COLSPAN="3"><HR>
<TR>
<TH WIDTH="40%" ALIGN="LEFT">Packet Type
<TH WIDTH="25%" ALIGN="LEFT">Fields
<TH WIDTH="35%" ALIGN="LEFT">Description
<TR>
<TD COLSPAN="3"><HR>
<TR>
<TD VALIGN="TOP">SP_GAME
<TD VALIGN="TOP">dealer
<TD>New game and the dealer.
<TR>
<TD>SP_TURN
<TD>seat
<TD>His turn to discard.
<TR>
<TD VALIGN="TOP">SP_DISCARD
<TD VALIGN="TOP">tile
<TD>A tile is discarded, or fourth of a gong.
<TR>
<TD>SP_TILES
<TD>seat, hand
<TD>Tiles of a player.
<TR>
<TD>SP_YOUR_PRIV
<TD>hand
<TD>Your concealed tiles.
<TR>
<TD VALIGN="TOP">SP_YOUR_DRAW
<TD VALIGN="TOP">tile
<TD>The tile you just drew in.
<TR>
<TD VALIGN="TOP">SP_YOUR_PLAY
<TD VALIGN="TOP">result
<TD>Was your last play accepted?
<TR>
<TD VALIGN="TOP">SP_YOUR_CHOICES
<TD VALIGN="TOP">flags
<TD>You can make these plays.
<TR>
<TD>SP_OUT_TILES
<TD>seat, hand
<TD>Previous discards.
<TR>
<TD>SP_WIN
<TD>seat
<TD>He wins the game.
<TR>
<TD COLSPAN="3"><HR>
</TABLE>
<H4 ALIGN="LEFT"><A NAME="Heading33"></A><FONT COLOR="#000077">Starting a New Game</FONT></H4>
<P>A new game starts when the table gets four players. First, in Table.join(), we check if the table has four players. If so, we call the NewGame() method, which does the following things:
</P>
<DL>
<DD><B>1.</B>&nbsp;&nbsp;Tells everyone that a new game has started, by sending an SP_GAME.
<DD><B>2.</B>&nbsp;&nbsp;Creates and shuffles a stockpile of 144 tiles.
<DD><B>3.</B>&nbsp;&nbsp;Deals 13 tiles to each player, and a 14th tile to a selected dealer.
<DD><B>4.</B>&nbsp;&nbsp;Sends updates on all tiles with the appropriate SP_TILES and SP_YOUR_PRIV packets. See the Table.play() method below to see how this is done.
<DD><B>5.</B>&nbsp;&nbsp;Tells everyone the dealer has the turn to discard, by sending an SP_TURN.
</DL>
<P>The NewGame() method is also called when a game ends and all four players agree to start a new one (say, by sending a CP_PLAY packet with action PASS).
</P>
<H4 ALIGN="LEFT"><A NAME="Heading34"></A><FONT COLOR="#000077">Adding the Server Code for Game Play</FONT></H4>
<P>Now we can finally add server code to handle a MahJong game. This involves writing a play() method in the Table class, and a handler hdPlay() in Player that reads in a CP_PLAY packet and calls the play() method of that player&#146;s table.
</P>
<!-- CODE SNIP //-->
<PRE>
// in class Table
public synchronized void play (Player him, byte action, byte tile) &#123;&#125;
</PRE>
<!-- END CODE SNIP //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="749-752.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="756-759.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -