0

I'm trying to make a Tic-Tac-Toe recursive algorithm that finds the best position to play. Right now it is supposed to return 10 if it can win when both players play optimally, -10 if it loses while playing optimally, and 0 if it will be a tie with both playing optimally. I'm trying to store the scores for each level of recursion in either array tempMax or tempMin depending on the computer or human is 'playing'. However, while it correctly stores the scores for each level of recursion, it modifies the tempMax/Min array in the recursive function that called it. Sorry if I didn't explain the issue well.

I've tried many versions of this code but none of them seem to work. For my code below, I cleaned up most of the stuff I've tried previously but left in print statements and testing stuff in the actual recursive function.

#include <iostream>
using namespace std;

string board[9];// = {"X", "O", "X", "O", "O", "_", "X", "_", "_"};
//uncomment out above line to enter a specific case 
int minBoard[9] = {999, 999, 999, 999, 999, 999, 999, 999, 999};
int maxBoard[9] = {-999, -999, -999, -999, -999, -999, -999, -999, -999};
string computer = "X", human = "O";

void reset(){
        for (int i = 0; i < 9; i++){
        minBoard[i] = 999;
        maxBoard[i] = -999;
    }
}

int maximum(int arr[]){
    int MAX = arr[0];
    for (int i = 1; i < 9; i++){
        MAX = max(arr[i], MAX);
    }return MAX;
}

int minimum(int arr[]){
    int MIN = arr[0];
    for (int i = 1; i < 9; i++){
        MIN = min(arr[i], MIN);
    }return MIN;
}

void printBoard(){
    for (int i = 0; i < 9; i++){
        if (i%3 != 0){
            cout << "|";
        }
        cout << board[i];
        if (i%3 == 2){
            cout << endl;
        }

    }cout << endl;
}

void updateSpots(){
    for (int i = 0; i < 9; i++){
        if (board[i] == "_"){
            availableSpots[i] = 1;
        }else{
            availableSpots[i] = 0;
        }
    }
}

bool tied(){
    for (int i = 0; i < 9; i++){
        if (board[i] == "_"){
            return false;
        }
    }return true;
} 

bool winning(string player){
    if ((board[0] == player && board[1] == player && board[2] == player) ||
    (board[3] == player && board[4] == player && board[5] == player) ||
    (board[6] == player && board[7] == player && board[8] == player) ||
    (board[0] == player && board[3] == player && board[6] == player) ||
    (board[1] == player && board[4] == player && board[7] == player) ||
    (board[2] == player && board[5] == player && board[8] == player) ||
    (board[0] == player && board[4] == player && board[8] == player) ||
    (board[2] == player && board[4] == player && board[6] == player)
){
    return true;
}else{
    return false;
}
}

int solve(string player, int tempMin[], int tempMax[]){
//  printBoard();
//  for (int i = 0; i < 9; i++){
//          cout << tempMax[i] << ", ";
//  }cout << " TEMPMAX" << endl;
//  for (int i = 0; i < 9; i++){
//          cout << tempMin[i] << ", ";
//  }cout << " TEMPMIN" << endl;
if (winning(human)){
    return -10;
}else if (winning(computer)){
    return 10;
}else if (tied()){
    return 0;
}else if (player == "X"){
    for (int i = 0; i < 9; i++){
        if (board[i] == "_"){
            board[i] = "X";
//              alpha = min(solve(human), alpha);
                reset();
                tempMax[i] = solve(human, minBoard, maxBoard);
//              cout << tempMax[i] << "   MAAAAAAAAAA " << i << endl;
                board[i] = "_";
            }
        }
//      for (int i = 0; i < 9; i++){
//          cout << tempMax[i] << ", ";
//      }cout << " TEMPMAX" << endl;
//      cout << maximum(tempMax) << " TEMPMAX" << endl;
        return maximum(tempMax);
//      int MAX = tempMax[0];
//      for (int i = 1; i < 9; i++){ 
//          MAX = max(tempMax[i], MAX);
//      }return MAX;
    }else if (player == "O"){
        for (int i = 0; i < 9; i++){  
            if (board[i] == "_"){
                board[i] = "O";
//              beta = max(solve(computer), beta);
                reset();
                tempMin[i] = solve(computer, minBoard, maxBoard);
//              cout << tempMin[i] << "   MIIIIIIIIII " << i << endl;
                board[i] = "_";
            }
        }
//      for (int i =  MPMIN" << endl;
//      for (int i = 0; i < 9; i++){
//          cout << tempMin[i] << ", ";
//      }cout << " TEMPMIN" << endl;
//      cout << minimum(tempMin) << " TEMPMIN" << endl;
        return minimum(tempMin);
//      int MIN = tempMin[0];
//      for (int i = 1; i < 9; i++){
//          MIN = min(tempMin[i], MIN);
//      }return MIN;
    }
    }

int main(){
    for (int i = 0; i < 9; i++){
        board[i] = "_";
    }//comment the for loop out for specific case testing
    cout << solve(computer, minBoard, maxBoard) << endl;
}

For an empty Tic-Tac-Toe board, if both players play optimally, it should be a tie so the program should return 0. However, it returns 10. I have also tried smaller cases but it still doesn't work.

Peyton
  • 1
  • 1
  • 3
  • 1
    Possibly relevant question: [Why can't we pass arrays to function by value?](https://stackoverflow.com/q/7454990/580083). Note that you can pass array by value by employing `std::array`. – Daniel Langr Feb 07 '19 at 06:47
  • 2
    First thing I'd do is stop using global variables. In your current code you have `minBoard` a global, and you have `tempMin` which is always a pointer to the same global. That's very confusing. Main thing to realise though is that you don't need a to save your scores in an array, just use a simple variable and keep track of the maximum or minimum score as you go, instead of calculating it at the end. – john Feb 07 '19 at 06:56
  • `board[0] == player` doesn't compare strings, it compares pointers. You always can pass all by value ie. make it `int solve(char *player, int tempMin0, int tempMin1, int tempMin2, ....` etc. and unroll your algorithm. – KamilCuk Feb 07 '19 at 07:59

1 Answers1

0

Arrays are passed by address so when you pass an array to a function it takes its address but you can make a copy of it and then pass it so declare a copy_array_function that returns a new address of copy of your original array