Не відповідь, а моделювання на допомогу
Я додав новий клас: GamePanel та відредагував Game and Controller
Це не дуже красиво ... поки. Чи знаєте ви, що у Unicode були шахові символи!?!? (абсолютно дивовижно!)
До речі, для показу цих символів вам потрібен UTF-8. Це працювало для мене, але не впевнений, як це буде працювати в інших операційних системах.
Виправлена помилка в кінці ігор (завдяки тим, що вони вказали на це).
GamePanel:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GamePanel extends JPanel{
private static final long serialVersionUID = 1L;
JFrame container;
Board currentBoard;
Game currentGame;
ArrayList<Game> games;
public GamePanel(ArrayList<Game> Games){
games = Games;
currentGame = games.get(0);
currentBoard = currentGame.allBoards.get(0);
container = new JFrame();
container.setSize(new Dimension(500,500));
container.setMinimumSize(new Dimension(150,150));
this.setMinimumSize(new Dimension(150,150));
JButton skipButton = new JButton("skip game");
skipButton.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent arg0) {
nextGame();
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
JButton undoButton = new JButton("go back");
undoButton.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent e) {
unStep();
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
});
JButton continueButton = new JButton("continue");
undoButton.setSize(40,40);
skipButton.setSize(40,40);
continueButton.setSize(40,40);
continueButton.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent arg0) {
step();
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(continueButton);
buttonPanel.add(undoButton);
buttonPanel.add(skipButton);
container.setLayout(new BorderLayout());
container.getContentPane().add(this,BorderLayout.CENTER);
container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container.getContentPane().add(buttonPanel,BorderLayout.NORTH);
container.setTitle("White: " + currentGame.players[0].getClass().getSimpleName()
+ " vs "+ "Black: " + currentGame.players[1].getClass().getSimpleName());
container.setVisible(true);
container.invalidate();
container.repaint();
}
private void unStep(){
if(currentBoard!=currentGame.allBoards.get(0)){
currentBoard=currentGame.allBoards.get(currentGame.allBoards.indexOf(currentBoard)-1);
}
container.invalidate();
container.repaint();
}
private void unGame(){
if(currentGame != games.get(0)){
currentGame = games.get(games.indexOf(currentGame)-1);
currentBoard = currentGame.allBoards.get(0);
}
container.invalidate();
container.repaint();
}
private void step(){
if(currentGame.allBoards.indexOf(currentBoard)==currentGame.allBoards.size()-1){
nextGame();
}
else{
currentBoard = currentGame.allBoards.get(currentGame.allBoards.indexOf(currentBoard)+1);
}
container.invalidate();
container.repaint();
}
private void nextGame(){
container.setTitle("White: " + currentGame.players[0].getClass().getSimpleName()
+ " vs "+ "Black: " + currentGame.players[1].getClass().getSimpleName());
if(currentGame != games.get(games.size()-1)){
currentGame = games.get(games.indexOf(currentGame)+1);
}
else{
//games complete
container.dispose();
}
currentBoard = currentGame.allBoards.get(0);
container.invalidate();
container.repaint();
}
@Override
public void paintComponent(Graphics g){
if(getWidth()>150 && getHeight() > 150){
int leftBounds,topBounds,width,height;
topBounds = 50;
leftBounds = 50;
if(getWidth() > getHeight()){
width = (int) (getHeight()-100);
height = (int) (getHeight()-100);
}
else{
width = (int) (getWidth()-100);
height = (int) (getWidth()-100);
}
//draw grid
java.awt.Color dark = new java.awt.Color(128, 78, 41);
java.awt.Color light = new java.awt.Color(250, 223, 173);
Field[][] feilds = currentBoard.getFields();
for(int x = leftBounds; x < leftBounds+width-width/8; x+=width/8){
for(int y = topBounds; y < topBounds+height-height/8; y+=height/8){
int xPos = (int)Math.round(((double)(x-leftBounds)/(double)width)*8);
int yPos = (int)Math.round(((double)(y-topBounds)/(double)height)*8);
String piece = "";
java.awt.Color stringColor = java.awt.Color.black;
if(feilds[xPos][yPos].hasPiece()){
piece = getPiece(feilds[xPos][yPos].getPiece());
if(feilds[xPos][yPos].getPiece().getTeam()==Color.WHITE){stringColor = java.awt.Color.WHITE;}
}
if(yPos % 2 == 1){
if(xPos % 2 == 1){
g.setColor(dark);
g.fillRect(x, y, width/8, height/8);
}
else{
g.setColor(light);
g.fillRect(x, y, width/8, height/8);
}
}
else{
if(xPos % 2 == 1){
g.setColor(light);
g.fillRect(x, y, width/8, height/8);
}
else{
g.setColor(dark);
g.fillRect(x, y, width/8, height/8);
}
}
g.setColor(java.awt.Color.black);
g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, width/8));
g.drawString(piece, x, y+width/8);
}
}
}
}
public String getPiece(Piece p){
if(p.getTeam() == Color.WHITE){
if(p.getType() == PieceType.BISHOP){return "\u2657";}
if(p.getType() == PieceType.PAWN){return "\u2659";}
if(p.getType() == PieceType.KING){return "\u2654";}
if(p.getType() == PieceType.QUEEN){return "\u2655";}
if(p.getType() == PieceType.ROOK){return "\u2656";}
if(p.getType() == PieceType.KNIGHT){return "\u2658";}
}
else{
if(p.getType() == PieceType.BISHOP){return "\u265D";}
if(p.getType() == PieceType.PAWN){return "\u265F";}
if(p.getType() == PieceType.KING){return "\u265A";}
if(p.getType() == PieceType.QUEEN){return "\u265B";}
if(p.getType() == PieceType.ROOK){return "\u265C";}
if(p.getType() == PieceType.KNIGHT){return "\u265E";}
}
return p.toString();
}
}
Гра:
import java.util.ArrayList;
public class Game {
private static final int MAX_TURNS_WITHOUT_CAPTURES = 100; //=50, counts for both teams
private static final int MAX_MILLISECONDS = 2000;
private Board board;
Player[] players = new Player[2];
private int turnsWithoutCaptures = 0;
private boolean draw = false;
ArrayList<Board> allBoards = new ArrayList<Board>();
public Game(Player player1, Player player2) {
board = new Board();
board.initialize();
players[0] = player1;
players[0].setTeam(Color.WHITE);
players[1] = player2;
players[1].setTeam(Color.BLACK);
allBoards.add(board.copy());
}
int run() {
int i = 0;
while (!gameOver()) {
if (!turnAvailable(players[i])) {
draw = true;
} else {
makeTurn(players[i], players[(i+1) % 2]);
i = (i + 1) % 2;
}
}
if (loses(players[0]) && !loses(players[1])) {
return Controller.LOSE_POINTS;
} else if (loses(players[1]) && !loses(players[0])) {
return Controller.WIN_POINTS;
} else {
return Controller.DRAW_POINTS;
}
}
private boolean loses(Player player) {
if (player.isDisqualified() || board.getKing(player) == null) {
return true;
}
return false;
}
// player can make a turn
private boolean turnAvailable(Player player) {
for (Piece piece : player.getPieces(board)) {
if (piece.getValidDestinationSet(board).size() > 0) {
return true;
}
}
return false;
}
private void makeTurn(Player player, Player enemy) {
player.setCheck(board.isCheck(player, enemy));
enemy.setCheck(board.isCheck(enemy, player));
try {
long start = System.currentTimeMillis();
Move move = player.getMove(board.copy(), enemy);
if ((System.currentTimeMillis() - start) > MAX_MILLISECONDS) {
player.setDisqualified();
}
if (move.isValid(board, player)) {
if (board.movePiece(move) || move.getPiece().getType() == PieceType.PAWN) {
turnsWithoutCaptures = 0;
} else {
turnsWithoutCaptures++;
}
} else {
player.setDisqualified(); //invalid move
}
} catch (Exception e) {
player.setDisqualified();
e.printStackTrace();
System.out.println("Exception while moving " + player);
}
allBoards.add(board.copy());
}
public boolean gameOver() {
for (Player player : players) {
if (player.isDisqualified() || board.getKing(player) == null
|| turnsWithoutCaptures >= MAX_TURNS_WITHOUT_CAPTURES || draw) {
return true;
}
}
return false;
}
}
Контролер:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import players.*;
public class Controller {
public static final int WIN_POINTS = 3;
public static final int DRAW_POINTS = 1;
public static final int LOSE_POINTS = 0;
private static final int GAMES_PER_PAIR = 10;
private final Class[] classes = {StretchPlayer.class,TestPlayer.class};
private final Map<Class<? extends Player>, Integer> scores = new HashMap<Class<? extends Player>, Integer>();
public static void main(String... args) {
new Controller().generateResult();
}
public Controller() {
for (Class player : classes) {
scores.put(player, 0);
}
}
ArrayList<Game> games = new ArrayList<Game>();
private void generateResult() {
for (int i = 0; i < classes.length - 1; i++) {
for (int j = i + 1; j < classes.length; j++) {
for (int k = 0; k < GAMES_PER_PAIR; k++) {
runGame(classes[i], classes[j], k>=GAMES_PER_PAIR);
}
}
}
GamePanel panel = new GamePanel(games);
printScores();
}
private void runGame(Class class1, Class class2, boolean switchSides) {
if (switchSides) { //switch sides
Class tempClass = class2;
class2 = class1;
class1 = tempClass;
}
try {
Player player1 = (Player) class1.newInstance();
Player player2 = (Player) class2.newInstance();
Game game = new Game(player1, player2);
games.add(game);
int result = game.run();
addResult(class1, result, false);
addResult(class2, result, true);
} catch (Exception e) {
System.out.println("Error in game between " + class1 + " and " + class2);
}
}
private void addResult(Class player, int result, boolean reverse) {
if (reverse) {
if (result == WIN_POINTS) {
result = LOSE_POINTS;
} else if (result == LOSE_POINTS) {
result = WIN_POINTS;
}
}
int newScore = scores.get(player) + result;
scores.put(player, newScore);
}
private void printScores() {
int bestScore = 0;
Class currPlayer = null;
int place = 1;
while (scores.size() > 0) {
bestScore = 0;
currPlayer = null;
for (Class player : scores.keySet()) {
int playerScore = scores.get(player);
if (scores.get(player) >= bestScore) {
bestScore = playerScore;
currPlayer = player;
}
}
System.out.println(String.format("%02d", place++) + ") " + currPlayer + ": " + bestScore);
scores.remove(currPlayer);
}
}
}