title: Implementing the minimax algorithm in C#
body: <p>I'm working on implementing minmax algorithm into a tic tac toe game as a personal learning project. I'm running into a few problems though. I have a logical error somewhere and i'm having trouble finding it. Was hoping for a spare set of eyes and brain to pick on the subject. The issue i'm having is that each consecutive time that findMove() is call it returns positions on the grid in a predictable order. mainly as follows [0,0] [0,1] [0,2] [1,0] [1,1] [1,2] [2,0] [2,1] [2,2] the only time the method returns a good move is when the computer can win in 1 move.</p>
  
  <p>[edit] I have done more testing and have determined that if the computer placed a move [0,0] for example then by the predictable pattern the computers next move would be [0,1] however if the human player takes the spot. On the next call of findMove() every condition statement is skipped and currBest is returned without ever checking it against reply from recursion</p>
  
  <p>[edit] updated and added in a scoring method to score the board for 1 in a row 2 in a row and 3 in a row.</p>
  
  <pre><code>public Best findMove(Cell[,] cells, int depth, bool Player)
  {
      Best currBest = new Best(); //my best move
      Best reply; // oponnents best move
      if (isDraw() || depth == 0)
      {
          currBest.score = evaluate();
          return currBest;
      }
      else
      {
          foreach (Cell m in cells)
          {
              if (m.value == 0)
              {
                  m.value = turn;
  
                  if (Player == true)
                  {
                      reply = findMove(cells, depth - 1, false);
                      if (reply.score &gt; currBest.score)
                      {
                          currBest.move = reply.move;
                          currBest.score = reply.score;
  
                      }
                  }
                  else
                  {
                      currBest.move = m;
                      reply = findMove(cells, depth - 1, true);
                      if (reply.score &gt; currBest.score)
                  {
                      currBest.move = reply.move;
                      currBest.score = reply.score;
  
                  }
              }
              m.value = 0;
          }
      }
  return currBest;
  }
  </code></pre>
  
  <p>And here is the evaluate method</p>
  
  <pre><code>private int evaluate()
  {
      int score = 0;
      //Evaluate score for each of the 8 lines
      score += evaluateLine(wins[0, 0], wins[1, 0], wins[2, 0]);
      score += evaluateLine(wins[0, 1], wins[1, 1], wins[2, 1]);
      score += evaluateLine(wins[0, 2], wins[1, 2], wins[2, 2]);
      score += evaluateLine(wins[0, 0], wins[0, 1], wins[0, 2]);
      score += evaluateLine(wins[1, 0], wins[1, 1], wins[1, 2]);
      score += evaluateLine(wins[2, 0], wins[2, 1], wins[2, 2]);
      score += evaluateLine(wins[0, 0], wins[1, 1], wins[2, 2]);
      score += evaluateLine(wins[2, 0], wins[1, 1], wins[0, 2]);
      return score;
  }
  </code></pre>
  
  <p>And the evaluate line method which are used for scoring the board.</p>
  
  <pre><code>private int evaluateLine(Point cell1, Point cell2, Point cell3)
  {
      int score = 0;
      int x1 = cell1.X;
      int y1 = cell1.Y;
      int x2 = cell2.X;
      int y2 = cell2.Y;
      int x3 = cell3.X;
      int y3 = cell3.Y;
      //First cell
      if (cells[x1, y1].value == 2)
      {
          score = 1;
      }
      else if (cells[x1, y1].value == 1)
      {
          score = -1;
      }
      //Second cell
      if (cells[x2, y2].value == 2)
      {
          if (score == 1) //condition only met if cell1 is O
          {
              score = 10;
          }
          else if (score == -1) //condition only met if cell1 is X
          {
              return 0;
          }
          else //condition only met if cell1 is empty
          {
              score = 1;
          }
      }
      else if (cells[x2, y2].value == 1)
      {
          if (score == -1) //condition only met if cell1 is X
          {
              score = -10;
          }
          else if (score == 1) //condition only met if cell1 is O
          {
              return 0;
          }
          else
          { //condition only met if cell1 is empty
              score = -1;
          }
      }
      else if (cells[x3, y3].value == 2)
      {
          if(score &gt; 0) //only met if cell1 or cell2 is O
          {
              score *= 10;
          }
          else if(score &lt; 0) //only met if cell1 or cell2 is X
          {
              return 0;
          }
          else //only met if cell1 and cell2 are empty
          {
              score = 1;
          }
      }
      else if (cells[x3, y3].value == 1)
      {
          if (score &gt; 0) //only met if cell1 or cell2 is X
          {
              score *= 10;
          }
          else if (score &lt; 0) //only met if cell1 or cell2 is O
          {
              return 0;
          }
          else //only met if cell1 and cell2 are empty
          {
              score = -1;
          }
      }
      return score;
  }
  </code></pre>