Set fields and variables to final when possible

This commit is contained in:
Victor 2014-01-17 18:32:23 +02:00
parent 431924adb6
commit c70ec31da6
3 changed files with 350 additions and 350 deletions

View File

@ -1,117 +1,117 @@
package jtictactoe; package jtictactoe;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Point; import java.awt.Point;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import javax.swing.JPanel; import javax.swing.JPanel;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class GameBoard extends JPanel { public class GameBoard extends JPanel {
private static final int CELL_SIZE = 150; private static final int CELL_SIZE = 150;
private static final int OFFSET = 15; private static final int OFFSET = 15;
private BufferedImage strikedHor, strikedVer, strikedDiag, strikedDiagRev; private BufferedImage strikedHor, strikedVer, strikedDiag, strikedDiagRev;
private BufferedImage background, figureX, figureO; private BufferedImage background, figureX, figureO;
private Table table; private final Table table;
private TitlePanel title; private final TitlePanel title;
private int imgWidth, imgHeight; private final int imgWidth, imgHeight;
public GameBoard(TitlePanel title) { public GameBoard(TitlePanel title) {
this.title = title; this.title = title;
initImages(); initImages();
imgWidth = background.getWidth(); imgWidth = background.getWidth();
imgHeight = background.getHeight(); imgHeight = background.getHeight();
setPreferredSize( new Dimension(imgWidth, imgHeight) ); setPreferredSize( new Dimension(imgWidth, imgHeight) );
addMouseListener(new MouseAdapter() { addMouseListener(new MouseAdapter() {
@Override @Override
public void mousePressed(MouseEvent evt) { public void mousePressed(MouseEvent evt) {
gameBoardMousePressed(evt); gameBoardMousePressed(evt);
} }
}); });
table = new Table(); table = new Table();
table.resetTable(); table.resetTable();
} }
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
super.paintComponent(g); super.paintComponent(g);
g.drawImage(background, 0, 0, null); g.drawImage(background, 0, 0, null);
drawTable(g); drawTable(g);
drawStrike(g); drawStrike(g);
} }
private void drawTable(Graphics g) { private void drawTable(Graphics g) {
Figure[][] figures = table.getFiguresArray(); final Figure[][] figures = table.getFiguresArray();
for (int i = 0; i < figures.length; i++) { for (int i = 0; i < figures.length; i++) {
for (int j = 0; j < figures[0].length; j++) { for (int j = 0; j < figures[0].length; j++) {
char figure = figures[i][j].getFigure(); final char figure = figures[i][j].getFigure();
if (figure != Figure.EMPTY) { if (figure != Figure.EMPTY) {
BufferedImage image = ( (figure == Figure.X) ? figureX : figureO ); BufferedImage image = ( (figure == Figure.X) ? figureX : figureO );
int x = j * CELL_SIZE + OFFSET + (CELL_SIZE - image.getWidth()) / 2; int x = j * CELL_SIZE + OFFSET + (CELL_SIZE - image.getWidth()) / 2;
int y = i * CELL_SIZE + OFFSET + (CELL_SIZE - image.getHeight()) / 2; int y = i * CELL_SIZE + OFFSET + (CELL_SIZE - image.getHeight()) / 2;
g.drawImage(image, x, y, null); g.drawImage(image, x, y, null);
} }
} }
} }
} }
private void drawStrike(Graphics g) { private void drawStrike(Graphics g) {
int strikeMode = table.getStrikedMode(); final int strikeMode = table.getStrikedMode();
if (strikeMode != Table.MODE_NOT_STRIKED) { if (strikeMode != Table.MODE_NOT_STRIKED) {
final int strikedSize = strikedHor.getHeight(); final int strikedSize = strikedHor.getHeight();
int coord = OFFSET + (CELL_SIZE - strikedSize) / 2; final int coord = OFFSET + (CELL_SIZE - strikedSize) / 2;
int strikePos = strikeMode & 0x03; final int strikePos = strikeMode & 0x03;
if ( (strikeMode & Table.MODE_STRIKE_DIAGONAL) != 0 ) { if ( (strikeMode & Table.MODE_STRIKE_DIAGONAL) != 0 ) {
g.drawImage(strikedDiag, coord, coord, null); g.drawImage(strikedDiag, coord, coord, null);
} else if ( (strikeMode & Table.MODE_STRIKE_DIAGONAL_REVERSE) != 0 ) { } else if ( (strikeMode & Table.MODE_STRIKE_DIAGONAL_REVERSE) != 0 ) {
g.drawImage(strikedDiagRev, coord - OFFSET / 2, coord - OFFSET / 2, null); g.drawImage(strikedDiagRev, coord - OFFSET / 2, coord - OFFSET / 2, null);
} else if ( (strikeMode & Table.MODE_STRIKE_HORIZONTAL) != 0 ) { } else if ( (strikeMode & Table.MODE_STRIKE_HORIZONTAL) != 0 ) {
g.drawImage(strikedHor, coord, coord + strikePos * CELL_SIZE, null); g.drawImage(strikedHor, coord, coord + strikePos * CELL_SIZE, null);
} else if ( (strikeMode & Table.MODE_STRIKE_VERTICAL) != 0 ) { } else if ( (strikeMode & Table.MODE_STRIKE_VERTICAL) != 0 ) {
g.drawImage(strikedVer, coord + strikePos * CELL_SIZE, coord, null); g.drawImage(strikedVer, coord + strikePos * CELL_SIZE, coord, null);
} }
} }
} }
private void gameBoardMousePressed(MouseEvent evt) { private void gameBoardMousePressed(MouseEvent evt) {
Point id = convertToID( evt.getPoint() ); final Point id = convertToID( evt.getPoint() );
//table.computerMove(); //table.computerMove();
table.setFigure(id.x, id.y); table.setFigure(id.x, id.y);
if (table.getStrikedMode() == Table.MODE_NOT_STRIKED) title.setMessage(""); if (table.getStrikedMode() == Table.MODE_NOT_STRIKED) title.setMessage("");
if (!table.hasMoreMoves()) { if (!table.hasMoreMoves()) {
char winner = table.checkWinner(); final char winner = table.checkWinner();
if (winner != Figure.EMPTY) { if (winner != Figure.EMPTY) {
int winX = (winner == Figure.X) ? 1 : 0; final int winX = (winner == Figure.X) ? 1 : 0;
title.updateWin(winX, 1 - winX); title.updateWin(winX, 1 - winX);
title.setMessage(winner + " is win"); title.setMessage(winner + " is win");
} else title.setMessage("Drow"); } else title.setMessage("Drow");
} }
repaint(); repaint();
} }
private void initImages() { private void initImages() {
background = Util.getImage("/res/table_bg.jpg"); background = Util.getImage("/res/table_bg.jpg");
figureX = Util.getImage("/res/x.png"); figureX = Util.getImage("/res/x.png");
figureO = Util.getImage("/res/o.png"); figureO = Util.getImage("/res/o.png");
strikedHor = Util.getImage("/res/striked.png"); strikedHor = Util.getImage("/res/striked.png");
strikedVer = Util.getImage("/res/striked_ver.png"); strikedVer = Util.getImage("/res/striked_ver.png");
strikedDiag = Util.getImage("/res/striked_diagonal.png"); strikedDiag = Util.getImage("/res/striked_diagonal.png");
strikedDiagRev = Util.getImage("/res/striked_diagonal_rev.png"); strikedDiagRev = Util.getImage("/res/striked_diagonal_rev.png");
} }
private Point convertToID(Point point) { private Point convertToID(Point point) {
point.x /= imgWidth / 3; point.x /= imgWidth / 3;
point.y /= imgHeight / 3; point.y /= imgHeight / 3;
return point; return point;
} }
} }

View File

@ -1,32 +1,32 @@
package jtictactoe; package jtictactoe;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import javax.swing.JFrame; import javax.swing.JFrame;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class Main extends JFrame { public class Main extends JFrame {
public static void main(String[] args) { public static void main(String[] args) {
new Main().setVisible(true); new Main().setVisible(true);
} }
public Main() { public Main() {
super("JTicTacToe"); super("JTicTacToe");
setResizable(false); setResizable(false);
setUndecorated(true); setUndecorated(true);
setAlwaysOnTop(true); setAlwaysOnTop(true);
setBounds(300, 120, 0, 0); setBounds(300, 120, 0, 0);
setDefaultCloseOperation(EXIT_ON_CLOSE); setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout(0, 0)); setLayout(new BorderLayout(0, 0));
TitlePanel title = new TitlePanel(this); final TitlePanel title = new TitlePanel(this);
add(title, BorderLayout.NORTH); add(title, BorderLayout.NORTH);
add(new GameBoard(title)); add(new GameBoard(title));
pack(); pack();
} }
} }

View File

@ -1,201 +1,201 @@
package jtictactoe; package jtictactoe;
import java.util.Random; import java.util.Random;
/** /**
* *
* @author aNNiMON * @author aNNiMON
*/ */
public class Table { public class Table {
public static final int public static final int
MODE_NOT_STRIKED = 0, MODE_NOT_STRIKED = 0,
MODE_STRIKE_HORIZONTAL = 0x04, MODE_STRIKE_HORIZONTAL = 0x04,
MODE_STRIKE_VERTICAL = 0x08, MODE_STRIKE_VERTICAL = 0x08,
MODE_STRIKE_DIAGONAL = 0x10, MODE_STRIKE_DIAGONAL = 0x10,
MODE_STRIKE_DIAGONAL_REVERSE = 0x20; MODE_STRIKE_DIAGONAL_REVERSE = 0x20;
private boolean nextMoveIsX; private final Figure[][] table;
private Figure[][] table; private final Random random;
private Random random; private int strikedMode;
private int strikedMode; private boolean nextMoveIsX;
public Table() { public Table() {
table = new Figure[3][3]; table = new Figure[3][3];
random = new Random(); random = new Random();
} }
public void resetTable() { public void resetTable() {
for (int i = 0; i < table.length; i++) { for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[0].length; j++) { for (int j = 0; j < table[0].length; j++) {
table[i][j] = new Figure(); table[i][j] = new Figure();
} }
} }
strikedMode = MODE_NOT_STRIKED; strikedMode = MODE_NOT_STRIKED;
nextMoveIsX = true; nextMoveIsX = true;
} }
public int getStrikedMode() { public int getStrikedMode() {
return strikedMode; return strikedMode;
} }
public Figure[][] getFiguresArray() { public Figure[][] getFiguresArray() {
return table; return table;
} }
public void setFigure(int x, int y) { public void setFigure(int x, int y) {
if( (checkWinner() != Figure.EMPTY) || (!hasMoreMoves()) ) { if( (checkWinner() != Figure.EMPTY) || (!hasMoreMoves()) ) {
resetTable(); resetTable();
return; return;
} }
boolean xIsNorm = ( (0 <= x) && (x < 3) ); boolean xIsNorm = ( (0 <= x) && (x < 3) );
boolean yIsNorm = ( (0 <= y) && (y < 3) ); boolean yIsNorm = ( (0 <= y) && (y < 3) );
if (xIsNorm && yIsNorm && table[y][x].isEmpty()) { if (xIsNorm && yIsNorm && table[y][x].isEmpty()) {
table[y][x].setFigure(nextMoveIsX ? Figure.X : Figure.O); table[y][x].setFigure(nextMoveIsX ? Figure.X : Figure.O);
nextMoveIsX = !nextMoveIsX; nextMoveIsX = !nextMoveIsX;
computerMove(); computerMove();
} }
} }
public void computerMove() { public void computerMove() {
if( (checkWinner() != Figure.EMPTY) || (!hasMoreMoves()) ) { if( (checkWinner() != Figure.EMPTY) || (!hasMoreMoves()) ) {
//resetTable(); //resetTable();
return; return;
} }
computerAI(); computerAI();
nextMoveIsX = !nextMoveIsX; nextMoveIsX = !nextMoveIsX;
} }
private void computerAI() { private void computerAI() {
final Figure[][] array = new Figure[][] { final Figure[][] array = new Figure[][] {
// Horizontal check // Horizontal check
table[0], table[0],
table[1], table[1],
table[2], table[2],
// Vertical check // Vertical check
{ table[0][0], table[1][0], table[2][0] }, { table[0][0], table[1][0], table[2][0] },
{ table[0][1], table[1][1], table[2][1] }, { table[0][1], table[1][1], table[2][1] },
{ table[0][2], table[1][2], table[2][2] }, { table[0][2], table[1][2], table[2][2] },
// Diagonal check // Diagonal check
{ table[0][0], table[1][1], table[2][2] }, { table[0][0], table[1][1], table[2][2] },
{ table[0][2], table[1][1], table[2][0] } { table[0][2], table[1][1], table[2][0] }
}; };
char[] maybeWinnerArray = new char[array.length]; final char[] maybeWinnerArray = new char[array.length];
// Calculate winning situations for computer (zeroes). // Calculate winning situations for computer (zeroes).
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
Figure[] figures = array[i]; Figure[] figures = array[i];
char maybeWinner = maybeWinnerComboIs(figures); char maybeWinner = maybeWinnerComboIs(figures);
maybeWinnerArray[i] = maybeWinner; maybeWinnerArray[i] = maybeWinner;
if (maybeWinner == Figure.O) { if (maybeWinner == Figure.O) {
if (setCompFigure(figures)) return; if (setCompFigure(figures)) return;
} }
} }
// Calculate winning situations for the player (crosses). // Calculate winning situations for the player (crosses).
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
Figure[] figures = array[i]; Figure[] figures = array[i];
char maybeWinner = maybeWinnerArray[i]; char maybeWinner = maybeWinnerArray[i];
if (maybeWinner == Figure.X) { if (maybeWinner == Figure.X) {
if (setCompFigure(figures)) return; if (setCompFigure(figures)) return;
} }
} }
// Trying to put figure to the center. // Trying to put figure to the center.
int x = 1, y = 1; int x = 1, y = 1;
if(!table[y][x].isEmpty() || (random.nextInt(5) <= 3) ) { if(!table[y][x].isEmpty() || (random.nextInt(5) <= 3) ) {
// If it's busy, put to the corners. // If it's busy, put to the corners.
int count = 0; int count = 0;
do { do {
x = random.nextBoolean() ? 0 : 2; x = random.nextBoolean() ? 0 : 2;
y = random.nextBoolean() ? 0 : 2; y = random.nextBoolean() ? 0 : 2;
count++; count++;
} while ( (!table[y][x].isEmpty()) && (count < 10)); } while ( (!table[y][x].isEmpty()) && (count < 10));
if (count > 9) { if (count > 9) {
// Put to the remaining cells. // Put to the remaining cells.
int[][] pair = {{0, 1}, {1, 0}, {1, 2}, {2, 1}}; int[][] pair = {{0, 1}, {1, 0}, {1, 2}, {2, 1}};
count = 0; count = 0;
do { do {
x = pair[random.nextInt(pair.length)][0]; x = pair[random.nextInt(pair.length)][0];
y = pair[random.nextInt(pair.length)][1]; y = pair[random.nextInt(pair.length)][1];
count++; count++;
} while ( (!table[y][x].isEmpty()) && (count < 10)); } while ( (!table[y][x].isEmpty()) && (count < 10));
} }
} }
table[y][x].setFigure(nextMoveIsX ? Figure.X : Figure.O); table[y][x].setFigure(nextMoveIsX ? Figure.X : Figure.O);
} }
public char checkWinner() { public char checkWinner() {
// Horizontal check // Horizontal check
for (int y = 0; y < 3; y++) { for (int y = 0; y < 3; y++) {
if (isWinnerCombo(table[y][0], table[y][1], table[y][2])) { if (isWinnerCombo(table[y][0], table[y][1], table[y][2])) {
strikedMode = MODE_STRIKE_HORIZONTAL | y; strikedMode = MODE_STRIKE_HORIZONTAL | y;
return table[y][0].getFigure(); return table[y][0].getFigure();
} }
} }
// Vertical check // Vertical check
for (int x = 0; x < 3; x++) { for (int x = 0; x < 3; x++) {
if (isWinnerCombo(table[0][x], table[1][x], table[2][x])) { if (isWinnerCombo(table[0][x], table[1][x], table[2][x])) {
strikedMode = MODE_STRIKE_VERTICAL | x; strikedMode = MODE_STRIKE_VERTICAL | x;
return table[0][x].getFigure(); return table[0][x].getFigure();
} }
} }
// Diagonal check // Diagonal check
if (isWinnerCombo(table[0][0], table[1][1], table[2][2])) { if (isWinnerCombo(table[0][0], table[1][1], table[2][2])) {
strikedMode = MODE_STRIKE_DIAGONAL; strikedMode = MODE_STRIKE_DIAGONAL;
return table[0][0].getFigure(); return table[0][0].getFigure();
} }
if (isWinnerCombo(table[0][2], table[1][1], table[2][0])) { if (isWinnerCombo(table[0][2], table[1][1], table[2][0])) {
strikedMode = MODE_STRIKE_DIAGONAL_REVERSE; strikedMode = MODE_STRIKE_DIAGONAL_REVERSE;
return table[0][2].getFigure(); return table[0][2].getFigure();
} }
// No winner // No winner
return Figure.EMPTY; return Figure.EMPTY;
} }
public boolean hasMoreMoves() { public boolean hasMoreMoves() {
if (checkWinner() != Figure.EMPTY) return false; if (checkWinner() != Figure.EMPTY) return false;
int emptyFiguresCount = 0; int emptyFiguresCount = 0;
for (int i = 0; i < table.length; i++) { for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[0].length; j++) { for (int j = 0; j < table[0].length; j++) {
if (table[i][j].isEmpty()) emptyFiguresCount++; if (table[i][j].isEmpty()) emptyFiguresCount++;
} }
} }
return (emptyFiguresCount != 0); return (emptyFiguresCount != 0);
} }
private boolean isWinnerCombo(Figure f1, Figure f2, Figure f3) { private boolean isWinnerCombo(Figure f1, Figure f2, Figure f3) {
if (f1.isEmpty()) return false; if (f1.isEmpty()) return false;
char figure = f1.getFigure(); final char figure = f1.getFigure();
return ( (figure == f2.getFigure()) && return ( (figure == f2.getFigure()) &&
(figure == f3.getFigure()) ); (figure == f3.getFigure()) );
} }
private char maybeWinnerComboIs(Figure[] array) { private char maybeWinnerComboIs(Figure[] array) {
int numX = 0, numO = 0; int numX = 0, numO = 0;
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
if (!array[i].isEmpty()) { if (!array[i].isEmpty()) {
if (array[i].getFigure() == Figure.X) numX++; if (array[i].getFigure() == Figure.X) numX++;
else numO++; else numO++;
} }
} }
if (numX == 2) return Figure.X; if (numX == 2) return Figure.X;
if (numO == 2) return Figure.O; if (numO == 2) return Figure.O;
return Figure.EMPTY; return Figure.EMPTY;
} }
private boolean setCompFigure(Figure[] array) { private boolean setCompFigure(Figure[] array) {
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
if (array[i].isEmpty()) { if (array[i].isEmpty()) {
array[i].setFigure(Figure.O); array[i].setFigure(Figure.O);
return true; return true;
} }
} }
return false; return false;
} }
} }