diff --git a/TicTacToe - MinMax/src/Board.java b/TicTacToe - MinMax/src/Board.java index 41c250a..0bf8df0 100644 --- a/TicTacToe - MinMax/src/Board.java +++ b/TicTacToe - MinMax/src/Board.java @@ -30,7 +30,17 @@ public class Board extends JPanel implements ActionListener { private void initBoard(){ painter = new Painter(B_WIDTH,B_HEIGHT); - addMouseListener(new MAdapter()); + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + int column = e.getX()/TILE_X; + int row = e.getY()/TILE_Y; + game.place(column * 3 + row, 1); + System.out.println(Arrays.toString(game.getPlayfield())); + } + }); + setBackground(Color.BLACK); setFocusable(true); setPreferredSize(new Dimension(B_WIDTH,B_HEIGHT)); @@ -64,30 +74,70 @@ public class Board extends JPanel implements ActionListener { actions++; } } + painter.paintWinnerLine(g); } + public void resetBoard(){ + for (int i = 0; i < game.getPlayfield().length; i++){ + game.setPlayfield(i, 0); + timer.start(); + oldPlayfield = game.getPlayfield().clone(); + game.setTurnTaken(false); + } + repaint(); + } + + public void setWinningLine(){ + painter.setWinningX1(game.getWinningX1()); + painter.setWinningY1(game.getWinningY1()); + painter.setWinningX2(game.getWinningX2()); + painter.setWinningY2(game.getWinningY2()); + } + + //game controlling method @Override public void actionPerformed(ActionEvent e) { - if (!game.checkWin() && isChanged(oldPlayfield)){ - repaint(); - oldPlayfield = game.getPlayfield().clone(); - System.out.println(2); - } else if (game.checkWin()){ - repaint(); - } + Thread actionThread = new Thread(){ + @Override + public void run() { + //check if game state evaluation needs to be done + if (isChanged(oldPlayfield)) { + gameWon = game.checkWin(); + //repaint board if not won + if (!gameWon) { + repaint(); + oldPlayfield = game.getPlayfield().clone(); + } + //stop timer if game won + else if (gameWon || game.emptyTiles() == 0) { + setWinningLine(); + repaint(); + timer.stop(); + System.out.println("Game ended"); + try { + Thread.sleep(1000); + int n = JOptionPane.showConfirmDialog(null, "Do you want to play again?"); + if (n == 0){ + resetBoard(); + } else { + System.exit(0); + } + } catch (InterruptedException interruptedException) { + interruptedException.printStackTrace(); + } + } + } + //check if computer needs to take a turn + if (game.isTurnTaken() && game.emptyTiles() != 0){ + game.setTurnTaken(false); + game.computersTurn(); + } + } + }; + actionThread.start(); } private boolean isChanged(int[] playfield){ return !Arrays.equals(game.getPlayfield(), playfield); } - - private class MAdapter extends MouseAdapter{ - @Override - public void mouseClicked(MouseEvent e) { - super.mouseClicked(e); - int column = e.getX()/TILE_X; - int row = e.getY()/TILE_Y; - game.setPlayfield(column * 3 + row, 1); - } - } } diff --git a/TicTacToe - MinMax/src/Executor.java b/TicTacToe - MinMax/src/Executor.java index 7734b07..881fc69 100644 --- a/TicTacToe - MinMax/src/Executor.java +++ b/TicTacToe - MinMax/src/Executor.java @@ -15,7 +15,12 @@ public class Executor extends JFrame { } public static void main(String[] args) { - Executor exc = new Executor(); - exc.setVisible(true); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + Executor exc = new Executor(); + exc.setVisible(true); + } + }); } } diff --git a/TicTacToe - MinMax/src/Game.java b/TicTacToe - MinMax/src/Game.java index 45c6d72..8eec455 100644 --- a/TicTacToe - MinMax/src/Game.java +++ b/TicTacToe - MinMax/src/Game.java @@ -1,36 +1,69 @@ import javax.swing.*; +import java.awt.*; public class Game { - int[] playfield; + private int[] playfield; + private boolean turnTaken = false; + private int winningX1,winningY1,winningX2,winningY2; public Game(){ playfield = new int[9]; } - public void place(int player, int position){ - if (playfield[position] == -1){ + public void place(int position, int player){ + if (playfield[position] == 0){ playfield[position] = player; + if (player == 1) { + turnTaken = true; + } } else { - JOptionPane.showConfirmDialog(null,"Tile is already taken"); + JOptionPane.showInternalMessageDialog(null,"Tile is already taken"); + } + } + + public void computersTurn(){ + boolean isPlaced = false; + try { + Thread.sleep(750); + } catch (InterruptedException e) { + e.printStackTrace(); + } + while(!isPlaced){ + int random = (int) (Math.random() * (8 - 0 + 1) + 0); + System.out.println(random); + // if field is free + if (playfield[random] == 0) { + place(random, -1); + isPlaced = true; + } } } public boolean checkWin() { + //only check if winning is possible if (emptyTiles() < 5) { for (int i = 0; i < 3; i++) { - if ((playfield[i] == playfield[i + 3]) && (playfield[i] == playfield[i + 6])) { - System.out.println("vertical"); + //horizontal + if ((playfield[i] == playfield[i + 3] && playfield[i] != 0) && (playfield[i] == playfield[i + 6])) { + winningX1 = 0; + winningX2 = 3; + winningY1 = winningY2 = i; return true; - } else if ((playfield[i * 3] == playfield[i * 3 + 1]) && (playfield[i * 3] == playfield[i * 3 + 2])) { - System.out.println("horizontal"); + } + //vertical + else if ((playfield[i * 3] == playfield[i * 3 + 1] && playfield[i * 3] != 0) && (playfield[i * 3] == playfield[i * 3 + 2])) { + winningX1 = winningX2 = i; + winningY1 = 0; + winningY2 = 3; return true; } } - return (playfield[2] == playfield[4]) && (playfield[2] == playfield[6]) || (playfield[0] == playfield[4]) && (playfield[0] == playfield[8]); - } else { - return false; + //diagonal + return (playfield[2] == playfield[4] && playfield[2] != 0) && (playfield[2] == playfield[6]) || + (playfield[0] == playfield[4] && playfield[0] != 0) && (playfield[0] == playfield[8]); } + return false; } public int emptyTiles(){ @@ -43,6 +76,14 @@ public class Game { return n; } + public boolean isTurnTaken() { + return turnTaken; + } + + public void setTurnTaken(boolean turnTaken) { + this.turnTaken = turnTaken; + } + public void setPlayfield(int position, int value) { playfield[position] = value; } @@ -50,4 +91,20 @@ public class Game { public int[] getPlayfield() { return playfield; } + + public int getWinningX1() { + return winningX1; + } + + public int getWinningX2() { + return winningX2; + } + + public int getWinningY1() { + return winningY1; + } + + public int getWinningY2() { + return winningY2; + } } diff --git a/TicTacToe - MinMax/src/Painter.java b/TicTacToe - MinMax/src/Painter.java index 1229a36..362be4d 100644 --- a/TicTacToe - MinMax/src/Painter.java +++ b/TicTacToe - MinMax/src/Painter.java @@ -5,9 +5,11 @@ public class Painter { private final int TILE_X; private final int TILE_Y; + private int winningX1, winningY1, winningX2, winningY2; + public Painter(int boardWidth, int boardHeight){ TILE_X = boardWidth/3; - TILE_Y = boardWidth/3; + TILE_Y = boardHeight/3; } public void drawX(Graphics g, int column, int row) { @@ -45,4 +47,28 @@ public class Painter { g2d.drawLine(TILE_X*i, 0, TILE_X*i, TILE_Y*3); } } + + public void paintWinnerLine(Graphics g){ + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(Color.RED); + g2d.setStroke(new BasicStroke(40)); + System.out.println(winningX1 + ", " + winningY1 + ", " + winningX2 + ", " + winningY2); + g2d.drawLine(winningX1 * 300 + 150, winningY1 * 300 + 150, winningX2 * 300 + 150, winningY2 * 300 + 150); + } + + public void setWinningX1(int winningX1) { + this.winningX1 = winningX1; + } + + public void setWinningX2(int winningX2) { + this.winningX2 = winningX2; + } + + public void setWinningY1(int winningY1) { + this.winningY1 = winningY1; + } + + public void setWinningY2(int winningY2) { + this.winningY2 = winningY2; + } } diff --git a/out/production/TicTacToe - MinMax/Board$1.class b/out/production/TicTacToe - MinMax/Board$1.class new file mode 100644 index 0000000..9068526 Binary files /dev/null and b/out/production/TicTacToe - MinMax/Board$1.class differ diff --git a/out/production/TicTacToe - MinMax/Board$2.class b/out/production/TicTacToe - MinMax/Board$2.class new file mode 100644 index 0000000..354d8c2 Binary files /dev/null and b/out/production/TicTacToe - MinMax/Board$2.class differ diff --git a/out/production/TicTacToe - MinMax/Board$MAdapter.class b/out/production/TicTacToe - MinMax/Board$MAdapter.class deleted file mode 100644 index 27fad55..0000000 Binary files a/out/production/TicTacToe - MinMax/Board$MAdapter.class and /dev/null differ diff --git a/out/production/TicTacToe - MinMax/Board.class b/out/production/TicTacToe - MinMax/Board.class index 2e48455..6551498 100644 Binary files a/out/production/TicTacToe - MinMax/Board.class and b/out/production/TicTacToe - MinMax/Board.class differ diff --git a/out/production/TicTacToe - MinMax/Executor$1.class b/out/production/TicTacToe - MinMax/Executor$1.class new file mode 100644 index 0000000..0b1bd9f Binary files /dev/null and b/out/production/TicTacToe - MinMax/Executor$1.class differ diff --git a/out/production/TicTacToe - MinMax/Executor.class b/out/production/TicTacToe - MinMax/Executor.class index 0e3030b..02da93f 100644 Binary files a/out/production/TicTacToe - MinMax/Executor.class and b/out/production/TicTacToe - MinMax/Executor.class differ diff --git a/out/production/TicTacToe - MinMax/Game.class b/out/production/TicTacToe - MinMax/Game.class index 296314f..ed55504 100644 Binary files a/out/production/TicTacToe - MinMax/Game.class and b/out/production/TicTacToe - MinMax/Game.class differ diff --git a/out/production/TicTacToe - MinMax/Painter.class b/out/production/TicTacToe - MinMax/Painter.class index 78f6409..1a2512f 100644 Binary files a/out/production/TicTacToe - MinMax/Painter.class and b/out/production/TicTacToe - MinMax/Painter.class differ