home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / inprise / JSAMPLES.Z / PlayerId.java < prev    next >
Text File  |  1998-05-08  |  15KB  |  431 lines

  1. /*
  2.  * Copyright (c) 1997-1998 Borland International, Inc. All Rights Reserved.
  3.  * 
  4.  * This SOURCE CODE FILE, which has been provided by Borland as part
  5.  * of a Borland product for use ONLY by licensed users of the product,
  6.  * includes CONFIDENTIAL and PROPRIETARY information of Borland.  
  7.  *
  8.  * USE OF THIS SOFTWARE IS GOVERNED BY THE TERMS AND CONDITIONS 
  9.  * OF THE LICENSE STATEMENT AND LIMITED WARRANTY FURNISHED WITH
  10.  * THE PRODUCT.
  11.  *
  12.  * IN PARTICULAR, YOU WILL INDEMNIFY AND HOLD BORLAND, ITS RELATED
  13.  * COMPANIES AND ITS SUPPLIERS, HARMLESS FROM AND AGAINST ANY CLAIMS
  14.  * OR LIABILITIES ARISING OUT OF THE USE, REPRODUCTION, OR DISTRIBUTION
  15.  * OF YOUR PROGRAMS, INCLUDING ANY CLAIMS OR LIABILITIES ARISING OUT OF
  16.  * OR RESULTING FROM THE USE, MODIFICATION, OR DISTRIBUTION OF PROGRAMS
  17.  * OR FILES CREATED FROM, BASED ON, AND/OR DERIVED FROM THIS SOURCE
  18.  * CODE FILE.
  19.  */
  20. package borland.samples.apps.chess.server;
  21.  
  22. import java.io.*;
  23. import java.util.*;
  24. import java.lang.*;
  25. import borland.samples.apps.chess.client.PersistString;
  26.  
  27. class PlayerId
  28. {
  29.   public static Hashtable usersByUser = new Hashtable();
  30.   public static Hashtable usersById   = new Hashtable();
  31.   private final static File partialGames = new File("Suspended");  //directory for holding suspended games
  32.   private final static File userlist     = new File("users.txt");  //file that holds user list
  33.   private static int nextId = 4096;   //highest userid, for constructing new users id's
  34.   private static boolean userListIsDirty = false;
  35.   String id   = null;    //unique string representation of a hex number. Key to usersById
  36.   String user = null;    //unique key to usersByUser
  37.   String password;
  38.   String name;
  39.   String email;
  40.   String location;
  41.   String extra;       //whatever
  42.   Vector message;     //array of undelivered messages
  43.   int rating;         //elo rating
  44.   int gamesPlayed;    //number of games played
  45.   long lastNoteTime;
  46.   Vector partialGame; //list of users suspended game filenames
  47.  
  48.   public PlayerId(String user,String password){
  49.     int idNum = PlayerId.nextId++;
  50.     id = "000" + Integer.toHexString(idNum);
  51.     if (id.length() > 4)
  52.       id = id.substring(id.length() - 4);
  53.     this.user = user;
  54.     this.password = password;
  55.     message = new Vector();
  56.     name = " ";
  57.     email = " ";
  58.     location = " ";
  59.     extra = " ";
  60.     rating = 1200;
  61.     partialGame = new Vector(1);
  62.     gamesPlayed = 0;
  63.     lastNoteTime = 0;
  64.   }
  65.   public void isDirty() {
  66.     userListIsDirty = true;
  67.   }
  68.   public  void update(String password,String email,String name,String location,String extra) {
  69.     this.password = password;
  70.     this.name = name;
  71.     this.email = email;
  72.     this.location = location;
  73.     this.extra = extra;
  74.     PlayerId.userListIsDirty = true;
  75.   }
  76.  
  77.   public PlayerId() {
  78.     partialGame = new Vector(5);
  79.     message = new Vector();
  80.   }
  81.  
  82.   public boolean addPlayer() {
  83.     if (id != null && user != null) {
  84.       PlayerId.usersByUser.put(user,this);
  85.       PlayerId.usersById.put(id,this);
  86.       PlayerId.userListIsDirty = true;
  87.       return true;
  88.     }
  89.     return false;
  90.   }
  91.   void addNote(String msg) {
  92.     long now = System.currentTimeMillis();
  93.     if (now - lastNoteTime > 180000) {
  94.       message.addElement(new Date(now).toString());
  95.       lastNoteTime = now;
  96.     }
  97.     message.addElement(msg);
  98.     isDirty();
  99.   }
  100.   void read(String data) {
  101.     try {
  102.       String [] temp = PersistString.parse(data);
  103.       id = temp[0];
  104.       user = temp[1];
  105.       password = temp[2];
  106.       name = temp[3];
  107.       email = temp[4];
  108.       location = temp[5];
  109.       extra = temp[6];
  110.       rating = Integer.parseInt(temp[7]);
  111.       gamesPlayed = Integer.parseInt(temp[8]);
  112.  
  113.  
  114.       for (int i= 9;i<temp.length;i++)
  115.          message.addElement(temp[i]);
  116.       //System.out.println ("user=" + user + " name=" + name + " rating=" + rating);
  117.       PlayerId.userListIsDirty = true; // this method is used to update data
  118.     }
  119.     catch (Exception e) {System.out.println("PlayerId.read " + e);
  120.        System.out.println("record: " + data);
  121.     }
  122.   }
  123.  
  124.   public String output() {
  125.  
  126.      String [] temp = new String [9+ message.size()];
  127.      temp[0] =  id;
  128.      temp[1] =  user ;
  129.      temp[2] =  password ;
  130.      temp[3] =  name  ;
  131.      temp[4] =  email;
  132.  
  133.      temp[5] =  location ;
  134.      temp[6] =  extra  ;
  135.      temp[7] =  String.valueOf(rating);
  136.      temp[8] =  String.valueOf( gamesPlayed) ;
  137.      for (int i = 0; i < message.size(); i++)
  138.        temp[i+9] = (String) message.elementAt(i);
  139.      return PersistString.concat(temp);
  140.   }
  141.  
  142.   public void addGame(String filename) {
  143.     partialGame.addElement(filename);
  144.   }
  145.  
  146.   public static void readUserFile() {
  147.     int numUsers = 0;
  148.     try {
  149.       // partialGames = new File("Suspended");
  150.       //userlist = new File("users.txt");
  151.       if (userlist.exists()) {
  152.         FileInputStream fs = new FileInputStream(userlist);
  153.         DataInputStream ds = new DataInputStream(fs);
  154.         InputStreamReader isr  = new InputStreamReader(ds);
  155.         BufferedReader br = new BufferedReader(isr);
  156.         PlayerId temp;
  157.         String inputData;
  158.         while (true) {
  159.           inputData =  br.readLine();
  160.           if (inputData == null || inputData.length() < 10)
  161.             break;
  162.           else
  163.             //System.out.println(inputData);
  164.             temp = new PlayerId() ;
  165.             temp.read(inputData);
  166.             numUsers++;
  167.             if (temp.addPlayer()) {
  168.               try {
  169.               int intId = Integer.parseInt(temp.id,16);
  170.               if (intId >= nextId)
  171.                 nextId = intId  + 1;
  172.             }
  173.             catch (NumberFormatException e) { System.out.println (temp.id +  "is not a hex number"); }
  174.           }
  175.           else
  176.             System.out.println(temp.id + " " + temp.user + ": junk data in user file");
  177.         }
  178.         fs.close();
  179.       }
  180.       else
  181.         System.out.println("User database " + userlist.getAbsolutePath() + " not found ");
  182.  
  183.       System.out.println("Read " + numUsers + " userId records from " + userlist.getAbsolutePath());
  184.       constructSuspendLists();
  185.       PlayerId.userListIsDirty = false;
  186.     }
  187.     catch (Exception e) {System.out.println("Exception  after reading " + numUsers + " " + e);}
  188.   }
  189.  
  190.   private static void constructSuspendLists() {
  191.     PgnFilter filter = new PgnFilter(13);
  192.     if (filter == null)
  193.       System.out.println("file filter object is null??");
  194.     if (partialGames == null)
  195.       System.out.println("game directory object is null??");
  196.     else if (!partialGames.exists())
  197.       partialGames.mkdir();
  198.     String [] dirlist  = partialGames.list(filter);
  199.     if (dirlist != null)
  200.       for (int i=0; i<dirlist.length;++i) {
  201.         PlayerId white = (PlayerId)usersById.get(dirlist[i].substring(0,4));
  202.         PlayerId black = (PlayerId)usersById.get(dirlist[i].substring(4,8));
  203.         if (white != null && black != null) {
  204.           System.out.println("added game " + dirlist[i] + " to " + white.user  + " & " + black.user + "'s suspended list");
  205.           white.addGame(dirlist[i]);
  206.           black.addGame(dirlist[i]);
  207.         }
  208.         else
  209.           System.out.println("could not find id " + dirlist[i].substring(0,8));
  210.       }
  211.     else
  212.       System.out.println("Suspended game directory is empty");
  213.   }
  214.  
  215.   //game is over. if it was a suspended game, delete it
  216.   public static void recordResult(Game g,String result) {
  217.     PlayerId white = (PlayerId) PlayerId.usersByUser.get(g.white) ;
  218.     PlayerId black = (PlayerId) PlayerId.usersByUser.get(g.black) ;
  219.     if (g.filename != null) {
  220.       black.partialGame.removeElement(g.filename);
  221.       white.partialGame.removeElement(g.filename);
  222.       File file = new File("Suspended",g.filename);
  223.       if (file.delete())
  224.         System.out.println("deleted " + g.filename);
  225.       else
  226.         System.out.println("delete " + g.filename + " failed ");
  227.     }
  228.     PlayerId winner = white;
  229.     PlayerId loser = black;
  230.     int loserdelta;
  231.     int winnerdelta;
  232.     if (result.startsWith("Abort"))
  233.        return;
  234.     if (result.startsWith("1/2-1/2")) {
  235.       if  (winner.gamesPlayed < 20)
  236.         winner.rating = ((winner.rating * winner.gamesPlayed) +
  237.                         loser.rating ) / (winner.gamesPlayed + 1) ;
  238.       else
  239.         winner.rating = winner.rating  - elo(winner.rating - loser.rating);
  240.       if  (winner.gamesPlayed < 20)
  241.         loser.rating = ((loser.rating * loser.gamesPlayed) +
  242.                        winner.rating ) / (loser.gamesPlayed + 1) ;
  243.       else
  244.         loser.rating = loser.rating  + elo(winner.rating - loser.rating);
  245.     }
  246.     else {
  247.       if (result.startsWith("0-1")) {
  248.         winner = black;
  249.         loser = white;
  250.       }
  251.       winnerdelta = loser.rating + 400;
  252.       loserdelta = winner.rating - 400;
  253.       if (winner.gamesPlayed < 20)
  254.         winner.rating = ((winner.rating * winner.gamesPlayed) +
  255.                         winnerdelta ) / (winner.gamesPlayed + 1) ;
  256.       else
  257.         winner.rating = winner.rating + 16 - elo(winner.rating - loser.rating);
  258.       if (loser.gamesPlayed < 20)
  259.         loser.rating = ((loser.rating * loser.gamesPlayed) +
  260.                        loserdelta ) / (loser.gamesPlayed + 1) ;
  261.       else
  262.         loser.rating = loser.rating - 16 + elo(winner.rating - loser.rating);
  263.     }
  264.     winner.gamesPlayed++;
  265.     loser.gamesPlayed++;
  266.     PlayerId.userListIsDirty = true;
  267.   }
  268.  
  269.   static int elo(int ratingdiff) {
  270.     int distribution[] = {0,12,34,56,8,101,126,151,177,206,239,273,315,366,446,471,714};
  271.     int sign = 1;
  272.     if (ratingdiff < 0)  {
  273.        sign = -1;
  274.        ratingdiff = -ratingdiff;
  275.     }
  276.     int oldsub = -1;
  277.     int i = 8;
  278.     int maxsub = 16;
  279.     int minsub = 0;
  280.     while (oldsub != i) {
  281.       oldsub = i;
  282.       i = (maxsub + minsub) /2;
  283.       if (ratingdiff > distribution[i])
  284.         minsub = i;
  285.       else
  286.         maxsub = i;
  287.     }
  288.     return oldsub * sign;
  289.   }
  290.   //Game is being suspended. Delete old version (if any) and
  291.   //write game to disk
  292.   public static void suspendGame(Game g) {
  293.     String tomove  = "1";
  294.     if (g.whitetomove)
  295.       tomove = "0" ;
  296.     String suffix = tomove + String.valueOf(g.offerFlag) + String.valueOf(g.movenum); //1 digit
  297.     String gameName;
  298.     PlayerId black = null;
  299.     PlayerId white = null;
  300.     if (g.filename != null ) {
  301.       if (g.blackId == null || g.whiteId == null)
  302.         System.out.println("weird Game object " + g.filename + g.white + g.black);
  303.       if (g.filename.substring(8).equals(suffix + ".pgn"))
  304.         return;
  305.     }
  306.     white = (PlayerId) PlayerId.usersByUser.get(g.white) ;
  307.     black = (PlayerId) PlayerId.usersByUser.get(g.black) ;
  308.     gameName =  white.id + black.id + suffix + ".pgn";
  309.     try {
  310.       File file = new File("Suspended",gameName);
  311.       System.out.println("Saving " + gameName);
  312.       if (file == null)
  313.         System.out.println("could not open file");
  314.       FileOutputStream fs = new FileOutputStream(file);
  315.       PrintWriter ps = new PrintWriter(fs);
  316.       ps.print(g.getMoves());
  317.       ps.flush();
  318.       ps.close();
  319.       System.out.println("Wrote file");
  320.       if (g.filename != null) {
  321.         black.partialGame.removeElement(g.filename);
  322.         white.partialGame.removeElement(g.filename);
  323.         file = new File("Suspended",g.filename);
  324.         if (file.delete())
  325.           System.out.println("deleted " + g.filename);
  326.         else
  327.           System.out.println("delete " + g.filename + " failed ");
  328.       }
  329.       black.partialGame.addElement(gameName);
  330.       white.partialGame.addElement(gameName);
  331.       g.filename = gameName;
  332.       g.blackId = black.id;
  333.       g.whiteId = white.id;
  334.     }
  335.     catch (Exception e ) {
  336.       System.out.println("err in SuspendGame " + e);
  337.     }
  338.   }
  339.  
  340.   //Create a game object for the suspended game file
  341.   public Game getGame(String filename) {
  342.     Game g = null;
  343.     try {
  344.       File gamefile = new File("Suspended",filename);
  345.       FileInputStream fs = new FileInputStream(gamefile) ;
  346.       DataInputStream ds = new DataInputStream(fs);
  347.       InputStreamReader isr  = new InputStreamReader(ds);
  348.       BufferedReader br = new BufferedReader(isr);
  349.       String moves = br.readLine();
  350.       fs.close();
  351.       String whiteId = filename.substring(0,4);
  352.       String blackId = filename.substring(4,8);
  353.       String tomove = filename.substring(8,9);
  354.       int movenum = Integer.parseInt(filename.substring(10,filename.indexOf('.',9)));
  355.       PlayerId white = (PlayerId) PlayerId.usersById.get(whiteId);
  356.       PlayerId black = (PlayerId) PlayerId.usersById.get(blackId);
  357.       g = new Game(white.user,black.user);
  358.       g.offerFlag = Integer.parseInt(filename.substring(9,10));
  359.       g.movenum = movenum;
  360.       int index;
  361.       if (tomove.equals("0"))
  362.         g.whitetomove = true;
  363.       else {
  364.         g.whitetomove = false;
  365.         index = moves.lastIndexOf('.') ;
  366.         String temp = moves.substring(index-5,index);
  367.         System.out.println("temp=" + temp);
  368.         int index1 = temp.lastIndexOf(' ');
  369.         g.whitesLastMove = moves.substring(index - 4 + index1);
  370.         System.out.println("indexes="+index + "," + index1+ g.whitesLastMove);
  371.       }
  372.       g.setInfo();
  373.       index = moves.indexOf("Whitetime");
  374.       int endindex = moves.indexOf("]",index);
  375.       g.whiteTime = moves.substring(index+10,endindex);
  376.       index = moves.indexOf("Blacktime");
  377.       endindex = moves.indexOf("]",index);
  378.       g.blackTime = moves.substring(index+10,endindex);
  379.       index = moves.indexOf("Movetime");
  380.       endindex = moves.indexOf("]",index);
  381.       g.moveTime = moves.substring(index+9,endindex);
  382.       g.moves = moves.substring(endindex+1);
  383.       g.whiteId = whiteId;
  384.       g.blackId = blackId;
  385.       g.filename = filename;
  386.     }
  387.     catch (Exception e) {System.out.println("PlayerId.getGame " + e);}
  388.     return g;
  389.   }
  390.  
  391.   static public void writeUserList() {
  392.     if (!PlayerId.userListIsDirty)
  393.       return;
  394.     FileOutputStream fo = null;
  395.     PrintWriter ps = null;
  396.     //System.out.println("Trying to write out updated user List")  ;
  397.     try {
  398.       fo = new FileOutputStream(PlayerId.userlist);
  399.       ps = new PrintWriter(fo);
  400.     }
  401.     catch (Exception e) {System.out.println("Things look bad for the home team");}
  402.     PlayerId p = null;
  403.     if (ps != null) {
  404.       for (Enumeration e = PlayerId.usersById.elements(); e.hasMoreElements();) {
  405.         p = (PlayerId) e.nextElement();
  406.         //System.out.println("Writing " + p.user );
  407.         ps.println(p.output());
  408.       }
  409.       System.out.println("Updated the user List");
  410.       ps.flush();
  411.       ps.close();
  412.       PlayerId.userListIsDirty = false;
  413.     }
  414.   }
  415. } //end of class
  416.  
  417. class PgnFilter implements FilenameFilter {
  418.   int minFileNameLength = 2;
  419.   public PgnFilter(int length) {
  420.     minFileNameLength = length;
  421.   }
  422.   public boolean accept(File dir,String name) {
  423.     if ( name != null && name.endsWith(".pgn") && name.length() > minFileNameLength)
  424.       return true;
  425.     else  {
  426.       System.out.println("Threw out " + name );
  427.       return false;
  428.     }
  429.   }
  430. }
  431.