MapReaderAdapter.java
package soen6441riskgame.utils.map;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import soen6441riskgame.enums.ConquestMapPart;
import soen6441riskgame.enums.DominationMapPart;
import soen6441riskgame.models.Continent;
import soen6441riskgame.models.Coordinate;
import soen6441riskgame.models.Country;
import soen6441riskgame.singleton.GameBoard;
import soen6441riskgame.utils.ConsolePrinter;
/**
* map reader adapter for both conquest and domination map style
*/
public class MapReaderAdapter implements DominationMapReadable, ConquestMapReadable {
/**
* load map from file
*
* @param fileName the exact path to map file, end with .map extension for example:
* D://src/test/java/soen6441riskgame/maps/RiskEurope.map
* @throws IOException exception
*/
@Override
public void loadMap(String fileName) throws IOException {
List<String> lines = readMapFile(fileName);
for (int index = 0; index < lines.size(); index++) {
index = loadMapComponents(lines, index);
}
ConsolePrinter.printFormat("Map loaded");
}
/**
* load domination map components
*
* @param lines lines in file
* @param index current line
* @return end of the current block
*/
@Override
public int loadMapComponents(List<String> lines, int index) {
String currentLine = lines.get(index);
if (currentLine.startsWith(";")) {
return index;
}
String firstWord = currentLine.split(" ")[0];
DominationMapPart part = DominationMapPart.fromString(firstWord);
switch (part) {
case NAME: {
GameBoard.getInstance()
.getGameBoardMap()
.setMapName(currentLine.split("name")[1].trim());
break;
}
case CONTINENTS: {
index = loadContinentsFromFile(index, lines);
break;
}
case COUNTRIES: {
index = loadCountriesFromFile(index, lines);
break;
}
case BORDERS: {
index = loadBordersFromFile(index, lines);
break;
}
case FILES:
case NONE: {
break;
}
}
return index;
}
/**
* Load all continent data from map file
*
* @param currentLineIndex the current line index
* @param lines all the line in map file
* @return the line index that end the continent block in map file
*/
public int loadContinentsFromFile(int currentLineIndex, List<String> lines) {
int continentOrder = 1;
for (int index = currentLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
String currentLine = lines.get(index);
String[] fragments = currentLine.split(" ");
String continentName = fragments[0];
int continentArmy = Integer.parseInt(fragments[1]);
// String continentColor = fragments[2];
addContinent(continentName, Integer.toString(continentArmy), continentOrder);
currentLineIndex = index;
continentOrder++;
}
return currentLineIndex + 1;
}
/**
* Load all country data from map file
*
* @param currentLineIndex the current line index
* @param lines all the line in map file
* @return the line index that end the country block in map file
*/
public int loadCountriesFromFile(int currentLineIndex, List<String> lines) {
for (int index = currentLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
String currentLine = lines.get(index);
String[] fragments = currentLine.split(" ");
int countryOrder = Integer.parseInt(fragments[0]);
String countryName = fragments[1];
int continentOrder = Integer.parseInt(fragments[2]);
int x = Integer.parseInt(fragments[3]);
int y = Integer.parseInt(fragments[4]);
Coordinate coordinate = new Coordinate(x, y);
addCountry(countryOrder, countryName, continentOrder, coordinate);
currentLineIndex = index;
}
return currentLineIndex + 1;
}
/**
* Load all border data from map file
*
* @param currentLineIndex the current line index
* @param lines all the line in map file
* @return the line index that end the border block in map file
*/
public int loadBordersFromFile(int currentLineIndex, List<String> lines) {
int numberOfCountry = GameBoard.getInstance().getGameBoardMap().getCountries().size();
GameBoard.getInstance().getGameBoardMap().setBorders(new int[numberOfCountry][numberOfCountry]);
for (int index = currentLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
String currentLine = lines.get(index);
String[] fragments = currentLine.split(" ");
int countryOrder = Integer.parseInt(fragments[0]);
int[] borderWithCountries = new int[fragments.length - 1];
for (int borderIndex = 0; borderIndex < borderWithCountries.length; borderIndex++) {
borderWithCountries[borderIndex] = Integer.parseInt(fragments[borderIndex + 1]);
}
addBorders(countryOrder, borderWithCountries);
currentLineIndex = index;
}
return currentLineIndex + 1;
}
/**
* save the map to a file
*
* @param fileName path to file
* @throws IOException exception
*/
public void writeMapToFile(String fileName) throws IOException {
FileWriter writer = new FileWriter(fileName);
writeContinentsToFile(writer);
writeCountriesToFile(writer);
writeBordersToFile(writer);
writer.close();
}
/**
* Write continent information to file
*
* @param writer file writer
* @throws IOException file not found or not exist
*/
public void writeContinentsToFile(FileWriter writer) throws IOException {
ArrayList<Continent> continents = GameBoard.getInstance().getGameBoardMap().getContinents();
writer.write(DominationMapPart.CONTINENTS.getPart() + "\n");
for (Continent continent : continents) {
writer.write(continent.getName() + " " + continent.getArmy() + "\n");
}
writer.write("\n");
}
/**
* Write borders information to file
*
* @param writer file writer
* @throws IOException file not found or not exist
*/
public void writeBordersToFile(FileWriter writer) throws IOException {
writer.write(DominationMapPart.BORDERS.getPart() + "\n");
for (Country country : GameBoard.getInstance().getGameBoardMap().getCountries()) {
ArrayList<Country> neighbors = country.getNeighbors();
StringBuilder neighborLine = new StringBuilder(Integer.toString(country.getOrder()));
for (Country neighbor : neighbors) {
neighborLine.append(" ").append(neighbor.getOrder());
}
writer.write(neighborLine + "\n");
}
}
/**
* Write countries information to file
*
* @param writer file writer
* @throws IOException file not found or not exist
*/
public void writeCountriesToFile(FileWriter writer) throws IOException {
ArrayList<Country> countries = GameBoard.getInstance().getGameBoardMap().getCountries();
writer.write(DominationMapPart.COUNTRIES.getPart() + "\n");
for (Country country : countries) {
writer.write(country.getOrder() + " "
+ country.getName() + " "
+ country.getContinent().getOrder() + " "
+ country.getCoordinate().getX() + " "
+ country.getCoordinate().getY() + "\n");
}
writer.write("\n");
}
/**
* load the conquest map from file
*
* @param fileName path to file
* @throws IOException if file not found or read file error
*/
@Override
public void loadConquestMap(String fileName) throws IOException {
List<String> lines = readMapFile(fileName);
for (int index = 0; index < lines.size(); index++) {
index = loadConquestMapComponents(lines, index);
}
ConsolePrinter.printFormat("Map loaded");
}
/**
* load conquest map components
*
* @param lines lines in file
* @param index current line
* @return end of the current block
*/
@Override
public int loadConquestMapComponents(List<String> lines, int index) {
String currentLine = lines.get(index);
String firstWord = currentLine.split(" ")[0];
ConquestMapPart part = ConquestMapPart.fromString(firstWord);
switch (part) {
case MAP: {
index = loadConquestMapInfo(lines, index);
break;
}
case CONTINENTS: {
index = loadContinentsFromConquestFile(index, lines);
break;
}
case TERRITORIES: {
index = loadCountriesFromConquestFile(index, lines);
break;
}
case NONE: {
break;
}
}
return index;
}
/**
* load conquest map info
*
* @param lines lines in file
* @param currentLineIndex current line
* @return end of the current block
*/
@Override
public int loadConquestMapInfo(List<String> lines, int currentLineIndex) {
for (int index = currentLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
currentLineIndex = index;
}
return currentLineIndex + 1;
}
/**
* load continents
*
* @param lines lines in file
* @param currentLineIndex current line
* @return end of the current block
*/
@Override
public int loadContinentsFromConquestFile(int currentLineIndex, List<String> lines) {
int continentOrder = 1;
for (int index = currentLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
String currentLine = lines.get(index);
String[] fragments = currentLine.split("=");
String continentName = legalizeString(fragments[0]);
int continentArmy = Integer.parseInt(fragments[1]);
addContinent(continentName, Integer.toString(continentArmy), continentOrder);
currentLineIndex = index;
continentOrder++;
}
return currentLineIndex + 1;
}
/**
* load countries
*
* @param lines lines in file
* @param currentLineIndex current line
* @return end of the current block
*/
@Override
public int loadCountriesFromConquestFile(int currentLineIndex, List<String> lines) {
// Cockpit01,658,355,Cockpit,Cockpit02,Territory33
// Territory name,x,y,Continent,neighbor1,neighbor1
int originalLineIndex = currentLineIndex;
for (int index = currentLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
String currentLine = lines.get(index);
String[] fragments = currentLine.split(",");
String countryName = legalizeString(fragments[0]);
int x = Integer.parseInt(fragments[1]);
int y = Integer.parseInt(fragments[2]);
Coordinate coordinate = new Coordinate(x, y);
String continentName = legalizeString(fragments[3]);
int countryOrder = GameBoard.getInstance()
.getGameBoardMap()
.getCountries()
.size()
+ 1;
int continentOrder = GameBoard.getInstance()
.getGameBoardMap()
.getContinentFromName(continentName)
.getOrder();
addCountry(countryOrder, countryName, continentOrder, coordinate);
}
originalLineIndex = loadBordersFromConquestFile(lines, originalLineIndex);
return originalLineIndex + 1;
}
/**
* load border from conquest file
*
* @param lines lines from file
* @param originalLineIndex the start index of the territories part
* @return line index that end the territories part
*/
private int loadBordersFromConquestFile(List<String> lines, int originalLineIndex) {
// load borders
// Cockpit01,658,355,Cockpit,Cockpit02,Territory33
// Territory name,x,y,Continent,neighbor1,neighbor1
int numberOfCountry = GameBoard.getInstance().getGameBoardMap().getCountries().size();
GameBoard.getInstance().getGameBoardMap().setBorders(new int[numberOfCountry][numberOfCountry]);
for (int index = originalLineIndex + 1; isStillInCurrentDataBlock(index, lines); index++) {
String currentLine = lines.get(index);
String[] fragments = currentLine.split(",");
int countryOrder = GameBoard.getInstance()
.getGameBoardMap()
.getCountryFromName(legalizeString(fragments[0]))
.getOrder();
// neighbors start from fragments[4]
int[] borderWithCountries = new int[fragments.length - 4];
for (int neighborIndex = 4; neighborIndex < fragments.length; neighborIndex++) {
int neighborOrder = GameBoard.getInstance()
.getGameBoardMap()
.getCountryFromName(legalizeString(fragments[neighborIndex]))
.getOrder();
borderWithCountries[neighborIndex - 4] = neighborOrder;
}
addBorders(countryOrder, borderWithCountries);
originalLineIndex = index;
}
return originalLineIndex;
}
/**
* write map to conquest file
*
* @param fileName path to file
* @throws IOException if file not found
*/
@Override
public void writeMapToConquestFile(String fileName) throws IOException {
FileWriter writer = new FileWriter(fileName);
writeContinentsToConquestFile(writer);
writeCountriesToConquestFile(writer);
writer.close();
}
/**
* write continents to conquest map file
*
* @param writer the file writer
* @throws IOException if cannot write to file
*/
@Override
public void writeContinentsToConquestFile(FileWriter writer) throws IOException {
ArrayList<Continent> continents = GameBoard.getInstance().getGameBoardMap().getContinents();
writer.write(ConquestMapPart.CONTINENTS.getPart() + "\n");
for (Continent continent : continents) {
writer.write(continent.getName() + "=" + continent.getArmy() + "\n");
}
writer.write("\n");
}
/**
* write countries to conquest map files
*
* @param writer the file writer
* @throws IOException if cannot write to file
*/
@Override
public void writeCountriesToConquestFile(FileWriter writer) throws IOException {
// Cockpit01,658,355,Cockpit,Cockpit02,Territory33
ArrayList<Country> countries = GameBoard.getInstance().getGameBoardMap().getCountries();
writer.write(ConquestMapPart.TERRITORIES.getPart() + "\n");
for (Country country : countries) {
String countryData = country.getName() + ","
+ country.getCoordinate().getX() + ","
+ country.getCoordinate().getY() + ","
+ country.getContinent().getName() + ",";
ArrayList<Country> neighbors = country.getNeighbors();
for (Country neighbor : neighbors) {
countryData += neighbor.getName() + ",";
}
countryData = countryData.substring(0, countryData.length() - 1);
writer.write(countryData + "\n");
}
writer.write("\n");
}
}