Skip to content

Commit

Permalink
Move the lastPlacePosition field to GameState
Browse files Browse the repository at this point in the history
  • Loading branch information
lscgh committed Feb 8, 2024
1 parent 94a5fc2 commit 0a55aef
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 81 deletions.
12 changes: 5 additions & 7 deletions mavenmcserver/src/main/java/mavenmcserver/game/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ public class Game {
public GameListener listener;

public GameState state;
/// The FieldPoint of the last marked field, starting as null
public FieldPoint lastPlacePosition = null;
private boolean didCompletePlace = true;
public boolean opponentPlayersTurn = true;

Expand Down Expand Up @@ -95,7 +93,7 @@ public Game(GameConfig config, Plugin plugin, boolean isReturnMatch) {

@Override
public void run() {
boolean didApplyAnyChange = state.applyGravityTick(lastPlacePosition);
boolean didApplyAnyChange = state.applyGravityTick();

if(didApplyAnyChange) {
state.applyVisually(location);
Expand Down Expand Up @@ -318,8 +316,8 @@ private void registerEnded() {
* @param position
*/
public void placeAt(FieldPoint position) {
// Store the position for use in checkForWin();
this.lastPlacePosition = position;
// Store the position for use in getWinnerIfAny(); and similar
this.state.lastPlacePosition = position;
this.didCompletePlace = false;

if(this.state.getStateAt(position) != FieldState.NEUTRAL) return;
Expand All @@ -339,14 +337,14 @@ public void placeAt(FieldPoint position) {

public void checkForWin() {

if(this.state.getWinnerIfAny(this.config.winRequiredAmount, this.lastPlacePosition) != FieldState.NEUTRAL) {
if(this.state.getWinnerIfAny(this.config.winRequiredAmount) != FieldState.NEUTRAL) {

this.listener.allowMarkingFields = false;

new BukkitRunnable() {

int i = -1;
ArrayList<Location> blockLocations = state.getWinRowBlockLocations(config.winRequiredAmount, location, lastPlacePosition);
ArrayList<Location> blockLocations = state.getWinRowBlockLocations(config.winRequiredAmount, location);

@Override
public void run() {
Expand Down
38 changes: 24 additions & 14 deletions mavenmcserver/src/main/java/mavenmcserver/game/GameState.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public int hashCode() {

return result;
}

public FieldPoint copy() {
return new FieldPoint(this.x, this.y, this.z);
}
}

/**
Expand Down Expand Up @@ -98,6 +102,9 @@ public enum FieldState {

FieldState blockStates[];

/// The FieldPoint of the last marked field, starting as null
public FieldPoint lastPlacePosition = null;

public GameState(Vector3i gameSize) {
this.gameSize = gameSize;

Expand Down Expand Up @@ -162,6 +169,7 @@ public void setStateAt(FieldPoint position, FieldState newState) {
if(!this.fieldPointIsValid(position)) throw new IllegalArgumentException("point " + position + " is invalid for size " + this.gameSize);

this.blockStates[position.x * this.gameSize.y * this.gameSize.z + position.y * this.gameSize.z + position.z] = newState;
this.lastPlacePosition = position.copy();
}

public void setStateAt(int x, int y, int z, FieldState newState) {
Expand All @@ -170,23 +178,26 @@ public void setStateAt(int x, int y, int z, FieldState newState) {

/**
* Advances the physics of this state by one tick. Every marking in air will fall down by a block.
* @param lastPlacePosition The FieldPoint of the last-changed block.
* @return Whether any changes were made.
*/
public boolean applyGravityTick(FieldPoint lastPlacePosition) {
public boolean applyGravityTick() {
boolean didApplyAnyChange = false;

for(int y = 1; y < this.gameSize.y; y++) {
for(int x = 0; x < this.gameSize.x; x++) {
for(int z = 0; z < this.gameSize.z; z++) {
if(this.getStateAt(x, y, z) != FieldState.NEUTRAL) {
if(this.getStateAt(x, y - 1, z) == FieldState.NEUTRAL) {
FieldPoint lastPlacePosition = this.lastPlacePosition;

this.setStateAt(x, y - 1, z, this.getStateAt(x, y, z));
this.setStateAt(x, y, z, FieldState.NEUTRAL);

boolean didModifyBlockAtLastPlacePosition = lastPlacePosition.equals(new FieldPoint(x, y, z));
this.lastPlacePosition = lastPlacePosition;

boolean didModifyBlockAtLastPlacePosition = this.lastPlacePosition.equals(new FieldPoint(x, y, z));
if(didModifyBlockAtLastPlacePosition) {
lastPlacePosition.y -= 1;
this.lastPlacePosition.y -= 1;
}

didApplyAnyChange = true;
Expand Down Expand Up @@ -231,24 +242,23 @@ public void applyVisually(Location gameStartBlock) {

/**
* Checks if a player won the game
* @param lastPlacePosition the field point that was last changed. Checks are done from this point into all possible directions.
* @return NEUTRAL if there is no winner yet. MAIN if the mainPlayer has won, OPPONENT if the opponentPlayer has won!
*/
public FieldState getWinnerIfAny(int winRequiredAmount, FieldPoint lastPlacePosition) {
public FieldState getWinnerIfAny(int winRequiredAmount) {

for(Vector3i direction: GameState.DIRECTIONS_TO_CHECK) {

int amountOfCorrectFields = this.getFieldsInARowCount(lastPlacePosition, direction);
int amountOfCorrectFields = this.getFieldsInARowCount(this.lastPlacePosition, direction);

if(amountOfCorrectFields >= winRequiredAmount) return this.getStateAt(lastPlacePosition);
if(amountOfCorrectFields >= winRequiredAmount) return this.getStateAt(this.lastPlacePosition);
else if(amountOfCorrectFields > 1) {

// Check in opposite direction
Vector3i oppositeDirection = new Vector3i(-direction.x, -direction.y, -direction.z);
amountOfCorrectFields += this.getFieldsInARowCount(lastPlacePosition, oppositeDirection) - 1; // subtract 1 because the lastChanged Block is counted twice.
amountOfCorrectFields += this.getFieldsInARowCount(this.lastPlacePosition, oppositeDirection) - 1; // subtract 1 because the lastChanged Block is counted twice.


if(amountOfCorrectFields >= winRequiredAmount) return this.getStateAt(lastPlacePosition);
if(amountOfCorrectFields >= winRequiredAmount) return this.getStateAt(this.lastPlacePosition);
}

}
Expand Down Expand Up @@ -286,25 +296,25 @@ public boolean winIsPossible() {
return false; // TODO: finish
}

public ArrayList<Location> getWinRowBlockLocations(int winRequiredAmount, Location gameStartBlock, FieldPoint lastPlacePosition) {
public ArrayList<Location> getWinRowBlockLocations(int winRequiredAmount, Location gameStartBlock) {

for(Vector3i direction : GameState.DIRECTIONS_TO_CHECK) {

int amountOfCorrectFields = this.getFieldsInARowCount(lastPlacePosition, direction) - 1;
int amountOfCorrectFields = this.getFieldsInARowCount(this.lastPlacePosition, direction) - 1;
int amountOfCorrectFieldsInOppositeDirection = 0;

if(amountOfCorrectFields > 0 && amountOfCorrectFields < winRequiredAmount - 1) {
// Check in opposite direction
Vector3i oppositeDirection = new Vector3i(-direction.x, -direction.y, -direction.z);
amountOfCorrectFieldsInOppositeDirection = this.getFieldsInARowCount(lastPlacePosition, oppositeDirection) - 1;
amountOfCorrectFieldsInOppositeDirection = this.getFieldsInARowCount(this.lastPlacePosition, oppositeDirection) - 1;
}

if(amountOfCorrectFields + amountOfCorrectFieldsInOppositeDirection < winRequiredAmount - 1) continue;

ArrayList<Location> blockLocations = new ArrayList<Location>();

for(int i = -amountOfCorrectFieldsInOppositeDirection; i <= amountOfCorrectFields; i++) {
FieldPoint currentPoint = lastPlacePosition.offsetBy(i * direction.x, i * direction.y, i * direction.z);
FieldPoint currentPoint = this.lastPlacePosition.offsetBy(i * direction.x, i * direction.y, i * direction.z);
Location fieldPointAsBlockLocation = this.fieldPointToBlockLocation(gameStartBlock, currentPoint);
blockLocations.add(fieldPointAsBlockLocation);
}
Expand Down
8 changes: 4 additions & 4 deletions mavenmcserver/src/main/resources/classes.uml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class FieldPoint {
+GameConfig config
+GameListener listener
+GameState state /' Stores the marked fields in a separate positioning system '/
+FieldPoint lastPlacePosition
boolean didCompletePlace
+boolean opponentPlayersTurn /' Whose turn it is! '/
+Location location /' Start block location; stores world '/
Expand Down Expand Up @@ -101,6 +100,7 @@ class GameState {
.. Fields ..
+Vector3i gameSize
FieldState blockStates[]
+FieldPoint lastPlacePosition

.. Methods ..
+GameState(Vector3i gameSize) /' Sizes the array and fills it with FieldState.NEUTRAL '/
Expand All @@ -113,14 +113,14 @@ class GameState {
+void setStateAt(FieldPoint position, FieldState newState)
+void setStateAt(int x, int y, int z, FieldState newState)

+boolean applyGravityTick(FieldPoint lastPlacePosition) /' Makes all blocks in air fall by one '/
+boolean applyGravityTick() /' Makes all blocks in air fall by one '/
+void applyVisually(Location gameStartBlock) /' Updates in-world blocks to match the state '/

// Returns NEUTRAL if there is no winner yet
+FieldState getWinnerIfAny(int winRequiredAmount, FieldPoint lastPlacePosition) /' Returns NEUTRAL for no winner yet '/
+FieldState getWinnerIfAny(int winRequiredAmount) /' Returns NEUTRAL for no winner yet '/
-int getFieldsInARowCount(FieldPoint startPoint, Vector3i direction) /' Counts how many fields, starting from *startPoint* and going into *direction*, have the same state. Immediate return if the state at *startPoint* == *FieldState.NEUTRAL* '/
+boolean winIsPossible() /' Whether (false) or not (true) to cancel the game '/
+ArrayList<Location> getWinRowBlockLocations(int winRequiredAmount, Location gameStartBlock, FieldPoint lastPlacePosition) /' Returns the Locations of the Blocks used to win the game '/
+ArrayList<Location> getWinRowBlockLocations(int winRequiredAmount, Location gameStartBlock) /' Returns the Locations of the Blocks used to win the game '/
}

+class GameListener {
Expand Down
Loading

0 comments on commit 0a55aef

Please sign in to comment.