Added game end dialogs & statistics
This commit is contained in:
parent
82c14e3ee1
commit
9f44b1dc78
9
.idea/libraries/jfreechart_1_5_3.xml
Normal file
9
.idea/libraries/jfreechart_1_5_3.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="jfreechart-1.5.3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/lib/jfreechart-1.5.3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -8,5 +8,6 @@
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="org.jfree.svg-5.0.5" level="project" />
|
<orderEntry type="library" name="org.jfree.svg-5.0.5" level="project" />
|
||||||
|
<orderEntry type="library" name="jfreechart-1.5.3" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
BIN
lib/jfreechart-1.5.3.jar
Normal file
BIN
lib/jfreechart-1.5.3.jar
Normal file
Binary file not shown.
|
@ -325,8 +325,8 @@ public abstract class APiece {
|
||||||
double startY = chessboard.startY + (fromY*chessboard.SQUARE_SIZE)*chessboard.boardScale;
|
double startY = chessboard.startY + (fromY*chessboard.SQUARE_SIZE)*chessboard.boardScale;
|
||||||
double endX = chessboard.startX + (toX*chessboard.SQUARE_SIZE)*chessboard.boardScale;
|
double endX = chessboard.startX + (toX*chessboard.SQUARE_SIZE)*chessboard.boardScale;
|
||||||
double endY = chessboard.startY + (toY*chessboard.SQUARE_SIZE)*chessboard.boardScale;
|
double endY = chessboard.startY + (toY*chessboard.SQUARE_SIZE)*chessboard.boardScale;
|
||||||
double stepX = (endX-startX)/100;
|
double stepX = (endX-startX)/250;
|
||||||
double stepY = (endY-startY)/100;
|
double stepY = (endY-startY)/250;
|
||||||
Timer timer = new Timer();
|
Timer timer = new Timer();
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
@ -334,7 +334,7 @@ public abstract class APiece {
|
||||||
double currentY = 0;
|
double currentY = 0;
|
||||||
public void run() {
|
public void run() {
|
||||||
chessboard.repaintRootPane(getRepaintRectangle());
|
chessboard.repaintRootPane(getRepaintRectangle());
|
||||||
if(i > 100) {
|
if(i > 250) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
setOverride(0, 0);
|
setOverride(0, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -345,7 +345,7 @@ public abstract class APiece {
|
||||||
chessboard.repaintRootPane(getRepaintRectangle());
|
chessboard.repaintRootPane(getRepaintRectangle());
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}, 5, 5);
|
}, 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(boolean animate) {
|
public void remove(boolean animate) {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import org.jfree.chart.ChartFactory;
|
||||||
|
import org.jfree.chart.ChartPanel;
|
||||||
|
import org.jfree.chart.JFreeChart;
|
||||||
|
import org.jfree.data.category.DefaultCategoryDataset;
|
||||||
import org.jfree.svg.SVGGraphics2D;
|
import org.jfree.svg.SVGGraphics2D;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
@ -7,6 +11,8 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main program layout
|
* Main program layout
|
||||||
|
@ -68,7 +74,10 @@ public class Chess {
|
||||||
JMenu menuGame = new JMenu("Game");
|
JMenu menuGame = new JMenu("Game");
|
||||||
|
|
||||||
JMenuItem startNewGame = new JMenuItem("Start new game");
|
JMenuItem startNewGame = new JMenuItem("Start new game");
|
||||||
startNewGame.addActionListener(l -> newGame(Chessboard.fromFEN(DEFAULT_FEN)));
|
startNewGame.addActionListener(l -> {
|
||||||
|
int response = JOptionPane.showConfirmDialog(chessboard, "Do you really want to start a new game?");
|
||||||
|
if(response == 0) newGame(Chessboard.fromFEN(DEFAULT_FEN));
|
||||||
|
});
|
||||||
menuGame.add(startNewGame);
|
menuGame.add(startNewGame);
|
||||||
|
|
||||||
JMenuItem newGameFromFEN = new JMenuItem("Load from FEN");
|
JMenuItem newGameFromFEN = new JMenuItem("Load from FEN");
|
||||||
|
@ -81,6 +90,18 @@ public class Chess {
|
||||||
});
|
});
|
||||||
menuGame.add(newGameFromFEN);
|
menuGame.add(newGameFromFEN);
|
||||||
|
|
||||||
|
JMenuItem getFEN = new JMenuItem("Get current FEN");
|
||||||
|
getFEN.addActionListener(l -> {
|
||||||
|
JOptionPane.showInputDialog("Here is current FEN: ", chessboard.toFEN());
|
||||||
|
});
|
||||||
|
menuGame.add(getFEN);
|
||||||
|
|
||||||
|
JMenuItem showStats = new JMenuItem("Statistics");
|
||||||
|
showStats.addActionListener(l -> {
|
||||||
|
showStatistics();
|
||||||
|
});
|
||||||
|
menuGame.add(showStats);
|
||||||
|
|
||||||
menuGame.add(new JPopupMenu.Separator());
|
menuGame.add(new JPopupMenu.Separator());
|
||||||
|
|
||||||
JCheckBoxMenuItem toggleBlindMode = new JCheckBoxMenuItem("Blind mode");
|
JCheckBoxMenuItem toggleBlindMode = new JCheckBoxMenuItem("Blind mode");
|
||||||
|
@ -273,4 +294,30 @@ public class Chess {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showStatistics() {
|
||||||
|
JFrame window = new JFrame();
|
||||||
|
window.setTitle("Statistics");
|
||||||
|
|
||||||
|
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
|
||||||
|
Player[] players = new Player[]{chessboard.getPlayer1(), chessboard.getPlayer2()};
|
||||||
|
String[] playerNames = new String[]{"White", "Black"};
|
||||||
|
for (int i = 0; i < players.length; i++) {
|
||||||
|
List<Integer> delays = players[i].getDelays();
|
||||||
|
for (int j = 0; j < delays.size(); j++) {
|
||||||
|
dataset.addValue(delays.get(j), playerNames[i], (j+1)+".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JFreeChart chart = ChartFactory.createLineChart(
|
||||||
|
"Turn speed", "Turns", "Time (ms)",
|
||||||
|
dataset
|
||||||
|
);
|
||||||
|
|
||||||
|
ChartPanel panel = new ChartPanel(chart);
|
||||||
|
window.add(panel);
|
||||||
|
window.pack();
|
||||||
|
window.setMinimumSize(new Dimension(500, 300));
|
||||||
|
|
||||||
|
window.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Set;
|
import java.util.Timer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chessboard class
|
* Chessboard class
|
||||||
|
@ -65,6 +65,8 @@ public class Chessboard extends JPanel {
|
||||||
|
|
||||||
static private Theme theme = Theme.activeTheme;
|
static private Theme theme = Theme.activeTheme;
|
||||||
|
|
||||||
|
private long lastMoveTime = System.currentTimeMillis();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor of the chessboard
|
* Constructor of the chessboard
|
||||||
*/
|
*/
|
||||||
|
@ -508,17 +510,41 @@ public class Chessboard extends JPanel {
|
||||||
return player2;
|
return player2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkGame() {
|
||||||
|
Player[] players = new Player[]{player1, player2};
|
||||||
|
String[] playerNames = new String[]{"White", "Black"};
|
||||||
|
for (int i = 0; i < players.length; i++) {
|
||||||
|
if(players[i].inCheck()) {
|
||||||
|
System.out.println(playerNames[i] + " is in check!");
|
||||||
|
if(players[i].hasNoPossibleMove()) {
|
||||||
|
String winner = playerNames[(i+1)%2];
|
||||||
|
delayedMessage("Checkmate! Congratulations " + winner + ", you have won the game.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!activePlayer.inCheck() && activePlayer.hasNoPossibleMove()) {
|
||||||
|
delayedMessage("It's a stalemate! Neither player can make a move without putting their king in checkmate.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delayedMessage(String msg) {
|
||||||
|
Timer t = new Timer();
|
||||||
|
t.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
JOptionPane.showMessageDialog(Chess.chessboard, msg);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
public void changeActivePlayer() {
|
public void changeActivePlayer() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
activePlayer.addDelay((int) (now-lastMoveTime));
|
||||||
|
lastMoveTime = now;
|
||||||
activePlayer = getOtherPlayer();
|
activePlayer = getOtherPlayer();
|
||||||
repaintRootPane();
|
repaintRootPane();
|
||||||
if(player1.inCheck()) {
|
checkGame();
|
||||||
System.out.println("Player1 in check!");
|
|
||||||
if(player1.inMate()) System.out.println("Player1 in mate!");
|
|
||||||
}
|
|
||||||
if(player2.inCheck()) {
|
|
||||||
System.out.println("Player2 in check!");
|
|
||||||
if(player2.inMate()) System.out.println("Player2 in mate!");
|
|
||||||
}
|
|
||||||
activePlayer.play();
|
activePlayer.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
public class Player {
|
public class Player {
|
||||||
|
|
||||||
|
@ -17,6 +14,8 @@ public class Player {
|
||||||
|
|
||||||
private boolean isPlaying = false;
|
private boolean isPlaying = false;
|
||||||
|
|
||||||
|
private ArrayList<Integer> delays = new ArrayList<>();
|
||||||
|
|
||||||
public Player(Chessboard chessboard, StartPosition startPosition, PieceColor color) {
|
public Player(Chessboard chessboard, StartPosition startPosition, PieceColor color) {
|
||||||
this.chessboard = chessboard;
|
this.chessboard = chessboard;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
@ -27,7 +26,7 @@ public class Player {
|
||||||
return king.isEndangered();
|
return king.isEndangered();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inMate() {
|
public boolean hasNoPossibleMove() {
|
||||||
for (APiece piece : getPieces()) {
|
for (APiece piece : getPieces()) {
|
||||||
boolean[][] possibleMoves = piece.getPossibleMoves();
|
boolean[][] possibleMoves = piece.getPossibleMoves();
|
||||||
for (int y = 0; y < possibleMoves.length; y++) {
|
for (int y = 0; y < possibleMoves.length; y++) {
|
||||||
|
@ -142,4 +141,12 @@ public class Player {
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDelay(int delay) {
|
||||||
|
delays.add(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getDelays() {
|
||||||
|
return delays;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue