简体   繁体   中英

Making a simple method more efficient

I'm currently developing a TicTacToe game which implements minimax. Within that minimax algorithm I have a method called canWin which greatly reduces the number of required steps(number of internal recursive calls to the minimax method) needed to be taken in order to calculate the best next move. Just to show how greatly canWin affects my program, the code without canWin for a 3x3 game requires about 2000 steps to calculate the move and for a 4x4 game 13810133 steps. With canWin however it needs only about 600 for 3x3 and 9246569 for 4x4.

The surprising problem now becomes run time. The weird thing is that the minimax method actually runs faster WITHOUT the addition of canWin even though it requires a lot more steps to finish calculating. Which leads me to believe that the canWin method slows it down hard. Which kinda beats it's purpose but is understandable given that it's a very badly written method. So I need help making canWin more efficient. This method is very long. Unnecessarily so. It's job is to look through the current state of the board(which is a char array containing X, O or - )and check if a potential win is available(for example XX -, or O - O). First it checks the size of the board, then it checks whose turn it is. Whoever has the turn checks if there is a chance for him to win. If there is a chance he takes it by filling the required slot. Otherwise he checks if his opponent has a chance to win. If his opponent has a chance to win he blocks it by filling the required slot. The method returns the slot(number of the slot) needed to be filled in order to make a potential win or block a potential loss.

Here it is, I know it's terrible but help me out here:

