Improves and fixes comments for the gate layout class

This commit is contained in:
Kristian Knarvik 2021-10-16 16:44:11 +02:00
parent 59069d1423
commit 3de785d5ab
2 changed files with 64 additions and 58 deletions

View File

@ -265,7 +265,7 @@ public class Gate {
bufferedWriter.newLine();
//Save the gate layout
layout.save(bufferedWriter);
layout.saveLayout(bufferedWriter);
bufferedWriter.close();
} catch (IOException ex) {

View File

@ -5,6 +5,7 @@ import net.knarcraft.stargate.container.RelativeBlockVector;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@ -12,7 +13,7 @@ import java.util.List;
*
* <p>The gate layout parses a layout described by a Character matrix and stores the different parts of the gate as
* relative block vectors. All relative vectors has an origin in the top-left block when looking at the gate's front
* (the side with the sign)</p>
* (the side with the sign). The origin of the relative vectors can also be seen as 0,0 in the character matrix.</p>
*/
public class GateLayout {
@ -26,7 +27,7 @@ public class GateLayout {
/**
* Instantiates a new gate layout
*
* @param layout <p>A character array describing the layout</p>
* @param layout <p>A character matrix describing the layout</p>
*/
public GateLayout(Character[][] layout) {
this.layout = layout;
@ -43,7 +44,9 @@ public class GateLayout {
}
/**
* Gets the locations of entrances for this gate
* Gets the locations of all entrances for this gate
*
* <p>Entrances contain both the portal entrance blocks and the portal exit blocks.</p>
*
* @return <p>The locations of entrances for this gate</p>
*/
@ -73,9 +76,12 @@ public class GateLayout {
}
/**
* Gets other possible exits of the gate
* Gets all possible exit locations defined in the layout
*
* @return <p>Other possible gate exits</p>
* <p>This returns all blocks usable as exits. This basically means it returns the lowest block in each opening of
* the gate layout.</p>
*
* @return <p>All possible exits</p>
*/
public List<RelativeBlockVector> getExits() {
return exits;
@ -84,7 +90,8 @@ public class GateLayout {
/**
* Gets the locations of the control blocks for this gate
*
* <p>The control blocks are the blocks where a sign can be placed to create a portal.</p>
* <p>The control blocks are the blocks where a sign can be placed to create a portal. The control block without a
* sign will be used for the button if necessary. There will always be exactly two control blocks.</p>
*
* @return <p>The locations of the control blocks for this gate</p>
*/
@ -98,44 +105,24 @@ public class GateLayout {
* @param bufferedWriter <p>The buffered writer to write to</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
public void save(BufferedWriter bufferedWriter) throws IOException {
public void saveLayout(BufferedWriter bufferedWriter) throws IOException {
for (Character[] line : this.layout) {
for (Character symbol : line) {
bufferedWriter.append(symbol);
}
bufferedWriter.append(Arrays.toString(line));
bufferedWriter.newLine();
}
}
/**
* Reads the gate layout to relative block vectors
* Reads the layout and stores key information
*
* <p>This methods reads the layout and stores exits, entrances, border blocks and control blocks.</p>
*/
private void readLayout() {
List<RelativeBlockVector> entranceList = new ArrayList<>();
List<RelativeBlockVector> borderList = new ArrayList<>();
List<RelativeBlockVector> controlList = new ArrayList<>();
RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length];
RelativeBlockVector lastExit = null;
int[] exitDepths = readLayout(controlList, entranceList, borderList);
//Generate other possible exits
for (int x = 0; x < exitDepths.length; x++) {
relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0);
}
//Add non-null exits to the exits list
for (int x = relativeExits.length - 1; x >= 0; x--) {
if (relativeExits[x] != null) {
lastExit = relativeExits[x];
} else {
relativeExits[x] = lastExit;
}
if (exitDepths[x] > 0) {
this.exits.add(relativeExits[x]);
}
}
readLayout(controlList, entranceList, borderList);
this.entrances = entranceList.toArray(this.entrances);
this.border = borderList.toArray(this.border);
@ -148,55 +135,74 @@ public class GateLayout {
* @param controlList <p>The list of control blocks to save to</p>
* @param entranceList <p>The list of entrances to save to</p>
* @param borderList <p>The list of border blocks to save to</p>
* @return <p>A list of depths of possible extra exits</p>
*/
private int[] readLayout(List<RelativeBlockVector> controlList, List<RelativeBlockVector> entranceList,
List<RelativeBlockVector> borderList) {
//Store the depth/line of each
private void readLayout(List<RelativeBlockVector> controlList, List<RelativeBlockVector> entranceList,
List<RelativeBlockVector> borderList) {
//Store the lowest opening for each column
int[] exitDepths = new int[layout[0].length];
//A row is the same as one line in the gate file
int lineCount = layout.length;
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
int rowSize = layout[lineIndex].length;
for (int rowIndex = 0; rowIndex < rowSize; rowIndex++) {
Character key = layout[lineIndex][rowIndex];
parseLayoutCharacter(key, rowIndex, lineIndex, exitDepths, controlList, entranceList, borderList);
for (int rowIndex = 0; rowIndex < lineCount; rowIndex++) {
Character[] row = layout[rowIndex];
int rowSize = row.length;
for (int columnIndex = 0; columnIndex < rowSize; columnIndex++) {
Character key = row[columnIndex];
parseLayoutCharacter(key, columnIndex, rowIndex, exitDepths, controlList, entranceList, borderList);
}
}
//Generate all possible exits
for (int x = 0; x < exitDepths.length; x++) {
//Ignore invalid exits
if (exitDepths[x] > 0) {
this.exits.add(new RelativeBlockVector(x, exitDepths[x], 0));
}
}
return exitDepths;
}
/**
* Parses one character of the layout
*
* @param key <p>The character read</p>
* @param rowIndex <p>The row of the read character</p>
* @param lineIndex <p>The line of the read character</p>
* @param key <p>The read character</p>
* @param columnIndex <p>The column containing the read character</p>
* @param rowIndex <p>The row containing the read character</p>
* @param exitDepths <p>The list of exit depths to save to</p>
* @param controlList <p>The list of control blocks to save to</p>
* @param entranceList <p>The list of entrances to save to</p>
* @param borderList <p>The list of border blocks to save to</p>
*/
private void parseLayoutCharacter(Character key, int rowIndex, int lineIndex, int[] exitDepths,
private void parseLayoutCharacter(Character key, int columnIndex, int rowIndex, int[] exitDepths,
List<RelativeBlockVector> controlList, List<RelativeBlockVector> entranceList,
List<RelativeBlockVector> borderList) {
//Add control blocks
//Add control blocks to the control block list
if (key.equals(GateHandler.getControlBlockCharacter())) {
controlList.add(new RelativeBlockVector(rowIndex, lineIndex, 0));
controlList.add(new RelativeBlockVector(columnIndex, rowIndex, 0));
}
if (key.equals(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) {
//Register entrances
entranceList.add(new RelativeBlockVector(rowIndex, lineIndex, 0));
//Find the lowest exit block at a given x position
exitDepths[rowIndex] = lineIndex;
//Register exit
if (isOpening(key)) {
//Register entrance
entranceList.add(new RelativeBlockVector(columnIndex, rowIndex, 0));
//Overwrite the lowest exit location for this column/x-coordinate
exitDepths[columnIndex] = rowIndex;
//Register exit if found
if (key.equals(GateHandler.getExitCharacter())) {
this.exitBlock = new RelativeBlockVector(rowIndex, lineIndex, 0);
this.exitBlock = new RelativeBlockVector(columnIndex, rowIndex, 0);
}
} else if (!key.equals(GateHandler.getAnythingCharacter())) {
//Add border
borderList.add(new RelativeBlockVector(rowIndex, lineIndex, 0));
//Register border block
borderList.add(new RelativeBlockVector(columnIndex, rowIndex, 0));
}
}
/**
* Checks whether the given character represents a gate opening
*
* @param character <p>The character to check</p>
* @return <p>True if the character represents an opening</p>
*/
private boolean isOpening(Character character) {
return character.equals(GateHandler.getEntranceCharacter()) || character.equals(GateHandler.getExitCharacter());
}
}