Skip to content

Commit

Permalink
Final fixes to replays
Browse files Browse the repository at this point in the history
  • Loading branch information
wyz3r0 committed Jan 31, 2024
1 parent 2cfe75a commit d4476bc
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
import shared.messages.PlayerResignedMsg;
import shared.messages.ResultsNegotiationMsg;

public class MultiplayerGameController {
public class GameController {
private static final int CIRCLE_RADIUS = 15;
private static final int SPACING = 5;
private int GRID_SIZE;
Expand Down Expand Up @@ -781,7 +781,7 @@ protected void setBoard(Stone[][] state) {
}


public MultiplayerGameController(Client client, GameMode gameMode) {
public GameController(Client client, GameMode gameMode) {
this.gameMode = gameMode;
this.client = client;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public void run() {

if (!alert.getResult().equals(ButtonType.CANCEL)) {
try {
App.setRoot("game", this, new MultiplayerGameController(this.client, GameMode.MULTI_PLAYER));
App.setRoot("game", this, new GameController(this.client, GameMode.MULTI_PLAYER));
} catch (IOException ex) {
ex.printStackTrace();
}
Expand Down Expand Up @@ -269,7 +269,7 @@ public void run() {

getClient().setGame(new Game(bs, gameJoinedMsg.getGameID(), gameJoinedMsg.getPlayerColors()));

App.setRoot("game", this, new MultiplayerGameController(this.client, GameMode.BOT));
App.setRoot("game", this, new GameController(this.client, GameMode.BOT));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
Expand Down
175 changes: 138 additions & 37 deletions go_client/src/main/java/com/go_game/client/ReplayController.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package com.go_game.client;

import java.io.IOException;
import java.net.Socket;
import java.net.URL;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.ResourceBundle;

import com.go_game.client.connection.Client;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
Expand All @@ -24,18 +31,28 @@
import javafx.scene.shape.Circle;
import javafx.scene.shape.Shape;
import javafx.stage.StageStyle;
import shared.enums.GameMode;
import shared.enums.Stone;
import shared.messages.BoardStateMsg;
import shared.messages.ClientInfoMsg;
import shared.messages.IndexSetMsg;
import shared.messages.ReplayFetchMsg;

public class ReplayController {
private static final int PORT = 4444;
private static final String HOST = "localhost";

private Client client;
private List<BoardStateMsg> moveList;
private int boardSize = -1;
private int movePointer;

@FXML
private ResourceBundle resources;

@FXML
private URL location;

@FXML
private AnchorPane boardAnchorPane;

@FXML
private HBox boardHBox;

Expand All @@ -48,9 +65,15 @@ public class ReplayController {
@FXML
private HBox mainHBox;

@FXML
private Button moveBackButton;

@FXML
private ListView<?> moveBoardListView;

@FXML
private Button moveForwardButton;

@FXML
private Label oponentNameLabel;

Expand All @@ -69,38 +92,31 @@ public class ReplayController {

@FXML
void initialize() {
assert boardAnchorPane != null : "fx:id=\"boardAnchorPane\" was not injected: check your FXML file 'replay.fxml'.";
assert boardHBox != null : "fx:id=\"boardHBox\" was not injected: check your FXML file 'replay.fxml'.";
assert controllsVBox != null : "fx:id=\"controllsVBox\" was not injected: check your FXML file 'replay.fxml'.";
assert exitButton != null : "fx:id=\"exitButton\" was not injected: check your FXML file 'replay.fxml'.";
assert mainHBox != null : "fx:id=\"mainHBox\" was not injected: check your FXML file 'replay.fxml'.";
assert moveBackButton != null : "fx:id=\"moveBackButton\" was not injected: check your FXML file 'replay.fxml'.";
assert moveBoardListView != null : "fx:id=\"moveBoardListView\" was not injected: check your FXML file 'replay.fxml'.";
assert moveForwardButton != null : "fx:id=\"moveForwardButton\" was not injected: check your FXML file 'replay.fxml'.";
assert oponentNameLabel != null : "fx:id=\"oponentNameLabel\" was not injected: check your FXML file 'replay.fxml'.";
assert oponentScoreLabel != null : "fx:id=\"oponentScoreLabel\" was not injected: check your FXML file 'replay.fxml'.";
assert playerNameLabel != null : "fx:id=\"playerNameLabel\" was not injected: check your FXML file 'replay.fxml'.";
assert playerScoreLabel != null : "fx:id=\"playerScoreLabel\" was not injected: check your FXML file 'replay.fxml'.";
assert selectReplayButton != null : "fx:id=\"selectReplayButton\" was not injected: check your FXML file 'replay.fxml'.";


//! for testing
List<List<String>> sampleList = Arrays.asList(
Arrays.asList("1", "2024-01-20 19-23"),
Arrays.asList("2", "2024-01-21 13-41"),
Arrays.asList("3", "2024-01-21 21-37")
);

// TODO: get replays from server

replayAlert(sampleList);

selectReplayButton.setOnAction(event -> replayAlert(sampleList));
selectReplay();
}


private void initializeBoard(int boardSize) {
final int gridSize = boardSize;
final int circleRadius = 15;
final int spacing = 5;

boardHBox.getChildren().clear();

boardHBox.setSpacing(spacing);
boardHBox.setAlignment(Pos.CENTER);

Expand Down Expand Up @@ -152,45 +168,60 @@ private void initializeBoard(int boardSize) {
}
}

private void replayAlert(List<List<String>> replayList) {
Alert alert = new Alert(Alert.AlertType.NONE, "", ButtonType.CLOSE);
private void replayAlert(Map<Integer, Date> replayList) {
ButtonType cancelButton = new ButtonType("cancel", ButtonData.CANCEL_CLOSE);

Alert alert = new Alert(Alert.AlertType.NONE, "", cancelButton);
alert.initStyle(StageStyle.UNDECORATED);
alert.getDialogPane().getStylesheets().add(getClass().getResource("darkTheme.css").toExternalForm());
alert.getDialogPane().setPrefSize(300, 300);

Button cancelBtn = (Button) alert.getDialogPane().lookupButton(cancelButton);
cancelBtn.addEventFilter(ActionEvent.ACTION, event -> {
if (boardSize == -1) {
exit();
}
});

ListView<String> listView = new ListView<>();
ObservableList<String> items = FXCollections.observableArrayList();

for (List<String> entry : replayList) {
items.add(String.join(" | ", entry));
}


// Use Java Streams to iterate over the entry set and create a formatted string
replayList.entrySet().stream().map(entry -> entry.getKey() + " | " + entry.getValue()).forEach(items::add);

listView.setItems(items);

listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
// TODO: get replay string from server
try {
System.out.println(newValue.split("\\s*\\|\\s*")[0]);

client.sendMessage(new ReplayFetchMsg(Integer.parseInt(newValue.split("\\s*\\|\\s*")[0])));

ReplayFetchMsg moveListMessage = (ReplayFetchMsg) client.receiveMessage();

moveList = moveListMessage.getReplaysList();
boardSize = moveList.get(0).getBoardState().length;

} catch (NumberFormatException | IOException | ClassNotFoundException e) {
e.printStackTrace();
exit();
}

boardHBox.getChildren().clear();
// TODO: pass board size to initializeBoard()
initializeBoard(9);
initializeBoard(boardSize);
alert.close();
}
});

VBox vBox = new VBox(listView);
alert.getDialogPane().setContent(vBox);

alert.setOnCloseRequest(event -> {
if (boardHBox.getChildren().isEmpty()) {
exit();
}
});

Platform.runLater(() -> {
alert.showAndWait();
});

Platform.runLater(() -> alert.showAndWait());
}


// TODO: change it to outline last placed stone
// private ChangeListener<Boolean> createHoverChangeListener(Circle circle, int y) {
Expand Down Expand Up @@ -218,9 +249,79 @@ private void replayAlert(List<List<String>> replayList) {
// };
// }

protected void setBoard(Stone[][] state) {
Platform.runLater(() -> {
for (int i = 1; i <= boardSize; i++) {
for (int j = 1; j <= boardSize; j++) {
Color color;

if (state[i - 1][j - 1] == Stone.BLACK) color = Color.BLACK;
else if (state[i - 1][j - 1] == Stone.WHITE) color = Color.WHITE;
else color = Color.web("#3E3E3E");

((Circle) ((VBox) boardHBox.getChildren().get(i)).getChildren().get(j)).setFill(color);
}
}
});
}

@FXML
void selectReplay() {
new Thread(new Runnable() {
@Override
public void run() {
try {
client = new Client(new Socket(HOST, PORT));
client.receiveMessage();

client.sendMessage(new ClientInfoMsg(GameMode.REPLAY));

ReplayFetchMsg replayList = (ReplayFetchMsg) client.receiveMessage();

Platform.runLater(() -> {
replayAlert(replayList.getGameIDsAndDates());

initializeBoard(boardSize);
});

setBoard(moveList.get(0).getBoardState());

movePointer = 0;

} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
exit();
}
}
}).start();
}

@FXML
void moveBack() {
if (movePointer > 0) {
movePointer--;
}

setBoard(moveList.get(movePointer).getBoardState());
}

@FXML
void moveForward() {
if (movePointer < moveList.size()) {
movePointer++;
}

setBoard(moveList.get(movePointer).getBoardState());
}

@FXML
void exit() {
try {
try {
client.closeConnection();
} catch (IOException e) {
e.printStackTrace();
}
App.setRoot("menu", this, new MenuController());
} catch (IOException e) {
e.printStackTrace();
Expand Down
23 changes: 22 additions & 1 deletion go_client/src/main/resources/com/go_game/client/replay.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<HBox fx:id="mainHBox" alignment="CENTER_RIGHT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="900.0" stylesheets="@darkTheme.css" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1">
<children>
Expand Down Expand Up @@ -60,11 +61,31 @@
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</VBox>
<Button fx:id="selectReplayButton" mnemonicParsing="false" text="select different replay">
<Button fx:id="selectReplayButton" mnemonicParsing="false" onAction="#selectReplay" text="select different replay">
<VBox.margin>
<Insets top="5.0" />
</VBox.margin>
</Button>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="5.0">
<children>
<Button fx:id="moveBackButton" mnemonicParsing="false" onAction="#moveBack" prefHeight="55.0" prefWidth="55.0" text="" textAlignment="CENTER">
<HBox.margin>
<Insets left="5.0" top="5.0" />
</HBox.margin>
<font>
<Font name="System Bold" size="22.0" />
</font>
</Button>
<Button fx:id="moveForwardButton" mnemonicParsing="false" onAction="#moveForward" prefHeight="55.0" prefWidth="55.0" text="" textAlignment="CENTER">
<HBox.margin>
<Insets right="5.0" top="5.0" />
</HBox.margin>
<font>
<Font size="22.0" />
</font>
</Button>
</children>
</HBox>
</children>
</VBox>
</children>
Expand Down
4 changes: 3 additions & 1 deletion go_server/src/main/java/com/go_game/server/ReplayThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
public class ReplayThread implements Runnable {
private DBQueuer dbQueuer;
private ClientConnection clientConnection;
private Thread fred;

/**
* Constructs a ReplayThread object with the specified client connection.
Expand All @@ -27,7 +28,8 @@ public class ReplayThread implements Runnable {
public ReplayThread(ClientConnection clientConnection)
{
this.dbQueuer = new DBQueuer(new DBManager());
Thread fred = new Thread(this);
this.clientConnection = clientConnection;
fred = new Thread(this);
fred.start();
}

Expand Down

0 comments on commit d4476bc

Please sign in to comment.