public int canWin3(){
        int pot=-1;
        if(n==3){
            if(turn=='O'){

                //O win gets priority
                //Check if 0 is free and potential winning spot for O
                if(((state[1] == 'O' && state[2] == 'O')  || 
                        (state[3] == 'O' && state[6]=='O')
                         || (state[4] == 'O' && state[8]=='O'))&&
                         (state[0]=='-')){
                        pot=0;
                }
                //Check if 1 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[2] == 'O')  || 
                        (state[4] == 'O' && state[7]=='O'))&&
                        (state[1]=='-')){
                       pot=1;
                }
                //Check if 2 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[1] == 'O')  || 
                        (state[4] == 'O' && state[6]=='O')
                         || (state[5] == 'O' && state[8]=='O'))&&
                         (state[2]=='-')){
                    pot=2;
                }
                //Check if 3 is free and potential winning spot for O   
                else if(((state[0] == 'O' && state[6] == 'O')  || 
                        (state[4] == 'O' && state[5]=='O'))&&
                        (state[3]=='-')){
                    pot=3;
                }
                //Check if 4 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[8] == 'O')  || 
                        (state[1] == 'O' && state[7]=='O') ||
                          (state[2] == 'O' && state[6]=='O') || 
                         (state[3] == 'O' && state[5] == 'O'))&&
                         (state[4]=='-')){
                    pot=4;
                }
                //Check if 5 is free and potential winning spot for O
                else if(((state[2] == 'O' && state[8] == 'O')  || 
                        (state[3] == 'O' && state[4]=='O'))&&
                        (state[5]=='-')){
                    pot=5;
                }
                //Check if 6 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[3] == 'O')  || 
                        (state[4] == 'O' && state[2]=='O')  ||
                          (state[7] == 'O' && state[8]=='O'))&&
                          (state[6]=='-')){
                    pot=6;
                }
                //Check if 7 is free and potential winning spot for O
                else if(((state[1] == 'O' && state[4] == 'O')  || 
                        (state[6] == 'O' && state[8]=='O'))&&
                        (state[7]=='-')){
                    pot=7;
                }
                //Check if 8 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[4] == 'O')  || 
                        (state[2] == 'O' && state[5]=='O')  || 
                         (state[6] == 'O' && state[7]=='O'))&&
                         (state[8]=='-')){
                    pot=8;
                }

                //Check for possible X win if there are no potential O wins
                //Check if 0 is free and potential winning spot for X
                else if(((state[1] == 'X' && state[2] == 'X')  || 
                        (state[3] == 'X' && state[6]=='X')   || 
                         (state[4] == 'X' && state[8]=='X'))&&
                         (state[0]=='-')){
                    pot=0;
                }
                //Check if 1 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[2] == 'X')  || 
                        (state[4] == 'X' && state[7]=='X'))&&
                        (state[1]=='-')){
                    pot=1;
                }
                //Check if 2 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[1] == 'X')  || 
                        (state[4] == 'X' && state[6]=='X')   || 
                         (state[5] == 'X' && state[8]=='X'))&&
                         (state[2]=='-')){
                    pot=2;
                }
                //Check if 3 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[6] == 'X')  || 
                        (state[4] == 'X' && state[5]=='X'))&&
                        (state[3]=='-')){
                    pot=3;
                }
                //Check if 4 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[8] == 'X')  || 
                        (state[1] == 'X' && state[7]=='X')   || 
                         (state[2] == 'X' && state[6]=='X') || 
                         (state[3] == 'X' && state[5] == 'X'))&&
                         (state[4]=='-')){
                    pot=4;
                }
                //Check if 5 is free and potential winning spot for X
                else if(((state[2] == 'X' && state[8] == 'X')  || 
                        (state[3] == 'X' && state[4]=='X'))&&
                        (state[5]=='-')){
                    pot=5;
                }
                //Check if 6 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[3] == 'X')  || 
                        (state[4] == 'X' && state[2]=='X')   || 
                         (state[7] == 'X' && state[8]=='X'))&&
                         (state[6]=='-')){
                    pot=6;
                }
                //Check if 7 is free and potential winning spot for X
                else if(((state[1] == 'X' && state[4] == 'X')  || 
                        (state[6] == 'X' && state[8]=='X'))&&
                        (state[7]=='-')){
                    pot=7;
                }
                //Check if 8 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[4] == 'X')  || 
                        (state[2] == 'X' && state[5]=='X')  || 
                         (state[6] == 'X' && state[7]=='X'))&&
                         (state[8]=='-')){
                    pot=8;
                }
            }
            //X win gets priority
            //Check if 0 is free and potential winning spot for X
            else {
                if(((state[1] == 'X' && state[2] == 'X')  || 
                        (state[3] == 'X' && state[6]=='X')  || 
                         (state[4] == 'X' && state[8]=='X'))&&
                         (state[0]=='-')){
                    pot=0;
                }
                //Check if 1 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[2] == 'X')  || 
                        (state[4] == 'X' && state[7]=='X'))&&
                        (state[1]=='-')){
                    pot=1;
                }
                //Check if 2 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[1] == 'X')  || 
                        (state[4] == 'X' && state[6]=='X')   || 
                         (state[5] == 'X' && state[8]=='X'))&&
                         (state[2]=='-')){
                    pot=2;
                }
                //Check if 3 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[6] == 'X')  || 
                        (state[4] == 'X' && state[5]=='X'))&&
                        (state[3]=='-')){
                    pot=3;
                }
                //Check if 4 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[8] == 'X')  || 
                        (state[1] == 'X' && state[7]=='X')   ||
                          (state[2] == 'X' && state[6]=='X') ||
                         (state[3] == 'X' && state[5] == 'X'))&&
                         (state[4]=='-')){
                    pot=4;
                }
                //Check if 5 is free and potential winning spot for X
                else if(((state[2] == 'X' && state[8] == 'X')  || 
                        (state[3] == 'X' && state[4]=='X'))&&
                        (state[5]=='-')){
                    pot=5;
                }
                //Check if 6 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[3] == 'X')  || 
                        (state[4] == 'X' && state[2]=='X')  ||
                          (state[7] == 'X' && state[8]=='X'))&&
                         (state[6]=='-')){
                    pot=6;
                }
                //Check if 7 is free and potential winning spot for X
                else if(((state[1] == 'X' && state[4] == 'X')  || 
                        (state[6] == 'X' && state[8]=='X'))&&
                        (state[7]=='-')){
                    pot=7;
                }
                //Check if 8 is free and potential winning spot for X
                else if(((state[0] == 'X' && state[4] == 'X')  || 
                        (state[2] == 'X' && state[5]=='X')  || 
                         (state[6] == 'X' && state[7]=='X'))&&
                         (state[8]=='-')){
                    pot=8;
                }

                //Check for possible O win if there are no X wins
                //Check if 0 is free and potential winning spot for O
                else if(((state[1] == 'O' && state[2] == 'O')  || 
                        (state[3] == 'O' && state[6]=='O')   ||
                          (state[4] == 'O' && state[8]=='O'))&&
                         (state[0]=='-')){
                        pot=0;
                }
                //Check if 1 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[2] == 'O')  || 
                        (state[4] == 'O' && state[7]=='O'))&&
                        (state[1]=='-')){
                       pot=1;
                }
                //Check if 2 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[1] == 'O')  || 
                        (state[4] == 'O' && state[6]=='O')   ||
                         (state[5] == 'O' && state[8]=='O'))&&
                         (state[2]=='-')){
                    pot=2;
                }
                //Check if 3 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[6] == 'O')  || 
                        (state[4] == 'O' && state[5]=='O'))&&
                        (state[3]=='-')){
                    pot=3;
                }
                //Check if 4 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[8] == 'O')  || 
                        (state[1] == 'O' && state[7]=='O')   || 
                         (state[2] == 'O' && state[6]=='O') || 
                         (state[3] == 'O' && state[5] == 'O'))&&
                         (state[4]=='-')){
                    pot=4;
                }
                //Check if 5 is free and potential winning spot for O
                else if(((state[2] == 'O' && state[8] == 'O')  || 
                        (state[3] == 'O' && state[4]=='O'))&&
                        (state[5]=='-')){
                    pot=5;
                }
                //Check if 6 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[3] == 'O')  || 
                        (state[4] == 'O' && state[2]=='O')   || 
                         (state[7] == 'O' && state[8]=='O'))&&
                         (state[6]=='-')){
                    pot=6;
                }
                //Check if 7 is free and potential winning spot for O
                else if(((state[1] == 'O' && state[4] == 'O')  ||
                        (state[6] == 'O' && state[8]=='O'))&&
                        (state[7]=='-')){
                    pot=7;
                }
                //Check if 8 is free and potential winning spot for O
                else if(((state[0] == 'O' && state[4] == 'O')  ||
                        (state[2] == 'O' && state[5]=='O')  || 
                         (state[6] == 'O' && state[7]=='O'))&&
                         (state[8]=='-')){
                    pot=8;
                }
            }
        }
        else {
                if(turn=='O'){
                    //potential O win gets priority
                    //Check if 0 is free and potential winning spot for O
                    if(((state[1] == 'O' && state[2] == 'O' && state[3]=='O')  ||
                            (state[4] == 'O' && state[8]=='O' && state[12]=='O') ||
                            (state[5] == 'O' && state[10]=='O' && state[15]=='O'))&&
                            (state[0]=='-')){
                        pot=0;
                    }
                    //Check if 1 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[2] == 'O' && state[3]=='O') ||
                            (state[5] == 'O' && state[9]=='O' && state[13]=='O'))&&
                            (state[1]=='-')){
                        pot=1;
                    }
                    //Check if 2 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[1] == 'O' && state[3]=='O') ||
                            (state[6] == 'O' && state[10]=='O' && state[14]=='O'))&&
                            (state[2]=='-')){
                        pot=2;
                    }
                    //Check if 3 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[1] == 'O' && state[2]=='O') ||
                            (state[7] == 'O' && state[11] =='O' && state[15]=='O') ||
                            (state[12] == 'O' && state[9] == 'O' && state[6] == 'O')) &&
                            (state[3]=='-')){
                        pot=3;
                    }
                    //Check if 4 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[8] == 'O' && state[12]=='O') ||
                            (state[5] == 'O' && state[6] =='O' && state[7]=='O')) &&
                            (state[4]=='-')){
                        pot=4;
                    }
                    //Check if 5 is free and potential winning spot for O
                    else if(((state[1] == 'O' && state[9] == 'O' && state[13]=='O') ||
                            (state[4] == 'O' && state[6] =='O' && state[7]=='O')) &&
                            (state[5]=='-')){
                        pot=5;
                    }
                    //Check if 6 is free and potential winning spot for O
                    else if(((state[2] == 'O' && state[10] == 'O' && state[14]=='O') ||
                            (state[4] == 'O' && state[5] =='O' && state[7]=='O')) &&
                            (state[6]=='-')){
                        pot=6;
                    }
                    //Check if 7 is free and potential winning spot for O
                    else if(((state[3] == 'O' && state[11] == 'O' && state[15]=='O') ||
                            (state[4] == 'O' && state[6] =='O' && state[5]=='O')) &&
                            (state[7]=='-')){
                        pot=7;
                    }
                    //Check if 8 is free and potential winning spot for O
                    else if(((state[9] == 'O' && state[10] == 'O' && state[11]=='O') ||
                            (state[0] == 'O' && state[4] =='O' && state[12]=='O')) &&
                            (state[8]=='-')){
                        pot=8;
                    }
                    //Check if 9 is free and potential winning spot for O
                    else if(((state[8] == 'O' && state[10] == 'O' && state[11]=='O') ||
                            (state[1] == 'O' && state[5] =='O' && state[13]=='O')) &&
                            (state[9]=='-')){
                        pot=9;
                    }
                    //Check if 10 is free and potential winning spot for O
                    else if(((state[8] == 'O' && state[9] == 'O' && state[11]=='O') ||
                            (state[2] == 'O' && state[6] =='O' && state[14]=='O')) &&
                            (state[10]=='-')){
                        pot=10;
                    }
                    //Check if 11 is free and potential winning spot for O
                    else if(((state[8] == 'O' && state[9] == 'O' && state[10]=='O') ||
                            (state[2] == 'O' && state[6] =='O' && state[14]=='O')) &&
                            (state[11]=='-')){
                        pot=11;
                    }
                    //Check if 12 is free and potential winning spot for O
                    else if(((state[13] == 'O' && state[14] == 'O' && state[15]=='O') ||
                            (state[0] == 'O' && state[4] =='O' && state[8]=='O') ||
                            (state[9] == 'O' && state[6] =='O' && state[3]=='O')) &&
                            (state[12]=='-')){
                        pot=12;
                    }
                    //Check if 13 is free and potential winning spot for O
                    else if(((state[12] == 'O' && state[14] == 'O' && state[15]=='O') ||
                            (state[1] == 'O' && state[5] =='O' && state[9]=='O')) &&
                            (state[13]=='-')){
                        pot=13;
                    }
                    //Check if 14 is free and potential winning spot for O
                    else if(((state[12] == 'O' && state[13] == 'O' && state[15]=='O') ||
                            (state[2] == 'O' && state[6] =='O' && state[10]=='O')) &&
                            (state[14]=='-')){
                        pot=14;
                    }
                    //Check if 15 is free and potential winning spot for O
                    else if(((state[12] == 'O' && state[13] == 'O' && state[14]=='O') ||
                            (state[3] == 'O' && state[7] =='O' && state[11]=='O') ||
                            (state[10] == 'O' && state[5] =='O' && state[0]=='O')) &&
                            (state[15]=='-')){
                        pot=15;
                    }
                    //Check if 0 is free and potential winning spot for X
                    else if(((state[1] == 'X' && state[2] == 'X' && state[3]=='X')  ||
                            (state[4] == 'X' && state[8]=='X' && state[12]=='X') ||
                            (state[5] == 'X' && state[10]=='X' && state[15]=='X'))&&
                            (state[0]=='-')){
                        pot=0;
                    }
                    //Check if 1 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[2] == 'X' && state[3]=='X') ||
                            (state[5] == 'X' && state[9]=='X' && state[13]=='X'))&&
                            (state[1]=='-')){
                        pot=1;
                    }
                    //Check if 2 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[1] == 'X' && state[3]=='X') ||
                            (state[6] == 'X' && state[10]=='X' && state[14]=='X'))&&
                            (state[2]=='-')){
                        pot=2;
                    }
                    //Check if 3 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[1] == 'X' && state[2]=='X') ||
                            (state[7] == 'X' && state[11] =='X' && state[15]=='X') ||
                            (state[12] == 'X' && state[9] == 'X' && state[6] == 'X')) &&
                            (state[3]=='-')){
                        pot=3;
                    }
                    //Check if 4 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[8] == 'X' && state[12]=='X') ||
                            (state[5] == 'X' && state[6] =='X' && state[7]=='X')) &&
                            (state[4]=='-')){
                        pot=4;
                    }
                    //Check if 5 is free and potential winning spot for X
                    else if(((state[1] == 'X' && state[9] == 'X' && state[13]=='X') ||
                            (state[4] == 'X' && state[6] =='X' && state[7]=='X')) &&
                            (state[5]=='-')){
                        pot=5;
                    }
                    //Check if 6 is free and potential winning spot for X
                    else if(((state[2] == 'X' && state[10] == 'X' && state[14]=='X') ||
                            (state[4] == 'X' && state[5] =='X' && state[7]=='X')) &&
                            (state[6]=='-')){
                        pot=6;
                    }
                    //Check if 7 is free and potential winning spot for X
                    else if(((state[3] == 'X' && state[11] == 'X' && state[15]=='X') ||
                            (state[4] == 'X' && state[6] =='X' && state[5]=='X')) &&
                            (state[7]=='-')){
                        pot=7;
                    }
                    //Check if 8 is free and potential winning spot for X
                    else if(((state[9] == 'X' && state[10] == 'X' && state[11]=='X') ||
                            (state[0] == 'X' && state[4] =='X' && state[12]=='X')) &&
                            (state[8]=='-')){
                        pot=8;
                    }
                    //Check if 9 is free and potential winning spot for X
                    else if(((state[8] == 'X' && state[10] == 'X' && state[11]=='X') ||
                            (state[1] == 'X' && state[5] =='X' && state[13]=='X')) &&
                            (state[9]=='-')){
                        pot=9;
                    }
                    //Check if 10 is free and potential winning spot for X
                    else if(((state[8] == 'X' && state[9] == 'X' && state[11]=='X') ||
                            (state[2] == 'X' && state[6] =='X' && state[14]=='X')) &&
                            (state[10]=='-')){
                        pot=10;
                    }
                    //Check if 11 is free and potential winning spot for X
                    else if(((state[8] == 'X' && state[9] == 'X' && state[10]=='X') ||
                            (state[2] == 'X' && state[6] =='X' && state[14]=='X')) &&
                            (state[11]=='-')){
                        pot=11;
                    }
                    //Check if 12 is free and potential winning spot for X
                    else if(((state[13] == 'X' && state[14] == 'X' && state[15]=='X') ||
                            (state[0] == 'X' && state[4] =='X' && state[8]=='X') ||
                            (state[9] == 'X' && state[6] =='X' && state[3]=='X')) &&
                            (state[12]=='-')){
                        pot=12;
                    }
                    //Check if 13 is free and potential winning spot for X
                    else if(((state[12] == 'X' && state[14] == 'X' && state[15]=='X') ||
                            (state[1] == 'X' && state[5] =='X' && state[9]=='X')) &&
                            (state[13]=='-')){
                        pot=13;
                    }
                    //Check if 14 is free and potential winning spot for X
                    else if(((state[12] == 'X' && state[13] == 'X' && state[15]=='X') ||
                            (state[2] == 'X' && state[6] =='X' && state[10]=='X')) &&
                            (state[14]=='-')){
                        pot=14;
                    }
                    //Check if 15 is free and potential winning spot for X
                    else if(((state[12] == 'X' && state[13] == 'X' && state[14]=='X') ||
                            (state[3] == 'X' && state[7] =='X' && state[11]=='X') ||
                            (state[10] == 'X' && state[5] =='X' && state[0]=='X')) &&
                            (state[15]=='-')){
                        pot=15;
                    }
                }
                else {
                    //potential O win gets priority
                    //Check if 0 is free and potential winning spot for X
                    if(((state[1] == 'X' && state[2] == 'X' && state[3]=='X')  ||
                            (state[4] == 'X' && state[8]=='X' && state[12]=='X') ||
                            (state[5] == 'X' && state[10]=='X' && state[15]=='X'))&&
                            (state[0]=='-')){
                        pot=0;
                    }
                    //Check if 1 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[2] == 'X' && state[3]=='X') ||
                            (state[5] == 'X' && state[9]=='X' && state[13]=='X'))&&
                            (state[1]=='-')){
                        pot=1;
                    }
                    //Check if 2 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[1] == 'X' && state[3]=='X') ||
                            (state[6] == 'X' && state[10]=='X' && state[14]=='X'))&&
                            (state[2]=='-')){
                        pot=2;
                    }
                    //Check if 3 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[1] == 'X' && state[2]=='X') ||
                            (state[7] == 'X' && state[11] =='X' && state[15]=='X') ||
                            (state[12] == 'X' && state[9] == 'X' && state[6] == 'X')) &&
                            (state[3]=='-')){
                        pot=3;
                    }
                    //Check if 4 is free and potential winning spot for X
                    else if(((state[0] == 'X' && state[8] == 'X' && state[12]=='X') ||
                            (state[5] == 'X' && state[6] =='X' && state[7]=='X')) &&
                            (state[4]=='-')){
                        pot=4;
                    }
                    //Check if 5 is free and potential winning spot for X
                    else if(((state[1] == 'X' && state[9] == 'X' && state[13]=='X') ||
                            (state[4] == 'X' && state[6] =='X' && state[7]=='X')) &&
                            (state[5]=='-')){
                        pot=5;
                    }
                    //Check if 6 is free and potential winning spot for X
                    else if(((state[2] == 'X' && state[10] == 'X' && state[14]=='X') ||
                            (state[4] == 'X' && state[5] =='X' && state[7]=='X')) &&
                            (state[6]=='-')){
                        pot=6;
                    }
                    //Check if 7 is free and potential winning spot for X
                    else if(((state[3] == 'X' && state[11] == 'X' && state[15]=='X') ||
                            (state[4] == 'X' && state[6] =='X' && state[5]=='X')) &&
                            (state[7]=='-')){
                        pot=7;
                    }
                    //Check if 8 is free and potential winning spot for X
                    else if(((state[9] == 'X' && state[10] == 'X' && state[11]=='X') ||
                            (state[0] == 'X' && state[4] =='X' && state[12]=='X')) &&
                            (state[8]=='-')){
                        pot=8;
                    }
                    //Check if 9 is free and potential winning spot for X
                    else if(((state[8] == 'X' && state[10] == 'X' && state[11]=='X') ||
                            (state[1] == 'X' && state[5] =='X' && state[13]=='X')) &&
                            (state[9]=='-')){
                        pot=9;
                    }
                    //Check if 10 is free and potential winning spot for X
                    else if(((state[8] == 'X' && state[9] == 'X' && state[11]=='X') ||
                            (state[2] == 'X' && state[6] =='X' && state[14]=='X')) &&
                            (state[10]=='-')){
                        pot=10;
                    }
                    //Check if 11 is free and potential winning spot for X
                    else if(((state[8] == 'X' && state[9] == 'X' && state[10]=='X') ||
                            (state[2] == 'X' && state[6] =='X' && state[14]=='X')) &&
                            (state[11]=='-')){
                        pot=11;
                    }
                    //Check if 12 is free and potential winning spot for X
                    else if(((state[13] == 'X' && state[14] == 'X' && state[15]=='X') ||
                            (state[0] == 'X' && state[4] =='X' && state[8]=='X') ||
                            (state[9] == 'X' && state[6] =='X' && state[3]=='X')) &&
                            (state[12]=='-')){
                        pot=12;
                    }
                    //Check if 13 is free and potential winning spot for X
                    else if(((state[12] == 'X' && state[14] == 'X' && state[15]=='X') ||
                            (state[1] == 'X' && state[5] =='X' && state[9]=='X')) &&
                            (state[13]=='-')){
                        pot=13;
                    }
                    //Check if 14 is free and potential winning spot for X
                    else if(((state[12] == 'X' && state[13] == 'X' && state[15]=='X') ||
                            (state[2] == 'X' && state[6] =='X' && state[10]=='X')) &&
                            (state[14]=='-')){
                        pot=14;
                    }
                    //Check if 15 is free and potential winning spot for X
                    else if(((state[12] == 'X' && state[13] == 'X' && state[14]=='X') ||
                            (state[3] == 'X' && state[7] =='X' && state[11]=='X') ||
                            (state[10] == 'X' && state[5] =='X' && state[0]=='X')) &&
                            (state[15]=='-')){
                        pot=15;
                    }
                    //Check if 0 is free and potential winning spot for O
                    if(((state[1] == 'O' && state[2] == 'O' && state[3]=='O')  ||
                            (state[4] == 'O' && state[8]=='O' && state[12]=='O') ||
                            (state[5] == 'O' && state[10]=='O' && state[15]=='O'))&&
                            (state[0]=='-')){
                        pot=0;
                    }
                    //Check if 1 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[2] == 'O' && state[3]=='O') ||
                            (state[5] == 'O' && state[9]=='O' && state[13]=='O'))&&
                            (state[1]=='-')){
                        pot=1;
                    }
                    //Check if 2 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[1] == 'O' && state[3]=='O') ||
                            (state[6] == 'O' && state[10]=='O' && state[14]=='O'))&&
                            (state[2]=='-')){
                        pot=2;
                    }
                    //Check if 3 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[1] == 'O' && state[2]=='O') ||
                            (state[7] == 'O' && state[11] =='O' && state[15]=='O') ||
                            (state[12] == 'O' && state[9] == 'O' && state[6] == 'O')) &&
                            (state[3]=='-')){
                        pot=3;
                    }
                    //Check if 4 is free and potential winning spot for O
                    else if(((state[0] == 'O' && state[8] == 'O' && state[12]=='O') ||
                            (state[5] == 'O' && state[6] =='O' && state[7]=='O')) &&
                            (state[4]=='-')){
                        pot=4;
                    }
                    //Check if 5 is free and potential winning spot for O
                    else if(((state[1] == 'O' && state[9] == 'O' && state[13]=='O') ||
                            (state[4] == 'O' && state[6] =='O' && state[7]=='O')) &&
                            (state[5]=='-')){
                        pot=5;
                    }
                    //Check if 6 is free and potential winning spot for O
                    else if(((state[2] == 'O' && state[10] == 'O' && state[14]=='O') ||
                            (state[4] == 'O' && state[5] =='O' && state[7]=='O')) &&
                            (state[6]=='-')){
                        pot=6;
                    }
                    //Check if 7 is free and potential winning spot for O
                    else if(((state[3] == 'O' && state[11] == 'O' && state[15]=='O') ||
                            (state[4] == 'O' && state[6] =='O' && state[5]=='O')) &&
                            (state[7]=='-')){
                        pot=7;
                    }
                    //Check if 8 is free and potential winning spot for O
                    else if(((state[9] == 'O' && state[10] == 'O' && state[11]=='O') ||
                            (state[0] == 'O' && state[4] =='O' && state[12]=='O')) &&
                            (state[8]=='-')){
                        pot=8;
                    }
                    //Check if 9 is free and potential winning spot for O
                    else if(((state[8] == 'O' && state[10] == 'O' && state[11]=='O') ||
                            (state[1] == 'O' && state[5] =='O' && state[13]=='O')) &&
                            (state[9]=='-')){
                        pot=9;
                    }
                    //Check if 10 is free and potential winning spot for O
                    else if(((state[8] == 'O' && state[9] == 'O' && state[11]=='O') ||
                            (state[2] == 'O' && state[6] =='O' && state[14]=='O')) &&
                            (state[10]=='-')){
                        pot=10;
                    }
                    //Check if 11 is free and potential winning spot for O
                    else if(((state[8] == 'O' && state[9] == 'O' && state[10]=='O') ||
                            (state[2] == 'O' && state[6] =='O' && state[14]=='O')) &&
                            (state[11]=='-')){
                        pot=11;
                    }
                    //Check if 12 is free and potential winning spot for O
                    else if(((state[13] == 'O' && state[14] == 'O' && state[15]=='O') ||
                            (state[0] == 'O' && state[4] =='O' && state[8]=='O') ||
                            (state[9] == 'O' && state[6] =='O' && state[3]=='O')) &&
                            (state[12]=='-')){
                        pot=12;
                    }
                    //Check if 13 is free and potential winning spot for O
                    else if(((state[12] == 'O' && state[14] == 'O' && state[15]=='O') ||
                            (state[1] == 'O' && state[5] =='O' && state[9]=='O')) &&
                            (state[13]=='-')){
                        pot=13;
                    }
                    //Check if 14 is free and potential winning spot for O
                    else if(((state[12] == 'O' && state[13] == 'O' && state[15]=='O') ||
                            (state[2] == 'O' && state[6] =='O' && state[10]=='O')) &&
                            (state[14]=='-')){
                        pot=14;
                    }
                    //Check if 15 is free and potential winning spot for O
                    else if(((state[12] == 'O' && state[13] == 'O' && state[14]=='O') ||
                            (state[3] == 'O' && state[7] =='O' && state[11]=='O') ||
                            (state[10] == 'O' && state[5] =='O' && state[0]=='O')) &&
                            (state[15]=='-')){
                        pot=15;
                    }
                }
        }
        return pot;
}

