diff --git a/src/main/java/com/billenius/img/splitscreen.png b/src/main/java/com/billenius/img/splitscreen.png new file mode 100644 index 0000000..2d09488 Binary files /dev/null and b/src/main/java/com/billenius/img/splitscreen.png differ diff --git a/src/main/java/com/billenius/schack/Move.java b/src/main/java/com/billenius/schack/Move.java index 432a1c6..13915b3 100644 --- a/src/main/java/com/billenius/schack/Move.java +++ b/src/main/java/com/billenius/schack/Move.java @@ -1,10 +1,11 @@ package com.billenius.schack; import java.awt.Point; +import java.io.Serializable; import com.billenius.schack.pieces.Piece; -public class Move { +public class Move implements Serializable { public Piece movedPiece; public Point from; public Point to; diff --git a/src/main/java/com/billenius/schack/Schack.java b/src/main/java/com/billenius/schack/Schack.java index b84ae61..0ae632b 100644 --- a/src/main/java/com/billenius/schack/Schack.java +++ b/src/main/java/com/billenius/schack/Schack.java @@ -1,5 +1,6 @@ package com.billenius.schack; +import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.HeadlessException; @@ -20,10 +21,10 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.UIManager; -import java.awt.BorderLayout; -import com.billenius.schack.Move; -import com.billenius.schack.PieceRenderer; +import com.billenius.schack.boards.Board; +import com.billenius.schack.boards.NetworkBoard; +import com.billenius.schack.boards.SameBoard; import com.formdev.flatlaf.FlatLightLaf; /** @@ -45,15 +46,30 @@ public class Schack { } catch (Exception cantGetSystemTheme) { } + String[] options = { "On the same screen", "Over the internet" }; + int choosenTransformations = JOptionPane.showOptionDialog(null, + "How do you want to connect with your opponent", + "Schack: Selection", + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, + null, + options, + options[0]); + + DefaultListModel listModel = new DefaultListModel<>(); + final Board board; + if (choosenTransformations == 0) + board = new SameBoard(listModel); + else + board = new NetworkBoard(listModel); + frame = new JFrame(); frame.setTitle("Schack"); frame.setAlwaysOnTop(false); frame.setResizable(true); - DefaultListModel listModel = new DefaultListModel<>(); - // Might throw an IOException if the icon of the Pieces isn't embedded correctly - final Board board = new Board(listModel); + // final Board board = new BlistModeloard(listModel); // Logger final JList jlist = new JList<>(listModel); diff --git a/src/main/java/com/billenius/schack/Board.java b/src/main/java/com/billenius/schack/boards/Board.java similarity index 86% rename from src/main/java/com/billenius/schack/Board.java rename to src/main/java/com/billenius/schack/boards/Board.java index aedbc48..7a5e827 100644 --- a/src/main/java/com/billenius/schack/Board.java +++ b/src/main/java/com/billenius/schack/boards/Board.java @@ -1,4 +1,4 @@ -package com.billenius.schack; +package com.billenius.schack.boards; import java.awt.Color; import java.awt.Dimension; @@ -12,9 +12,10 @@ import java.util.ArrayList; import java.util.List; import javax.swing.DefaultListModel; -import javax.swing.JOptionPane; import javax.swing.JPanel; +import com.billenius.schack.Move; +import com.billenius.schack.SchackState; import com.billenius.schack.pieces.Bishop; import com.billenius.schack.pieces.Horse; import com.billenius.schack.pieces.King; @@ -23,15 +24,15 @@ import com.billenius.schack.pieces.Piece; import com.billenius.schack.pieces.Queen; import com.billenius.schack.pieces.Rook; -public class Board extends JPanel implements MouseListener { +public abstract class Board extends JPanel implements MouseListener { public static final int SIZE_OF_TILE = 100; - private Piece[][] pieces = new Piece[8][8]; - private List validMovesToDraw = new ArrayList<>(); + protected Piece[][] pieces = new Piece[8][8]; + protected List validMovesToDraw = new ArrayList<>(); private Point previouslyClickedPoint = new Point(); private final Color moveableColor = new Color(255, 191, 0); short turnCount = 0; - private boolean whitesTurn = true; + protected boolean whitesTurn = true; private DefaultListModel moveList; public Board(DefaultListModel listModel) throws IOException { @@ -115,33 +116,7 @@ public class Board extends JPanel implements MouseListener { } } - private void makeMove(Move move) { - move.movedPiece.move(pieces, move.to); - turnCount++; - whitesTurn = !whitesTurn; - - SchackState state = getSchackState(); - switch (state) { - case SCHACK: - JOptionPane.showMessageDialog(this, "Du står i schack"); - break; - case SCHACKMATT: - case PATT: - String stateStr = state.toString(); - String msg = stateStr.charAt(0) + stateStr.substring(1, stateStr.length()).toLowerCase(); - int choice = JOptionPane.showConfirmDialog(this, msg + "\nVill du starta om?"); - - if (choice == JOptionPane.YES_OPTION) - try { - restartGame(); - } catch (IOException ex) { - } - - break; - default: - } - - } + protected abstract void makeMove(Move move); @Override public void mousePressed(MouseEvent mouseEvent) { @@ -168,7 +143,7 @@ public class Board extends JPanel implements MouseListener { // Om vi inte redan har valt en pjäs klickar vi på en pjäs if (!validMovesToDraw.contains(clickedCoordinate)) { Piece selectedPiece = pieces[clickedCoordinate.x][clickedCoordinate.y]; - + toDoIfNoPreviousPieceSelected(selectedPiece); if (selectedPiece != null && selectedPiece.isWhite() == whitesTurn) validMovesToDraw.addAll(selectedPiece.validMoves(pieces, true)); else @@ -180,12 +155,14 @@ public class Board extends JPanel implements MouseListener { getParent().repaint(); } + protected abstract void toDoIfNoPreviousPieceSelected(Piece selectedPiece); + /** * Få status över brädet * * @return SCHACK, SCHACKMATT, PATT, NORMAL */ - private SchackState getSchackState() { + protected SchackState getSchackState() { List allValidMoves = getMoves(whitesTurn); List opposingAttacks = getAttacks(!whitesTurn); boolean weCanMove = !allValidMoves.isEmpty(); diff --git a/src/main/java/com/billenius/schack/boards/NetworkBoard.java b/src/main/java/com/billenius/schack/boards/NetworkBoard.java new file mode 100644 index 0000000..3cb7b28 --- /dev/null +++ b/src/main/java/com/billenius/schack/boards/NetworkBoard.java @@ -0,0 +1,129 @@ +package com.billenius.schack.boards; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Inet4Address; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Random; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Font; + +import javax.swing.DefaultListModel; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import com.billenius.schack.Move; +import com.billenius.schack.SchackState; +import com.billenius.schack.pieces.Piece; + +public final class NetworkBoard extends Board { + private final Socket socket; + private ServerSocket serverSocket = null; + private final ObjectInputStream inputStream; + private final ObjectOutputStream outputStream; + + private Boolean myColor = null; + + public NetworkBoard(DefaultListModel listModel) throws IOException { + super(listModel); + String[] options = { "Opponent connects to me", "I'am connecting to the opponent" }; + int choosenOption = JOptionPane.showOptionDialog(null, + "Are you going to connect to the opponent or the reverse?", + "Schack: Networking", + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, + null, + options, + options[0]); + + if (choosenOption == 0) { + String ip = Inet4Address.getLocalHost().toString(); + + final JFrame frame = new JFrame("Schack: Networking"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + JPanel panel = new JPanel(new BorderLayout()); + panel.setPreferredSize(new Dimension(200, 200)); + + JLabel loading = new JLabel( + "Waiting for opponent to connect...\nYour ip is " + ip + " Listening on port 1339"); + loading.setFont(new Font("Cantarell", Font.PLAIN, 24)); + loading.setHorizontalAlignment(JLabel.CENTER); + + panel.add(loading, BorderLayout.CENTER); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + serverSocket = new ServerSocket(1339); + this.socket = serverSocket.accept(); + // myColor = new Random().nextBoolean(); + myColor = true; + frame.setVisible(false); + + // Get input/output stream + System.out.println("Getting inputstream"); + inputStream = new ObjectInputStream(socket.getInputStream()); + System.out.println("Getting outputstream"); + outputStream = new ObjectOutputStream(socket.getOutputStream()); + } else { + String ip = JOptionPane.showInputDialog(null, + "What's the IP of your opponent?", + "Schack: Networking", + JOptionPane.QUESTION_MESSAGE); + this.socket = new Socket(ip, 1339); + myColor = false; + + // Get input/output stream + System.out.println("Getting outputstream"); + outputStream = new ObjectOutputStream(socket.getOutputStream()); + System.out.println("Getting inputstream"); + inputStream = new ObjectInputStream(socket.getInputStream()); + } + } + + @Override + protected void makeMove(Move move) { + try { + move.movedPiece.move(pieces, move.to); + outputStream.writeObject(move); + + SchackState state = getSchackState(); + switch (state) { + case SCHACK: + JOptionPane.showMessageDialog(this, "Du står i schack"); + break; + case SCHACKMATT: + case PATT: + String stateStr = state.toString(); + String msg = stateStr.charAt(0) + stateStr.substring(1, stateStr.length()).toLowerCase(); + int choice = JOptionPane.showConfirmDialog(this, msg + "\nVill du starta om?"); + + if (choice == JOptionPane.YES_OPTION) + try { + restartGame(); + } catch (IOException ex) { + } + + break; + default: + } + + move = (Move) inputStream.readObject(); + move.movedPiece.move(pieces, move.to); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + @Override + protected void toDoIfNoPreviousPieceSelected(Piece selectedPiece) { + if (selectedPiece != null && selectedPiece.isWhite() == myColor) + validMovesToDraw.addAll(selectedPiece.validMoves(pieces, true)); + } + +} diff --git a/src/main/java/com/billenius/schack/boards/SameBoard.java b/src/main/java/com/billenius/schack/boards/SameBoard.java new file mode 100644 index 0000000..059dac8 --- /dev/null +++ b/src/main/java/com/billenius/schack/boards/SameBoard.java @@ -0,0 +1,56 @@ +package com.billenius.schack.boards; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.swing.DefaultListModel; +import javax.swing.JOptionPane; + +import com.billenius.schack.Move; +import com.billenius.schack.SchackState; +import com.billenius.schack.pieces.Piece; + +public final class SameBoard extends Board { + + public SameBoard(DefaultListModel listModel) throws IOException { + super(listModel); + } + + @Override + protected void makeMove(Move move) { + move.movedPiece.move(pieces, move.to); + turnCount++; + whitesTurn = !whitesTurn; + + SchackState state = getSchackState(); + switch (state) { + case SCHACK: + JOptionPane.showMessageDialog(this, "Du står i schack"); + break; + case SCHACKMATT: + case PATT: + String stateStr = state.toString(); + String msg = stateStr.charAt(0) + stateStr.substring(1, stateStr.length()).toLowerCase(); + int choice = JOptionPane.showConfirmDialog(this, msg + "\nVill du starta om?"); + + if (choice == JOptionPane.YES_OPTION) + try { + restartGame(); + } catch (IOException ex) { + } + + break; + default: + } + } + + @Override + protected void toDoIfNoPreviousPieceSelected(Piece selectedPiece) { + if (selectedPiece != null && selectedPiece.isWhite() == whitesTurn) + validMovesToDraw.addAll(selectedPiece.validMoves(pieces, true)); + else + validMovesToDraw = new ArrayList<>(); // Snabbare än .clear + + } + +} diff --git a/src/main/java/com/billenius/schack/pieces/Piece.java b/src/main/java/com/billenius/schack/pieces/Piece.java index 843c7cf..a9e6620 100644 --- a/src/main/java/com/billenius/schack/pieces/Piece.java +++ b/src/main/java/com/billenius/schack/pieces/Piece.java @@ -5,13 +5,14 @@ import java.awt.Point; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; -import com.billenius.schack.Board; +import com.billenius.schack.boards.Board; -public abstract class Piece { +public abstract class Piece implements Serializable { /** * Variabel som alltid bör vara samma värde som pjäsen är i brädes av