title: Processing: Tic Tac Toe minimax algorithm
body: <p>I am currently working on a schoolproject. I am developing a classic Tic-Tac-Toe Player vs. Computer in Processing.</p>
  <p>My issue: I have tried to declare the minimax algorithm, however the Computer still follows a loop when making the next move instead of finding the best move. The minimax algorithm is in the Computer class.</p>
  <p>Here are my classes:</p>
  <pre><code>Square[][] grid; //field
  int row, col,turns;
  float h,w,x,y; // used variables in methods
  int scoreP = 0; // scorecounter player 1
  int scoreC = 0; // scorecounter computer
  String[] players = {&quot;X&quot;,&quot;O&quot;}; 
  String winner;
  String currentPlayer;
  boolean play;
  float w_button = 200;            // play again button
  float h_button = 40;
  float x_button = 200;
  float y_button = 650;
  
  
  void setup(){
    size(602,700);  
    row=3;
    col=3;
    
    grid = new Square[row][col];
    startGame();
    
   }
  
    void draw(){ 
    textSize(30);
    text(&quot;Player: &quot; + scoreP, 20, 25); 
    fill(255);
    
    textSize(30);
    text(&quot;Computer: &quot; + scoreC, 400, 25); 
    fill(255);
    
    if(play == true) {
       for(int i = 0; i &lt; row; i++){
        for(int j = 0; j &lt; col; j++){
          grid[i][j].drawSymbol();
        }
       }
       checkWinner();
       computerPlays();
       } else {
          playAgainButton();
         if(winner.equals(players[0])) {
           println(&quot;You Win&quot;);
           fill(0);
           rect(120,0, 30,30);
           scoreP += 1;
           noLoop();
         } else if (winner.equals(players[1])) {
           println(&quot;Computer Wins&quot;);
           fill(0);
           rect(555,0, 30,30);
           scoreC += 1;
           noLoop();
         } else if (winner == &quot;&quot;) {
           println(&quot;tie&quot;);
           noLoop();
         }
       }   
  }
  
  void mousePressed() {
    for(int i = 0; i &lt; row; i++){
      for(int j = 0; j &lt; col; j++){
        grid[i][j].click();
      }
    }
    
    if (mouseX &gt; x_button &amp;&amp; mouseX &lt; x_button + w_button &amp;&amp; mouseY &gt; y_button &amp;&amp; mouseY &lt; y_button + h_button){
      redraw();
      loop();
      startGame();
    }
  
  }
  
  boolean isEqual(String a, String b, String c){ // checks if 3 fields are equal
    return a == b &amp;&amp; b == c &amp;&amp; a != &quot;&quot;; 
  } 
  
  void checkWinner(){
    
    //horizontal
    for(int i = 0; i &lt; 3; i++){
      if(isEqual(grid[i][0].val,grid[i][1].val,grid[i][2].val)){
        play = false;
        winner = grid[i][0].val;
      }
      
    }
    
    //vertical
    for(int i = 0; i &lt; 3; i++){
      if(isEqual(grid[0][i].val,grid[1][i].val,grid[2][i].val)){
        play = false;
        winner = grid[0][i].val;
      }
    }
    
    //Diagonal
    if(isEqual(grid[0][0].val,grid[1][1].val,grid[2][2].val)){
      play = false;
      winner = grid[0][0].val;
    }
  
    if(isEqual(grid[2][0].val,grid[1][1].val,grid[0][2].val)){
      play = false;
      winner = grid[2][0].val;
    }
    
    if(turns == 0  &amp;&amp; winner.equals(&quot;&quot;)) {
      play = false;
    }
  }
  
  public void startGame() {
    currentPlayer = players[0];
    winner = &quot;&quot;;
    play = true;
    turns = 9;
    h = 600/3;
    w = 600/3;
    x = 0;
    y = 35;
    
    background(0);    
    
     for(int i = 0; i &lt; row; i++){
      for(int j = 0; j &lt; col; j++){
        grid[i][j] = new Square(x, y, w, h);
        x += w;  
      }
      y += h;    
      x = 0;  
     }
    }
    
    void computerPlays() {
      Computer c = new Computer();
      if(&quot;O&quot;.equals(currentPlayer) &amp;&amp;  turns != 0) {
       Move m = c.findBestMove();
        grid[m.row][m.col].val = &quot;O&quot;;
        turns--;
        currentPlayer = &quot;X&quot;;
      }
    }
    
    void playAgainButton(){
     fill(200);
     stroke(200);
     rect(x_button, y_button, w_button, h_button); 
     stroke(0);
     fill(0);
     text(&quot;PLAY AGAIN&quot;, x_button+15, y_button+30);
     fill(255);
   }
  </code></pre>
  <p>Computer class</p>
  <pre><code>public class Computer {
  
      public ArrayList&lt;Move&gt; getAvailableSpace() {
         ArrayList&lt;Move&gt; availableSpace = new ArrayList&lt;Move&gt;();
          for (int i = 0; i &lt; 3; ++i) {
              for (int j = 0; j &lt; 3; ++j) {
                  if (grid[i][j].val == &quot;&quot;) {
                      availableSpace.add(new Move(i, j));
                  }
              }
          }
          return availableSpace;
      }
      
      public int minimax() { 
        int score;
        if(winner != null) {
          if(winner == &quot;O&quot;) {
            score = 1;
            return score;
          } else if (winner == &quot;&quot;) {
            score = 0;
            return score;
          } else {
            score = -1;
            return score;
          }
        }
        int computerCount = 0;
        int humanCount = 0;
        
          for (int i = 0; i &lt; 3; ++i) {
              for (int j = 0; j &lt; 3; ++j) {
                if(grid[i][j].val == &quot;O&quot;) {
                  computerCount++;
              } else if (grid[i][j].val == &quot;X&quot;) {
                humanCount++;
              }
          }
        }
        int bestScore;
        if(humanCount &gt; computerCount) {
          bestScore = -1;
        } else {
          bestScore = 1;
        }
        
        for(Move m : getAvailableSpace()) {
          if(humanCount &gt; computerCount) {
          grid[m.row][m.col].val = &quot;O&quot;;
        } else {
          grid[m.row][m.col].val = &quot;X&quot;;
        }
        int currentScore = minimax();
        grid[m.row][m.col].val = &quot;&quot;;
          if(humanCount &gt; computerCount ? currentScore &gt; bestScore : currentScore &lt; bestScore) {
            bestScore = currentScore;
          }
        }
        return bestScore;
    }
    
    public Move findBestMove() {
      int bestScore = -100;
      Move bestMove = new Move();
      for(Move m : getAvailableSpace()) {
        grid[m.row][m.col].val = &quot;O&quot;;
        int score = minimax();
        grid[m.row][m.col].val = &quot;&quot;;
        if(score &gt; bestScore) {
          bestScore = score;
          bestMove = m;
        }
      }
     
      return bestMove;
  
    }
    
  }
  </code></pre>
  <p>Move class:</p>
  <pre><code>    public class Move {
    
    int row;
    int col;
    
    public Move() {
    }
    
    public Move(int row, int col) {
      this.row = row;
      this.col = col;
    }
    
  }
  </code></pre>
  <p>Square class</p>
  <pre><code>    public class Square {
    
    float x, y, w, h;
    String val;
    
    public Square(float x, float y, float w, float h) {
      this.h = h;
      this.w = w;
      this.x = x;
      this.y = y;  
      val = &quot;&quot;;
    }
    
    void drawSymbol() {
      rect(x, y, w, h);
      if(&quot;X&quot;.equals(val)) {
        line(this.x, this.y, this.x+this.w-1, this.y+this.w-1);
        line(this.x, this.y+this.w-1, this.x+this.w-1, this.y);
         
      } else if (&quot;O&quot;.equals(val)) {
        noFill();
        ellipse(this.x +  (this.w/2), this.y + (this.h/2),this.w,this.w);
      }
    }
    
    
    void click() {
      if(mouseX &gt; x &amp;&amp; mouseX &lt; x + w &amp;&amp; mouseY &gt; y &amp;&amp; mouseY &lt; y + h) {
        if(&quot;&quot;.equals(val) &amp;&amp; &quot;X&quot;.equals(currentPlayer)) {
            val = &quot;X&quot;;
            currentPlayer = &quot;O&quot;;
            turns--;
          }
      }  
    }
  }
  </code></pre>
  <p>What am I doing wrong?</p>