Added player management and related UI components
+ Game Mode selection dialog + Game class for turn management + Abstract Player class with NaturalPlayer implementation - Moved mouse input handling from BoardPanel to NaturalPlayer
This commit is contained in:
parent
7bf4f78b70
commit
716c84bf49
41
src/dev/kske/chess/game/Game.java
Normal file
41
src/dev/kske/chess/game/Game.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package dev.kske.chess.game;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import dev.kske.chess.board.Board;
|
||||||
|
import dev.kske.chess.board.Move;
|
||||||
|
import dev.kske.chess.board.Piece.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>Game.java</strong><br>
|
||||||
|
* Created: <strong>06.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public class Game {
|
||||||
|
|
||||||
|
private Map<Color, Player> players;
|
||||||
|
private Board board;
|
||||||
|
|
||||||
|
public Game(Map<Color, Player> players, Board board) {
|
||||||
|
this.players = players;
|
||||||
|
this.board = board;
|
||||||
|
|
||||||
|
// Initialize the game variable in each player
|
||||||
|
players.values().forEach(player -> player.setGame(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
players.get(Color.WHITE).requestMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onMove(Player player, Move move) {
|
||||||
|
if (board.getPos(move).getColor() == player.color && board.attemptMove(move)) {
|
||||||
|
System.out.printf("%s: %s%n", player.color, move);
|
||||||
|
players.get(player.color.opposite()).requestMove();
|
||||||
|
} else {
|
||||||
|
System.out.printf("%s: Illegal move!%n", player.getColor());
|
||||||
|
player.requestMove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
src/dev/kske/chess/game/NaturalPlayer.java
Normal file
56
src/dev/kske/chess/game/NaturalPlayer.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package dev.kske.chess.game;
|
||||||
|
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
|
import dev.kske.chess.board.Board;
|
||||||
|
import dev.kske.chess.board.Move;
|
||||||
|
import dev.kske.chess.board.Piece.Color;
|
||||||
|
import dev.kske.chess.board.Position;
|
||||||
|
import dev.kske.chess.ui.BoardPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>NaturalPlayer.java</strong><br>
|
||||||
|
* Created: <strong>06.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public class NaturalPlayer extends Player {
|
||||||
|
|
||||||
|
private boolean moveRequested;
|
||||||
|
|
||||||
|
public NaturalPlayer(Board board, Color color, BoardPanel boardPanel) {
|
||||||
|
super(board, color);
|
||||||
|
moveRequested = false;
|
||||||
|
boardPanel.addMouseListener(new MouseAdapter() {
|
||||||
|
|
||||||
|
private Position pos;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent evt) {
|
||||||
|
if (!moveRequested) return;
|
||||||
|
if (pos == null) {
|
||||||
|
pos = new Position(evt.getPoint().x / boardPanel.getTileSize(),
|
||||||
|
evt.getPoint().y / boardPanel.getTileSize());
|
||||||
|
|
||||||
|
if (board.get(pos) != null && board.get(pos).getColor() == color)
|
||||||
|
boardPanel.displayMoves(board.getMoves(pos));
|
||||||
|
else pos = null;
|
||||||
|
} else {
|
||||||
|
Position dest = new Position(evt.getPoint().x / boardPanel.getTileSize(),
|
||||||
|
evt.getPoint().y / boardPanel.getTileSize());
|
||||||
|
|
||||||
|
boardPanel.clearDisplayMoves();
|
||||||
|
moveRequested = false;
|
||||||
|
game.onMove(NaturalPlayer.this, new Move(pos, dest));
|
||||||
|
pos = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestMove() {
|
||||||
|
moveRequested = true;
|
||||||
|
}
|
||||||
|
}
|
36
src/dev/kske/chess/game/Player.java
Normal file
36
src/dev/kske/chess/game/Player.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package dev.kske.chess.game;
|
||||||
|
|
||||||
|
import dev.kske.chess.board.Board;
|
||||||
|
import dev.kske.chess.board.Piece.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>Player.java</strong><br>
|
||||||
|
* Created: <strong>06.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public abstract class Player {
|
||||||
|
|
||||||
|
protected Game game;
|
||||||
|
protected Board board;
|
||||||
|
protected Color color;
|
||||||
|
|
||||||
|
public Player(Board board, Color color) {
|
||||||
|
this.board = board;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void requestMove();
|
||||||
|
|
||||||
|
public Game getGame() { return game; }
|
||||||
|
|
||||||
|
public void setGame(Game game) { this.game = game; }
|
||||||
|
|
||||||
|
public Board getBoard() { return board; }
|
||||||
|
|
||||||
|
public void setBoard(Board board) { this.board = board; }
|
||||||
|
|
||||||
|
public Color getColor() { return color; }
|
||||||
|
|
||||||
|
public void setColor(Color color) { this.color = color; }
|
||||||
|
}
|
@ -5,8 +5,6 @@ import java.awt.Dimension;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.event.ComponentAdapter;
|
import java.awt.event.ComponentAdapter;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -15,7 +13,6 @@ import javax.swing.JPanel;
|
|||||||
|
|
||||||
import dev.kske.chess.board.Board;
|
import dev.kske.chess.board.Board;
|
||||||
import dev.kske.chess.board.Move;
|
import dev.kske.chess.board.Move;
|
||||||
import dev.kske.chess.board.Position;
|
|
||||||
import dev.kske.chess.event.GameEvent;
|
import dev.kske.chess.event.GameEvent;
|
||||||
import dev.kske.chess.event.GameEventListener;
|
import dev.kske.chess.event.GameEventListener;
|
||||||
|
|
||||||
@ -61,33 +58,6 @@ public class BoardPanel extends JPanel implements GameEventListener {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setSize(getPreferredSize());
|
setSize(getPreferredSize());
|
||||||
|
|
||||||
// Add a mouse adapter for testing piece movement
|
|
||||||
addMouseListener(new MouseAdapter() {
|
|
||||||
|
|
||||||
private Position pos;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent evt) {
|
|
||||||
if (pos == null) {
|
|
||||||
pos = new Position(evt.getPoint().x / tileSize, evt.getPoint().y / tileSize);
|
|
||||||
|
|
||||||
if (board.get(pos) != null) {
|
|
||||||
displayMoves.clear();
|
|
||||||
displayMoves.addAll(board.getMoves(pos));
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Position dest = new Position(evt.getPoint().x / tileSize, evt.getPoint().y / tileSize);
|
|
||||||
|
|
||||||
if (board.attemptMove(new Move(pos, dest))) {
|
|
||||||
displayMoves.clear();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
pos = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -133,7 +103,26 @@ public class BoardPanel extends JPanel implements GameEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverts the board to its initial state
|
* Displays move destinations on the board.
|
||||||
|
*
|
||||||
|
* @param moves The moves to display
|
||||||
|
*/
|
||||||
|
public void displayMoves(List<Move> moves) {
|
||||||
|
displayMoves.clear();
|
||||||
|
displayMoves.addAll(moves);
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all display moves.
|
||||||
|
*/
|
||||||
|
public void clearDisplayMoves() {
|
||||||
|
displayMoves.clear();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts the board to its initial state.
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
board.initializeDefaultPositions();
|
board.initializeDefaultPositions();
|
||||||
@ -149,6 +138,8 @@ public class BoardPanel extends JPanel implements GameEventListener {
|
|||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() { return new Dimension(480, 480); }
|
public Dimension getPreferredSize() { return new Dimension(480, 480); }
|
||||||
|
|
||||||
|
public int getTileSize() { return tileSize; }
|
||||||
|
|
||||||
public Board getBoard() { return board; }
|
public Board getBoard() { return board; }
|
||||||
|
|
||||||
public void setBoard(Board board) {
|
public void setBoard(Board board) {
|
||||||
|
49
src/dev/kske/chess/ui/GameModeDialog.java
Normal file
49
src/dev/kske/chess/ui/GameModeDialog.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package dev.kske.chess.ui;
|
||||||
|
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
|
||||||
|
import dev.kske.chess.board.Piece.Color;
|
||||||
|
import dev.kske.chess.game.Game;
|
||||||
|
import dev.kske.chess.game.NaturalPlayer;
|
||||||
|
import dev.kske.chess.game.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>GameModeDialog.java</strong><br>
|
||||||
|
* Created: <strong>06.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public class GameModeDialog extends JDialog {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5470026233924735607L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the dialog.
|
||||||
|
*/
|
||||||
|
public GameModeDialog(BoardPanel boardPanel) {
|
||||||
|
super();
|
||||||
|
setModal(true);
|
||||||
|
setTitle("Game Mode Selection");
|
||||||
|
setBounds(100, 100, 231, 99);
|
||||||
|
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||||
|
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
|
||||||
|
|
||||||
|
JButton btnNatural = new JButton("Game against natural opponent");
|
||||||
|
btnNatural.addActionListener((evt) -> {
|
||||||
|
Map<Color, Player> players = new HashMap<>();
|
||||||
|
players.put(Color.WHITE, new NaturalPlayer(boardPanel.getBoard(), Color.WHITE, boardPanel));
|
||||||
|
players.put(Color.BLACK, new NaturalPlayer(boardPanel.getBoard(), Color.BLACK, boardPanel));
|
||||||
|
new Game(players, boardPanel.getBoard()).start();
|
||||||
|
dispose();
|
||||||
|
});
|
||||||
|
getContentPane().add(btnNatural);
|
||||||
|
|
||||||
|
JButton btnAI = new JButton("Game against AI");
|
||||||
|
getContentPane().add(btnAI);
|
||||||
|
}
|
||||||
|
}
|
@ -64,5 +64,8 @@ public class MainWindow {
|
|||||||
btnRestart.addActionListener((evt) -> boardPanel.reset());
|
btnRestart.addActionListener((evt) -> boardPanel.reset());
|
||||||
toolPanel.add(btnRestart);
|
toolPanel.add(btnRestart);
|
||||||
mframe.pack();
|
mframe.pack();
|
||||||
|
|
||||||
|
// Display dialog for game mode selection
|
||||||
|
new GameModeDialog(boardPanel).setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user