Implemented game restarting
+ Restarting method in Game + Abstract cancelMove method in Player + Stopping calculations in AIPlayer when the game has been restarted
This commit is contained in:
		@@ -29,10 +29,6 @@ public class Game {
 | 
			
		||||
		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);
 | 
			
		||||
@@ -51,4 +47,15 @@ public class Game {
 | 
			
		||||
			}
 | 
			
		||||
		} else player.requestMove();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void start() {
 | 
			
		||||
		players.get(Color.WHITE).requestMove();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void restart() {
 | 
			
		||||
		players.forEach((k, v) -> v.cancelMove());
 | 
			
		||||
		board.initializeDefaultPositions();
 | 
			
		||||
		boardComponent.repaint();
 | 
			
		||||
		start();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -61,4 +61,9 @@ public class NaturalPlayer extends Player {
 | 
			
		||||
	public void requestMove() {
 | 
			
		||||
		moveRequested = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void cancelMove() {
 | 
			
		||||
		moveRequested = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,8 @@ public abstract class Player {
 | 
			
		||||
 | 
			
		||||
	public abstract void requestMove();
 | 
			
		||||
 | 
			
		||||
	public abstract void cancelMove();
 | 
			
		||||
 | 
			
		||||
	public Game getGame() { return game; }
 | 
			
		||||
 | 
			
		||||
	public void setGame(Game game) { this.game = game; }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import java.util.concurrent.ExecutionException;
 | 
			
		||||
import java.util.concurrent.ExecutorService;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
import java.util.concurrent.Future;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import javax.swing.SwingUtilities;
 | 
			
		||||
 | 
			
		||||
@@ -25,14 +26,19 @@ public class AIPlayer extends Player {
 | 
			
		||||
	private int	availableProcessors;
 | 
			
		||||
	private int	maxDepth;
 | 
			
		||||
 | 
			
		||||
	private volatile boolean exitRequested;
 | 
			
		||||
	private volatile ExecutorService	executor;
 | 
			
		||||
 | 
			
		||||
	public AIPlayer(Board board, Color color, int maxDepth) {
 | 
			
		||||
		super(board, color);
 | 
			
		||||
		availableProcessors	= Runtime.getRuntime().availableProcessors();
 | 
			
		||||
		this.maxDepth		= maxDepth;
 | 
			
		||||
		exitRequested		= false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void requestMove() {
 | 
			
		||||
		exitRequested = false;
 | 
			
		||||
		/*
 | 
			
		||||
		 * Define some processing threads, split the available moves between them and
 | 
			
		||||
		 * retrieve the result after their execution.
 | 
			
		||||
@@ -41,8 +47,8 @@ public class AIPlayer extends Player {
 | 
			
		||||
			/*
 | 
			
		||||
			 * Get a copy of the board and the available moves.
 | 
			
		||||
			 */
 | 
			
		||||
			Board				board		= (Board) AIPlayer.this.board.clone();
 | 
			
		||||
			List<Move>			moves		= board.getMoves(color);
 | 
			
		||||
			Board		board	= (Board) AIPlayer.this.board.clone();
 | 
			
		||||
			List<Move>	moves	= board.getMoves(color);
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Define move processors and split the available moves between them.
 | 
			
		||||
@@ -63,7 +69,7 @@ public class AIPlayer extends Player {
 | 
			
		||||
			/*
 | 
			
		||||
			 * Execute processors, get the best result and pass it back to the Game class
 | 
			
		||||
			 */
 | 
			
		||||
			ExecutorService			executor	= Executors.newFixedThreadPool(numThreads);
 | 
			
		||||
			executor = Executors.newFixedThreadPool(numThreads);
 | 
			
		||||
			List<ProcessingResult>	results		= new ArrayList<>(numThreads);
 | 
			
		||||
			try {
 | 
			
		||||
				List<Future<ProcessingResult>> futures = executor.invokeAll(processors);
 | 
			
		||||
@@ -74,7 +80,18 @@ public class AIPlayer extends Player {
 | 
			
		||||
				ex.printStackTrace();
 | 
			
		||||
			}
 | 
			
		||||
			results.sort((r1, r2) -> Integer.compare(r2.score, r1.score));
 | 
			
		||||
			SwingUtilities.invokeLater(() -> game.onMove(this, results.get(0).move));
 | 
			
		||||
			if (!exitRequested) SwingUtilities.invokeLater(() -> game.onMove(this, results.get(0).move));
 | 
			
		||||
		}, "AIPlayer calculation setup").start();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void cancelMove() {
 | 
			
		||||
		exitRequested = true;
 | 
			
		||||
		executor.shutdownNow();
 | 
			
		||||
		try {
 | 
			
		||||
			executor.awaitTermination(500, TimeUnit.MILLISECONDS);
 | 
			
		||||
		} catch (InterruptedException e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,10 +26,16 @@ public class GameModeDialog extends JDialog {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = 5470026233924735607L;
 | 
			
		||||
 | 
			
		||||
	private final MainWindow			parent;
 | 
			
		||||
	private final Board					board;
 | 
			
		||||
	private final OverlayComponent		overlayComponent;
 | 
			
		||||
	private final BoardComponent		boardComponent;
 | 
			
		||||
	private final Map<Color, Player>	players;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create the dialog.
 | 
			
		||||
	 */
 | 
			
		||||
	public GameModeDialog(BoardPane boardPane) {
 | 
			
		||||
	public GameModeDialog(MainWindow parent, BoardPane boardPane) {
 | 
			
		||||
		super();
 | 
			
		||||
		setModal(true);
 | 
			
		||||
		setTitle("Game Mode Selection");
 | 
			
		||||
@@ -46,40 +52,43 @@ public class GameModeDialog extends JDialog {
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		final BoardComponent	boardComponent		= boardPane.getBoardComponent();
 | 
			
		||||
		final OverlayComponent	overlayComponent	= boardPane.getOverlayComponent();
 | 
			
		||||
		final Board				board				= boardComponent.getBoard();
 | 
			
		||||
		this.parent			= parent;
 | 
			
		||||
		boardComponent		= boardPane.getBoardComponent();
 | 
			
		||||
		overlayComponent	= boardPane.getOverlayComponent();
 | 
			
		||||
		board				= boardComponent.getBoard();
 | 
			
		||||
		players				= new HashMap<>();
 | 
			
		||||
 | 
			
		||||
		JButton btnNatural = new JButton("Game against natural opponent");
 | 
			
		||||
		btnNatural.addActionListener((evt) -> {
 | 
			
		||||
			Map<Color, Player> players = new HashMap<>();
 | 
			
		||||
			players.put(Color.WHITE, new NaturalPlayer(board, Color.WHITE, overlayComponent));
 | 
			
		||||
			players.put(Color.BLACK, new NaturalPlayer(board, Color.BLACK, overlayComponent));
 | 
			
		||||
			new Game(players, boardComponent).start();
 | 
			
		||||
			dispose();
 | 
			
		||||
			startGame();
 | 
			
		||||
		});
 | 
			
		||||
		getContentPane().add(btnNatural);
 | 
			
		||||
 | 
			
		||||
		JButton btnAI = new JButton("Game against AI");
 | 
			
		||||
		btnAI.addActionListener((evt) -> {
 | 
			
		||||
			Map<Color, Player> players = new HashMap<>();
 | 
			
		||||
			players.put(Color.WHITE, new NaturalPlayer(board, Color.WHITE, overlayComponent));
 | 
			
		||||
			players.put(Color.BLACK, new AIPlayer(board, Color.BLACK, 5));
 | 
			
		||||
			new Game(players, boardComponent).start();
 | 
			
		||||
			dispose();
 | 
			
		||||
			startGame();
 | 
			
		||||
		});
 | 
			
		||||
		getContentPane().add(btnAI);
 | 
			
		||||
 | 
			
		||||
		JButton btnAI2 = new JButton("AI against AI");
 | 
			
		||||
		btnAI2.addActionListener((evt) -> {
 | 
			
		||||
			Map<Color, Player> players = new HashMap<>();
 | 
			
		||||
			players.put(Color.WHITE, new AIPlayer(board, Color.WHITE, 5));
 | 
			
		||||
			players.put(Color.BLACK, new AIPlayer(board, Color.BLACK, 4));
 | 
			
		||||
			new Game(players, boardComponent).start();
 | 
			
		||||
			dispose();
 | 
			
		||||
			startGame();
 | 
			
		||||
		});
 | 
			
		||||
		getContentPane().add(btnAI2);
 | 
			
		||||
 | 
			
		||||
		setLocationRelativeTo(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void startGame() {
 | 
			
		||||
		Game game = new Game(players, boardComponent);
 | 
			
		||||
		parent.setGame(game);
 | 
			
		||||
		game.start();
 | 
			
		||||
		dispose();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import javax.swing.JFrame;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
 | 
			
		||||
import dev.kske.chess.board.Board;
 | 
			
		||||
 | 
			
		||||
import dev.kske.chess.game.Game;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Project: <strong>Chess</strong><br>
 | 
			
		||||
@@ -18,7 +18,8 @@ import dev.kske.chess.board.Board;
 | 
			
		||||
 */
 | 
			
		||||
public class MainWindow {
 | 
			
		||||
 | 
			
		||||
	private JFrame mframe;
 | 
			
		||||
	private JFrame	mframe;
 | 
			
		||||
	private Game	game;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Launch the application.
 | 
			
		||||
@@ -61,12 +62,16 @@ public class MainWindow {
 | 
			
		||||
		mframe.getContentPane().add(toolPanel, BorderLayout.NORTH);
 | 
			
		||||
 | 
			
		||||
		JButton btnRestart = new JButton("Restart");
 | 
			
		||||
		btnRestart.addActionListener((evt) -> System.err.println("Resetting not implemented!"));
 | 
			
		||||
		btnRestart.addActionListener((evt) -> { if (game != null) game.restart(); });
 | 
			
		||||
		toolPanel.add(btnRestart);
 | 
			
		||||
		mframe.pack();
 | 
			
		||||
		mframe.setLocationRelativeTo(null);
 | 
			
		||||
 | 
			
		||||
		// Display dialog for game mode selection
 | 
			
		||||
		new GameModeDialog(boardPane).setVisible(true);
 | 
			
		||||
		new GameModeDialog(this, boardPane).setVisible(true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Game getGame() { return game; }
 | 
			
		||||
 | 
			
		||||
	public void setGame(Game game) { this.game = game; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user