home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / src / como / commlet / nicnacnoe / nicnacnoe.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  13.2 KB  |  471 lines

  1. /*
  2. * @(#)NicNacNoe.java    1.0 95/11/09 Ulrich Gall & Jan Kautz
  3. *
  4. * Copyright (c) 1996 Ulrich Gall & Jan Kautz
  5. * uhgall@cip.informatik.uni-erlangen.de
  6. * Hofmannstr. 48, D-91052 Erlangen, Germany, Fax: +49-9131-201358
  7. *
  8. * Permission to use, copy, and distribute this software
  9. * and its documentation for NON-COMMERCIAL purposes and without
  10. * fee is hereby granted provided that this copyright notice
  11. * appears in all copies. Please contact us for  further copyright
  12. * and licensing information.
  13. *
  14. * WE MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  15. * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  16. * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WE SHALL NOT BE LIABLE FOR
  18. * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  19. * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  20. */
  21.  
  22. package como.commlet.nicnacnoe;
  23.  
  24. import java.util.*;
  25. import java.awt.*;
  26. import java.io.*;
  27.  
  28. import como.sys.*;
  29. import como.util.*;
  30. import como.awt.*;
  31. import como.commlet.*;
  32. import como.commlet.draw.*;
  33. import como.commlet.superchat.*;
  34. import como.commlet.userlist.*;
  35. import como.commlet.messagelog.*;
  36. import como.io.*;
  37.  
  38. /**
  39. * This is an example how to program a MetaCommlet.
  40. */
  41. public class NicNacNoe extends MetaCommlet {
  42.  
  43. public static int MSG_PUT_PIECE = 10011;
  44. public static int MSG_NEW_BOARD = 10012;
  45. public static int MSG_TURN = 10013;
  46.  
  47. public static int EVT_NEW_BOARD = 15002;
  48. public static int EVT_CANCEL = 15003;
  49. public static int EVT_CANCEL_INFORM = 15004;
  50. public static int EVT_DISABLE_INFORM = 15005;
  51.  
  52. Board board = null;
  53. GameControls controls = null;
  54. TextField topTF;
  55. MenuItem miNewBoard = null;
  56. MenuItem miNextPlayer = null;
  57. CheckboxMenuItem miInformTurn = null;
  58.  
  59. SmartFrame newboardframe;
  60. SmartFrame notYourTurnFrame;
  61. SmartFrame yourTurnFrame;
  62. SmartFrame winFrame;
  63. TextField xtf,ytf;
  64. TextField wintf;
  65.  
  66. Hashtable gameparams;
  67.  
  68. int whoseturn = -1;// whose turn is it right now? -1 = nobody's
  69. int nextturn = -1; // master has to remember whose turn it is next
  70.  
  71. public String getCommletName()
  72.        {
  73.        return "NicNacNoe";
  74.        }
  75.  
  76. public String getCommletInfo()
  77.        {
  78.        return("NicNacNoe, demo Commlet, V 1.0, (c) Jan Kautz & Ulrich Gall");
  79.        }
  80.  
  81. /**
  82. * Commlets must have an empty constructor.
  83. */
  84. public NicNacNoe()
  85.        {
  86.     gameparams = new Hashtable();
  87.        }
  88.  
  89. public void init()
  90.      {
  91.      super.init();
  92.     
  93.      // include some basic Commlets in the menu
  94.      SuperChat c = new SuperChat();
  95.      addCommlet(c,"SuperChat");
  96.  
  97.      UserList ul = new UserList();
  98.      addCommlet(ul,"Players");
  99.  
  100.      Menu men= new Menu("Game");
  101.      miNewBoard = new MenuItem("New");
  102.      miNextPlayer = new MenuItem("Skip this Player");
  103.      if (com.iAmMaster()) {
  104.         miNewBoard.enable();
  105.         miNextPlayer.enable();
  106.         add("North",topTF = new TextField("Select 'New' from the 'Game' menu to start a new Game"));
  107.         }
  108.     else {
  109.         miNewBoard.disable();
  110.         miNextPlayer.disable();
  111.         add("North",topTF = new TextField("Please wait until a Game is started..."));
  112.     }
  113.     topTF.setEditable(false);        
  114.      men.add(miNewBoard);
  115.      men.add(miNextPlayer);
  116.      getMenuBar().add(men);
  117.  
  118.     men = new Menu("Options");
  119.     miInformTurn = new CheckboxMenuItem("Notify when it's your turn");
  120.     miInformTurn.setState(true);
  121.     men.add(miInformTurn);
  122.     getMenuBar().add(men);
  123.  
  124.  
  125.      board = new Board();
  126.      add("Center",board);
  127.      resize(480,480);
  128.      }
  129.  
  130. /**
  131. * This is called whenever a new user joins.
  132. */
  133. public void addUser(int who) {
  134.     int x,y;
  135.     if (com.iAmMaster() && (gameparams.size() != 0)) {
  136.         // send the current state of the game over the net
  137.         // It would be nicer to send the whole board, but the regular IRCd
  138.         // server can not process messages longer than 397 bytes. The Java IRCd can, though.
  139.         Hashtable sendparams = (Hashtable)gameparams.clone();
  140.         sendparams.remove(Board.PLAYERS); // we don't want to send too much over the net.
  141.         com.sendTo(new Msg(MSG_NEW_BOARD,com.getMyID(),who,sendparams));
  142.         for (x=0;x<board.xs;x++)
  143.             for (y=0;y<board.ys;y++)
  144.                 if (board.get(x,y) != Board.EMPTY)
  145.                     com.sendTo(new Msg(MSG_PUT_PIECE, who,
  146.                         new Piece(x,y,board.get(x,y))));
  147.         updateUserInfo(who);
  148.     }
  149. }
  150. public void updateUserInfo(int who) {
  151.     User u = com.getUser(who);
  152.     board.updateUserInfo(u); // this keeps the old score and takes over the rest
  153.     if (controls != null) controls.update(u);
  154.     }
  155.  
  156. private void sendTurn(int t) {
  157.        com.sendToAll(new Msg(MSG_TURN,new Integer(t)));
  158. }
  159. private int nextPlayer(int w) {
  160.     // This is a little awkward, but shorter than implementing a container
  161.     // class with circularly linked elements.
  162.     Integer firstelement = null;
  163.     Enumeration e = ((Hashtable)gameparams.get(Board.PLAYERS)).keys();
  164.     while (e.hasMoreElements()) {
  165.         Integer next = (Integer)e.nextElement();
  166.         if (firstelement == null) firstelement = next;
  167.         if (next.equals(new Integer(w))) {
  168.             if (e.hasMoreElements()) {
  169.                 return ((Integer)e.nextElement()).intValue();
  170.             }
  171.             else {
  172.                 return firstelement.intValue();
  173.             }
  174.         }
  175.     }
  176.     return -1;
  177. }
  178. private void sendPutPiece(Piece p) {
  179.        com.sendToAll(new Msg(MSG_PUT_PIECE,p));
  180. }
  181. private void doPutPiece(Piece p)
  182.        {
  183.        // Put the piece on the board
  184.        if (p.p != -1) {
  185.             board.set(p);
  186.            // Update the score...
  187.             int add = 0;
  188.             // left-right
  189.     int c1,c2;
  190.     c1 = 0; c2 = 0;
  191.     while (board.get(p.x+c1,p.y) == p.p) c1++;
  192.     while (board.get(p.x-c2,p.y) == p.p) c2++;
  193.     add = add + board.getPoints(c1+c2-1);
  194.     c1 = 0; c2 = 0;
  195.     while (board.get(p.x,p.y+c1) == p.p) c1++;
  196.     while (board.get(p.x,p.y-c2) == p.p) c2++;
  197.     add = add + board.getPoints(c1+c2-1);
  198.     c1 = 0; c2 = 0;
  199.     while (board.get(p.x+c1,p.y+c1) == p.p) c1++;
  200.     while (board.get(p.x-c2,p.y-c2) == p.p) c2++;
  201.     add = add + board.getPoints(c1+c2-1);
  202.     c1 = 0; c2 = 0;
  203.     while (board.get(p.x-c1,p.y+c1) == p.p) c1++;
  204.     while (board.get(p.x+c2,p.y-c2) == p.p) c2++;
  205.     add = add + board.getPoints(c1+c2-1);
  206.     
  207.     if ((board.getScore(p.p) < board.getWinScore()) && (board.getScore(p.p)+add >= board.getWinScore())) {
  208.         whoseturn = -1;
  209.         nextturn = -1;
  210.         if (com.iAmMaster()) sendTurn(-1); // just to make sure... not really necessary.
  211.         if (p.p == com.getMyID()) {
  212.             winFrame = new SmartFrame("Congratulations! You won the game");
  213.         }
  214.         else {
  215.             winFrame = new SmartFrame(com.getUser(p.p).getName()+" has won the game.");
  216.         }
  217.  
  218.     }
  219.     board.setScore(p.p,board.getScore(p.p)+add);
  220.     controls.update(p.p);
  221.     }
  222. }
  223. private Hashtable loadParams(String filename) {
  224. try {
  225. Hashtable h = new Hashtable();
  226. DataInputStream s = new DataInputStream(com.openInputStream(filename));
  227. String l;
  228. StringTokenizer st;
  229. h.put(Board.DESCRIPTION,s.readLine());
  230. st = new StringTokenizer(s.readLine()," ");
  231. int w = new Integer(st.nextToken()).intValue();
  232. st.nextToken();
  233. int hei = new Integer(st.nextToken()).intValue();
  234. h.put(Board.DIMENSION,new Dimension(w,hei));
  235. st = new StringTokenizer(s.readLine());
  236. int minp = new Integer(st.nextToken()).intValue();
  237. st.nextToken();
  238. int maxp = new Integer(st.nextToken()).intValue();
  239. h.put(Board.NUMPLAYERS,new Dimension(minp,maxp));
  240. st = new StringTokenizer(s.readLine()," ");
  241. h.put(Board.WINSCORE,new Integer(st.nextToken()));
  242. st = new StringTokenizer(s.readLine()," ");
  243. while(st.hasMoreTokens()) {
  244.     if (st.nextToken().equals("FALL")) h.put(Board.FALL,new Boolean(true));
  245. byte[] points = new byte[10];
  246. int i;
  247. for (i=0;i<10;i++) points[i] = 0;
  248. l = s.readLine();
  249. while ((l != null) && (l.length() > 0)) {
  250.     st = new StringTokenizer(l," ");
  251.     int a = new Integer(st.nextToken()).intValue();
  252.     points[a] = (byte)(new Integer(st.nextToken()).intValue());
  253.     l = s.readLine();
  254.     }
  255. h.put(Board.POINTS,points);
  256. return h;
  257.     }
  258. catch (Exception e) {
  259. new SmartFrame("Error loading game file:"+e);
  260. return null;
  261. }
  262. }
  263. public boolean action(Event evt,Object what) {
  264.     if ((evt.target == miNextPlayer) && (gameparams.size() > 0)) {
  265.         //  skip current player 
  266.         sendTurn(nextturn);
  267.         nextturn = nextPlayer(nextturn);
  268.     }
  269.     if ((evt.target == miNewBoard) && (newboardframe == null)) {
  270.         if (winFrame != null) winFrame.dispose();
  271.         winFrame = null;
  272.         newboardframe = new SmartFrame(this);
  273.         newboardframe.setTitle("NicNacNoe: New Game");
  274.         Panel p = new RemoteFileDialog(com,"games.txt",this);
  275.         newboardframe.add("North",new Label("Currently, there are "+com.getUsers().size()+ " players who would like to play. Which game would you like to start?"));
  276.         newboardframe.add("Center",p);
  277.         newboardframe.pack();
  278.         newboardframe.show();
  279.         return true;
  280.         }
  281.     if (evt.target instanceof RemoteFileDialog) {
  282.         if (evt.arg == null ) {
  283.             newboardframe.dispose();
  284.             newboardframe = null;
  285.             return true;
  286.         }
  287.         Hashtable pars = loadParams((String)evt.arg);
  288.         if (pars != null) {
  289.         Vector users = com.getUsers();
  290.         int minplayers = ((Dimension)pars.get(Board.NUMPLAYERS)).width;
  291.         int maxplayers = ((Dimension)pars.get(Board.NUMPLAYERS)).height;
  292.         if (users.size() < minplayers) {
  293.             new SmartFrame("You need at least "+minplayers+" players for this game.");
  294.             return true;
  295.         }
  296.         if (users.size() > maxplayers) {
  297.             new SmartFrame("At the most, "+maxplayers+
  298.                 " players can play this game. The other will have to watch");
  299.         }
  300.         gameparams = pars;
  301.         int numplayers = maxplayers;
  302.         if (users.size() < maxplayers) numplayers = users.size();
  303.         Enumeration e = users.elements();
  304.         byte[] scores = new byte[numplayers];
  305.         int[] ids = new int[numplayers];
  306.         int i = 0;
  307.         while (e.hasMoreElements() && (i < numplayers)) {
  308.             User u = (User)e.nextElement();
  309.             ids[i] = u.getID();
  310.             scores[i] = 0;
  311.             i++;
  312.         }
  313.         gameparams.put(Board.IDS,ids);
  314.         gameparams.put(Board.SCORES,scores);
  315.         com.sendToAll(new Msg(MSG_NEW_BOARD,gameparams));
  316.         newboardframe.dispose();
  317.         newboardframe = null;
  318.         return true;
  319.         }
  320.     }
  321.     return false;
  322.         
  323. }
  324. public void showYourTurn() {
  325.     hideNotYourTurn();
  326.     if (miInformTurn.getState()) {
  327.         if (yourTurnFrame == null) {
  328.               yourTurnFrame = new SmartFrame(this,
  329.                   "OK, thanks.", new Event(this,EVT_CANCEL_INFORM,null),
  330.                   "I know. Shut up!", new Event(this,EVT_DISABLE_INFORM,null));
  331.               yourTurnFrame.setTitle("NicNacNoe: your turn...");
  332.               Panel p = new Panel();
  333.               // too make it look nicer under netscape win 95
  334.               p.setLayout(new VertLayout(VertLayout.STRETCH));
  335.               p.add(new Label(""));
  336.               p.add(new Label("It is now your turn.",Label.CENTER));
  337.               p.add(new Label(""));
  338.             yourTurnFrame.add("North", p);
  339.             yourTurnFrame.pack();
  340.             yourTurnFrame.show();
  341.         }    
  342.     }
  343. }
  344. public void showNotYourTurn() {
  345.     hideYourTurn();
  346.     if (notYourTurnFrame == null) {
  347.         notYourTurnFrame = new SmartFrame("It's not your turn!");
  348.     }
  349. }
  350. public void hideNotYourTurn() {
  351.     if (notYourTurnFrame != null) {
  352.         notYourTurnFrame.dispose();
  353.         notYourTurnFrame = null;
  354.     }
  355. }
  356. public void hideYourTurn() {
  357.     if (yourTurnFrame != null) {
  358.         yourTurnFrame.dispose();
  359.         yourTurnFrame = null;
  360.     }
  361. }
  362. public boolean handleEvent(Event evt) {
  363. if (evt.id == EVT_DISABLE_INFORM) {
  364.     miInformTurn.setState(false);
  365.     hideYourTurn();
  366.     return true;
  367. }
  368. if (evt.id == EVT_CANCEL_INFORM) {
  369.         hideYourTurn();
  370.         return true;
  371. }
  372. return super.handleEvent(evt);
  373. }
  374. public boolean mouseDown(Event evt,int x,int y) {
  375.        if (evt.target == board) {
  376.             if (whoseturn == com.getMyID()) {
  377.                 if (board.get(x,y) == Board.EMPTY) {
  378.                     controls.disable(whoseturn);
  379.                     whoseturn = -1;
  380.                     sendPutPiece(new Piece(x,y,com.getMyID()));
  381.                     board.set(new Piece(x,y,com.getMyID()));
  382.                 }
  383.            }
  384.            else {
  385.                 showNotYourTurn();
  386.            }
  387.        }
  388.        return true;
  389. }
  390. /**
  391. * Handle an incoming message. This is called by the ComObj.
  392. */
  393. public synchronized boolean handleMsg(Msg msg) {
  394.       if (msg.type == Msg.NEW_USER_INFO) {
  395.         if (gameparams != null) updateUserInfo(msg.from);
  396.     }
  397.       else if (msg.type == MSG_NEW_BOARD) {
  398.         gameparams = (Hashtable)msg.arg;
  399.         whoseturn = -1;
  400.         nextturn = -1;
  401.         // We have to set the PLAYERS field, since it could not be sent...
  402.         int i;
  403.         Hashtable pl = new Hashtable();
  404.         int [] ids = (int[])gameparams.get(Board.IDS);
  405.         byte [] scores = (byte[])gameparams.get(Board.SCORES);
  406.         for (i=0;i<ids.length;i++) {
  407.             User u = com.getUser(ids[i]);
  408.             if (u == null) {
  409.                 // construct a new user-- the information about this
  410.                 // user is not available yet.
  411.                 u = new User(ids[i],"Unknown user");
  412.                 u.put(u.COLOR,Color.white);
  413.             }
  414.             u.put(u.SCORE,new Integer(scores[i]));
  415.             pl.put(new Integer(ids[i]),u);
  416.         }
  417.         gameparams.put(Board.PLAYERS,pl);
  418.         board.reset(gameparams);
  419.         Hashtable players = (Hashtable)gameparams.get(Board.PLAYERS);
  420.  
  421.         if (!players.containsKey(new Integer(com.getMyID()))) {
  422.                 new SmartFrame("You may watch this game and play when the next game is started.");
  423.         }
  424.  
  425.         if (controls != null) remove(controls);
  426.  
  427.         controls = new GameControls(players);
  428.         add("South",controls);
  429.         topTF.setText((String)gameparams.get(Board.DESCRIPTION));
  430.         layout();
  431.         paintAll(getGraphics());
  432.  
  433.         if (com.iAmMaster()) {
  434.           sendTurn(com.getMyID());
  435.           nextturn = nextPlayer(com.getMyID());
  436.         }
  437.     }
  438.     else if ((msg.type == MSG_TURN) && (controls != null)) {
  439.         controls.disable(whoseturn);
  440.         whoseturn = ((Integer)msg.arg).intValue();
  441.  
  442.         controls.enable(whoseturn);
  443.         if (whoseturn == com.getMyID()) 
  444.             showYourTurn();
  445.         else
  446.             hideYourTurn();
  447.     }
  448.     else if (msg.type == MSG_PUT_PIECE) {
  449.         doPutPiece((Piece)msg.arg);
  450.         if (com.iAmMaster()) {
  451.             // send next-turn message
  452.             sendTurn(nextturn);
  453.             nextturn = nextPlayer(nextturn);
  454.         }
  455.     }
  456.     else if (msg.type == Msg.NEW_MASTER) {
  457.         miNewBoard.disable();
  458.         miNextPlayer.disable();
  459.         if (((Integer)msg.arg).intValue() == com.getMyID()) {
  460.             miNewBoard.enable();
  461.             miNextPlayer.enable();
  462.         }
  463.     }
  464.  
  465.    return super.handleMsg(msg);
  466.     }
  467. }
  468.  
  469.  
  470.