mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 19:04:49 +00:00
refactor
This commit is contained in:
6
app/src/main/java/org/toop/Main.java
Normal file
6
app/src/main/java/org/toop/Main.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package org.toop.app;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/org/toop/gui/BackgroundPanel.java
Normal file
21
app/src/main/java/org/toop/gui/BackgroundPanel.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.toop.app.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class BackgroundPanel extends JPanel {
|
||||
private Image backgroundImage;
|
||||
|
||||
public void setBackgroundImage(Image image) {
|
||||
this.backgroundImage = image;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
if (backgroundImage != null) {
|
||||
g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
app/src/main/java/org/toop/gui/LocalGameSelector.form
Normal file
37
app/src/main/java/org/toop/gui/LocalGameSelector.form
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.toop.app.gui.LocalGameSelector">
|
||||
<grid id="27dc6" binding="panel1" default-binding="true" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="780" height="600"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="3f7f6" class="javax.swing.JComboBox" binding="gameSelectionComboBox">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<model/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4700f" class="javax.swing.JButton" binding="startGame">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Start game"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="41f79" class="javax.swing.JComboBox" binding="playerTypeSelectionBox">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<editable value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
107
app/src/main/java/org/toop/gui/LocalGameSelector.java
Normal file
107
app/src/main/java/org/toop/gui/LocalGameSelector.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package org.toop.app.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.toop.app.tictactoe.LocalTicTacToe;
|
||||
import org.toop.app.tictactoe.gui.UIGameBoard;
|
||||
|
||||
public class LocalGameSelector extends JFrame {
|
||||
private static final Logger logger = LogManager.getLogger(LocalGameSelector.class);
|
||||
|
||||
private JPanel panel1;
|
||||
private JComboBox gameSelectionComboBox;
|
||||
private JButton startGame;
|
||||
private JComboBox playerTypeSelectionBox;
|
||||
private JButton deleteSave;
|
||||
|
||||
private JPanel cards; // CardLayout panel
|
||||
private CardLayout cardLayout;
|
||||
|
||||
private UIGameBoard tttBoard;
|
||||
|
||||
public LocalGameSelector() {
|
||||
setTitle("Local Game Selector");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setSize(1920, 1080);
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
// Setup CardLayout
|
||||
cardLayout = new CardLayout();
|
||||
cards = new JPanel(cardLayout);
|
||||
setContentPane(cards);
|
||||
|
||||
// --- Main menu panel ---
|
||||
panel1 = new JPanel();
|
||||
panel1.setLayout(new FlowLayout());
|
||||
gameSelectionComboBox = new JComboBox<>();
|
||||
gameSelectionComboBox.addItem("Tic Tac Toe");
|
||||
gameSelectionComboBox.addItem("Reversi");
|
||||
|
||||
playerTypeSelectionBox = new JComboBox<>();
|
||||
playerTypeSelectionBox.addItem("Player vs Player");
|
||||
playerTypeSelectionBox.addItem("Player vs AI");
|
||||
playerTypeSelectionBox.addItem("AI vs Player");
|
||||
|
||||
panel1.add(gameSelectionComboBox);
|
||||
panel1.add(playerTypeSelectionBox);
|
||||
|
||||
startGame = new JButton("Start Game");
|
||||
panel1.add(startGame);
|
||||
|
||||
deleteSave = new JButton("Delete Save");
|
||||
panel1.add(deleteSave);
|
||||
deleteSave.setEnabled(false);
|
||||
deleteSave.addActionListener(
|
||||
e -> {
|
||||
tttBoard = null;
|
||||
deleteSave.setEnabled(false);
|
||||
});
|
||||
|
||||
cards.add(panel1, "MainMenu");
|
||||
|
||||
// Start button action
|
||||
startGame.addActionListener(e -> startGameClicked());
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private void startGameClicked() {
|
||||
String playerTypes = (String) playerTypeSelectionBox.getSelectedItem();
|
||||
String selectedGame = (String) gameSelectionComboBox.getSelectedItem();
|
||||
|
||||
LocalTicTacToe lttt = null;
|
||||
|
||||
if (playerTypes.equals("Player vs Player")) {
|
||||
logger.info("Player vs Player");
|
||||
lttt = LocalTicTacToe.createLocal(new boolean[] {false, false});
|
||||
} else {
|
||||
if (playerTypes.equals("Player vs AI")) {
|
||||
logger.info("Player vs AI");
|
||||
lttt = LocalTicTacToe.createLocal(new boolean[] {false, true});
|
||||
} else {
|
||||
logger.info("AI vs Player");
|
||||
lttt = LocalTicTacToe.createLocal(new boolean[] {true, false});
|
||||
}
|
||||
}
|
||||
|
||||
if ("Tic Tac Toe".equalsIgnoreCase(selectedGame)) {
|
||||
if (tttBoard == null) {
|
||||
tttBoard = new UIGameBoard(lttt, this);
|
||||
cards.add(tttBoard.getTTTPanel(), "TicTacToe");
|
||||
}
|
||||
cardLayout.show(cards, "TicTacToe");
|
||||
}
|
||||
lttt.startThreads();
|
||||
}
|
||||
|
||||
public void showMainMenu() {
|
||||
cardLayout.show(cards, "MainMenu");
|
||||
gameSelectionComboBox.setSelectedIndex(0);
|
||||
playerTypeSelectionBox.setSelectedIndex(0);
|
||||
if (tttBoard != null) {
|
||||
deleteSave.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
app/src/main/java/org/toop/gui/LocalServerSelector.form
Normal file
39
app/src/main/java/org/toop/gui/LocalServerSelector.form
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.toop.app.gui.LocalServerSelector">
|
||||
<grid id="27dc6" binding="panel1" default-binding="true" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="7774a" class="javax.swing.JButton" binding="serverButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Server"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="ca0c8" class="javax.swing.JButton" binding="localButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Local"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="74dd2">
|
||||
<constraints>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<hspacer id="50fd">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
32
app/src/main/java/org/toop/gui/LocalServerSelector.java
Normal file
32
app/src/main/java/org/toop/gui/LocalServerSelector.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package org.toop.app.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class LocalServerSelector {
|
||||
private JPanel panel1;
|
||||
private JButton serverButton;
|
||||
private JButton localButton;
|
||||
private final JFrame frame;
|
||||
|
||||
public LocalServerSelector() {
|
||||
frame = new JFrame("Server Selector");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setContentPane(panel1);
|
||||
frame.setSize(1920, 1080);
|
||||
frame.setLocationRelativeTo(null); // Sets to center
|
||||
frame.setVisible(true);
|
||||
|
||||
serverButton.addActionListener(e -> onServerClicked());
|
||||
localButton.addActionListener(e -> onLocalClicked());
|
||||
}
|
||||
|
||||
private void onServerClicked() {
|
||||
frame.dispose();
|
||||
new RemoteGameSelector();
|
||||
}
|
||||
|
||||
private void onLocalClicked() {
|
||||
frame.dispose();
|
||||
new LocalGameSelector();
|
||||
}
|
||||
}
|
||||
147
app/src/main/java/org/toop/gui/RemoteGameSelector.form
Normal file
147
app/src/main/java/org/toop/gui/RemoteGameSelector.form
Normal file
@@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.toop.app.gui.RemoteGameSelector">
|
||||
<grid id="27dc6" binding="mainMenu" layout-manager="GridLayoutManager" row-count="10" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="741" height="625"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<opaque value="true"/>
|
||||
<preferredSize width="800" height="600"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="ed019" class="javax.swing.JTextField" binding="nameTextField">
|
||||
<constraints>
|
||||
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="4e05c">
|
||||
<constraints>
|
||||
<grid row="9" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="1d2f1" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Name:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="70d8c" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Welcome to ISY games selector!"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5cc82" class="javax.swing.JTextField" binding="name2TextField">
|
||||
<constraints>
|
||||
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="27f2a">
|
||||
<constraints>
|
||||
<grid row="3" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="3874e" class="javax.swing.JLabel" binding="fillAllFields">
|
||||
<constraints>
|
||||
<grid row="8" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="true"/>
|
||||
<foreground color="-65536"/>
|
||||
<text value="Please fill all fields"/>
|
||||
<visible value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="a2f0" class="javax.swing.JButton" binding="connectButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="7" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Connect"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6a4c6" class="javax.swing.JTextField" binding="ipTextField">
|
||||
<constraints>
|
||||
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="4214e" class="javax.swing.JComboBox" binding="gameSelectorBox">
|
||||
<constraints>
|
||||
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<model/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4225c" class="javax.swing.JTextField" binding="portTextField">
|
||||
<constraints>
|
||||
<grid row="5" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="43a89" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Select game:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3abc3" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Port:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="514db" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="IP:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5723c" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Name 2:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="2e34c">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<vspacer id="93fc6">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
152
app/src/main/java/org/toop/gui/RemoteGameSelector.java
Normal file
152
app/src/main/java/org/toop/gui/RemoteGameSelector.java
Normal file
@@ -0,0 +1,152 @@
|
||||
package org.toop.app.gui;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.swing.*;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.toop.framework.eventbus.events.Events;
|
||||
import org.toop.framework.eventbus.GlobalEventBus;
|
||||
import org.toop.framework.eventbus.events.NetworkEvents;
|
||||
import org.toop.app.tictactoe.LocalTicTacToe;
|
||||
import org.toop.framework.networking.NetworkingGameClientHandler;
|
||||
import org.toop.app.tictactoe.gui.UIGameBoard;
|
||||
|
||||
public class RemoteGameSelector {
|
||||
private static final Logger logger = LogManager.getLogger(RemoteGameSelector.class);
|
||||
|
||||
private JPanel mainMenu;
|
||||
private JTextField nameTextField;
|
||||
private JTextField name2TextField;
|
||||
private JTextField ipTextField;
|
||||
private JTextField portTextField;
|
||||
private JButton connectButton;
|
||||
private JComboBox gameSelectorBox;
|
||||
private JPanel cards;
|
||||
private JPanel gameSelector;
|
||||
private JFrame frame;
|
||||
private JLabel fillAllFields;
|
||||
|
||||
private LocalTicTacToe localTicTacToe;
|
||||
|
||||
public RemoteGameSelector() {
|
||||
gameSelectorBox.addItem("Tic Tac Toe");
|
||||
gameSelectorBox.addItem("Reversi");
|
||||
// todo get supported games from server and add to gameSelectorBox
|
||||
frame = new JFrame("Game Selector");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setSize(1920, 1080);
|
||||
frame.setResizable(true);
|
||||
|
||||
init();
|
||||
frame.add(mainMenu);
|
||||
frame.setVisible(true);
|
||||
// GlobalEventBus.subscribeAndRegister() Todo add game panel to frame when connection
|
||||
// succeeds
|
||||
|
||||
}
|
||||
|
||||
private void init() {
|
||||
connectButton.addActionListener(
|
||||
(ActionEvent e) -> {
|
||||
if (!nameTextField.getText().isEmpty()
|
||||
&& !name2TextField.getText().isEmpty()
|
||||
&& !ipTextField.getText().isEmpty()
|
||||
&& !portTextField.getText().isEmpty()) {
|
||||
|
||||
CompletableFuture<String> serverIdFuture = new CompletableFuture<>();
|
||||
GlobalEventBus.post(
|
||||
new Events.ServerEvents.StartServerRequest(
|
||||
Integer.parseInt(portTextField.getText()), // TODO: Unsafe parse
|
||||
Objects.requireNonNull(gameSelectorBox.getSelectedItem())
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.replace(" ", ""),
|
||||
serverIdFuture));
|
||||
String serverId;
|
||||
try {
|
||||
serverId = serverIdFuture.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} // TODO: Better error handling to not crash the system.
|
||||
|
||||
CompletableFuture<String> connectionIdFuture = new CompletableFuture<>();
|
||||
GlobalEventBus.post(
|
||||
new NetworkEvents.StartClientRequest(
|
||||
NetworkingGameClientHandler::new,
|
||||
ipTextField.getText(),
|
||||
Integer.parseInt(portTextField.getText()), // TODO: Not safe parsing
|
||||
connectionIdFuture));
|
||||
String connectionId;
|
||||
try {
|
||||
connectionId = connectionIdFuture.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} // TODO: Better error handling to not crash the system.
|
||||
|
||||
// GlobalEventBus.subscribeAndRegister(
|
||||
// NetworkEvents.ReceivedMessage.class,
|
||||
// event -> {
|
||||
// if (event.message().equalsIgnoreCase("ok")) {
|
||||
// logger.info("received ok from server.");
|
||||
// } else if (event.message().toLowerCase().startsWith("gameid")) {
|
||||
// String gameId =
|
||||
// event.message()
|
||||
// .toLowerCase()
|
||||
// .replace("gameid ", "");
|
||||
// GlobalEventBus.post(
|
||||
// new NetworkEvents.SendCommand(
|
||||
// "start_game " + gameId));
|
||||
// } else {
|
||||
// logger.info("{}", event.message());
|
||||
// }
|
||||
// });
|
||||
|
||||
GlobalEventBus.post(
|
||||
new Events.ServerEvents.SendCommand(
|
||||
connectionId,
|
||||
"create_game",
|
||||
nameTextField.getText(),
|
||||
name2TextField.getText()));
|
||||
|
||||
// CompletableFuture<String> ticTacToeGame = new
|
||||
// CompletableFuture<>();
|
||||
// GlobalEventBus.post(new
|
||||
// Events.ServerEvents.CreateTicTacToeGameRequest( // TODO: Make this happen
|
||||
// through commands send through the connection, instead of an event.
|
||||
// serverId,
|
||||
// nameTextField.getText(),
|
||||
// name2TextField.getText(),
|
||||
// ticTacToeGame
|
||||
// ));
|
||||
// String ticTacToeGameId;
|
||||
// try {
|
||||
// ticTacToeGameId = ticTacToeGame.get();
|
||||
// } catch (InterruptedException | ExecutionException ex) {
|
||||
// throw new RuntimeException(ex);
|
||||
// } // TODO: Better error handling to not crash the system.
|
||||
|
||||
frame.remove(mainMenu);
|
||||
localTicTacToe =
|
||||
LocalTicTacToe.createRemote(
|
||||
ipTextField.getText(), portTextField.getText());
|
||||
UIGameBoard ttt = new UIGameBoard(localTicTacToe, this);
|
||||
localTicTacToe.startThreads();
|
||||
frame.add(ttt.getTTTPanel()); // TODO: Fix later
|
||||
frame.revalidate();
|
||||
frame.repaint();
|
||||
} else {
|
||||
fillAllFields.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showMainMenu() {
|
||||
frame.removeAll();
|
||||
frame.add(mainMenu);
|
||||
frame.revalidate();
|
||||
frame.repaint();
|
||||
}
|
||||
}
|
||||
272
app/src/main/java/org/toop/tictactoe/LocalTicTacToe.java
Normal file
272
app/src/main/java/org/toop/tictactoe/LocalTicTacToe.java
Normal file
@@ -0,0 +1,272 @@
|
||||
package org.toop.app.tictactoe;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.toop.eventbus.EventPublisher;
|
||||
import org.toop.framework.eventbus.events.Events;
|
||||
import org.toop.framework.eventbus.events.NetworkEvents;
|
||||
import org.toop.app.tictactoe.gui.UIGameBoard;
|
||||
import org.toop.framework.networking.NetworkingGameClientHandler;
|
||||
import org.toop.games.GameBase;
|
||||
import org.toop.game.tictactoe.ai.MinMaxTicTacToe;
|
||||
import org.toop.games.tictactoe.TicTacToe;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.lang.Thread.sleep;
|
||||
|
||||
/**
|
||||
* A representation of a local tic-tac-toe game. Calls are made to a server for information about
|
||||
* current game state. MOST OF THIS CODE IS TRASH, THROW IT OUT OF THE WINDOW AFTER DEMO.
|
||||
*/
|
||||
// Todo: refactor
|
||||
public class LocalTicTacToe { // TODO: Implement runnable
|
||||
private static final Logger logger = LogManager.getLogger(LocalTicTacToe.class);
|
||||
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(3);
|
||||
private final BlockingQueue<String> receivedQueue = new LinkedBlockingQueue<>();
|
||||
private final BlockingQueue<Integer> moveQueuePlayerA = new LinkedBlockingQueue<>();
|
||||
private final BlockingQueue<Integer> moveQueuePlayerB = new LinkedBlockingQueue<>();
|
||||
|
||||
private Object receivedMessageListener = null;
|
||||
|
||||
private boolean isLocal;
|
||||
private String gameId;
|
||||
private String connectionId = null;
|
||||
private String serverId = null;
|
||||
|
||||
private boolean isAiPlayer[] = new boolean[2];
|
||||
private MinMaxTicTacToe[] aiPlayers = new MinMaxTicTacToe[2];
|
||||
private TicTacToe ticTacToe;
|
||||
private UIGameBoard ui;
|
||||
|
||||
/** Is either 0 or 1. */
|
||||
private int playersTurn = 0;
|
||||
|
||||
/**
|
||||
* @return The current players turn.
|
||||
*/
|
||||
public int getCurrentPlayersTurn() {
|
||||
return this.playersTurn;
|
||||
}
|
||||
|
||||
// LocalTicTacToe(String gameId, String connectionId, String serverId) {
|
||||
// this.gameId = gameId;
|
||||
// this.connectionId = connectionId;
|
||||
// this.serverId = serverId;
|
||||
// this.receivedMessageListener =
|
||||
// GlobalEventBus.subscribe(Events.ServerEvents.ReceivedMessage.class,
|
||||
// this::receiveMessageAction);
|
||||
// GlobalEventBus.register(this.receivedMessageListener);
|
||||
//
|
||||
//
|
||||
// this.executor.submit(this::gameThread);
|
||||
// } TODO: If remote server
|
||||
|
||||
/**
|
||||
* Starts a connection with a remote server.
|
||||
*
|
||||
* @param ip The IP of the server to connect to.
|
||||
* @param port The port of the server to connect to.
|
||||
*/
|
||||
private LocalTicTacToe(String ip, int port) {
|
||||
// this.receivedMessageListener =
|
||||
// GlobalEventBus.subscribe(this::receiveMessageAction);
|
||||
// GlobalEventBus.subscribe(this.receivedMessageListener);
|
||||
this.connectionId = this.createConnection(ip, port);
|
||||
this.createGame("X", "O");
|
||||
this.isLocal = false;
|
||||
//this.executor.submit(this::remoteGameThread);
|
||||
}
|
||||
|
||||
private LocalTicTacToe(boolean[] aiFlags) {
|
||||
this.isAiPlayer = aiFlags; // store who is AI
|
||||
|
||||
for (int i = 0; i < aiFlags.length && i < this.aiPlayers.length; i++) {
|
||||
if (aiFlags[i]) {
|
||||
this.aiPlayers[i] = new MinMaxTicTacToe(); // create AI for that player
|
||||
} else {
|
||||
this.aiPlayers[i] = null; // not an AI player
|
||||
}
|
||||
}
|
||||
|
||||
this.isLocal = true;
|
||||
//this.executor.submit(this::localGameThread);
|
||||
}
|
||||
public void startThreads(){
|
||||
if (isLocal) {
|
||||
this.executor.submit(this::localGameThread);
|
||||
}else {
|
||||
this.executor.submit(this::remoteGameThread);
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalTicTacToe createLocal(boolean[] aiPlayers) {
|
||||
return new LocalTicTacToe(aiPlayers);
|
||||
}
|
||||
|
||||
public static LocalTicTacToe createRemote(String ip, int port) {
|
||||
return new LocalTicTacToe(ip, port);
|
||||
}
|
||||
|
||||
private String createServer(int port) {
|
||||
CompletableFuture<String> serverIdFuture = new CompletableFuture<>();
|
||||
new EventPublisher<>(Events.ServerEvents.StartServerRequest.class, port, "tictactoe", serverIdFuture)
|
||||
.postEvent();
|
||||
try {
|
||||
return serverIdFuture.get();
|
||||
} catch (Exception e) {
|
||||
logger.error("Error getting server ID", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String createConnection(String ip, int port) {
|
||||
CompletableFuture<String> connectionIdFuture = new CompletableFuture<>();
|
||||
new EventPublisher<>(NetworkEvents.StartClientRequest.class,
|
||||
(Supplier<NetworkingGameClientHandler>) NetworkingGameClientHandler::new,
|
||||
ip, port, connectionIdFuture).postEvent(); // TODO: what if server couldn't be started with port.
|
||||
try {
|
||||
return connectionIdFuture.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
logger.error("Error getting connection ID", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void createGame(String nameA, String nameB) {
|
||||
nameA = nameA.trim().replace(" ", "-");
|
||||
nameB = nameB.trim().replace(" ", "-");
|
||||
this.sendCommand("create_game", nameA, nameB);
|
||||
}
|
||||
|
||||
private void startGame() {
|
||||
if (this.gameId == null) {
|
||||
return;
|
||||
}
|
||||
this.sendCommand("start_game", this.gameId);
|
||||
}
|
||||
|
||||
private void localGameThread() {
|
||||
boolean running = true;
|
||||
this.ticTacToe = new TicTacToe("X", "O");
|
||||
while (running) {
|
||||
try {
|
||||
GameBase.State state;
|
||||
if (!isAiPlayer[0]) {
|
||||
state = this.ticTacToe.play(this.moveQueuePlayerA.take());
|
||||
} else {
|
||||
int bestMove = aiPlayers[0].findBestMove(this.ticTacToe);
|
||||
state = this.ticTacToe.play(bestMove);
|
||||
if (state != GameBase.State.INVALID) {
|
||||
ui.setCell(bestMove, "X");
|
||||
}
|
||||
}
|
||||
if (state == GameBase.State.WIN || state == GameBase.State.DRAW) {
|
||||
ui.setState(state, "X");
|
||||
running = false;
|
||||
}
|
||||
this.setNextPlayersTurn();
|
||||
if (!isAiPlayer[1]) {
|
||||
state = this.ticTacToe.play(this.moveQueuePlayerB.take());
|
||||
} else {
|
||||
int bestMove = aiPlayers[1].findBestMove(this.ticTacToe);
|
||||
state = this.ticTacToe.play(bestMove);
|
||||
if (state != GameBase.State.INVALID) {
|
||||
ui.setCell(bestMove, "O");
|
||||
}
|
||||
}
|
||||
if (state == GameBase.State.WIN || state == GameBase.State.DRAW) {
|
||||
ui.setState(state, "O");
|
||||
running = false;
|
||||
}
|
||||
this.setNextPlayersTurn();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void remoteGameThread() {
|
||||
// TODO: If server start this.
|
||||
}
|
||||
|
||||
public void setNextPlayersTurn() {
|
||||
if (this.playersTurn == 0) {
|
||||
this.playersTurn += 1;
|
||||
} else {
|
||||
this.playersTurn -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getCurrentBoard() {
|
||||
return ticTacToe.getGrid();
|
||||
}
|
||||
|
||||
/** End the current game. */
|
||||
public void endGame() {
|
||||
sendCommand("gameid", "end_game"); // TODO: Command is a bit wrong.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param moveIndex The index of the move to make.
|
||||
*/
|
||||
public void move(int moveIndex) {
|
||||
this.executor.submit(
|
||||
() -> {
|
||||
try {
|
||||
if (this.playersTurn == 0 && !isAiPlayer[0]) {
|
||||
this.moveQueuePlayerA.put(moveIndex);
|
||||
logger.info(
|
||||
"Adding player's {}, move: {} to queue A",
|
||||
this.playersTurn,
|
||||
moveIndex);
|
||||
} else if (this.playersTurn == 1 && !isAiPlayer[1]) {
|
||||
this.moveQueuePlayerB.put(moveIndex);
|
||||
logger.info(
|
||||
"Adding player's {}, move: {} to queue B",
|
||||
this.playersTurn,
|
||||
moveIndex);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(
|
||||
"Could not add player: {}'s, move {}",
|
||||
this.playersTurn,
|
||||
moveIndex); // TODO: Error handling instead of crash.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void endTheGame() {
|
||||
this.sendCommand("end_game", this.gameId);
|
||||
// this.endListeners();
|
||||
}
|
||||
|
||||
private void receiveMessageAction(NetworkEvents.ReceivedMessage receivedMessage) {
|
||||
if (!receivedMessage.ConnectionUuid().equals(this.connectionId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info(
|
||||
"Received message from {}: {}", this.connectionId, receivedMessage.message());
|
||||
this.receivedQueue.put(receivedMessage.message());
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Error waiting for received Message", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendCommand(String... args) {
|
||||
new EventPublisher<>(NetworkEvents.SendCommand.class, this.connectionId, args).postEvent();
|
||||
}
|
||||
|
||||
// private void endListeners() {
|
||||
// GlobalEventBus.unregister(this.receivedMessageListener);
|
||||
// } TODO
|
||||
|
||||
public void setUIReference(UIGameBoard uiGameBoard) {
|
||||
this.ui = uiGameBoard;
|
||||
}
|
||||
}
|
||||
23
app/src/main/java/org/toop/tictactoe/gui/UIGameBoard.form
Normal file
23
app/src/main/java/org/toop/tictactoe/gui/UIGameBoard.form
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.toop.app.tictactoe.gui.UIGameBoard">
|
||||
<grid id="27dc6" binding="tttPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<preferredSize width="800" height="600"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="e1a78" class="javax.swing.JButton" binding="backToMainMenuButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Back to main menu"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
142
app/src/main/java/org/toop/tictactoe/gui/UIGameBoard.java
Normal file
142
app/src/main/java/org/toop/tictactoe/gui/UIGameBoard.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package org.toop.app.tictactoe.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.*;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.toop.app.gui.LocalGameSelector;
|
||||
import org.toop.app.gui.RemoteGameSelector;
|
||||
import org.toop.app.tictactoe.LocalTicTacToe;
|
||||
import org.toop.games.GameBase;
|
||||
|
||||
public class UIGameBoard {
|
||||
private static final int TICTACTOE_SIZE = 3;
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(LocalGameSelector.class);
|
||||
|
||||
private JPanel tttPanel; // Root panel for this game
|
||||
private JButton backToMainMenuButton;
|
||||
private JButton[] cells;
|
||||
private String currentPlayer = "X";
|
||||
private int currentPlayerIndex = 0;
|
||||
|
||||
private Object parentSelector;
|
||||
private boolean parentLocal;
|
||||
private LocalTicTacToe localTicTacToe;
|
||||
|
||||
private boolean gameOver = false;
|
||||
|
||||
public UIGameBoard(LocalTicTacToe lttt, Object parent) {
|
||||
if (!(parent == null)) {
|
||||
if (parent instanceof LocalGameSelector) {
|
||||
parentLocal = true;
|
||||
} else if (parent instanceof RemoteGameSelector) {
|
||||
parentLocal = false;
|
||||
}
|
||||
}
|
||||
this.parentSelector = parent;
|
||||
this.localTicTacToe = lttt;
|
||||
lttt.setUIReference(this);
|
||||
|
||||
// Root panel
|
||||
tttPanel = new JPanel(new BorderLayout());
|
||||
|
||||
// Back button
|
||||
backToMainMenuButton = new JButton("Back to Main Menu");
|
||||
tttPanel.add(backToMainMenuButton, BorderLayout.SOUTH);
|
||||
backToMainMenuButton.addActionListener(
|
||||
_ -> {
|
||||
// TODO reset game and connections
|
||||
// Game now gets reset in local
|
||||
if (parentLocal) {
|
||||
((LocalGameSelector) parent).showMainMenu();
|
||||
} else {
|
||||
((RemoteGameSelector) parent).showMainMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Game grid
|
||||
JPanel gameGrid = createGridPanel(TICTACTOE_SIZE, TICTACTOE_SIZE);
|
||||
tttPanel.add(gameGrid, BorderLayout.CENTER);
|
||||
|
||||
// localTicTacToe.setMoveListener((playerIndex, moveIndex, symbol) -> {
|
||||
// SwingUtilities.invokeLater(() -> {
|
||||
// cells[moveIndex].setText(String.valueOf(symbol));
|
||||
// });
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
private JPanel createGridPanel(int sizeX, int sizeY) {
|
||||
JPanel panel = new JPanel(new GridLayout(sizeX, sizeY));
|
||||
cells = new JButton[sizeX * sizeY];
|
||||
|
||||
for (int i = 0; i < sizeX * sizeY; i++) {
|
||||
cells[i] = new JButton(" ");
|
||||
cells[i].setFont(new Font("Arial", Font.BOLD, 400 / sizeX));
|
||||
panel.add(cells[i]);
|
||||
cells[i].setFocusable(false);
|
||||
|
||||
final int index = i;
|
||||
cells[i].addActionListener(
|
||||
(ActionEvent _) -> {
|
||||
if (!gameOver) {
|
||||
if (cells[index].getText().equals(" ")) {
|
||||
int cp = this.localTicTacToe.getCurrentPlayersTurn();
|
||||
if (cp == 0) {
|
||||
this.currentPlayer = "X";
|
||||
currentPlayerIndex = 0;
|
||||
} else if (cp == 1) {
|
||||
this.currentPlayer = "O";
|
||||
currentPlayerIndex = 1;
|
||||
}
|
||||
this.localTicTacToe.move(index);
|
||||
cells[index].setText(currentPlayer);
|
||||
} else {
|
||||
logger.info(
|
||||
"Player "
|
||||
+ currentPlayerIndex
|
||||
+ " attempted invalid move at: "
|
||||
+ cells[index].getText());
|
||||
}
|
||||
} else {
|
||||
logger.info(
|
||||
"Player "
|
||||
+ currentPlayerIndex
|
||||
+ " attempted to move after the game has ended.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
public void setCell(int index, String move) {
|
||||
System.out.println(cells[index].getText());
|
||||
cells[index].setText(move);
|
||||
}
|
||||
|
||||
public void setState(GameBase.State state, String playerMove) {
|
||||
Color color;
|
||||
if (state == GameBase.State.WIN && playerMove.equals(currentPlayer)) {
|
||||
color = new Color(160, 220, 160);
|
||||
} else if (state == GameBase.State.WIN) {
|
||||
color = new Color(220, 160, 160);
|
||||
} else if (state == GameBase.State.DRAW) {
|
||||
color = new Color(220, 220, 160);
|
||||
} else {
|
||||
color = new Color(220, 220, 220);
|
||||
}
|
||||
for (JButton cell : cells) {
|
||||
cell.setBackground(color);
|
||||
}
|
||||
if (state == GameBase.State.DRAW || state == GameBase.State.WIN) {
|
||||
gameOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
public JPanel getTTTPanel() {
|
||||
return tttPanel;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user