mirror of
https://github.com/lov3b/Schack.git
synced 2025-01-18 04:40:11 +01:00
Merge branch 'multiplayer'
This commit is contained in:
commit
3e5bd56780
BIN
src/main/java/com/billenius/img/splitscreen.png
Normal file
BIN
src/main/java/com/billenius/img/splitscreen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
24
src/main/java/com/billenius/schack/BasicMove.java
Normal file
24
src/main/java/com/billenius/schack/BasicMove.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.billenius.schack;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class BasicMove implements Serializable {
|
||||
public Point from;
|
||||
public Point to;
|
||||
|
||||
public BasicMove(Point from, Point to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public BasicMove(Move m) {
|
||||
this.from = m.from;
|
||||
this.to = m.to;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (from.x + 1) + ":" + (from.y + 1)
|
||||
+ " " + '\u27F6' + " " + (to.x + 1) + ":" + (to.y + 1);
|
||||
}
|
||||
}
|
@ -4,21 +4,17 @@ import java.awt.Point;
|
||||
|
||||
import com.billenius.schack.pieces.Piece;
|
||||
|
||||
public class Move {
|
||||
public class Move extends BasicMove {
|
||||
public Piece movedPiece;
|
||||
public Point from;
|
||||
public Point to;
|
||||
public String color;
|
||||
|
||||
public Move(Piece movedPiece, Point from, Point to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.color = movedPiece.isWhite() ? "White" : "Black";
|
||||
this.movedPiece = movedPiece;
|
||||
public Move(Piece piece, Point from, Point to) {
|
||||
super(from, to);
|
||||
this.movedPiece = piece;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (from.x + 1) + ":" + (from.y + 1)
|
||||
+ " " + '\u27F6' + " " + (to.x + 1) + ":" + (to.y + 1);
|
||||
public Move(Piece piece, BasicMove basicMove) {
|
||||
super(basicMove.from, basicMove.to);
|
||||
this.movedPiece = piece;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
package com.billenius.schack;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JFrame;
|
||||
@ -20,10 +24,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;
|
||||
|
||||
/**
|
||||
@ -33,6 +37,10 @@ import com.formdev.flatlaf.FlatLightLaf;
|
||||
public class Schack {
|
||||
|
||||
final JFrame frame;
|
||||
// Förlåt mig fader för jag kommer synda
|
||||
public final static Map<String, BufferedImage> pieceIcons = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
public Schack() throws IOException {
|
||||
// Set theme
|
||||
@ -45,15 +53,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<Move> 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<Move> 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<Move> jlist = new JList<>(listModel);
|
||||
|
@ -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,16 +24,16 @@ 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<Point> validMovesToDraw = new ArrayList<>();
|
||||
protected Piece[][] pieces = new Piece[8][8];
|
||||
protected List<Point> validMovesToDraw = new ArrayList<>();
|
||||
private Point previouslyClickedPoint = new Point();
|
||||
private final Color moveableColor = new Color(255, 191, 0);
|
||||
short turnCount = 0;
|
||||
private boolean whitesTurn = true;
|
||||
private DefaultListModel<Move> moveList;
|
||||
protected boolean whitesTurn = true;
|
||||
protected DefaultListModel<Move> moveList;
|
||||
|
||||
public Board(DefaultListModel<Move> listModel) throws IOException {
|
||||
this.pieces = getPieces();
|
||||
@ -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) {
|
||||
@ -158,7 +133,6 @@ public class Board extends JPanel implements MouseListener {
|
||||
}
|
||||
|
||||
Move move = new Move(selectedPiece, selectedPiece.position, clickedCoordinate);
|
||||
moveList.addElement(move);
|
||||
makeMove(move);
|
||||
} else {
|
||||
previouslyClickedPoint = new Point(clickedCoordinate);
|
||||
@ -168,24 +142,21 @@ 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];
|
||||
|
||||
if (selectedPiece != null && selectedPiece.isWhite() == whitesTurn)
|
||||
validMovesToDraw.addAll(selectedPiece.validMoves(pieces, true));
|
||||
else
|
||||
validMovesToDraw = new ArrayList<>(); // Snabbare än .clear
|
||||
|
||||
toDoIfNoPreviousPieceSelected(selectedPiece);
|
||||
} else
|
||||
validMovesToDraw = new ArrayList<>(); // Snabbare än .clear
|
||||
|
||||
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<Point> allValidMoves = getMoves(whitesTurn);
|
||||
List<Point> opposingAttacks = getAttacks(!whitesTurn);
|
||||
boolean weCanMove = !allValidMoves.isEmpty();
|
168
src/main/java/com/billenius/schack/boards/NetworkBoard.java
Normal file
168
src/main/java/com/billenius/schack/boards/NetworkBoard.java
Normal file
@ -0,0 +1,168 @@
|
||||
package com.billenius.schack.boards;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.io.EOFException;
|
||||
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.net.SocketException;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.billenius.schack.BasicMove;
|
||||
import com.billenius.schack.Move;
|
||||
import com.billenius.schack.SchackState;
|
||||
import com.billenius.schack.pieces.Piece;
|
||||
|
||||
public final class NetworkBoard extends Board implements Runnable {
|
||||
public final static int PORT = 1339;
|
||||
private final Socket socket;
|
||||
private ServerSocket serverSocket = null;
|
||||
private final ObjectInputStream inputStream;
|
||||
private final ObjectOutputStream outputStream;
|
||||
private final Thread inputListener;
|
||||
private Boolean myColor = null;
|
||||
|
||||
public NetworkBoard(DefaultListModel<Move> 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]);
|
||||
|
||||
// Nu ska vi bli en Server
|
||||
if (choosenOption == 0) {
|
||||
String ip = Inet4Address.getLocalHost().getHostAddress();
|
||||
|
||||
final JFrame frame = new JFrame("Schack: Networking");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.setPreferredSize(new Dimension(600, 200));
|
||||
|
||||
JLabel loading = new JLabel(
|
||||
"<html>Waiting for opponent to connect...<br/>Listening on <i>" + ip + ":" + PORT + "</i></html>");
|
||||
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(PORT);
|
||||
this.socket = serverSocket.accept();
|
||||
// myColor = new Random().nextBoolean();
|
||||
myColor = true; // VIT
|
||||
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());
|
||||
}
|
||||
// Nu ska vi bli en klient
|
||||
else {
|
||||
String ip = JOptionPane.showInputDialog(null,
|
||||
"What's the IP of your opponent?",
|
||||
"Schack: Networking",
|
||||
JOptionPane.QUESTION_MESSAGE);
|
||||
if (ip.equals(""))
|
||||
ip = "localhost";
|
||||
this.socket = new Socket(ip, 1339);
|
||||
myColor = false; // SVART
|
||||
|
||||
// Get input/output stream
|
||||
System.out.println("Getting outputstream");
|
||||
outputStream = new ObjectOutputStream(socket.getOutputStream());
|
||||
System.out.println("Getting inputstream");
|
||||
inputStream = new ObjectInputStream(socket.getInputStream());
|
||||
}
|
||||
inputListener = new Thread(this);
|
||||
inputListener.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeMove(Move move) {
|
||||
try {
|
||||
turnCount++;
|
||||
moveList.addElement(move);
|
||||
move.movedPiece.move(pieces, move.to);
|
||||
System.out.println("repainting");
|
||||
getParent().repaint();
|
||||
System.out.println("Sending move to opponent");
|
||||
outputStream.writeObject(new BasicMove(move));
|
||||
System.out.println("Move sent");
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toDoIfNoPreviousPieceSelected(Piece selectedPiece) {
|
||||
if (selectedPiece != null && selectedPiece.isWhite() == myColor)
|
||||
validMovesToDraw.addAll(selectedPiece.validMoves(pieces, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
BasicMove basicMove = (BasicMove) inputStream.readObject();
|
||||
Move move = new Move(pieces[basicMove.from.x][basicMove.from.y], basicMove);
|
||||
System.out.println("Got move");
|
||||
moveList.addElement(move);
|
||||
turnCount++;
|
||||
|
||||
System.out.println("Moving piece");
|
||||
move.movedPiece.move(pieces, move.to);
|
||||
System.out.println("Repainting");
|
||||
getParent().repaint();
|
||||
|
||||
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:
|
||||
}
|
||||
|
||||
}
|
||||
} catch (EOFException | SocketException e) {
|
||||
JOptionPane.showMessageDialog(this, "Lost connection to opponent");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
JOptionPane.showMessageDialog(this, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
57
src/main/java/com/billenius/schack/boards/SameBoard.java
Normal file
57
src/main/java/com/billenius/schack/boards/SameBoard.java
Normal file
@ -0,0 +1,57 @@
|
||||
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<Move> listModel) throws IOException {
|
||||
super(listModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeMove(Move move) {
|
||||
moveList.addElement(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
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,7 @@ 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 {
|
||||
|
||||
@ -26,40 +26,23 @@ public abstract class Piece {
|
||||
* SPECIAL RULÖES APPLY TO THE KING, (ITS GOOD TO BE THE KING:)
|
||||
*/
|
||||
public boolean supremeRuler = false;
|
||||
/**
|
||||
* Bild av pjäsen som ritas ut på bärdet
|
||||
*/
|
||||
protected BufferedImage icon;
|
||||
|
||||
/**
|
||||
* Nödvändigt för rockad
|
||||
*/
|
||||
protected boolean moved = false;
|
||||
protected BufferedImage pieceIcon;
|
||||
|
||||
public Piece(boolean white, Point startingPosition) throws IOException {
|
||||
this.isWhite = white;
|
||||
this.position = startingPosition;
|
||||
setPieceIcon();
|
||||
this.pieceIcon = getPieceIcon();
|
||||
}
|
||||
|
||||
public Piece(boolean white) {
|
||||
this.isWhite = white;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ladda in pjäsbild från paketet img
|
||||
*
|
||||
* @param className
|
||||
* @throws IOException ifall det inte finns någon bild på pjäsen
|
||||
*/
|
||||
private void setPieceIcon() throws IOException {
|
||||
String className = this.getClass().getSimpleName();
|
||||
String colorName = this.isWhite() ? "White" : "Black";
|
||||
String fileName = colorName + className + ".png";
|
||||
InputStream is = getClass().getResourceAsStream("/com/billenius/img/" + fileName);
|
||||
icon = ImageIO.read(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ger tillbaks alla ställen pjäsen kan gå till
|
||||
*
|
||||
@ -82,14 +65,22 @@ public abstract class Piece {
|
||||
return validMoves(pieces, false);
|
||||
}
|
||||
|
||||
private BufferedImage getPieceIcon() throws IOException {
|
||||
String colorName = isWhite() ? "White" : "Black";
|
||||
String path = "/com/billenius/img/" + colorName + getClass().getSimpleName() + ".png";
|
||||
InputStream inputStream = getClass().getResourceAsStream(path);
|
||||
return ImageIO.read(inputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ritar ut pjäsen baserat på den ihågkommna positionen
|
||||
*
|
||||
* @param g2
|
||||
*/
|
||||
public void draw(Graphics2D g2) {
|
||||
|
||||
g2.drawImage(
|
||||
icon,
|
||||
getIcon(),
|
||||
position.x * Board.SIZE_OF_TILE,
|
||||
position.y * Board.SIZE_OF_TILE,
|
||||
null);
|
||||
@ -211,6 +202,13 @@ public abstract class Piece {
|
||||
return this.getClass().getSimpleName() + "{" + "position=" + position + ", isWhite=" + isWhite + '}';
|
||||
}
|
||||
|
||||
public boolean equals(Piece otherPiece) {
|
||||
return getClass().getName().equals(otherPiece.getClass().getName())
|
||||
&& isWhite() == otherPiece.isWhite()
|
||||
&& supremeRuler == otherPiece.supremeRuler && moved == otherPiece.moved
|
||||
&& position.equals(otherPiece.position);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true ifall pjäsen är vit
|
||||
@ -229,7 +227,7 @@ public abstract class Piece {
|
||||
}
|
||||
|
||||
public BufferedImage getIcon() {
|
||||
return this.icon;
|
||||
return this.pieceIcon;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user