// // File: MServer.java Author: David Sinclair // Version: 1.1 Date: 09 Jan 2001 // // Server for Intelligent Game Theory Assignment - Game Matrix with side paymets // import java.io.*; import java.net.*; import java.util.*; import java.lang.*; // Player Class // Contains all the data for each player class Player { String IDString; int playerNumber; long balance; int contractedStrategy[], sidePayments[]; DataInputStream in; PrintStream out; // Constructor Player(int number) { playerNumber = number; balance = 0; } // endInt // Returns an index just past the integer at the specified index in the specified string. private int endInt (String s, int index) { int i; if (s.charAt(index) == '-') i = index + 1; else i = index; // skip to end of number while ((i < s.length ()) && (Character.isDigit(s.charAt(i)))) { i++; } return (i); } // setContract // Sets the contract strategy and side payments from the speciied string. void setContract (String contractString, int NumberOfPlayers) { int i, m, strategy, value; for (i = 0, m = 0; i < NumberOfPlayers; i++) { // check if a player offered a side payment is being offering // a larger side payment by another player. strategy = Integer.parseInt (contractString.substring (m, endInt (contractString, m))); for (; (m < contractString.length ()) && (Character.isDigit(contractString.charAt(m))); m++); for (; (m < contractString.length ()) && (!Character.isDigit(contractString.charAt(m))); m++); value = Integer.parseInt (contractString.substring (m, endInt (contractString, m))); if (strategy != 0) { contractedStrategy [i] = strategy; sidePayments [i] = value; } for (; (m < contractString.length ()) && (Character.isDigit(contractString.charAt(m))); m++); for (; (m < contractString.length ()) && (!Character.isDigit(contractString.charAt(m))); m++); } return; } // resetContract // Resets the contract strategy and side payments. void resetContract (int NumberOfPlayers) { int i; contractedStrategy = new int [NumberOfPlayers]; sidePayments = new int [NumberOfPlayers]; for (i = 0; i < NumberOfPlayers; i++) { contractedStrategy [i] = 0; sidePayments [i] = 0; } return; } // dispalyContracts // Display the current contracts to the specified stream void displayContracts (PrintStream ps) { int i; ps.print ("Contracts for Player " + (playerNumber + 1) + " :"); for (i = 0; i < contractedStrategy.length; i++) { if (contractedStrategy [i] != 0) { ps.print (" " + (i+1) + "/" + contractedStrategy [i] + "/" + sidePayments [i]); } } ps.println (); return; } // setStreams // Set up communications streams to a player's client program void setStreams (Socket s) throws IOException { in = new DataInputStream (s.getInputStream ()); out = new PrintStream (s.getOutputStream (), true); } } // GameMatrix Class // Builds and interrogates game matrix class GameMatrix { int NumberOfPlayers; int dimensions[]; int game[][]; int strategyIterator[] = null; // Constructor - generates a random game matrix based on the number of players // and the number of strategies specified by params. GameMatrix (int params[]) { int i, j, size; Random r = new Random (); NumberOfPlayers = params [0]; dimensions = new int [NumberOfPlayers]; for (i = 0; i < NumberOfPlayers; i++) { dimensions [i] = params [i+1]; } for (i = 0, size = 1; i < NumberOfPlayers; i++) { size = size * dimensions [i]; } game = new int [size][NumberOfPlayers]; for (i = 0; i < size; i++) { for (j = 0; j < NumberOfPlayers; j++) { game [i][j] = r.nextInt (41) - 20; } } } // payoffs // Return the payoffs for the specified strategy int [] payoffs (int strategy[]) { int i, index, multiplier = 1; index = strategy [0] - 1; for (i = 1; i < NumberOfPlayers; i++) { multiplier = multiplier * dimensions [i-1]; index = index + ((strategy [i] -1) * multiplier); } return (game [index]); } // getNumberOfStrategies // Return number of strategies for the specified player less one int getNumberOfStrategies (int i) { return (dimensions [i]); } // initIterator // Creates and returns an iterator to iterate the possible strategies. int [] initIterator () { int i; // create the initial strategy strategyIterator = new int [NumberOfPlayers]; for (i = 0; i < NumberOfPlayers; i++) { strategyIterator [i] = 1; } return (strategyIterator); } // nextStrategy // Returns next strategy in from the iterator. If there are no more strategies // or the iterator has not been initialise return null. int [] nextStrategy () { int index; if (strategyIterator == null) return (null); else { // increment strategy for (index = 0; index < NumberOfPlayers; index++) { strategyIterator [index] = strategyIterator [index] + 1; if (strategyIterator [index] > dimensions [index]) { strategyIterator [index] = 1; } else { break; } } // check if we have run out of strategies if (index == NumberOfPlayers) { strategyIterator = null; // if so set iterator to null } return (strategyIterator); } } // display // Display the contents on the game matrix. void display (PrintStream ps) { int i, index = 0; int strategy[], payoff[]; ps.println ("Number of Players = " + NumberOfPlayers); // create the initial strategy strategy = initIterator (); // iterate through all the strategies for each player. while (strategy != null) { payoff = payoffs (strategy); ps.print ("Strategy "); for (i = 0; i < NumberOfPlayers; i++) { ps.print (strategy [i] + " "); } ps.print (" : "); for (i = 0; i < NumberOfPlayers; i++) { ps.print (payoff [i] + " "); } ps.println (); // increment strategy strategy = nextStrategy (); } return; } } // Application class MServer { public static void main (String args[]) throws IOException { int base_port = 4000; int i, j, k; int GameNumber, NumberOfPlayers, NumberOfGames; int currentPlayer, firstPlayer = 0; String message; GameMatrix game; int params[], payoff[], payout[], strategy[]; Random rand = new Random (); PrintStream log = new PrintStream ((new FileOutputStream ("log.txt"))); NumberOfPlayers = Integer.parseInt (args[0]); NumberOfGames = Integer.parseInt (args[1]); ServerSocket ss[] = new ServerSocket [NumberOfPlayers]; Socket sock[] = new Socket [NumberOfPlayers]; Player p[] = new Player [NumberOfPlayers]; for (i = 0; i < NumberOfPlayers; i++) { p[i] = new Player (i); } payout = new int [NumberOfPlayers]; // Connect to each player's client for (i = 0; i < NumberOfPlayers; i++) { ss[i] = new ServerSocket (base_port+i,1); sock[i] = ss[i].accept (); p[i].setStreams (sock[i]); } // Determine each player's identity and set their initial balance for (i = 0; i < NumberOfPlayers; i++) { p[i].out.println ("W"); p[i].IDString = p[i].in.readLine (); System.out.println ("Player " + (i+1) + " is " + p[i].IDString); log.println ("Player " + (i+1) + " is " + p[i].IDString); p[i].out.println ("B" + Long.toString(p[i].balance)); } // Play each game for (GameNumber = 0; GameNumber < NumberOfGames; GameNumber++, firstPlayer = (firstPlayer + 1) % NumberOfPlayers) { System.out.println ("Game " + Integer.toString (GameNumber + 1)); log.println ("Game " + Integer.toString (GameNumber + 1)); params = new int [NumberOfPlayers + 1]; params [0] = NumberOfPlayers; for (i = 0; i < NumberOfPlayers; i++) { params [i+1] = rand.nextInt (4) + 2; } game = new GameMatrix (params); game.display (log); // send game matrix to each players for (i = 0; i < NumberOfPlayers; i++) { p[i].out.print ("M " + NumberOfPlayers); for (j = 0; j < NumberOfPlayers; j++) { p[i].out.print (" " + game.getNumberOfStrategies (j)); } p[i].out.println (); for (strategy = game.initIterator (); strategy != null; strategy = game.nextStrategy ()) { payoff = game.payoffs (strategy); for (j = 0; j < NumberOfPlayers; j++) { p[i].out.print (payoff [j] + " "); } p[i].out.println (); } } // Side payment phase for (i = 0; i < NumberOfPlayers; i++) { p[i].out.println ("R1"); p[i].resetContract (NumberOfPlayers); } for (i = 0; i < 3; i++) { for (j = 0; j < NumberOfPlayers; j++) { currentPlayer = (firstPlayer + j) % NumberOfPlayers; // rotate starting player p[currentPlayer].out.println ("G" + (currentPlayer + 1)); message = p[currentPlayer].in.readLine (); p[currentPlayer].setContract (message.substring (2), NumberOfPlayers); for (k = 0; k < NumberOfPlayers; k++) // echo to other players { if (k != currentPlayer) { p[k].out.println ("G" + (currentPlayer + 1)); p[k].out.println (message); } } } } // Display contracts for (i = 0; i < NumberOfPlayers; i++) { p[i].displayContracts (log); } // Receive strategies and determine payoffs for (i = 0; i < NumberOfPlayers; i++) { p[i].out.println ("R2"); } strategy = new int [NumberOfPlayers]; for (i = 0; i < NumberOfPlayers; i++) { message = p[i].in.readLine (); strategy [i] = Integer.parseInt (message.substring (1)); } payoff = game.payoffs (strategy); for (i = 0; i < NumberOfPlayers; i++) { payout [i] = payoff [i]; } for (i = 0; i < NumberOfPlayers; i++) { for (j = 0; j < NumberOfPlayers; j++) { if ((j != i) && (strategy [j] == p[i].contractedStrategy [j])) { log.print ("Player " + (j+1) + " has fullfilled a contract with Player " + (i+1)); log.println (" on strategy " + strategy [j] + " for " + p[i].sidePayments [j]); payout [j] += p[i].sidePayments [j]; payout [i] -= p[i].sidePayments [j]; } } } for (i = 0; i < NumberOfPlayers; i++) { p[i].balance += payout [i]; } System.out.print ("Strategy played "); log.print ("Strategy played "); for (i = 0; i < NumberOfPlayers; i++) { System.out.print (strategy [i] + " "); log.print (strategy [i] + " "); } System.out.print (" : "); log.print (" : "); for (i = 0; i < NumberOfPlayers; i++) { System.out.print (payoff [i] + " "); log.print (payoff [i] + " "); } System.out.print (" : "); log.print (" : "); for (i = 0; i < NumberOfPlayers; i++) { System.out.print (payout [i] + " "); log.print (payout [i] + " "); } System.out.println (); log.println (); // inform players of the payoffs for (i = 0; i < NumberOfPlayers; i++) { p[i].out.print ("P"); for (j = 0; j < NumberOfPlayers; j++) { p[i].out.print (" " + payoff [j]); } p[i].out.println (); } } // end of game loop for (i = 0; i < NumberOfPlayers; i++) { p[i].out.println ("E"); } System.out.print ("Final Score: "); log.print ("Final Score: "); for (i = 0; i < NumberOfPlayers; i++) { System.out.print (Long.toString (p[i].balance) + ' '); log.print (Long.toString (p[i].balance) + ' '); } System.out.println (); log.println (); for (i = 0; i < NumberOfPlayers; i++) { sock[i].close(); } } }