mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 19:04:49 +00:00
tourney ready
This commit is contained in:
@@ -20,6 +20,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public final class Server {
|
public final class Server {
|
||||||
private String user = "";
|
private String user = "";
|
||||||
@@ -31,6 +32,8 @@ public final class Server {
|
|||||||
private ServerView view;
|
private ServerView view;
|
||||||
private boolean isPolling = true;
|
private boolean isPolling = true;
|
||||||
|
|
||||||
|
private AtomicBoolean isSingleGame = new AtomicBoolean(false);
|
||||||
|
|
||||||
private ScheduledExecutorService scheduler;
|
private ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
public static GameInformation.Type gameToType(String game) {
|
public static GameInformation.Type gameToType(String game) {
|
||||||
@@ -93,9 +96,10 @@ public final class Server {
|
|||||||
private void sendChallenge(String opponent) {
|
private void sendChallenge(String opponent) {
|
||||||
if (!isPolling) return;
|
if (!isPolling) return;
|
||||||
|
|
||||||
|
|
||||||
ViewStack.push(new SendChallengeView(this, opponent, (playerInformation, gameType) -> {
|
ViewStack.push(new SendChallengeView(this, opponent, (playerInformation, gameType) -> {
|
||||||
new EventFlow().addPostEvent(new NetworkEvents.SendChallenge(clientId, opponent, gameType))
|
new EventFlow().addPostEvent(new NetworkEvents.SendChallenge(clientId, opponent, gameType)).postEvent();
|
||||||
.listen(NetworkEvents.GameMatchResponse.class, e -> {
|
/* .listen(NetworkEvents.GameMatchResponse.class, e -> {
|
||||||
if (e.clientId() == clientId) {
|
if (e.clientId() == clientId) {
|
||||||
isPolling = false;
|
isPolling = false;
|
||||||
onlinePlayers.clear();
|
onlinePlayers.clear();
|
||||||
@@ -120,7 +124,9 @@ public final class Server {
|
|||||||
default -> ViewStack.push(new ErrorView("Unsupported game type."));
|
default -> ViewStack.push(new ErrorView("Unsupported game type."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).postEvent();
|
}) */
|
||||||
|
ViewStack.pop();
|
||||||
|
isSingleGame.set(true);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,13 +154,16 @@ public final class Server {
|
|||||||
information.players[0].computerDifficulty = 5;
|
information.players[0].computerDifficulty = 5;
|
||||||
information.players[1].name = response.opponent();
|
information.players[1].name = response.opponent();
|
||||||
|
|
||||||
|
Runnable onGameOverRunnable = isSingleGame.get()? null: this::gameOver;
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TICTACTOE ->
|
case TICTACTOE ->
|
||||||
new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage);
|
new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||||
case REVERSI ->
|
case REVERSI ->
|
||||||
new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage);
|
new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||||
case CONNECT4 ->
|
case CONNECT4 ->
|
||||||
new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage);
|
new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||||
default -> ViewStack.push(new ErrorView("Unsupported game type."));
|
default -> ViewStack.push(new ErrorView("Unsupported game type."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,11 +175,11 @@ public final class Server {
|
|||||||
String challengerName = extractQuotedValue(response.challengerName());
|
String challengerName = extractQuotedValue(response.challengerName());
|
||||||
String gameType = extractQuotedValue(response.gameType());
|
String gameType = extractQuotedValue(response.gameType());
|
||||||
final String finalGameType = gameType;
|
final String finalGameType = gameType;
|
||||||
|
|
||||||
ViewStack.push(new ChallengeView(challengerName, gameType, (playerInformation) -> {
|
ViewStack.push(new ChallengeView(challengerName, gameType, (playerInformation) -> {
|
||||||
final int challengeId = Integer.parseInt(response.challengeId().replaceAll("\\D", ""));
|
final int challengeId = Integer.parseInt(response.challengeId().replaceAll("\\D", ""));
|
||||||
new EventFlow().addPostEvent(new NetworkEvents.SendAcceptChallenge(clientId, challengeId)).postEvent();
|
new EventFlow().addPostEvent(new NetworkEvents.SendAcceptChallenge(clientId, challengeId)).postEvent();
|
||||||
ViewStack.pop();
|
ViewStack.pop();
|
||||||
|
isSingleGame.set(true);
|
||||||
|
|
||||||
//new EventFlow().listen(NetworkEvents.GameMatchResponse.class, e -> {
|
//new EventFlow().listen(NetworkEvents.GameMatchResponse.class, e -> {
|
||||||
|
|
||||||
@@ -200,8 +209,16 @@ public final class Server {
|
|||||||
startPopulateScheduler();
|
startPopulateScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void gameOver(){
|
||||||
|
ViewStack.pop();
|
||||||
|
ViewStack.push(view);
|
||||||
|
startPopulateScheduler();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void startPopulateScheduler() {
|
private void startPopulateScheduler() {
|
||||||
isPolling = true;
|
isPolling = true;
|
||||||
|
isSingleGame.set(false);
|
||||||
stopScheduler();
|
stopScheduler();
|
||||||
|
|
||||||
new EventFlow()
|
new EventFlow()
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public class Connect4Game {
|
|||||||
private final GameInformation information;
|
private final GameInformation information;
|
||||||
|
|
||||||
private final int myTurn;
|
private final int myTurn;
|
||||||
|
private Runnable onGameOver;
|
||||||
private final BlockingQueue<Game.Move> moveQueue;
|
private final BlockingQueue<Game.Move> moveQueue;
|
||||||
|
|
||||||
private final Connect4 game;
|
private final Connect4 game;
|
||||||
@@ -35,9 +36,10 @@ public class Connect4Game {
|
|||||||
|
|
||||||
private final AtomicBoolean isRunning;
|
private final AtomicBoolean isRunning;
|
||||||
|
|
||||||
public Connect4Game(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage) {
|
public Connect4Game(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
|
||||||
this.information = information;
|
this.information = information;
|
||||||
this.myTurn = myTurn;
|
this.myTurn = myTurn;
|
||||||
|
this.onGameOver = onGameOver;
|
||||||
moveQueue = new LinkedBlockingQueue<Game.Move>();
|
moveQueue = new LinkedBlockingQueue<Game.Move>();
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ public class Connect4Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Connect4Game(GameInformation information) {
|
public Connect4Game(GameInformation information) {
|
||||||
this(information, 0, null, null, null);
|
this(information, 0, null, null, null, null);
|
||||||
}
|
}
|
||||||
private void localGameThread() {
|
private void localGameThread() {
|
||||||
while (isRunning.get()) {
|
while (isRunning.get()) {
|
||||||
@@ -179,11 +181,14 @@ public class Connect4Game {
|
|||||||
if (state == Game.State.WIN) {
|
if (state == Game.State.WIN) {
|
||||||
if (response.player().equalsIgnoreCase(information.players[0].name)) {
|
if (response.player().equalsIgnoreCase(information.players[0].name)) {
|
||||||
view.gameOver(true, information.players[0].name);
|
view.gameOver(true, information.players[0].name);
|
||||||
|
gameOver();
|
||||||
} else {
|
} else {
|
||||||
view.gameOver(false, information.players[1].name);
|
view.gameOver(false, information.players[1].name);
|
||||||
|
gameOver();
|
||||||
}
|
}
|
||||||
} else if (state == Game.State.DRAW) {
|
} else if (state == Game.State.DRAW) {
|
||||||
view.gameOver(false, "");
|
view.gameOver(false, "");
|
||||||
|
gameOver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,6 +202,14 @@ public class Connect4Game {
|
|||||||
setGameLabels(game.getCurrentTurn() == myTurn);
|
setGameLabels(game.getCurrentTurn() == myTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void gameOver() {
|
||||||
|
if (onGameOver == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isRunning.set(false);
|
||||||
|
onGameOver.run();
|
||||||
|
}
|
||||||
|
|
||||||
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
||||||
new EventFlow().addPostEvent(new NetworkEvents.SendCommand(response.clientId(), "MESSAGE hoi"))
|
new EventFlow().addPostEvent(new NetworkEvents.SendCommand(response.clientId(), "MESSAGE hoi"))
|
||||||
.postEvent();
|
.postEvent();
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public final class ReversiGame {
|
|||||||
private final GameInformation information;
|
private final GameInformation information;
|
||||||
|
|
||||||
private final int myTurn;
|
private final int myTurn;
|
||||||
|
private Runnable onGameOver;
|
||||||
private final BlockingQueue<Game.Move> moveQueue;
|
private final BlockingQueue<Game.Move> moveQueue;
|
||||||
|
|
||||||
private final Reversi game;
|
private final Reversi game;
|
||||||
@@ -38,10 +39,11 @@ public final class ReversiGame {
|
|||||||
private final AtomicBoolean isRunning;
|
private final AtomicBoolean isRunning;
|
||||||
private final AtomicBoolean isPaused;
|
private final AtomicBoolean isPaused;
|
||||||
|
|
||||||
public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage) {
|
public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
|
||||||
this.information = information;
|
this.information = information;
|
||||||
|
|
||||||
this.myTurn = myTurn;
|
this.myTurn = myTurn;
|
||||||
|
this.onGameOver = onGameOver;
|
||||||
moveQueue = new LinkedBlockingQueue<Game.Move>();
|
moveQueue = new LinkedBlockingQueue<Game.Move>();
|
||||||
|
|
||||||
game = new Reversi();
|
game = new Reversi();
|
||||||
@@ -102,7 +104,7 @@ public final class ReversiGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ReversiGame(GameInformation information) {
|
public ReversiGame(GameInformation information) {
|
||||||
this(information, 0, null, null, null);
|
this(information, 0, null, null, null,null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void localGameThread() {
|
private void localGameThread() {
|
||||||
@@ -187,11 +189,14 @@ public final class ReversiGame {
|
|||||||
if (state == Game.State.WIN) {
|
if (state == Game.State.WIN) {
|
||||||
if (response.player().equalsIgnoreCase(information.players[0].name)) {
|
if (response.player().equalsIgnoreCase(information.players[0].name)) {
|
||||||
view.gameOver(true, information.players[0].name);
|
view.gameOver(true, information.players[0].name);
|
||||||
|
gameOver();
|
||||||
} else {
|
} else {
|
||||||
view.gameOver(false, information.players[1].name);
|
view.gameOver(false, information.players[1].name);
|
||||||
|
gameOver();
|
||||||
}
|
}
|
||||||
} else if (state == Game.State.DRAW) {
|
} else if (state == Game.State.DRAW) {
|
||||||
view.gameOver(false, "");
|
view.gameOver(false, "");
|
||||||
|
game.play(move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +204,14 @@ public final class ReversiGame {
|
|||||||
setGameLabels(game.getCurrentTurn() == myTurn);
|
setGameLabels(game.getCurrentTurn() == myTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void gameOver() {
|
||||||
|
if (onGameOver == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isRunning.set(false);
|
||||||
|
onGameOver.run();
|
||||||
|
}
|
||||||
|
|
||||||
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
||||||
if (!isRunning.get()) {
|
if (!isRunning.get()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public final class TicTacToeGame {
|
|||||||
private final GameInformation information;
|
private final GameInformation information;
|
||||||
|
|
||||||
private final int myTurn;
|
private final int myTurn;
|
||||||
|
private Runnable onGameOver;
|
||||||
private final BlockingQueue<Game.Move> moveQueue;
|
private final BlockingQueue<Game.Move> moveQueue;
|
||||||
|
|
||||||
private final TicTacToe game;
|
private final TicTacToe game;
|
||||||
@@ -34,10 +35,11 @@ public final class TicTacToeGame {
|
|||||||
|
|
||||||
private final AtomicBoolean isRunning;
|
private final AtomicBoolean isRunning;
|
||||||
|
|
||||||
public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage) {
|
public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
|
||||||
this.information = information;
|
this.information = information;
|
||||||
|
|
||||||
this.myTurn = myTurn;
|
this.myTurn = myTurn;
|
||||||
|
this.onGameOver = onGameOver;
|
||||||
moveQueue = new LinkedBlockingQueue<Game.Move>();
|
moveQueue = new LinkedBlockingQueue<Game.Move>();
|
||||||
|
|
||||||
game = new TicTacToe();
|
game = new TicTacToe();
|
||||||
@@ -95,7 +97,7 @@ public final class TicTacToeGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TicTacToeGame(GameInformation information) {
|
public TicTacToeGame(GameInformation information) {
|
||||||
this(information, 0, null, null, null);
|
this(information, 0, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void localGameThread() {
|
private void localGameThread() {
|
||||||
@@ -177,12 +179,15 @@ public final class TicTacToeGame {
|
|||||||
if (state == Game.State.WIN) {
|
if (state == Game.State.WIN) {
|
||||||
if (response.player().equalsIgnoreCase(information.players[0].name)) {
|
if (response.player().equalsIgnoreCase(information.players[0].name)) {
|
||||||
view.gameOver(true, information.players[0].name);
|
view.gameOver(true, information.players[0].name);
|
||||||
|
gameOver();
|
||||||
} else {
|
} else {
|
||||||
view.gameOver(false, information.players[1].name);
|
view.gameOver(false, information.players[1].name);
|
||||||
|
gameOver();
|
||||||
}
|
}
|
||||||
} else if (state == Game.State.DRAW) {
|
} else if (state == Game.State.DRAW) {
|
||||||
if(game.getLegalMoves().length == 0) { //only return draw in online multiplayer if the game is actually over.
|
if(game.getLegalMoves().length == 0) { //only return draw in online multiplayer if the game is actually over.
|
||||||
view.gameOver(false, "");
|
view.gameOver(false, "");
|
||||||
|
gameOver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,6 +201,14 @@ public final class TicTacToeGame {
|
|||||||
setGameLabels(game.getCurrentTurn() == myTurn);
|
setGameLabels(game.getCurrentTurn() == myTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void gameOver() {
|
||||||
|
if (onGameOver == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isRunning.set(false);
|
||||||
|
onGameOver.run();
|
||||||
|
}
|
||||||
|
|
||||||
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
||||||
if (!isRunning.get()) {
|
if (!isRunning.get()) {
|
||||||
return;
|
return;
|
||||||
@@ -210,7 +223,14 @@ public final class TicTacToeGame {
|
|||||||
position = moveQueue.take().position();
|
position = moveQueue.take().position();
|
||||||
} catch (InterruptedException _) {}
|
} catch (InterruptedException _) {}
|
||||||
} else {
|
} else {
|
||||||
final Game.Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
|
final Game.Move move;
|
||||||
|
IO.println(information.players[0].name + " " + information.players[1].name);
|
||||||
|
if (information.players[1].name.equalsIgnoreCase("pism")) {
|
||||||
|
IO.println("got worst move");
|
||||||
|
move = ai.findWorstMove(game,9);
|
||||||
|
}else{
|
||||||
|
move = ai.findBestMove(game, information.players[0].computerDifficulty);
|
||||||
|
}
|
||||||
|
|
||||||
assert move != null;
|
assert move != null;
|
||||||
position = move.position();
|
position = move.position();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.toop.app.view.views;
|
package org.toop.app.view.views;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
import org.toop.app.view.View;
|
import org.toop.app.view.View;
|
||||||
import org.toop.app.view.ViewStack;
|
import org.toop.app.view.ViewStack;
|
||||||
import org.toop.app.view.displays.SongDisplay;
|
import org.toop.app.view.displays.SongDisplay;
|
||||||
@@ -151,6 +152,7 @@ public final class GameView extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer) {
|
public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
currentPlayerHeader.setText(currentPlayer);
|
currentPlayerHeader.setText(currentPlayer);
|
||||||
currentMoveHeader.setText(currentMove);
|
currentMoveHeader.setText(currentMove);
|
||||||
|
|
||||||
@@ -161,6 +163,8 @@ public final class GameView extends View {
|
|||||||
} else {
|
} else {
|
||||||
currentPlayerHeader.getStyleClass().remove("my-turn");
|
currentPlayerHeader.getStyleClass().remove("my-turn");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateChat(String message) {
|
public void updateChat(String message) {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import org.toop.game.Game;
|
|||||||
public final class ReversiAI extends AI<Reversi> {
|
public final class ReversiAI extends AI<Reversi> {
|
||||||
@Override
|
@Override
|
||||||
public Game.Move findBestMove(Reversi game, int depth) {
|
public Game.Move findBestMove(Reversi game, int depth) {
|
||||||
return game.getLegalMoves()[0];
|
Game.Move[] moves = game.getLegalMoves();
|
||||||
|
int inty = (int)(Math.random() * moves.length-.5f);
|
||||||
|
return moves[inty];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public final class TicTacToeAI extends AI<TicTacToe> {
|
|||||||
|
|
||||||
final Game.Move[] legalMoves = game.getLegalMoves();
|
final Game.Move[] legalMoves = game.getLegalMoves();
|
||||||
|
|
||||||
if (legalMoves.length <= 0) {
|
if (legalMoves.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +38,24 @@ public final class TicTacToeAI extends AI<TicTacToe> {
|
|||||||
|
|
||||||
return bestMove != null? bestMove : legalMoves[(int)(Math.random() * legalMoves.length)];
|
return bestMove != null? bestMove : legalMoves[(int)(Math.random() * legalMoves.length)];
|
||||||
}
|
}
|
||||||
|
public Game.Move findWorstMove(TicTacToe game, int depth){
|
||||||
|
|
||||||
|
|
||||||
|
Game.Move[] legalMoves = game.getLegalMoves();
|
||||||
|
|
||||||
|
int bestScore = -depth;
|
||||||
|
Game.Move bestMove = null;
|
||||||
|
|
||||||
|
for (final Game.Move move : legalMoves) {
|
||||||
|
final int score = getMoveScore(game, depth, move, false);
|
||||||
|
|
||||||
|
if (score > bestScore) {
|
||||||
|
bestMove = move;
|
||||||
|
bestScore = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestMove;
|
||||||
|
}
|
||||||
|
|
||||||
private int getMoveScore(TicTacToe game, int depth, Game.Move move, boolean maximizing) {
|
private int getMoveScore(TicTacToe game, int depth, Game.Move move, boolean maximizing) {
|
||||||
final TicTacToe copy = new TicTacToe(game);
|
final TicTacToe copy = new TicTacToe(game);
|
||||||
|
|||||||
Reference in New Issue
Block a user