Dieser Commit ist enthalten in:
Ursprung
cfaddb01d0
Commit
2ce06ea780
@ -137,6 +137,9 @@ JUMP_AND_RUN_PERSONAL_BEST_NO_TIME = §cNo personal best
|
||||
|
||||
# Games
|
||||
GAMES_TICTACTOE = TicTacToe
|
||||
GAMES_CONNECT_4 = Connect 4
|
||||
|
||||
GAMES_ALREADY_PRESENT = §cYou already have an open invitation
|
||||
GAMES_NO_SELF = §cYou can\'t play against yourself
|
||||
GAMES_CHALLENGED_BY = §e{0} §7challenged you to a game of §e{1}
|
||||
GAMES_CHALLENGED_BY_HOVER = §7Click to accept
|
||||
|
@ -128,6 +128,9 @@ JUMP_AND_RUN_PERSONAL_BEST_NO_TIME = §cDu hast noch keinen Rekord
|
||||
|
||||
# Games
|
||||
GAMES_TICTACTOE = TicTacToe
|
||||
GAMES_CONNECT_4 = Vier Gewinnt
|
||||
|
||||
GAMES_ALREADY_PRESENT = §cDu hast bereits eine Herausforderung!
|
||||
GAMES_NO_SELF = §cDu kannst dich nicht selbst herausfordern!
|
||||
GAMES_CHALLENGED_BY = §e{0} §7hat dich zu einem Spiel §e{1}§7 herausgefordert!
|
||||
GAMES_CHALLENGED_BY_HOVER = §7Klicke hier, um das Spiel zu bestätigen
|
||||
|
30
src/de/steamwar/lobby/games/Game.java
Normale Datei
30
src/de/steamwar/lobby/games/Game.java
Normale Datei
@ -0,0 +1,30 @@
|
||||
package de.steamwar.lobby.games;
|
||||
|
||||
import de.steamwar.lobby.LobbySystem;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public abstract class Game implements Listener {
|
||||
|
||||
@Getter
|
||||
private final Player player;
|
||||
|
||||
@Getter
|
||||
private final Player opponent;
|
||||
|
||||
protected Game(Player player, Player opponent) {
|
||||
this.player = player;
|
||||
this.opponent = opponent;
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin());
|
||||
}
|
||||
|
||||
public abstract void start();
|
||||
|
||||
public void end() {
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
}
|
62
src/de/steamwar/lobby/games/GameManager.java
Normale Datei
62
src/de/steamwar/lobby/games/GameManager.java
Normale Datei
@ -0,0 +1,62 @@
|
||||
package de.steamwar.lobby.games;
|
||||
|
||||
import de.steamwar.lobby.LobbySystem;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@UtilityClass
|
||||
public class GameManager {
|
||||
|
||||
private Map<Player, Game> games = new HashMap<>();
|
||||
|
||||
private GameListener gameListener = new GameListener();
|
||||
|
||||
static {
|
||||
Bukkit.getPluginManager().registerEvents(gameListener, LobbySystem.getPlugin());
|
||||
}
|
||||
|
||||
private static class GameListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
games.remove(event.getPlayer());
|
||||
games.values().removeIf(game -> game.getOpponent() == event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public void registerGame(Games games, Player player, Player opponent) {
|
||||
if (opponent == player) {
|
||||
LobbySystem.getMessage().send("GAMES_NO_SELF", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameManager.games.containsKey(opponent)) {
|
||||
Game game = GameManager.games.get(opponent);
|
||||
if (game.getOpponent() == player && games.isGame(game)) {
|
||||
game.start();
|
||||
GameManager.games.remove(opponent);
|
||||
GameManager.games.remove(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (GameManager.games.containsKey(player)) {
|
||||
LobbySystem.getMessage().send("GAMES_ALREADY_PRESENT", player);
|
||||
return;
|
||||
}
|
||||
GameManager.games.put(player, games.createGame(player, opponent));
|
||||
LobbySystem.getMessage().send("GAMES_CHALLENGED_BY", opponent, LobbySystem.getMessage().parse("GAMES_CHALLENGED_BY_HOVER", opponent), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/games " + games.name() + " " + player.getName()), player.getName(), LobbySystem.getMessage().parse("GAMES_TICTACTOE", opponent));
|
||||
}
|
||||
|
||||
public void unregisterGame(Player player) {
|
||||
games.remove(player);
|
||||
}
|
||||
}
|
49
src/de/steamwar/lobby/games/Games.java
Normale Datei
49
src/de/steamwar/lobby/games/Games.java
Normale Datei
@ -0,0 +1,49 @@
|
||||
package de.steamwar.lobby.games;
|
||||
|
||||
import de.steamwar.lobby.games.tictactoe.TicTacToe;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public enum Games {
|
||||
|
||||
TICTACTOE {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "GAMES_TICTACTOE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGame(Game game) {
|
||||
return game instanceof TicTacToe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game createGame(Player player, Player opponent) {
|
||||
return new TicTacToe(player, opponent);
|
||||
}
|
||||
},
|
||||
/*
|
||||
CONNECT_4 {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "GAMES_CONNECT_4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGame(Game game) {
|
||||
return game instanceof Connect4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game createGame(Player player, Player opponent) {
|
||||
return new Connect4(player, opponent);
|
||||
}
|
||||
},
|
||||
*/
|
||||
;
|
||||
|
||||
public abstract String getName();
|
||||
|
||||
public abstract boolean isGame(Game game);
|
||||
|
||||
public abstract Game createGame(Player player, Player opponent);
|
||||
}
|
@ -1,38 +1,21 @@
|
||||
package de.steamwar.lobby.games;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.lobby.LobbySystem;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GamesCommand extends SWCommand {
|
||||
|
||||
private final Map<Player, List<Player>> CHALLENGES = new HashMap<>();
|
||||
|
||||
public GamesCommand() {
|
||||
super("games");
|
||||
}
|
||||
|
||||
@Register("tictactoe")
|
||||
public void tictactoe(Player player, Player target) {
|
||||
if(player == target) {
|
||||
LobbySystem.getMessage().send("GAMES_NO_SELF", player);
|
||||
return;
|
||||
}
|
||||
@Register
|
||||
public void game(Player player, Games games, Player opponent) {
|
||||
GameManager.registerGame(games, player, opponent);
|
||||
}
|
||||
|
||||
if(CHALLENGES.containsKey(player) && CHALLENGES.get(player).contains(target)) {
|
||||
new TicTacToe(player, target).updateBoard();
|
||||
CHALLENGES.remove(player);
|
||||
CHALLENGES.remove(target);
|
||||
return;
|
||||
}
|
||||
|
||||
CHALLENGES.computeIfAbsent(target, k -> new ArrayList<>()).add(player);
|
||||
LobbySystem.getMessage().send("GAMES_CHALLENGED_BY", target, LobbySystem.getMessage().parse("GAMES_CHALLENGED_BY_HOVER", target), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/games tictactoe " + player.getName()), player.getName(), LobbySystem.getMessage().parse("GAMES_TICTACTOE", target));
|
||||
@Register("stop")
|
||||
public void stop(Player player) {
|
||||
GameManager.unregisterGame(player);
|
||||
}
|
||||
}
|
||||
|
15
src/de/steamwar/lobby/games/Pair.java
Normale Datei
15
src/de/steamwar/lobby/games/Pair.java
Normale Datei
@ -0,0 +1,15 @@
|
||||
package de.steamwar.lobby.games;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class Pair<A, B> {
|
||||
private A a;
|
||||
private B b;
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
package de.steamwar.lobby.games;
|
||||
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.lobby.LobbySystem;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TicTacToe implements Listener {
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
private static final int[][] WINNING_COMBINATIONS = {
|
||||
{0, 1, 2},
|
||||
{3, 4, 5},
|
||||
{6, 7, 8},
|
||||
{0, 3, 6},
|
||||
{1, 4, 7},
|
||||
{2, 5, 8},
|
||||
{0, 4, 8},
|
||||
{2, 4, 6}
|
||||
};
|
||||
|
||||
private final Player player1;
|
||||
private final Player player2;
|
||||
private Player turn;
|
||||
|
||||
private final int[] board = new int[9];
|
||||
|
||||
private int turns = 0;
|
||||
|
||||
private boolean running = true;
|
||||
|
||||
public TicTacToe(Player player1, Player player2) {
|
||||
this.player1 = player1;
|
||||
this.player2 = player2;
|
||||
this.turn = random.nextBoolean() ? player1 : player2;
|
||||
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin());
|
||||
}
|
||||
|
||||
public void updateBoard() {
|
||||
for (int[] winningCombination : WINNING_COMBINATIONS) {
|
||||
if(board[winningCombination[0]] == board[winningCombination[1]] &&
|
||||
board[winningCombination[1]] == board[winningCombination[2]] &&
|
||||
board[winningCombination[0]] != 0) {
|
||||
win(turn, winningCombination);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(turns++ == 9) {
|
||||
draw();
|
||||
return;
|
||||
}
|
||||
|
||||
turn = turn == player1 ? player2 : player1;
|
||||
showBoard(player1);
|
||||
showBoard(player2);
|
||||
}
|
||||
|
||||
private void win(Player player, int[] winningCombination) {
|
||||
running = false;
|
||||
SWInventory inventory = createCurrentBoard(player1, LobbySystem.getMessage().parse("GAMES_WON", player1, player.getName()));
|
||||
SWInventory inventory2 = createCurrentBoard(player2, LobbySystem.getMessage().parse("GAMES_WON", player2, player.getName()));
|
||||
for (int j : winningCombination) {
|
||||
inventory.setItem(j, new SWItem(Material.LIME_WOOL, "§" + j + "§a" + (board[j] == 1 ? "X" : "O")));
|
||||
inventory2.setItem(j, new SWItem(Material.LIME_WOOL, "§" + j + "§a" + (board[j] == 1 ? "X" : "O")));
|
||||
}
|
||||
remake(inventory, inventory2);
|
||||
inventory.open();
|
||||
inventory2.open();
|
||||
}
|
||||
|
||||
private void draw() {
|
||||
running = false;
|
||||
SWInventory inventory = createCurrentBoard(player1, LobbySystem.getMessage().parse("GAMES_DRAW", player1));
|
||||
SWInventory inventory2 = createCurrentBoard(player2, LobbySystem.getMessage().parse("GAMES_DRAW", player2));
|
||||
remake(inventory, inventory2);
|
||||
inventory.open();
|
||||
inventory2.open();
|
||||
}
|
||||
|
||||
private void remake(SWInventory inventory, SWInventory inventory2) {
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
inventory.setCallback(i, clickType -> player1.performCommand("games tictactoe " + player2.getName()));
|
||||
inventory2.setCallback(i, clickType -> player2.performCommand("games tictactoe " + player1.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private void end() {
|
||||
running = false;
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
private void showBoard(Player player) {
|
||||
SWInventory inventory = createCurrentBoard(player, LobbySystem.getMessage().parse("GAMES_TURN", player, turn.getName()));
|
||||
inventory.addCloseRunnable(() -> {
|
||||
Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> {
|
||||
if(player.getOpenInventory().getTopInventory().getType() != InventoryType.DROPPER && running) {
|
||||
player1.closeInventory();
|
||||
player2.closeInventory();
|
||||
LobbySystem.getMessage().send("GAMES_LEFT", player1, player.getName());
|
||||
LobbySystem.getMessage().send("GAMES_LEFT", player2, player.getName());
|
||||
end();
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
inventory.open();
|
||||
}
|
||||
|
||||
private SWInventory createCurrentBoard(Player player, String title) {
|
||||
SWInventory inventory = new SWInventory(player, () -> Bukkit.createInventory(null, InventoryType.DROPPER, title));
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
if(board[i] == 0) {
|
||||
int finalI = i;
|
||||
inventory.setItem(i, new SWItem(Material.LIGHT_GRAY_WOOL, "§" + i, clickType -> makeMove(player, finalI)));
|
||||
} else {
|
||||
inventory.setItem(i, new SWItem(board[i] == 1 ? Material.RED_WOOL : Material.BLUE_WOOL, "§" + i + "§" + (board[i] == 1? "c" : "3") + (board[i] == 1 ? "X" : "O")));
|
||||
}
|
||||
}
|
||||
return inventory;
|
||||
}
|
||||
|
||||
private void makeMove(Player player, int i) {
|
||||
if(player != turn) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(board[i] != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
board[i] = player == player1 ? 1 : 2;
|
||||
updateBoard();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
if(event.getPlayer() == player1 || event.getPlayer() == player2) {
|
||||
player1.closeInventory();
|
||||
player2.closeInventory();
|
||||
end();
|
||||
}
|
||||
}
|
||||
}
|
32
src/de/steamwar/lobby/games/connect4/Connect4.java
Normale Datei
32
src/de/steamwar/lobby/games/connect4/Connect4.java
Normale Datei
@ -0,0 +1,32 @@
|
||||
package de.steamwar.lobby.games.connect4;
|
||||
|
||||
import de.steamwar.lobby.games.Game;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Connect4 extends Game {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* {@code false} means player, {@code true} means opponent
|
||||
*/
|
||||
private boolean turn = RANDOM.nextBoolean();
|
||||
|
||||
/**
|
||||
* 0 = empty, 1 = player, 2 = opponent
|
||||
*/
|
||||
private final int[] board = new int[42];
|
||||
|
||||
private int turns = 0;
|
||||
|
||||
public Connect4(Player player, Player opponent) {
|
||||
super(player, opponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
}
|
||||
}
|
122
src/de/steamwar/lobby/games/tictactoe/TicTacToe.java
Normale Datei
122
src/de/steamwar/lobby/games/tictactoe/TicTacToe.java
Normale Datei
@ -0,0 +1,122 @@
|
||||
package de.steamwar.lobby.games.tictactoe;
|
||||
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.lobby.LobbySystem;
|
||||
import de.steamwar.lobby.games.Game;
|
||||
import de.steamwar.lobby.games.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TicTacToe extends Game {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private static final int[][] WINNING_COMBINATIONS = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}, {0, 4, 8}, {2, 4, 6}};
|
||||
|
||||
/**
|
||||
* {@code false} means player, {@code true} means opponent
|
||||
*/
|
||||
private boolean turn = RANDOM.nextBoolean();
|
||||
|
||||
/**
|
||||
* 0 = empty, 1 = player, 2 = opponent
|
||||
*/
|
||||
private final int[] board = new int[9];
|
||||
|
||||
private int turns = 0;
|
||||
|
||||
public TicTacToe(Player player, Player opponent) {
|
||||
super(player, opponent);
|
||||
}
|
||||
|
||||
private void showBoard(Player player) {
|
||||
Pair<Player, int[]> winner = checkWin();
|
||||
boolean draw = turns == 9;
|
||||
|
||||
String title;
|
||||
if (winner != null) {
|
||||
title = LobbySystem.getMessage().parse("GAMES_WON", player, winner.getA().getName());
|
||||
} else if (draw) {
|
||||
title = LobbySystem.getMessage().parse("GAMES_DRAW", player);
|
||||
} else {
|
||||
title = LobbySystem.getMessage().parse("GAMES_TURN", player, (turn ? getOpponent() : getPlayer()).getName());
|
||||
}
|
||||
|
||||
SWInventory inventory = new SWInventory(player, () -> Bukkit.createInventory(null, InventoryType.DROPPER, title));
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (board[i] == 0) {
|
||||
int finalI = i;
|
||||
if (winner != null) {
|
||||
inventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§" + i));
|
||||
} else {
|
||||
inventory.setItem(i, new SWItem(Material.LIGHT_GRAY_WOOL, "§" + i, clickType -> {
|
||||
if (turn == (player == getPlayer())) return;
|
||||
|
||||
board[finalI] = turn ? 2 : 1;
|
||||
turn = !turn;
|
||||
turns++;
|
||||
showBoard(getPlayer());
|
||||
showBoard(getOpponent());
|
||||
}));
|
||||
}
|
||||
} else if (board[i] == 1) {
|
||||
inventory.setItem(i, new SWItem((winner == null || contains(winner.getB(), i)) ? Material.RED_WOOL : Material.RED_STAINED_GLASS_PANE, "§" + i + "§cX"));
|
||||
} else {
|
||||
inventory.setItem(i, new SWItem((winner == null || contains(winner.getB(), i)) ? Material.BLUE_WOOL : Material.BLUE_STAINED_GLASS_PANE, "§" + i + "§bO"));
|
||||
}
|
||||
}
|
||||
|
||||
// Remake
|
||||
if (winner != null || draw) {
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
inventory.setCallback(i, clickType -> {
|
||||
player.performCommand("games tictactoe " + getOpponent().getName());
|
||||
player.getOpenInventory().close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
inventory.addCloseRunnable(() -> {
|
||||
Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> {
|
||||
if (getOpponent().getOpenInventory().getTopInventory().getType() != InventoryType.DROPPER) {
|
||||
return;
|
||||
}
|
||||
if (player.getOpenInventory().getTopInventory().getType() != InventoryType.DROPPER) {
|
||||
getPlayer().closeInventory();
|
||||
getOpponent().closeInventory();
|
||||
LobbySystem.getMessage().send("GAMES_LEFT", getPlayer(), player.getName());
|
||||
LobbySystem.getMessage().send("GAMES_LEFT", getOpponent(), player.getName());
|
||||
end();
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
inventory.open();
|
||||
}
|
||||
|
||||
private boolean contains(int[] ints, int i) {
|
||||
for (int anInt : ints) {
|
||||
if (anInt == i) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Pair<Player, int[]> checkWin() {
|
||||
for (int[] winningCombination : WINNING_COMBINATIONS) {
|
||||
if (board[winningCombination[0]] == board[winningCombination[1]] && board[winningCombination[1]] == board[winningCombination[2]] && board[winningCombination[0]] != 0) {
|
||||
return new Pair<>(board[winningCombination[0]] == 1 ? getPlayer() : getOpponent(), winningCombination);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
showBoard(getPlayer());
|
||||
showBoard(getOpponent());
|
||||
}
|
||||
}
|
In neuem Issue referenzieren
Einen Benutzer sperren