Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.02 KB | None | 0 0
  1. /*
  2.  *
  3.  * Gjorts i par, Lucas Fransman 42289 & Maxemilian Grönblom 42047-25-2017
  4.  *
  5.  */
  6.  
  7. import java.awt.*;
  8. import java.awt.event.*;
  9. import java.util.Arrays;
  10. import java.util.HashSet;
  11.  
  12. import javax.swing.*;
  13.  
  14. class Move {
  15.     int val; int row; int col;
  16.     public Move(int v, int r, int c) {
  17.     val=v; row=r; col=c;
  18.     }
  19. }
  20.  
  21. // Class Button extends JButton with (x,y) coordinates
  22. class Button extends javax.swing.JButton {
  23.     public int i;   // The x- and y- coordinate of the button in a GridLayout
  24.     public int j;
  25.  
  26.     public Button (int x, int y) {
  27.     super();      // Create a JButton with a blank icon
  28.     super.setIcon(new javax.swing.ImageIcon(getClass().getResource("/None.png")));
  29.     this.i = x;
  30.     this.j = y;
  31.     }
  32.  
  33.     // Return row coordinate
  34.     public int get_i () {
  35.     return i;
  36.     }
  37.  
  38.     // Return column coordinate
  39.     public int get_j () {
  40.     return j;
  41.     }
  42.  
  43. }
  44.  
  45. public class LSv2 extends javax.swing.JFrame {
  46.    
  47.     public static final int EMPTY    = 0;
  48.     public static final int HUMAN    = 1;
  49.     public static final int COMPUTER = 2;
  50.    
  51.     public static final int HUMAN_WIN    = 4;
  52.     public static final int DRAW         = 5;
  53.     public static final int CONTINUE     = 6;
  54.     public static final int COMPUTER_WIN = 7;
  55.    
  56.     public static final int MAXDEPTH = Integer.MAX_VALUE;
  57.    
  58.     public static final int SIZE = 3;
  59.     private int[][] board = new int[SIZE][SIZE];  // The marks on the board
  60.     private javax.swing.JButton[][] jB;           // The buttons of the board
  61.     private static long count = 0;
  62.     private int turn = HUMAN;                    // HUMAN starts the game
  63.     private Move compMove = null;
  64.     private Move humanMove;
  65.    
  66.     public static boolean canCorner = true;
  67.  
  68.     /* Constructor for the Tic Tac Toe game */
  69.     public LSv2() {
  70.         // Close the window when the user exits
  71.         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  72.         initBoard();      // Set up the board
  73.     }
  74.  
  75.     // Initalize the board
  76.     private void initBoard(){
  77.         // Create a 3*3 gridlayput to hold the buttons
  78.         java.awt.GridLayout layout = new GridLayout(3, 3);
  79.         getContentPane().setLayout(layout);
  80.    
  81.         // The board is a 3*3 grid of buttons
  82.         jB = new Button[SIZE][SIZE];
  83.         for (int i=0; i<SIZE; i++) {
  84.             for (int j=0; j<SIZE; j++) {
  85.             // Create a new button and add an actionListerner to it
  86.             jB[i][j] = new Button(i,j);
  87.             // Add an action listener to the button to handle mouse clicks
  88.             jB[i][j].addActionListener(new java.awt.event.ActionListener() {
  89.                 public void actionPerformed(java.awt.event.ActionEvent act) {
  90.                     jBAction(act);
  91.                 }
  92.                 });
  93.             add(jB[i][j]);   // Add the buttons to the GridLayout
  94.            
  95.             board[i][j] = EMPTY;     // Initialize all marks on the board to empty
  96.             }
  97.         }
  98.        
  99.         // Pack the GridLayout and make it visible
  100.         pack();
  101.     }
  102.  
  103.     // Action listener which handles mouse clicks on the buttons
  104.     private void jBAction(java.awt.event.ActionEvent act) {
  105.         Button thisButton = (Button) act.getSource();   // Get the button clicked on
  106.         // Get the grid coordinates of the clicked button
  107.         int i = thisButton.get_i();
  108.         int j = thisButton.get_j();
  109.         if (!isEmpty(board[i][j])) {
  110.             JOptionPane.showMessageDialog(null, "Cannot override that");
  111.             return;
  112.         }
  113.         System.out.println("Button[" + i + "][" + j + "] was clicked by " + turn);  // DEBUG
  114.        
  115.         // Set an X or O mark in the clicked button
  116.         if (turn == HUMAN) {
  117.             thisButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/X.png")));
  118.         }
  119.         if (turn == COMPUTER) {
  120.             thisButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/O.png")));
  121.         }
  122.         place (i, j, turn);    // Mark the move on the board
  123.         // Give the turn to the opponent
  124.         turn = (turn == HUMAN) ? COMPUTER : HUMAN;
  125.        
  126.         // Check if we are done
  127.         if (isGameOver()) {
  128.             String winner = checkResult() == DRAW ? "It is a draw" : checkResult() == COMPUTER_WIN ? "The winner is: Computer" : "The winner is: Human";
  129.             JOptionPane.showMessageDialog(null, winner);
  130.             return;
  131.         }
  132.         if (turn == COMPUTER) {
  133.             makeComputerMove();
  134.         }
  135.     }
  136.    
  137.     private void makeComputerMove() {
  138.        
  139.         Move directWin = checkTerminal();
  140.         Move directLoss = checkBlock();
  141.         Move optimalMove = getMove();
  142.    
  143. //        if (isEmpty(board[1][1])) {
  144. //            jB[1][1].doClick();
  145. //            return;
  146. //        } else {
  147.             if (directWin != null) { compMove = directWin;}
  148.             else if (directLoss != null) { compMove = directLoss;}
  149.             else { compMove = optimalMove;}
  150.             //if (directWin == null && directLoss == null) test = minMax(COMPUTER, MAXDEPTH);
  151.             //System.out.println(test);
  152.             //System.out.println(compMove.row + " " + compMove.col);
  153.             System.out.println("I made it through");
  154.            
  155.             System.out.println(compMove.row + "   " + compMove.col);
  156.            
  157.             jB[compMove.row][compMove.col].doClick();
  158.        
  159.     }
  160.    
  161.     private Move getMove() {
  162.        
  163.         int value = 0;
  164.         Move move = null;
  165.        
  166.          for (int i = 0; i < SIZE; i++) {
  167.              for (int j = 0; j < SIZE; j++) {
  168.                  
  169.                  if (isEmpty(board[i][j])) {
  170.                    
  171.                      place(i, j, COMPUTER);
  172.                      
  173.                      int newValue = checkResultPlusOne();
  174.                      
  175.                      System.out.println(newValue);
  176.                      
  177.                      if(newValue > value) {
  178.                          
  179.                          value = newValue;
  180.                          move = new Move(0, i, j);
  181.                                  
  182.                      }
  183.                      
  184.                     unplace(i, j);
  185.                    
  186.                  }
  187.                  
  188.              }
  189.          }
  190.          
  191.          if(move != null)
  192.              return move;
  193.          else {
  194.  
  195.              for (int i = 0; i < SIZE; i++) {
  196.                  for (int j = 0; j < SIZE; j++) {
  197.                      
  198.                      if (isEmpty(board[i][j])) {
  199.                          move = new Move(0, i, j);
  200.                      }
  201.                      
  202.                  }
  203.              }
  204.              return move;
  205.          }
  206.     }
  207.  
  208.     private int checkResultPlusOne() {
  209.        
  210.         return getValue(0) - getValue(1); // 1 = human 0 = computer
  211.        
  212.     }
  213.  
  214.     private int getValue(int check) { // check = 0 = Computer, check = 1 = Human
  215.        
  216.         int state;
  217.         int toCheckFor;
  218.        
  219.         if(check == 0) {
  220.             state = COMPUTER;
  221.             toCheckFor = COMPUTER_WIN;
  222.         } else {
  223.             state = HUMAN;
  224.             toCheckFor = HUMAN_WIN;
  225.         }
  226.        
  227.         int returnValue = 0;
  228.        
  229.         for (int i = 0; i < SIZE; i++) {
  230.             for (int j = 0; j < SIZE; j++) {
  231.                
  232.                 if (isEmpty(board[i][j]) && state == HUMAN) {
  233.                    
  234.                     place(i, j, state);
  235.                    
  236.                     for (int x = 0; x < SIZE; x++) {
  237.                         for (int y = 0; y < SIZE; y++) {
  238.                            
  239.                             if (isEmpty(board[x][y])) {
  240.                                 place(x, y, state);
  241.                            
  242.                             if(checkResult() == toCheckFor) {
  243.                                 returnValue++;
  244.                             }
  245.                            
  246.                             unplace(x, y);
  247.                            
  248.                             }
  249.                         }
  250.                     }
  251.                    
  252.                     unplace(i, j);
  253.                    
  254.                 } else if(isEmpty(board[i][j])) {
  255.                    
  256.                     for (int x = 0; x < SIZE; x++) {
  257.                         for (int y = 0; y < SIZE; y++) {
  258.                            
  259.                             if (isEmpty(board[x][y])) {
  260.                                 place(x, y, state);
  261.                            
  262.                            
  263.                             if(checkResult() == toCheckFor) {
  264.                                 returnValue++;
  265.                             }
  266.                            
  267.                             unplace(x, y);
  268.                            
  269.                             }
  270.                         }
  271.                     }
  272.                    
  273.                    
  274.                 }
  275.             }
  276.          }
  277.         return returnValue;
  278.     }
  279.  
  280.  
  281.     private boolean isFull() {
  282.         for (int i = 0; i < SIZE; i++) {
  283.             for (int j = 0; j < SIZE; j++) {
  284.                 if (board[i][j] == EMPTY) return false;
  285.             }
  286.         }
  287.         return true;
  288.     }
  289.    
  290.     private int minMax(int turn, int depth) {
  291.         if (depth == 0 || isGameOver()) {
  292.             return getScore(turn);
  293.         }
  294.        
  295.         if (turn == COMPUTER) {
  296.             return getCompMove(depth, turn);
  297.         } else {
  298.             return getHumanMove(depth, turn);
  299.         }
  300.        
  301.     }
  302.    
  303.     private int getCompMove(int currentDepth, int turn) {
  304.         int value = Integer.MIN_VALUE;
  305.         int humanValue;
  306.        
  307.         for (int row = 0; row < SIZE; row++) {
  308.             for (int col = 0; col < SIZE; col++) {
  309.                 if (isEmpty(board[row][col])) {
  310.                     place(row, col, COMPUTER);
  311.                     humanValue = minMax(HUMAN, currentDepth++);
  312.                     unplace(row, col);
  313.                    
  314.                     if (humanValue >= value) {
  315.                         value = humanValue;
  316.                         compMove = new Move(value, row, col);
  317.                     }
  318.                 }
  319.             }
  320.         }
  321.  
  322.         return value;
  323.     }
  324.    
  325.     private int getHumanMove(int currentDepth, int turn) {
  326.         int value = Integer.MAX_VALUE;
  327.         int compValue;
  328.        
  329.         for (int row = 0; row < SIZE; row++) {
  330.             for (int col = 0; col < SIZE; col++) {
  331.                 if (isEmpty(board[row][col])) {
  332.                     place(row, col, HUMAN);
  333.                     compValue = minMax(COMPUTER, currentDepth++);
  334.                     unplace(row, col);
  335.                    
  336.                     if (compValue <= value) {
  337.                         value = compValue;
  338.                         humanMove = new Move(value, row, col);
  339.                     }
  340.                 }
  341.             }
  342.         }
  343.        
  344.         return value;
  345.     }
  346.    
  347.     private Move checkTerminal() {
  348.         for (int i = 0; i < SIZE; i++) {
  349.             for (int j = 0; j < SIZE; j++) {
  350.                 if (isEmpty(board[i][j])) {
  351.                     place(i, j, COMPUTER);
  352.                     if (checkResult() == COMPUTER_WIN) {
  353.                         Move move = new Move(10, i, j);
  354.                         unplace(i, j);
  355.                         compMove = move;
  356.                         return move;
  357.                     }
  358.                     unplace(i, j);
  359.                 }
  360.             }
  361.         }
  362.        
  363.         return null;
  364.     }
  365.    
  366.     private Move checkBlock() {
  367.         for (int i = 0; i < SIZE; i++) {
  368.             for (int j = 0; j < SIZE; j++) {
  369.                 if (isEmpty(board[i][j])) {
  370.                     place(i, j, HUMAN);
  371.                     if (checkResult() == HUMAN_WIN) {
  372.                         Move move = new Move(10, i, j);
  373.                         unplace(i, j);
  374.                         compMove = move;
  375.                         return move;
  376.                     }
  377.                     unplace(i, j);
  378.                 }
  379.             }
  380.         }
  381.        
  382.         return null;
  383.     }
  384.    
  385.     private int getScore(int turn) {
  386.         int result = checkResult();
  387.         System.out.println(result);
  388.         if (result == COMPUTER_WIN) {
  389.             return 10;
  390.         } else if (result != COMPUTER_WIN) {
  391.             return -10;
  392.         } else {
  393.             return 0;
  394.         }
  395.     }
  396.    
  397.     private boolean isEmpty(int place) {
  398.         return place == EMPTY;
  399.     }
  400.    
  401.     public static int[][] deepCopy(int[][] original) {
  402.         if (original == null) {
  403.             return null;
  404.         }
  405.  
  406.         final int[][] result = new int[original.length][];
  407.         for (int i = 0; i < original.length; i++) {
  408.             result[i] = Arrays.copyOf(original[i], original[i].length);
  409.             // For Java versions prior to Java 6 use the next:
  410.             // System.arraycopy(original[i], 0, result[i], 0, original[i].length);
  411.         }
  412.         return result;
  413.     }
  414.    
  415.     private boolean isGameOver() {
  416.         return checkResult() != CONTINUE;
  417.     }
  418.  
  419.     private int checkResult() {
  420.         // Check rows
  421.         for (int row = 0; row < SIZE; row++) {
  422.             for (int col = 1; col < SIZE; col++) {
  423.                 if (board[row][col] == EMPTY) break;
  424.                 if (board[row][col] != board[row][col - 1]) break;
  425.                 if (col == SIZE -1) {
  426.                     return board[row][col] == COMPUTER ? COMPUTER_WIN : HUMAN_WIN;
  427.                 }
  428.             }
  429.         }
  430.         // Check columns
  431.         for (int col = 0; col < SIZE; col++) {
  432.             for (int row = 1; row < SIZE; row++) {
  433.                 if (board[row][col] == EMPTY) break;
  434.                 if (board[row][col] != board[row - 1][col]) break;
  435.                 if (row == SIZE -1) {
  436.                     return board[row][col] == COMPUTER ? COMPUTER_WIN : HUMAN_WIN;
  437.                 }
  438.             }
  439.         }
  440.         // Check top left diagonal
  441.         for (int i = 1; i < SIZE; i++) {
  442.             if (board[i][i] == EMPTY) break;
  443.             if (board[i][i] != board[i - 1][i - 1]) break;
  444.             if (i == SIZE - 1) {
  445.                 return board[i][i] == COMPUTER ?  COMPUTER_WIN : HUMAN_WIN;
  446.  
  447.             }
  448.         }
  449.         // Check the top right diagonal
  450.         if (board[0][2] != EMPTY && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
  451.             return board[0][2] == COMPUTER ?  COMPUTER_WIN : HUMAN_WIN;
  452.         }
  453.        
  454.         if (isFull()) return DRAW;
  455.        
  456.         return CONTINUE;
  457.     }
  458.    
  459.     // Place a mark in the specified position
  460.     public void place (int row, int col, int player){
  461.         board [row][col] = player;
  462.     }
  463.    
  464.     public void unplace(int row, int col) {
  465.         place(row, col, EMPTY);
  466.     }
  467.  
  468.    
  469.     public static void main (String [] args){
  470.  
  471.         String threadName = Thread.currentThread().getName();
  472.         LSv2 lsGUI = new LSv2();      // Create a new user inteface for the game
  473.         lsGUI.setVisible(true);
  474.        
  475.         java.awt.EventQueue.invokeLater (new Runnable() {
  476.             public void run() {
  477.                 while ( (Thread.currentThread().getName() == threadName) && (lsGUI.checkResult() == CONTINUE) ){
  478.                     try {
  479.                         Thread.sleep(100);  // Sleep for 100 millisecond, wait for button press
  480.                     } catch (InterruptedException e) { };
  481.                 }
  482.             }
  483.         });
  484.  
  485.     }
  486. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement