/**
* Reads a data for a Monopoly game from a file
*
* @author Mr. Kevin Dietzler
*/
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.ArrayList;
public class MonopolyDataReader
{
/**
* A Monopoly data file should be separated into three sections:
* <p>
* 1: Monopoly variable data<br>
* 2: Monopoly token data<br>
* 3: Monopoly property data<br>
*
* @param filename the name of the file holding the data
* @param vars the MonopVars object for the game
* @param tokens the Token object for the game
* @param properties the ArrayList to which properties should be added
*/
public void readMonopolyFile (String filename, MonopVars vars, Token tokens,
ArrayList<Property> properties)
throws IOException, BadDataException
{
FileReader reader = new FileReader (filename);
try
{
Scanner in = new Scanner(reader);
readVarsData(in, vars);
in.nextLine();
readTokenData(in, tokens);
in.nextLine();
readPropertyData(in, properties);
if (in.hasNext())
throw new BadDataException ("End of file expected");
}
finally
{
reader.close();
}
}//end readMonopolyFile method
/**
* Reads the set of data for the MonopVars object<br>
* <p>
* Format for a MonopVars data should appear as follows:<br>
* *game name* - String<br>
* *currency symbol* - String<br>
* (All the following ints appear on the same line)<br>
* *go amount* *starting money amount* *jail bail fee* *number of dice sides* - all ints<br>
* *monopoly color #1* - String<br>
* *monopoly color #2* - String<br>
* ...<br>
* *monopoly color #8* - String
*
* @param in the scanner that scans the data
* @param vars the MonopVars object
*/
public void readVarsData (Scanner in, MonopVars vars)
throws BadDataException
{
String version, curSymbol;
int goAmount, startAmount, jailBailFee, numDiceSides;
String [] colors = new String [8];
if (!in.hasNextLine())
throw new BadDataException("Missing version name");
else
version = in.nextLine();
vars.setVersion (version);
if (!in.hasNextLine())
throw new BadDataException("Missing currency symbol");
else
curSymbol = in.nextLine();
vars.setCurrencySymbol (curSymbol);
if(!in.hasNextInt())
throw new BadDataException("Missing the amount for passing go.");
else
goAmount = in.nextInt();
vars.setGoAmount (goAmount);
if(!in.hasNextInt())
throw new BadDataException("Missing the amount of money a player starts with.");
else
startAmount = in.nextInt();
vars.setStartingMoneyAmount (startAmount);
if(!in.hasNextInt())
throw new BadDataException("Missing the amount for the fee to get out of jail.");
else
jailBailFee = in.nextInt();
vars.setJailBailFee (jailBailFee);
if(!in.hasNextInt())
throw new BadDataException("Missing the number of sides for the dice.");
else
numDiceSides = in.nextInt();
vars.setNumDiceSides (numDiceSides);
in.nextLine();
for (int i = 0; i < colors.length; i++)
{
if(!in.hasNextLine())
throw new BadDataException("Missing the " + (i + 1) + "" +
Monopoly.getSuffix(i + 1) + " Monopoly color.");
else
colors[i] = new String (in.nextLine());
}//end for
vars.setMonopolyColors (colors);
}//end readVarsData method
/**
* Reads the set of data for the Tokens object.
* <p>
* Token information should be in the following format:<br>
* *number of tokens (min. 2)* - int<br>
* *token #1* - String<br>
* *token #2* - String<br>
* ...<br>
* *token #n* - String
*
* @param in the scanner that scans the data
* @param tokens the Token object.
*/
public void readTokenData (Scanner in, Token tokens)
throws BadDataException
{
int numTokens;
String [] toks;
if (!in.hasNextInt())
throw new BadDataException("Number of tokens expected");
else
numTokens = in.nextInt();
in.nextLine();
toks = new String [numTokens];
for (int i = 0; i < toks.length; i++)
{
if (!in.hasNextLine())
throw new BadDataException("Missing the " + (i+1) + "" +
Monopoly.getSuffix(i+1) +
" token.");
else
toks[i] = in.nextLine();
}//end for
tokens.setTokens (toks);
}//end readTokensData method
/**
* Reads the set of Property data for the
* properties ArrayList.
* <p>
* See the getType() method of the Property class
*
* @param in the scanner that scans the data
* @param properties the ArrayList of Property objects.
*/
public void readPropertyData (Scanner in,
ArrayList<Property> properties)
throws BadDataException
{
int type;
Property nextProperty;
//There are ALWAYS 40 spaces on a Monopoly board
for (int index = 0; index < 40; index++)
{
if (!in.hasNext())
throw new BadDataException("Missing property number " +
(index + 1));
else if (!in.hasNextInt())
throw new BadDataException("Property type expected");
else
{
type = in.nextInt();
in.nextLine();
}
//Determine which property type this is
//(see the getType() method of the Property class)
//A Monopoly property
if (type == 1)
nextProperty = readMonopolyProperty (in, type, index);
//A Railroad Property
else if (type == 2)
nextProperty = readRailroadProperty (in, type, index);
//A Utility Property
else if (type == 3)
nextProperty = readUtilityProperty (in, type, index);
else if (type > 3 && type < 12)
nextProperty = readProperty (in, type, index);
else
throw new BadDataException ("Invalid property type.");
properties.add (nextProperty);
}//end for
}//end readPropertyData method
/**
* Reads the set of Property data for a Property of
* type MonopolyProperty.
* <p>
* Monopoly properties should appear in this format:<br>
* *property type* - int (see Property class)<br>
* *property name* - String<br>
* (all on same line in this order separated by spaces)
* *cost* *mortgage* *index of Monopoly color* *basic rent* *rent w/1 house* *rent w/2houses* *rent w/3houses* *rent w/4houses* *rent w/hotel* *building cost* - all ints
*
* @param in the scanner that scans the data
* @param type the type of Property this is.
* @param index the index of this Property on the board.
*/
public Property readMonopolyProperty (Scanner in, int type, int index)
throws BadDataException
{
String name;
int cost, mortgage, colorIndex, basicRent, oneHouseRent, twoHouseRent,
threeHouseRent, fourHouseRent, hotelRent, buildingCost;
//Check for and receive the property name
if (!in.hasNextLine())
throw new BadDataException("Missing property name");
else
name = in.nextLine();
//Check for and receive the cost
if (!in.hasNextInt())
throw new BadDataException("Missing property cost");
else
cost = in.nextInt();
//Check for and receive the mortgage
if (!in.hasNextInt())
throw new BadDataException("Missing property mortgage");
else
mortgage = in.nextInt();
//Check for and receive the index of the Monopoly color
if (!in.hasNextInt())
throw new BadDataException("Missing index (0 - 7) of the property's color");
else
colorIndex = in.nextInt();
//Check for and receive the basic rent
if (!in.hasNextInt())
throw new BadDataException("Missing basic rent");
else
basicRent = in.nextInt();
//Check for and receive the rent with one house
if (!in.hasNextInt())
throw new BadDataException("Missing rent with one house amount");
else
oneHouseRent = in.nextInt();
//Check for and receive the rent with two houses
if (!in.hasNextInt())
throw new BadDataException("Missing rent with two houses amount");
else
twoHouseRent = in.nextInt();
//Check for and receive the rent with three houses
if (!in.hasNextInt())
throw new BadDataException("Missing rent with three houses amount");
else
threeHouseRent = in.nextInt();
//Check for and receive the rent with four houses
if (!in.hasNextInt())
throw new BadDataException("Missing rent with four houses amount");
else
fourHouseRent = in.nextInt();
//Check for and receive the rent with a hotel
if (!in.hasNextInt())
throw new BadDataException("Missing rent with one a hotel amount");
else
hotelRent = in.nextInt();
//Check for and receive the building cost
if (!in.hasNextInt())
throw new BadDataException("Missing building cost amount");
else
buildingCost = in.nextInt();
return new MonopolyProperty (name, type, index, cost, mortgage,
colorIndex, basicRent, oneHouseRent,
twoHouseRent, threeHouseRent,
fourHouseRent, hotelRent, buildingCost);
}//end readMonopolyPropertyData method
/**
* Reads the set of Property data for a Property of
* type RailroadProperty.
* <p>
* Railroads & Utilities should appear in this format:<br>
* *property type* - int (see Property class)<br>
* *name of railroad/utility* - String<br>
* (both variables below are on the same line)<br>
* *cost* *mortgage* - both ints
*
* @param in the scanner that scans the data
* @param type the type of Property this is.
* @param index the index of this Property on the board.
*/
public Property readRailroadProperty (Scanner in, int type, int index)
throws BadDataException
{
String name;
int cost, mortgage;
//Check for and receive the property name
if (!in.hasNextLine())
throw new BadDataException("Missing property name");
else
name = in.nextLine();
//Check for and receive the cost
if (!in.hasNextInt())
throw new BadDataException("Missing property cost");
else
cost = in.nextInt();
//Check for and receive the mortgage
if (!in.hasNextInt())
throw new BadDataException("Missing property mortgage");
else
mortgage = in.nextInt();
System.out.println("HERE!!");
return new RailroadProperty (name, type, index, cost, mortgage);
}//end readRailroadPropertyData method
/**
* Reads the set of Property data for a Property of
* type UtilityProperty.
* <p>
* Railroads & Utilities should appear in this format:<br>
* *property type* - int (see Property class)<br>
* *name of railroad/utility* - String<br>
* (both variables below are on the same line)<br>
* *cost* *mortgage* - both ints
*
* @param in the scanner that scans the data
* @param type the type of Property this is.
* @param index the index of this Property on the board.
*/
public Property readUtilityProperty (Scanner in, int type, int index)
throws BadDataException
{
String name;
int cost, mortgage;
//Check for and receive the property name
if (!in.hasNextLine())
throw new BadDataException("Missing property name");
else
name = in.nextLine();
//Check for and receive the cost
if (!in.hasNextInt())
throw new BadDataException("Missing property cost");
else
cost = in.nextInt();
//Check for and receive the mortgage
if (!in.hasNextInt())
throw new BadDataException("Missing property mortgage");
else
mortgage = in.nextInt();
System.out.println("HERE!!");
return new UtilityProperty (name, type, index, cost, mortgage);
}//end readUtilityPropertyData method
/**
* Reads the set of Property data for a regular Property.
* <p>
* All other properties should appear in this format:<br>
* *property type* - int (see Property class)<br>
* *property name* - String
*
* @param in the scanner that scans the data
* @param type the type of Property this is.
* @param index the index of this Property on the board.
*/
public Property readProperty (Scanner in, int type, int index)
throws BadDataException
{
String name;
//Check for and receive the property name
if (!in.hasNextLine())
throw new BadDataException("Missing property name");
else
name = in.nextLine();
System.out.println("HERE!!");
return new Property (name, type, index);
}//end readRegularProperty method
}//end MonopolyDataReader class