Since state # is less than 16, and each "else if" condition is fixed, you could use a lookup table (just combine each condition to an unsigned short int using bitmask, and when needed just return its mapped value).

const int base = 16;
const int maxn = 16;

int hv[256];
int state[maxn];

void preprocess() 
{
    hv['O'] = 0;
    hv['X'] = 1;
    hv['-'] = 2;
    ...
}

// may instead use std::map<int,int>
int mapt() 
{
    switch(hashkey) {
        case ..: return 0;
        ...
    }
}

int hash(char *st) {
    int ret = 0;
    for (int i = 0; i < maxn; ++i) {
        ret = ret*base + hv[ st[i] ];
    }
    return mapt(ret);
}

int GetPot()
{
    ...
    return hash(state);
}

This should be quite fast as you need!

All that repetition you have there for checking for wins is bad code practice- and can lead to a lot of confusion. Check out this thread- it helped me a lot when I created my first tic tac toe algorithm.

Algorithm for Determining Tic Tac Toe Game Over

Also some suggestions on how you could make your code more readable.

public int canWin3(){
    int pot=-1;

    if(n != 3 && turn !='O') {
        return pot; // or something meaning full
    } elseif (zeroIsFree()) {
        pot = 0;
    } else if (oneIsFree()) {
        pot =1;
    } ...

    return pot;

}

private function zeroIsFree() {
    return ((state[1] == 'O' && state[2] == 'O')  || 
           (state[3] == 'O' && state[6]=='O') || 
           (state[4] == 'O' && state[8]=='O')) &&
           (state[0]=='-'));
}

That will make the implementation of canWin3 function more readable and will make it easier to debug too. Of course the whole code could be improved better but this suggestion is based upon reading your existing code and trying to guess your current level of skill.

You can also combine techniques from Wyatt Lowery's answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM