📄 746-749.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, Macmillan Computer Publishing
<br>
<b>ISBN:</b> 1571690433<b> Pub Date:</b> 11/01/96</font>
</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=746-749//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="742-746.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="749-752.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P>There is a table area for displaying each player’s tiles. For “myself,” I use another area near the bottom to display the tiles that are concealed from others; other players’ concealed tiles show up facedown in their respective tile areas. In the center is a small area to show the current discarded tile, and around it I display player names and other information. At the bottom of the table panel, I display a row of buttons, each corresponding to a certain MahJong play (pass, chow, etc.). The server determines which buttons are clickable at any particular stage of the game; clicking on a button makes the corresponding play.
</P>
<P>The table panel uses a GridBagLayout, with the bottom row of buttons in a subpanel managed by a FlowLayout. I summarize the values for GridBagConstraints fields in Table 18-3.</P>
<TABLE WIDTH="100%"><CAPTION ALIGN=LEFT><B>Table 18-3</B> Laying out the MahJong table
<TR>
<TH COLSPAN="4"><HR>
<TR>
<TH WIDTH="30%" ALIGN="LEFT" VALIGN="BOTTOM">Component
<TH WIDTH="20%" ALIGN="LEFT" VALIGN="BOTTOM">gridx, gridy
<TH WIDTH="30%" ALIGN="LEFT" VALIGN="BOTTOM">gridwidth, gridheight
<TH WIDTH="20%" ALIGN="LEFT">weightx, weighty
<TR>
<TD COLSPAN="4"><HR>
<TR>
<TD>seat[0]
<TD>1, 6
<TD>3, 1
<TD>0.0, 0.0
<TR>
<TD>seat[1]
<TD>4, 1
<TD>1, 5
<TD>0.0, 0.0
<TR>
<TD>seat[2]
<TD>1, 0
<TD>3, 1
<TD>0.0, 0.0
<TR>
<TD>seat[3]
<TD>0, 1
<TD>1, 5
<TD>0.0, 0.0
<TR>
<TD>discard
<TD>2, 3
<TD>1, 1
<TD>0.0, 0.0
<TR>
<TD>my_concealed
<TD>0, 7
<TD>5, 1
<TD>1.0, 0.0
<TR>
<TD>name[0]
<TD>2, 4
<TD>1, 1
<TD>0.0, 0.0
<TR>
<TD>name[1]
<TD>3, 3
<TD>1, 1
<TD>0.0, 0.0
<TR>
<TD>name[2]
<TD>2, 2
<TD>1, 1
<TD>0.0, 0.0
<TR>
<TD>name[3]
<TD>1, 3
<TD>1, 1
<TD>0.0, 0.0
<TR>
<TD>prompt_1
<TD>1, 1
<TD>3, 1
<TD>0.0, 1.0
<TR>
<TD>prompt_2
<TD>1, 5
<TD>3, 1
<TD>0.0, 1.0
<TR>
<TD>low_panel
<TD>0, 8
<TD>5, 1
<TD>0.0, 0.0
<TR>
<TD COLSPAN="4"><HR>
</TABLE>
<H4 ALIGN="LEFT"><A NAME="Heading28"></A><FONT COLOR="#000077">The Tile and Hand Classes</FONT></H4>
<P>Since there are a total of 42 distinct tiles in MahJong, a tile can be represented by a byte. I use the numbers 1 to 42 and reserve 0 for a concealed tile.
</P>
<P>The Tile class only needs static methods that figure out the category and value of a tile given its byte representation.</P>
<P>The Hand class stores a sequence of tiles, together with the following information:</P>
<DL>
<DD><B>•</B> Subsets of tiles can be grouped together. Typically, a group may be a <I>set</I> or a <I>pair</I> in MahJong terminology.
<DD><B>•</B> A number of tiles/groups may be marked. Marks would cause highlighting when the hand is displayed.
<DD><B>•</B> Operations like grouping and deletion take effect on marked tiles.
</DL>
<P>Thus, the prototype of the Hand class would pretty much be
</P>
<!-- CODE //-->
<PRE>
packet common;
public class Hand {
// the following 3 arrays have 1 element for each tile
private byte[] tiles;
private byte[] groups;
private boolean[] select;
private int length; // number of tiles
// constants for groups:
public static final byte SINGLE = 0; // singleton tile
public static final byte HEAD = 1; // head of a group
public static final byte MIDDLE = 2; // middle of a group
public static final byte TAIL = 3; // tail of a group
// construct a hand with buffer size
public Hand (int size) {}
// return the length variable
public int length () {}
// truncate the hand to given length
public synchronized int setLength (int len) {}
// return the tile at given location
public synchronized byte tileAt (int pos) {}
// set the tile at given location
public synchronized byte setTileAt (int pos, byte tile, byte gp) {}
// return the group info at given location
public synchronized bytre groupAt (int pos) {}
// return the marker info at given location
public synchronized boolean isSelected (int pos) {}
// add a tile to the end of the hand, returns the hand itself
public synchronized Hand addTile (byte t, byte g, boolean s) {}
// remove a tile at given location
public synchronized Hand killTile (int pos) {}
// insert a tile at given location
public synchronized Hand insertTile (int pos, byte t,
group g, boolean s) {}
// append another hand to this one
public synchronized Hand append (Hand h) {}
// mark a tile/group, return the pos of the 1st tile in the group
public synchronized int select (int pos) {}
// undo the above process
public synchronized int unselect (int pos) {}
// unmark all the tiles
public synchronized void unselectAll () {}
// make all tiles SINGLE and unmarked
public synchronized void clearAll () {}
// group together all marked tiles, return false if none marked
public synchronized boolean group () {}
// make all marked tiles SINGLE, return false if none marked
public synchronized boolean ungroup () {}
// see whether the marked tiles form a single group
public synchronized boolean isGroup () {}
// remove all marked tiles, return false if none marked
public synchronized boolean delete () {}
// mark the first n of the given tile, return actual number found
public synchronized int search (byte t, int n) {}
// return a new hand with marked tiles
public synchronized Hand selection (boolean keep_orig) {}
// return a new hand with unmarked tiles
public synchronized Hand unselected (boolean keep_orig) {}
// randomly shuffle the tiles in this hand
public synchronized void shuffle () {}
// sort the tiles in this hand
public synchronized void sort() {}
}
</PRE>
<!-- END CODE //-->
<P>There will inevitably be packets that contain tiles and hands. For a tile we can simply use its byte representation. For hands, however, we need to write two methods to read and write them. They are best put in the Packet class:
</P>
<!-- CODE //-->
<PRE>
// in class Packet
public static void writeHand (DataOutputStream S, Hand h)
throws IOException {
S.writeInt(h.length());
for (int i = 0; i < h.length(); i++) {
S.writeByte(h.tileAt(i));
S.writeByte(h.groupAt(i) | (byte)(h.isSelected(i) ? 16 : 0));
}
}
public static Hand readHand (DataInputStream S, Hand h)
throws IOException {
int len = S.readInt();
if (h == null)
h = new Hand(len);
h.setLength(0);
for (int i = 0; i < len; i++) {
byte t = S.readByte();
byte g = S.readByte();
boolean s = ((g & (byte)16) != 0);
h.addTile(t, (byte)(g & 15), s);
}
return h;
}
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="742-746.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="749-752.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -