Skip to content
This repository has been archived by the owner on Jan 31, 2019. It is now read-only.

Commit

Permalink
Added network multi player mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tilosp committed May 3, 2016
1 parent e78d15c commit 6aecc3a
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/main/java/de/tilosp/chess/gui/ChessboardGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ public void windowClosing(WindowEvent e) {
@Override
public void windowClosed(WindowEvent e) {
timerThread.running = false;
for (Player p : players)
p.onClosed();
}

@Override
Expand Down
38 changes: 36 additions & 2 deletions src/main/java/de/tilosp/chess/gui/NewGameGUI.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package de.tilosp.chess.gui;

import de.tilosp.chess.lib.PlayerColor;
import de.tilosp.chess.localisation.Localisation;
import de.tilosp.chess.player.ComputerPlayer;
import de.tilosp.chess.player.LocalPlayer;
import de.tilosp.chess.player.NetworkPlayer;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public final class NewGameGUI extends GUI {

Expand Down Expand Up @@ -136,9 +142,37 @@ private void onStartButtonPressed() {
// 2 Players local
new ChessboardGUI(new LocalPlayer(), new LocalPlayer()).setVisible(true);
} else if(twoPlayerModeComboBox.getSelectedIndex() == 1) {
// TODO 2 Players host
for (int port = 49152; port <= 65535; port++) {
try {
ServerSocket socket = new ServerSocket(port);
new WaitGUI(socket, PlayerColor.values()[colorComboBox.getSelectedIndex()]).setVisible(true);
break;
} catch (IOException ignored) {}
}
} else {
// TODO 2 Players client
try {
int port = Integer.parseInt(portTextField.getText());
if (port >= 49152 && port <= 65535) {
new Thread(() -> {
try {
Socket socket = new Socket(hostTextField.getText(), port);
InputStream in = socket.getInputStream();
while (true) {
if (in.available() > 0)
break;
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {}
}
PlayerColor playerColor = PlayerColor.values()[in.read()];
if (playerColor == PlayerColor.WHITE)
new ChessboardGUI(new LocalPlayer(), new NetworkPlayer(socket)).setVisible(true);
else
new ChessboardGUI(new NetworkPlayer(socket), new LocalPlayer()).setVisible(true);
} catch (IOException ignored) {}
}).start();
}
} catch (NumberFormatException ignored) {}
}
}
dispose();
Expand Down
100 changes: 100 additions & 0 deletions src/main/java/de/tilosp/chess/gui/WaitGUI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package de.tilosp.chess.gui;

import de.tilosp.chess.lib.PlayerColor;
import de.tilosp.chess.localisation.Localisation;
import de.tilosp.chess.player.LocalPlayer;
import de.tilosp.chess.player.NetworkPlayer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

final class WaitGUI extends GUI implements WindowListener {

private final ServerSocket socket;
private JLabel label;

WaitGUI(ServerSocket socket, PlayerColor playerColor) {
super();
this.socket = socket;
label.setText(String.format(Localisation.getString("wait.text"), socket.getLocalPort()));

new Thread(() -> {
try {
Socket s = socket.accept();
OutputStream out = s.getOutputStream();
out.write(playerColor.otherColor().ordinal());
out.flush();

if (playerColor == PlayerColor.WHITE)
new ChessboardGUI(new LocalPlayer(), new NetworkPlayer(s)).setVisible(true);
else
new ChessboardGUI(new NetworkPlayer(s), new LocalPlayer()).setVisible(true);
dispose();
} catch (IOException ignored) {}
}).start();
}

@Override
void initGUI() {
setTitle(Localisation.getString("wait.title"));
setResizable(false);
setPreferredSize(new Dimension(300, 100));
addWindowListener(this);

panel.setLayout(new BorderLayout());

label = new JLabel();
label.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(label);

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}

@Override
void initListeners() {

}

@Override
public void windowOpened(WindowEvent e) {

}

@Override
public void windowClosing(WindowEvent e) {

}

@Override
public void windowClosed(WindowEvent e) {
try {
socket.close();
} catch (IOException ignore) {}
}

@Override
public void windowIconified(WindowEvent e) {

}

@Override
public void windowDeiconified(WindowEvent e) {

}

@Override
public void windowActivated(WindowEvent e) {

}

@Override
public void windowDeactivated(WindowEvent e) {

}
}
18 changes: 17 additions & 1 deletion src/main/java/de/tilosp/chess/lib/ChessPiece.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package de.tilosp.chess.lib;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public final class ChessPiece {

public final ChessPieceType chessPieceType;
Expand Down Expand Up @@ -53,7 +57,19 @@ public String toString() {
return chessPieceType.toString() + playerColor.toString();
}

public char toChar() {
char toChar() {
return playerColor == PlayerColor.WHITE ? chessPieceType.symbolWhite : chessPieceType.symbolBlack;
}

public void write(DataOutputStream stream) throws IOException {
stream.writeByte(chessPieceType.ordinal());
stream.writeByte(playerColor.ordinal());
stream.writeInt(movements);
stream.writeInt(movedInTurn);
stream.writeBoolean(enPassant);
}

public static ChessPiece read(DataInputStream stream) throws IOException {
return new ChessPiece(ChessPieceType.values()[stream.readByte()], PlayerColor.values()[stream.readByte()], stream.readInt(), stream.readInt(), stream.readBoolean());
}
}
30 changes: 30 additions & 0 deletions src/main/java/de/tilosp/chess/lib/Chessboard.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package de.tilosp.chess.lib;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -242,4 +245,31 @@ public boolean isDraw() {
public boolean isWin(PlayerColor color) {
return color != playerColor && !canMove() && inCheck(playerColor);
}

public void write(DataOutputStream stream) throws IOException {
for (int i1 = 0; i1 < 8; i1++) {
for (int i2 = 0; i2 < 8; i2++) {
stream.writeBoolean(chessPieces[i1][i2] != null);
if (chessPieces[i1][i2] != null)
chessPieces[i1][i2].write(stream);
}
}
stream.writeInt(turn);
stream.writeByte(playerColor.ordinal());
stream.writeBoolean(promotion);
stream.writeInt(promotionX);
stream.writeInt(promotionY);
stream.writeBoolean(lastMove != null);
if (lastMove != null)
lastMove.write(stream);
}

public static Chessboard read(DataInputStream stream) throws IOException {
ChessPiece[][] chessPieces = new ChessPiece[8][8];
for (int i1 = 0; i1 < 8; i1++)
for (int i2 = 0; i2 < 8; i2++)
if (stream.readBoolean())
chessPieces[i1][i2] = ChessPiece.read(stream);
return new Chessboard(chessPieces, stream.readInt(), PlayerColor.values()[stream.readByte()], stream.readBoolean(), stream.readInt(), stream.readInt(), stream.readBoolean() ? Move.read(stream) : null);
}
}
21 changes: 21 additions & 0 deletions src/main/java/de/tilosp/chess/lib/Move.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package de.tilosp.chess.lib;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public final class Move {

private final int fromX;
Expand Down Expand Up @@ -36,4 +40,21 @@ private static String getInt(int i) {
private static String getChar(int i) {
return Character.toString((char) (0x61 + i));
}

public void write(DataOutputStream stream) throws IOException {
stream.writeInt(fromX);
stream.writeInt(fromY);
stream.writeInt(toX);
stream.writeInt(toY);
chessPiece.write(stream);
stream.writeInt(captureX);
stream.writeInt(captureY);
stream.writeBoolean(captureChessPiece != null);
if (captureChessPiece != null)
captureChessPiece.write(stream);
}

public static Move read(DataInputStream stream) throws IOException {
return new Move(stream.readInt(), stream.readInt(), stream.readInt(), stream.readInt(), ChessPiece.read(stream), stream.readInt(), stream.readInt(), stream.readBoolean() ? ChessPiece.read(stream) : null);
}
}
5 changes: 5 additions & 0 deletions src/main/java/de/tilosp/chess/player/ComputerPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ public void sendUpdate(Chessboard chessboard) {
}).start();
}
}

@Override
public void onClosed() {

}
}
3 changes: 3 additions & 0 deletions src/main/java/de/tilosp/chess/player/LocalPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ public final class LocalPlayer extends Player {

@Override
public void sendUpdate(Chessboard chessboard) {}

@Override
public void onClosed() {}
}
57 changes: 57 additions & 0 deletions src/main/java/de/tilosp/chess/player/NetworkPlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package de.tilosp.chess.player;

import de.tilosp.chess.lib.ChessEngine;
import de.tilosp.chess.lib.Chessboard;
import de.tilosp.chess.lib.PlayerColor;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public final class NetworkPlayer extends Player {

private final Socket socket;
private final DataInputStream in;
private final DataOutputStream out;
private volatile boolean running = true;

public NetworkPlayer(Socket socket) throws IOException {
this.socket = socket;
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());

new Thread(() -> {
while (running) {
try {
if (in.available() > 0)
update(Chessboard.read(in));
} catch (IOException ignored) {}
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {}
}
}).start();
}

@Override
public void sendUpdate(Chessboard chessboard) {
if (chessboard.playerColor == color && !chessboard.isDraw() && !chessboard.isWin(PlayerColor.WHITE) && !chessboard.isWin(PlayerColor.BLACK)) {
try {
chessboard.write(out);
out.flush();
} catch (IOException ignored) {}

}
}

@Override
public void onClosed() {
running = false;
try {
in.close();
out.close();
socket.close();
} catch (IOException ignored) {}
}
}
2 changes: 2 additions & 0 deletions src/main/java/de/tilosp/chess/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public void init(PlayerColor color, ChessboardGUI gui) {
void update(Chessboard chessboard) {
SwingUtilities.invokeLater(() -> gui.externalUpdate(chessboard));
}

public abstract void onClosed();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ new_game.start=Starten
new_game.title=Neues Spiel
new_game.two_players=Mehrspieler
player_color.black=Schwarz
player_color.white=Weiß
player_color.white=Weiß
wait.text=Warte auf anderen Spieler. Port: %d
wait.title=Warte
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ new_game.start=Start
new_game.title=New Game
new_game.two_players=Multiplayer
player_color.black=Black
player_color.white=White
player_color.white=White
wait.text=Waiting for other Player. Port: %d
wait.title=Waiting

0 comments on commit 6aecc3a

Please sign in to comment.