package game; import java.util.Arrays; import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Document; import data.Derivative; import input.InputReader; import output.PlayersFileWriter; import participant.Player; import transaction.*; import utilities.FileManager; /** * class to represent the game administrator * * @author Rukmal Fernando * @author Hardik Kotecha * @author Radhika Srinivasan */ public class Administrator { private ArrayList players; int activePlayerIndex = -1; // index for finding the active player PlayersFileWriter pfw; // writer for players xml file FileManager fm; int round = 1; // initial game round /** * default constructor * * @exception RuntimeException */ public Administrator() { throw new RuntimeException( "Cannot instantiate default Administrator" ); } /** * constructor */ public Administrator( ArrayList pPlayers ) { setPlayers( pPlayers ); History.readHistory(); Store.readStore(); } /*======================================================================== | getters and setters +-----------------------------------------------------------------------*/ /** * get the players of the game * * @return ArrayList */ private ArrayList getPlayers() { return players; } /** * set the players of the game to the given list pPlayers * * @param pPlayers */ private void setPlayers( ArrayList pPlayers ) { players = pPlayers; } /** * get the active player's index * * @return int */ private int getActivePlayerIndex() { return activePlayerIndex; } /** * set the index of the active player * * @param pActivePlayerIndex */ private void setActivePlayerIndex( int pActivePlayerIndex ) { activePlayerIndex = pActivePlayerIndex; } /** * get the name of the active player * @return String */ private String getActivePlayerName() { ArrayList localPlayers = getPlayers(); int index = getActivePlayerIndex(); Player retPlayer; if( index < 0 || index >= localPlayers.size() ) retPlayer = localPlayers.get( 0 ); else retPlayer = localPlayers.get( index ); return retPlayer.getName(); } /*----------------------------------------------------------------------- | end getters and setters +======================================================================*/ /** * write the players file in the blackboard */ private void writePlayersFile() { String allPlayers = new String( "\n" ); //opening tag for players Iterator playersIterator = players.iterator(); //iterator for ArrayList while ( playersIterator.hasNext() ) //while the iterator has more elements { Player tmp = playersIterator.next(); //get the next Player allPlayers = allPlayers.concat( tmp.generateXML() ); //generate the XML for this Player and add it } allPlayers = allPlayers.concat( "" ); //add closing tag for players pfw = PlayersFileWriter.initialize(); //get the FileWrite for Players pfw.writeFile( allPlayers ); //write the generated XML to the file } /** * read the done file given a path * * @param pDoneFilePath : String * @return ArrayList */ private ArrayList readDoneFile( String pDoneFilePath ) { try { InputReader xmlReader = InputReader.initialize(); //get an reader for the XML Document playerTransactionsDoc = xmlReader.prepareDocument( pDoneFilePath ); //build a document from the XML return xmlReader.parseTransactions( playerTransactionsDoc ); //parse the document of the player's transactions } catch( Exception e ) { e.printStackTrace(); return null; } } /** * update the account of the given player with the given value * * @param pPlayerName : String * @param pValue : Float */ private void updatePlayerAccount( String pPlayerName, Float pValue ) { Iterator playersIterator = getPlayers().iterator(); while ( playersIterator.hasNext() ) { Player currentPlayer = playersIterator.next(); String currentPlayerName = currentPlayer.getName(); if ( pPlayerName.compareTo( currentPlayerName ) == 0 ) { currentPlayer.updateAccount( pValue ); } } } /** * process the given transaction * * @param pTransaction : Transaction */ private void processTransaction( Transaction pTransaction ) { Derivative transactionDerivative = pTransaction.getDerivative(); String creatorName = transactionDerivative.getCreator(); String buyerName = transactionDerivative.getBoughtBy(); if ( pTransaction instanceof Create ) { Store.add( transactionDerivative ); } else if ( pTransaction instanceof Buy ) { if ( !Store.updateDerivative( transactionDerivative ) ) throw new RuntimeException( "Failed to update derivative, does not exist in store" ); Float derivativePrice = transactionDerivative.getPrice().getValue(); updatePlayerAccount( buyerName, 0 - derivativePrice ); updatePlayerAccount( creatorName, derivativePrice ); } else if ( pTransaction instanceof Finish ) { if ( !Store.removeDerivative( transactionDerivative.getName() ) ) throw new RuntimeException( "Failed to remove derivative, does not exist in store" ); Float finishedProductQuality = transactionDerivative.getFinishedProduct().getQuality().getValue(); updatePlayerAccount( buyerName, finishedProductQuality ); updatePlayerAccount( creatorName, 0 - finishedProductQuality ); } else if ( pTransaction instanceof Deliver ) { if ( !Store.updateDerivative( transactionDerivative ) ) throw new RuntimeException( "Failed to update derivative, does not exist in store" ); } } /** * read player transactions file given a path * * @param pDoneFilePath : String */ public void processPlayerTransactions( String pDoneFilePath ) { ArrayList playerTransactions = readDoneFile( pDoneFilePath ); //read done file and get transactions fm = FileManager.initialize(); fm.deleteFile( pDoneFilePath ); // after reading the done file, delete it Iterator transactionsIterator = playerTransactions.iterator(); // process all the player transactions while ( transactionsIterator.hasNext() ) //iterate over transactions { Transaction currentTransaction = transactionsIterator.next(); //get the next transaction processTransaction( currentTransaction ); } // write the new updated store to file Store.writeStore(); // update the history with the current transactions History.add( playerTransactions ); History.writeHistory(); } /** * increment the active player index */ private void incrementActivePlayerIndex() { int newIndex = getActivePlayerIndex() + 1; setActivePlayerIndex( newIndex ); } /** * change current player turn and write new players.xml file in blackboard */ public void changeTurn() { int index = getActivePlayerIndex(); if ( index != -1 ) //if it is not the initial turn ( all turn values false ) { Player lastPlayer = players.get( activePlayerIndex ); //get the last active player lastPlayer.setTurn( false ); //set last active player turn to false } if ( index < players.size() - 1 ) //if the counter hasn't reached the last player { incrementActivePlayerIndex(); //increment counter } else //if the counter has reached the last player { setActivePlayerIndex( 0 ); //reset counter round++; } Player active = players.get( activePlayerIndex ); active.setTurn( true ); //set the next player's turn status to active System.out.println( "(Round " + round + ") Turn: " + active.getName() ); writePlayersFile(); //write updated players file } /** * check for player done file */ void beginTurnTimer() { String doneFilePath = Config.getBlackBoardPath() + "/" + getActivePlayerName() + "_done.xml"; long initialTime = System.currentTimeMillis(); long currentTime = initialTime; long timeLimit = Config.getTimeLimit() * 1000; long endTime = initialTime + timeLimit; while(currentTime < endTime && !utilities.FileManager.exists( doneFilePath ) ) { currentTime = System.currentTimeMillis(); try { Thread.sleep( 500 ); } catch( Exception e ) { e.printStackTrace(); } } System.out.println( "found " + getActivePlayerName() + " done file" ); processPlayerTransactions( doneFilePath ); } /** * start the game * * @param pNumRounds : int */ void startGame( int pNumRounds ) { while ( round <= pNumRounds ) { changeTurn(); beginTurnTimer(); } } /** * sort the list of players based on Money * (first having the most Money) * * @return ArrayList : sorted list of Player */ public ArrayList sortPlayers() { Object[] playersArray = players.toArray(); //convert the ArrayList to an array to be sorted Arrays.sort( playersArray ); //sort the players using the comparable interface in player ArrayList sorted = new ArrayList(); //create a new arraylist for the sorted players int playersArraySize = playersArray.length; for( int i = 0; i < playersArraySize; i++) //loop over the array { sorted.add( (Player)playersArray[i] ); //add the player in the array to the ArrayList } return sorted; } }