Skip to content

Commit

Permalink
add undo button for last move (resolves #1)
Browse files Browse the repository at this point in the history
  • Loading branch information
NiklasEi committed Jul 29, 2018
1 parent e712f43 commit e3d0ac0
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 27 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### v 2.1.1
- fix top navigation
- make display name of surrounding grid items configurable
- add optional "undo last move button" (#1)

### v 2.1.0
- compatibility with minecraft 1.13
Expand Down
49 changes: 30 additions & 19 deletions src/main/java/me/nikl/gamebox/games/twoofoureight/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;

Expand Down Expand Up @@ -44,6 +45,8 @@ public class Game extends BukkitRunnable{
private float volume = 0.5f, pitch= 1f;
private ItemStack left, right, up, down;
private Set<Integer> combined = new HashSet<>();
private GameState lastState;
private ItemStack undoLastMoveButton;

public Game(GameRules rule, Tofe tofe, Player player, Map<Integer, ItemStack> items, boolean playSounds, boolean topNav, boolean surroundGrid, ItemStack surroundItemStack){
this.tofe = tofe;
Expand All @@ -53,6 +56,7 @@ public Game(GameRules rule, Tofe tofe, Player player, Map<Integer, ItemStack> it
this.player = player;
this.random = new Random(System.currentTimeMillis());
this.items = new HashMap<>(items);
this.undoLastMoveButton = ((GameManager)tofe.getGameManager()).getUndoLastMoveButton();
loadIcons();

String title= lang.GAME_TITLE.replace("%score%", String.valueOf(score));
Expand All @@ -61,6 +65,8 @@ public Game(GameRules rule, Tofe tofe, Player player, Map<Integer, ItemStack> it
}
this.inventory = tofe.createInventory(54, title);
prepareInventory(topNav, surroundGrid, surroundItemStack);
this.lastState = new GameState(gridSize);
lastState.set(score, grid);
build();
this.runTaskTimer(tofe.getGameBox(), 0, 3);
}
Expand Down Expand Up @@ -89,6 +95,9 @@ private void prepareInventory(boolean topNav, boolean surroundGrid, ItemStack su
}
}
}
if (rule.isUndoLastMove()) {
player.getOpenInventory().getBottomInventory().setItem(25, undoLastMoveButton);
}
spawn();
spawn();
player.openInventory(inventory);
Expand Down Expand Up @@ -201,7 +210,7 @@ private boolean moveLeft(boolean set){
for (int y = 0; y < gridSize;y++){
for (int x = 1; x < gridSize;x++) {
if((grid[x][y] != 0 && grid[x-1][y] == 0)
|| (grid[x][y] != 0 && grid[x][y] == grid[x-1][y] && !combined.contains(x+y*gridSize) && !combined.contains(x-1+y*gridSize))){
|| (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x - 1][y]) && !combined.contains(x+y*gridSize) && !combined.contains(x-1+y*gridSize))){
if(set)this.status = Status.LEFT;
return true;
}
Expand All @@ -217,7 +226,7 @@ private void moveOneLeft(){
if(grid[x][y] != 0 && grid[x-1][y] == 0){
grid[x-1][y] = grid[x][y];
grid[x][y] = 0;
} else if (grid[x][y] != 0 && grid[x][y] == grid[x-1][y] && !combined.contains(x+y*gridSize) && !combined.contains(x-1+y*gridSize)){
} else if (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x - 1][y]) && !combined.contains(x+y*gridSize) && !combined.contains(x-1+y*gridSize)){
grid[x][y] = 0;
grid[x-1][y] ++;
combined.add(x-1 + y*gridSize);
Expand All @@ -241,7 +250,7 @@ private void moveOneLeft(){
private boolean moveRight(boolean set){
for (int y = 0; y < gridSize;y++){
for (int x = gridSize - 2; x >= 0 ;x--){
if((grid[x][y] != 0 && grid[x+1][y] == 0) || (grid[x][y] != 0 && grid[x][y] == grid[x+1][y] && !combined.contains(x+y*gridSize) && !combined.contains(x+1+y*gridSize))){
if((grid[x][y] != 0 && grid[x+1][y] == 0) || (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x + 1][y]) && !combined.contains(x+y*gridSize) && !combined.contains(x+1+y*gridSize))){
if(set)this.status = Status.RIGHT;
return true;
}
Expand All @@ -257,7 +266,7 @@ private void moveOneRight(){
if(grid[x][y] != 0 && grid[x+1][y] == 0){
grid[x+1][y] = grid[x][y];
grid[x][y] = 0;
} else if (grid[x][y] != 0 && grid[x][y] == grid[x+1][y] && !combined.contains(x+y*gridSize) && !combined.contains(x+1+y*gridSize)){
} else if (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x + 1][y]) && !combined.contains(x+y*gridSize) && !combined.contains(x+1+y*gridSize)){
grid[x][y] = 0;
grid[x+1][y] ++;
combined.add(x+1 + y*gridSize);
Expand All @@ -281,7 +290,7 @@ private void moveOneRight(){
private boolean moveUp(boolean set){
for (int x = 0; x < gridSize;x++){
for (int y = 1; y < gridSize;y++){
if((grid[x][y] != 0 && grid[x][y-1] == 0) || (grid[x][y] != 0 && grid[x][y] == grid[x][y-1] && !combined.contains(x+y*gridSize) && !combined.contains(x+(y-1)*gridSize))){
if((grid[x][y] != 0 && grid[x][y-1] == 0) || (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x][y - 1]) && !combined.contains(x+y*gridSize) && !combined.contains(x+(y-1)*gridSize))){
if(set) this.status = Status.UP;
return true;
}
Expand All @@ -297,7 +306,7 @@ private void moveOneUp(){
if(grid[x][y] != 0 && grid[x][y-1] == 0){
grid[x][y-1] = grid[x][y];
grid[x][y] = 0;
} else if (grid[x][y] != 0 && grid[x][y] == grid[x][y-1] && !combined.contains(x+y*gridSize) && !combined.contains(x+(y-1)*gridSize)){
} else if (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x][y - 1]) && !combined.contains(x+y*gridSize) && !combined.contains(x+(y-1)*gridSize)){
grid[x][y] = 0;
grid[x][y-1] ++;
combined.add(x + (y-1)*gridSize);
Expand Down Expand Up @@ -325,7 +334,7 @@ private boolean moveDown(boolean set){
if(grid[x][y] != 0 && grid[x][y+1] == 0){
if(set)this.status = Status.DOWN;
return true;
} else if (grid[x][y] != 0 && grid[x][y] == grid[x][y+1] && !combined.contains(x+y*gridSize) && !combined.contains(x+(y+1)*gridSize)){
} else if (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x][y + 1]) && !combined.contains(x+y*gridSize) && !combined.contains(x+(y+1)*gridSize)){
tofe.debug("continue because of x: " + x + " y: " + y);
if(set)this.status = Status.DOWN;
return true;
Expand All @@ -342,7 +351,7 @@ private void moveOneDown(){
if(grid[x][y] != 0 && grid[x][y+1] == 0){
grid[x][y+1] = grid[x][y];
grid[x][y] = 0;
} else if (grid[x][y] != 0 && grid[x][y] == grid[x][y+1] && !combined.contains(x+y*gridSize) && !combined.contains(x+(y+1)*gridSize)){
} else if (grid[x][y] != 0 && Objects.equals(grid[x][y], grid[x][y + 1]) && !combined.contains(x+y*gridSize) && !combined.contains(x+(y+1)*gridSize)){
grid[x][y] = 0;
grid[x][y+1] ++;
combined.add(x + (y+1)*gridSize);
Expand Down Expand Up @@ -371,20 +380,27 @@ public void onClick(InventoryClickEvent event){
ItemStack item = event.getCurrentItem();
if(item.isSimilar(this.left)){
onClick(Clicks.LEFT);
return;
} else if(item.isSimilar(this.right)){
onClick(Clicks.RIGHT);
return;
} else if(item.isSimilar(this.up)){
onClick(Clicks.UP);
return;
} else if(item.isSimilar(this.down)){
onClick(Clicks.DOWN);
return;
} else if (item.isSimilar(undoLastMoveButton)) {
loadGameState(lastState);
}
}

private void loadGameState(GameState lastState) {
this.grid = lastState.getGrid();
this.score = lastState.getScore();
build();
}

public void onClick(Clicks click){
if (status != Status.PLAY) return;
// save state for 'go back button'
lastState.set(score, grid);
tofe.debug("clicked");
switch (click){
case LEFT:
Expand Down Expand Up @@ -422,35 +438,30 @@ public void run() {
if(status != Status.LEFT){
spawn();
}
build();

break;

case DOWN:
moveOneDown();
if(status != Status.DOWN){
spawn();
}
build();

break;

case RIGHT:
moveOneRight();
if(status != Status.RIGHT){
spawn();
}
build();
break;

case UP:
moveOneUp();
if(status != Status.UP){
spawn();
}
build();

break;
}
build();
}

public enum Clicks{
Expand Down
44 changes: 37 additions & 7 deletions src/main/java/me/nikl/gamebox/games/twoofoureight/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class GameManager extends EasyManager {
private Map<String,GameRules> gameTypes = new HashMap<>();
private boolean topNav, surroundGrid;
private ItemStack surroundItemStack;
private ItemStack undoLastMoveButton;

public GameManager(Tofe tofe){
this.tofe = tofe;
Expand All @@ -47,16 +48,40 @@ public GameManager(Tofe tofe){
loadTiles();
this.topNav = tofe.getConfig().getBoolean("rules.topNavigation", false);
this.surroundGrid = tofe.getConfig().getBoolean("rules.surroundTheGrid.enable", true);
surroundItemStack = ItemStackUtility.loadItem(tofe.getConfig().getConfigurationSection("rules.surroundTheGrid"));
if (!tofe.getConfig().isConfigurationSection("rules.surroundTheGrid")) {
loadDefaultSurroundItemStack();
} else {
surroundItemStack = ItemStackUtility.loadItem(tofe.getConfig().getConfigurationSection("rules.surroundTheGrid"));
}
if (surroundItemStack == null) {
tofe.warn("invalid surroundItemStack... falling back to default");
surroundItemStack = ItemStackUtility.getItemStack("stained_glass_pane:15");
ItemMeta meta = surroundItemStack.getItemMeta();
meta.setDisplayName(ChatColor.AQUA.toString());
surroundItemStack.setItemMeta(meta);
loadDefaultSurroundItemStack();
}
if (!tofe.getConfig().isConfigurationSection("rules.undoLastMove")) {
loadDefaultUndoLastMoveButton();
} else {
undoLastMoveButton = ItemStackUtility.loadItem(tofe.getConfig().getConfigurationSection("rules.undoLastMove"));
}
if (undoLastMoveButton == null) {
loadDefaultUndoLastMoveButton();
}
}

private void loadDefaultUndoLastMoveButton() {
tofe.warn("invalid undoLastMoveButton... falling back to default");
undoLastMoveButton = ItemStackUtility.getItemStack("lever");
ItemMeta meta = undoLastMoveButton.getItemMeta();
meta.setDisplayName(ChatColor.AQUA.toString() + "Undo last move");
undoLastMoveButton.setItemMeta(meta);
}

private void loadDefaultSurroundItemStack() {
tofe.warn("invalid surroundItemStack... falling back to default");
surroundItemStack = ItemStackUtility.getItemStack("stained_glass_pane:15");
ItemMeta meta = surroundItemStack.getItemMeta();
meta.setDisplayName(ChatColor.AQUA.toString());
surroundItemStack.setItemMeta(meta);
}

private void loadTiles() {
if(!tofe.getConfig().isConfigurationSection("tiles")){
Bukkit.getLogger().log(Level.SEVERE, "Configuration error.. cannot find any tiles");
Expand Down Expand Up @@ -158,7 +183,8 @@ public void removeFromGame(UUID uuid) {
public void loadGameRules(ConfigurationSection buttonSec, String buttonID) {
double cost = buttonSec.getDouble("cost", 0.);
boolean saveStats = buttonSec.getBoolean("saveStats", false);
gameTypes.put(buttonID, new GameRules(tofe, buttonID, cost, saveStats));
boolean undoLastMove = buttonSec.getBoolean("undoLastMove", false);
gameTypes.put(buttonID, new GameRules(tofe, buttonID, cost, saveStats, undoLastMove));
}

@Override
Expand All @@ -170,4 +196,8 @@ public void loadGameRules(ConfigurationSection buttonSec, String buttonID) {
private boolean pay(Player[] player, double cost) {
return tofe.payIfNecessary(player[0], cost);
}

protected ItemStack getUndoLastMoveButton() {
return this.undoLastMoveButton;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
* Created by Niklas on 16.02.2017.
*/
public class GameRules extends GameRuleMultiRewards {
private boolean undoLastMove;

public GameRules(Tofe game, String key, double cost, boolean saveStats){
public GameRules(Tofe game, String key, double cost, boolean saveStats, boolean undoLastMove){
super(key, saveStats, SaveType.SCORE, cost);
loadRewards(game);
this.undoLastMove = undoLastMove;
}

private void loadRewards(Tofe game) {
Expand All @@ -38,4 +40,8 @@ private void loadRewards(Tofe game) {
}
}
}

public boolean isUndoLastMove() {
return undoLastMove;
}
}
33 changes: 33 additions & 0 deletions src/main/java/me/nikl/gamebox/games/twoofoureight/GameState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package me.nikl.gamebox.games.twoofoureight;

/**
* @author Niklas Eicker
*/
public class GameState {
private Integer[][] grid;
private int score;
private int gridSize;

public GameState(int gridSize) {
this.score = 0;
this.gridSize = gridSize;
}

public void set(int score, Integer[][] grid) {
this.score = score;
this.grid = new Integer[gridSize][gridSize];
for (int y = 0; y < grid.length; y++) {
for (int x = 0; x < grid.length; x++) {
this.grid[x][y] = new Integer(grid[x][y]);
}
}
}

public int getScore() {
return this.score;
}

public Integer[][] getGrid() {
return this.grid;
}
}
8 changes: 8 additions & 0 deletions src/main/resources/games/twoofoureight/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ gameBox:
- "&1You can win tokens above &61000"
slot: 20
cost: 5
# adds a button that allows to undo the last move
undoLastMove: true
scoreIntervals:
# all keys have to be integers otherwise they will be ignored and a warning will be printed in the console

Expand Down Expand Up @@ -68,6 +70,7 @@ gameBox:
cost: 50
# if true the best score of this button is saved
saveStats: true
undoLastMove: false
scoreIntervals:
0:
money: 0
Expand Down Expand Up @@ -111,6 +114,11 @@ rules:
enable: true
materialData: "stained_glass_pane:15"
displayName: "&a"
# undo last move button
# this functionality can be turned off on per game mode basis
undoLastMove:
materialData: "lever"
displayName: "&l&aUndo last move"

# Buttons in the game
buttons:
Expand Down

0 comments on commit e3d0ac0

Please sign in to comment.