diff --git a/.idea/libraries/jfreechart_1_5_3.xml b/.idea/libraries/jfreechart_1_5_3.xml
new file mode 100644
index 0000000..2b8d511
--- /dev/null
+++ b/.idea/libraries/jfreechart_1_5_3.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Chess.iml b/Chess.iml
index 4a41191..f1845b4 100644
--- a/Chess.iml
+++ b/Chess.iml
@@ -8,5 +8,6 @@
+
\ No newline at end of file
diff --git a/lib/jfreechart-1.5.3.jar b/lib/jfreechart-1.5.3.jar
new file mode 100644
index 0000000..0f73437
Binary files /dev/null and b/lib/jfreechart-1.5.3.jar differ
diff --git a/src/APiece.java b/src/APiece.java
index 93a0666..85d6a65 100644
--- a/src/APiece.java
+++ b/src/APiece.java
@@ -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) {
diff --git a/src/Chess.java b/src/Chess.java
index 24e3a24..a02b606 100644
--- a/src/Chess.java
+++ b/src/Chess.java
@@ -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 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);
+ }
+
}
diff --git a/src/Chessboard.java b/src/Chessboard.java
index a8f2cb2..af5c248 100644
--- a/src/Chessboard.java
+++ b/src/Chessboard.java
@@ -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();
}
diff --git a/src/Player.java b/src/Player.java
index c8c9380..e618cce 100644
--- a/src/Player.java
+++ b/src/Player.java
@@ -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 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 getDelays() {
+ return delays;
+ }
+
}