Added game end dialogs & statistics

This commit is contained in:
Filip Znachor 2023-05-05 00:34:52 +02:00
parent 82c14e3ee1
commit 9f44b1dc78
7 changed files with 110 additions and 20 deletions

View 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>

View file

@ -8,5 +8,6 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="org.jfree.svg-5.0.5" level="project" />
<orderEntry type="library" name="jfreechart-1.5.3" level="project" />
</component>
</module>

BIN
lib/jfreechart-1.5.3.jar Normal file

Binary file not shown.

View file

@ -325,8 +325,8 @@ public abstract class APiece {
double startY = chessboard.startY + (fromY*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 stepX = (endX-startX)/100;
double stepY = (endY-startY)/100;
double stepX = (endX-startX)/250;
double stepY = (endY-startY)/250;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
int i = 1;
@ -334,7 +334,7 @@ public abstract class APiece {
double currentY = 0;
public void run() {
chessboard.repaintRootPane(getRepaintRectangle());
if(i > 100) {
if(i > 250) {
timer.cancel();
setOverride(0, 0);
} else {
@ -345,7 +345,7 @@ public abstract class APiece {
chessboard.repaintRootPane(getRepaintRectangle());
i++;
}
}, 5, 5);
}, 2, 2);
}
public void remove(boolean animate) {

View file

@ -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 javax.imageio.ImageIO;
@ -7,6 +11,8 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Main program layout
@ -68,7 +74,10 @@ public class Chess {
JMenu menuGame = new JMenu("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);
JMenuItem newGameFromFEN = new JMenuItem("Load from FEN");
@ -81,6 +90,18 @@ public class Chess {
});
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());
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);
}
}

View file

@ -1,8 +1,8 @@
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import java.util.Timer;
/**
* Chessboard class
@ -65,6 +65,8 @@ public class Chessboard extends JPanel {
static private Theme theme = Theme.activeTheme;
private long lastMoveTime = System.currentTimeMillis();
/**
* Constructor of the chessboard
*/
@ -508,17 +510,41 @@ public class Chessboard extends JPanel {
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() {
long now = System.currentTimeMillis();
activePlayer.addDelay((int) (now-lastMoveTime));
lastMoveTime = now;
activePlayer = getOtherPlayer();
repaintRootPane();
if(player1.inCheck()) {
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!");
}
checkGame();
activePlayer.play();
}

View file

@ -1,7 +1,4 @@
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.*;
public class Player {
@ -17,6 +14,8 @@ public class Player {
private boolean isPlaying = false;
private ArrayList<Integer> delays = new ArrayList<>();
public Player(Chessboard chessboard, StartPosition startPosition, PieceColor color) {
this.chessboard = chessboard;
this.color = color;
@ -27,7 +26,7 @@ public class Player {
return king.isEndangered();
}
public boolean inMate() {
public boolean hasNoPossibleMove() {
for (APiece piece : getPieces()) {
boolean[][] possibleMoves = piece.getPossibleMoves();
for (int y = 0; y < possibleMoves.length; y++) {
@ -142,4 +141,12 @@ public class Player {
return cpu;
}
public void addDelay(int delay) {
delays.add(delay);
}
public List<Integer> getDelays() {
return delays;
}
}