Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *
- * Gjorts i par, Lucas Fransman 42289 & Maxemilian Grönblom 42047-25-2017
- *
- */
- import java.awt.*;
- import java.awt.event.*;
- import java.util.Arrays;
- import java.util.HashSet;
- import javax.swing.*;
- class Move {
- int val; int row; int col;
- public Move(int v, int r, int c) {
- val=v; row=r; col=c;
- }
- }
- // Class Button extends JButton with (x,y) coordinates
- class Button extends javax.swing.JButton {
- public int i; // The x- and y- coordinate of the button in a GridLayout
- public int j;
- public Button (int x, int y) {
- super(); // Create a JButton with a blank icon
- super.setIcon(new javax.swing.ImageIcon(getClass().getResource("/None.png")));
- this.i = x;
- this.j = y;
- }
- // Return row coordinate
- public int get_i () {
- return i;
- }
- // Return column coordinate
- public int get_j () {
- return j;
- }
- }
- public class LSv2 extends javax.swing.JFrame {
- public static final int EMPTY = 0;
- public static final int HUMAN = 1;
- public static final int COMPUTER = 2;
- public static final int HUMAN_WIN = 4;
- public static final int DRAW = 5;
- public static final int CONTINUE = 6;
- public static final int COMPUTER_WIN = 7;
- public static final int MAXDEPTH = Integer.MAX_VALUE;
- public static final int SIZE = 3;
- private int[][] board = new int[SIZE][SIZE]; // The marks on the board
- private javax.swing.JButton[][] jB; // The buttons of the board
- private static long count = 0;
- private int turn = HUMAN; // HUMAN starts the game
- private Move compMove = null;
- private Move humanMove;
- public static boolean canCorner = true;
- /* Constructor for the Tic Tac Toe game */
- public LSv2() {
- // Close the window when the user exits
- setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
- initBoard(); // Set up the board
- }
- // Initalize the board
- private void initBoard(){
- // Create a 3*3 gridlayput to hold the buttons
- java.awt.GridLayout layout = new GridLayout(3, 3);
- getContentPane().setLayout(layout);
- // The board is a 3*3 grid of buttons
- jB = new Button[SIZE][SIZE];
- for (int i=0; i<SIZE; i++) {
- for (int j=0; j<SIZE; j++) {
- // Create a new button and add an actionListerner to it
- jB[i][j] = new Button(i,j);
- // Add an action listener to the button to handle mouse clicks
- jB[i][j].addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent act) {
- jBAction(act);
- }
- });
- add(jB[i][j]); // Add the buttons to the GridLayout
- board[i][j] = EMPTY; // Initialize all marks on the board to empty
- }
- }
- // Pack the GridLayout and make it visible
- pack();
- }
- // Action listener which handles mouse clicks on the buttons
- private void jBAction(java.awt.event.ActionEvent act) {
- Button thisButton = (Button) act.getSource(); // Get the button clicked on
- // Get the grid coordinates of the clicked button
- int i = thisButton.get_i();
- int j = thisButton.get_j();
- if (!isEmpty(board[i][j])) {
- JOptionPane.showMessageDialog(null, "Cannot override that");
- return;
- }
- System.out.println("Button[" + i + "][" + j + "] was clicked by " + turn); // DEBUG
- // Set an X or O mark in the clicked button
- if (turn == HUMAN) {
- thisButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/X.png")));
- }
- if (turn == COMPUTER) {
- thisButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/O.png")));
- }
- place (i, j, turn); // Mark the move on the board
- // Give the turn to the opponent
- turn = (turn == HUMAN) ? COMPUTER : HUMAN;
- // Check if we are done
- if (isGameOver()) {
- String winner = checkResult() == DRAW ? "It is a draw" : checkResult() == COMPUTER_WIN ? "The winner is: Computer" : "The winner is: Human";
- JOptionPane.showMessageDialog(null, winner);
- return;
- }
- if (turn == COMPUTER) {
- makeComputerMove();
- }
- }
- private void makeComputerMove() {
- Move directWin = checkTerminal();
- Move directLoss = checkBlock();
- Move optimalMove = getMove();
- // if (isEmpty(board[1][1])) {
- // jB[1][1].doClick();
- // return;
- // } else {
- if (directWin != null) { compMove = directWin;}
- else if (directLoss != null) { compMove = directLoss;}
- else { compMove = optimalMove;}
- //if (directWin == null && directLoss == null) test = minMax(COMPUTER, MAXDEPTH);
- //System.out.println(test);
- //System.out.println(compMove.row + " " + compMove.col);
- System.out.println("I made it through");
- System.out.println(compMove.row + " " + compMove.col);
- jB[compMove.row][compMove.col].doClick();
- }
- private Move getMove() {
- int value = 0;
- Move move = null;
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (isEmpty(board[i][j])) {
- place(i, j, COMPUTER);
- int newValue = checkResultPlusOne();
- System.out.println(newValue);
- if(newValue > value) {
- value = newValue;
- move = new Move(0, i, j);
- }
- unplace(i, j);
- }
- }
- }
- if(move != null)
- return move;
- else {
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (isEmpty(board[i][j])) {
- move = new Move(0, i, j);
- }
- }
- }
- return move;
- }
- }
- private int checkResultPlusOne() {
- return getValue(0) - getValue(1); // 1 = human 0 = computer
- }
- private int getValue(int check) { // check = 0 = Computer, check = 1 = Human
- int state;
- int toCheckFor;
- if(check == 0) {
- state = COMPUTER;
- toCheckFor = COMPUTER_WIN;
- } else {
- state = HUMAN;
- toCheckFor = HUMAN_WIN;
- }
- int returnValue = 0;
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (isEmpty(board[i][j]) && state == HUMAN) {
- place(i, j, state);
- for (int x = 0; x < SIZE; x++) {
- for (int y = 0; y < SIZE; y++) {
- if (isEmpty(board[x][y])) {
- place(x, y, state);
- if(checkResult() == toCheckFor) {
- returnValue++;
- }
- unplace(x, y);
- }
- }
- }
- unplace(i, j);
- } else if(isEmpty(board[i][j])) {
- for (int x = 0; x < SIZE; x++) {
- for (int y = 0; y < SIZE; y++) {
- if (isEmpty(board[x][y])) {
- place(x, y, state);
- if(checkResult() == toCheckFor) {
- returnValue++;
- }
- unplace(x, y);
- }
- }
- }
- }
- }
- }
- return returnValue;
- }
- private boolean isFull() {
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (board[i][j] == EMPTY) return false;
- }
- }
- return true;
- }
- private int minMax(int turn, int depth) {
- if (depth == 0 || isGameOver()) {
- return getScore(turn);
- }
- if (turn == COMPUTER) {
- return getCompMove(depth, turn);
- } else {
- return getHumanMove(depth, turn);
- }
- }
- private int getCompMove(int currentDepth, int turn) {
- int value = Integer.MIN_VALUE;
- int humanValue;
- for (int row = 0; row < SIZE; row++) {
- for (int col = 0; col < SIZE; col++) {
- if (isEmpty(board[row][col])) {
- place(row, col, COMPUTER);
- humanValue = minMax(HUMAN, currentDepth++);
- unplace(row, col);
- if (humanValue >= value) {
- value = humanValue;
- compMove = new Move(value, row, col);
- }
- }
- }
- }
- return value;
- }
- private int getHumanMove(int currentDepth, int turn) {
- int value = Integer.MAX_VALUE;
- int compValue;
- for (int row = 0; row < SIZE; row++) {
- for (int col = 0; col < SIZE; col++) {
- if (isEmpty(board[row][col])) {
- place(row, col, HUMAN);
- compValue = minMax(COMPUTER, currentDepth++);
- unplace(row, col);
- if (compValue <= value) {
- value = compValue;
- humanMove = new Move(value, row, col);
- }
- }
- }
- }
- return value;
- }
- private Move checkTerminal() {
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (isEmpty(board[i][j])) {
- place(i, j, COMPUTER);
- if (checkResult() == COMPUTER_WIN) {
- Move move = new Move(10, i, j);
- unplace(i, j);
- compMove = move;
- return move;
- }
- unplace(i, j);
- }
- }
- }
- return null;
- }
- private Move checkBlock() {
- for (int i = 0; i < SIZE; i++) {
- for (int j = 0; j < SIZE; j++) {
- if (isEmpty(board[i][j])) {
- place(i, j, HUMAN);
- if (checkResult() == HUMAN_WIN) {
- Move move = new Move(10, i, j);
- unplace(i, j);
- compMove = move;
- return move;
- }
- unplace(i, j);
- }
- }
- }
- return null;
- }
- private int getScore(int turn) {
- int result = checkResult();
- System.out.println(result);
- if (result == COMPUTER_WIN) {
- return 10;
- } else if (result != COMPUTER_WIN) {
- return -10;
- } else {
- return 0;
- }
- }
- private boolean isEmpty(int place) {
- return place == EMPTY;
- }
- public static int[][] deepCopy(int[][] original) {
- if (original == null) {
- return null;
- }
- final int[][] result = new int[original.length][];
- for (int i = 0; i < original.length; i++) {
- result[i] = Arrays.copyOf(original[i], original[i].length);
- // For Java versions prior to Java 6 use the next:
- // System.arraycopy(original[i], 0, result[i], 0, original[i].length);
- }
- return result;
- }
- private boolean isGameOver() {
- return checkResult() != CONTINUE;
- }
- private int checkResult() {
- // Check rows
- for (int row = 0; row < SIZE; row++) {
- for (int col = 1; col < SIZE; col++) {
- if (board[row][col] == EMPTY) break;
- if (board[row][col] != board[row][col - 1]) break;
- if (col == SIZE -1) {
- return board[row][col] == COMPUTER ? COMPUTER_WIN : HUMAN_WIN;
- }
- }
- }
- // Check columns
- for (int col = 0; col < SIZE; col++) {
- for (int row = 1; row < SIZE; row++) {
- if (board[row][col] == EMPTY) break;
- if (board[row][col] != board[row - 1][col]) break;
- if (row == SIZE -1) {
- return board[row][col] == COMPUTER ? COMPUTER_WIN : HUMAN_WIN;
- }
- }
- }
- // Check top left diagonal
- for (int i = 1; i < SIZE; i++) {
- if (board[i][i] == EMPTY) break;
- if (board[i][i] != board[i - 1][i - 1]) break;
- if (i == SIZE - 1) {
- return board[i][i] == COMPUTER ? COMPUTER_WIN : HUMAN_WIN;
- }
- }
- // Check the top right diagonal
- if (board[0][2] != EMPTY && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
- return board[0][2] == COMPUTER ? COMPUTER_WIN : HUMAN_WIN;
- }
- if (isFull()) return DRAW;
- return CONTINUE;
- }
- // Place a mark in the specified position
- public void place (int row, int col, int player){
- board [row][col] = player;
- }
- public void unplace(int row, int col) {
- place(row, col, EMPTY);
- }
- public static void main (String [] args){
- String threadName = Thread.currentThread().getName();
- LSv2 lsGUI = new LSv2(); // Create a new user inteface for the game
- lsGUI.setVisible(true);
- java.awt.EventQueue.invokeLater (new Runnable() {
- public void run() {
- while ( (Thread.currentThread().getName() == threadName) && (lsGUI.checkResult() == CONTINUE) ){
- try {
- Thread.sleep(100); // Sleep for 100 millisecond, wait for button press
- } catch (InterruptedException e) { };
- }
- }
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement