C ++迭代2D向量以连续找到3个

时间:2010-11-04 21:39:36

标签: c++ vector iterator iteration

嘿所有人,正在开发C ++小游戏,“连接3”。这就像Connect 4,除了我们只需要3的匹配来赢得比赛。我将我的电路板存储在一个2D矢量中,该矢量包含整数。

vector< vector<int> > vector2d;

我将一个“X”存储为1,将“O”存储为-1,其中0表示空白。到目前为止似乎工作正常。

因此,在我对抗计算机的算法中,它找到了最好的移动方式。我已经完成了算法,但它需要知道何时遇到“基本案例”。 (它是递归的。)基本情况是:

  1. 有人已经连续3次,或
  2. 董事会已满
  3. 检查电路板是否已满是很容易的。我只是迭代,看看是否有任何空格是“0”。如果是,则电路板未满。但在我检查之前,我需要看看是否有人连续3次,这是我遇到问题的地方。我能想到做到这一点的唯一方法是大而复杂,通过董事会3次不同,寻找3的水平匹配,3的垂直匹配和3的对角线匹配。我甚至不确定从哪里开始这样做,我希望有更好的方法来做到这一点。非常感谢帮助!

    另外,不确定我是否允许使用Boost,我还没有到目前为止,我不想使用它。 (不确定学校的电脑是否有它)。

    编辑:主板不需要3乘3.它可以是1乘7,7乘7或任何大小。如果它不是合法的大小(0,0),我的代码将告诉用户,但任何其他板应该工作。我已经使用矢量大小来查看电路板的大小。

5 个答案:

答案 0 :(得分:8)

您不必每次都检查整个电路板。只有新作品才有所作为,所以你只需要检查包含新作品的最终条件。您需要检查8个不同的方向,但每两个方向都在同一条线上,应该一起检查。方向可以定义为(delta_X,delta_Y)对:(1,0),(0,1),(1,1),(1,-1)。您的代码应该遍历每个方向(如Leonid的代码中所示)并尝试计算与新部分具有相同值的多个部分。然后它应该从当前方向以(-x,-y)的相反方向移动,并计算这些部分。如果计算的棋子数是N-1(新棋子已经计算在内)那么你就有了胜利者。

答案 1 :(得分:7)

因此,假设您使用的是3x3电路板。可以形成有限数量的获胜线。

1 0 0    1 1 1   1 0 0   0 0 1   0 0 1   0 0 0   0 0 0   0 1 0
1 0 0    0 0 0   0 1 0   0 1 0   0 0 1   1 1 1   0 0 0   0 1 0
1 0 0    0 0 0   0 0 1   1 0 0   0 0 1   0 0 0   1 1 1   0 1 0

现在,如果您按照以下方式为每个电路板位置分配一个位:

 1   2   4
 8  16  32
64 128 256

现在你可以看出8条获胜线如下:

  1 |   8 |  64  = 73
  1 |   2 |   4  = 7
  1 |  16 | 256  = 273
  4 |  16 |  64  = 84
  4 |  32 | 256  = 292
  8 |  16 |  32  = 56
 64 | 128 | 256  = 448
  2 |  16 | 128  = 146

现在,如果您在给定玩家所拥有的任何位置存储1,您可以轻松地逐步浏览上述每个“解决方案”,并针对上述8个值进行测试。

假设两名球员有以下位置:

  1 1 0  0 0 1
  1 0 0  0 1 1
  1 0 1  0 1 0

如果您按照以下方式输入“解决方案”的值,则

  1 |  2 |  8 |  64 | 256 = 331
  4 | 16 | 32 | 128       = 180

所以我们知道winnign线是1 | 8 | 64 = 73行所以我们可以使用一点点测试,如下所示

  331 & 73 = 73
  180 & 73 = 0

所以我们可以很容易地检测出玩家1连续3个并且因为“和”不是0而有一个。

这意味着你可以计算最多8个步骤的胜利者(即根据8个可能的答案检查两个玩家的总数)。

显然,当你变得越来越大时复杂度会增加,当你用完比特时看起来会更复杂(看看std :: bitset,例如如何处理它)但是最后的游戏总是需要更少的迭代检查比蛮力方法。显然,设置需要花费更多的时间,但你只计算每种电路板类型的最终游戏条件,以便时间在几个游戏中分摊。

无论如何......多数民众赞成我怎么做:D

答案 2 :(得分:3)

从算法复杂性的角度来看,以下C ++ O(N*M)解决方案是最好的,因为我们需要在最坏的情况下检查电路板的每个单元。它遍历棋盘中的所有单元格(ij),尝试向4个方向(k),并从那里检查3个单元格(l)方向k被占用并且相等。

vector<vector<int> > board(n, vector<int>(m)); // initialize
/*          down  down-right right  up-right */
int di[] = {1,    1,          0,    -1        }; // four directions i coordinate
int dj[] = {0,    1,          1,     1        }; // four directions j coordinate
for (int i = 0; i < n; i++) { // for each row
    for (int j = 0; j < m; j++) { // for each column
        for (int k = 0; k < 4; k++) { // for each direction
            int ii = i, jj = j;
            bool found = true;
            if (board[ii][jj] == 0) continue; // empty space
            for (int l = 1; l < 3 && found; l++) { // need 3 in a row
                int iii = ii + di[k], jjj = jj + dj[k];
                if (iii < 0 || iii >= n) found = false, continue; // off bounds
                if (jjj < 0 || jjj >= n) found = false, continue; // off bounds
                if (board[iii][jjj] != board[ii][jj]) found = false;
            }
            if (found) {
                printf("Hurray!\n");
                return;
            }
        }
    }
}

答案 3 :(得分:1)

我制作了这样的游戏,实际上我用C ++做过的第一件事(谁需要你好世界:P)

如果他们愿意,每个人都可以使用它。

只是不要忘记它是我的第一个C ++的东西,它肯定没有正确编码:P但它有一些很好的C ++之类的东西。但是在那里有一个100%优化的搜索算法,它检查绝对最少的所需排列量,以连续三次检查具有大量评论和ASCII艺术的胜利条件。这可能非常有用。

哦差点忘了提到,这是一个控制台应用程序东西(黑屏DOS envi,无论它叫什么)。它有一个AI(如果这是我的最新版本)应该做得很好。并且网格是动态构建的(这是很难的部分)你可以连续玩3个,但是最大的网格是20x20(我发现了蹩脚游戏,比重力连续4个更有趣)

你走了:

// DrieOpEenRij.cpp : Defines the entry point for the console application.

     #include "stdafx.h"
     #include <iostream>
     #include <string>
     #include <typeinfo>

    using namespace std;

    typedef unsigned short USHORT;

    //USE ONLY IN A SQUARE GRID
    //This method checks a win for the minimimum amount of spaces covering 100% amount of the grid
    //It has 100% coverage and close to 0% overhead, discrimination between who to check for is required and
    //so currentMove char is required to check for win on 'H' human and 'C' Computer
    void CheckForWin(const char* Grid_ptr , const USHORT GridSize , const USHORT GridWidth ,bool &humanWin, bool &computerWin, const char currentMove)
    {
        //check for an x from 1-end of array
        //for all x's check if that makes a 3 line once per linetype
        //check for horizontal win (dont get overhead on edges)

    //A non square grid will have been detected by now
    const USHORT rowStart = 0;
    const USHORT rowEnd = GridWidth-1;
    USHORT passRowCounter = 1;
    const USHORT Side = GridWidth;

    const USHORT cond1 = rowEnd-2;
    const USHORT cond2 = GridSize-Side*2;   

    //Check for all human win options ( after a human move )
    if (currentMove == 'H')
    {
        //Check for human win code
        //Check all array slots for an occurence of 'X'
        for(USHORT i = 0; i < GridSize; i++)
        {   
            //Local stack variables, optimizations for iterations in loops and if statements,
            //also for readability, this is (only efficient and) done only when it is guaranteed
            //to be used in every for jump. 
            USHORT iModSide = i % Side;
            USHORT SideMinTwo = Side - 2;
            USHORT SidePlusTwo = Side + 2;
            USHORT iPlusSide = i + Side;
            USHORT iPlusSideTimesTwo = i + Side * 2;
            USHORT iPlusOne = i + 1;
            USHORT iPlusTwo = i + 2;

            //If an X is found evaluate a win scenario
            if (Grid_ptr[i] == 'X')
            {
                //For each row -->
                if (iModSide < SideMinTwo)
                {
                    //Check horizontal win from left to right
                    if (Grid_ptr[i + 1] == 'X' && Grid_ptr[i + 2] == 'X')
                    {
                        humanWin = true;
                        break;
                    }
                }

                //For the two values under the 'X' (colomn wise) check for 'X''X'
                if (iPlusSideTimesTwo < GridSize)
                {
                    if(Grid_ptr[iPlusSide] == 'X' && Grid_ptr[iPlusSideTimesTwo] == 'X')
                    {
                        humanWin = true; 
                        break;
                    }
                }

                //CHECK FOR DIAGONAL WIN FROM TOP LEFT TO DOWN RIGHT IN ALL POSSIBLE+LEGAL SLOTS!
                // [X] [X] [?] [?]   This illustration shows that checking only at X will suffice
                // [X] [X] [?] [?]   for this specific check in screening for all Top Left --> Down Right
                // [?] [?] [?] [?]   diagonal wins, similarly the Top Right --> Down Left is done mirrored
                // [?] [?] [?] [?]   All other wins using this vector are impossible!
                // Using this amount of conditions to find it saves a lot of searching and with it time
                if (iPlusSideTimesTwo < GridSize && iModSide < SideMinTwo)
                {
                    if (Grid_ptr[i+Side+1] == 'X' && Grid_ptr[iPlusSideTimesTwo+2] == 'X')
                    {
                        humanWin = true; 
                        break;
                    }
                }

                //CHECK FOR DIAGONAL WIN FROM TOP LEFT TO DOWN RIGHT IN ALL POSSIBLE+LEGAL SLOTS!
                // [?] [?] [Y] [Y]   This illustration shows that checking only at Y will suffice
                // [?] [?] [Y] [Y]   for this specific check in screening for all Top Right --> Down Left
                // [?] [?] [?] [?]   diagonal wins, similarly the Top Left --> Down Right is done mirrored
                // [?] [?] [?] [?]   This because all other wins using this vector are impossible!
                // Using this amount of conditions to find it saves a lot of searching and with it time
                if (i % Side > 1 && i + Side*2-2 < GridSize)
                {
                    if (Grid_ptr[i+Side-1] == 'X' && Grid_ptr[i+Side*2-2] == 'X')
                    {
                        humanWin = true; 
                        break;
                    }
                }
            } //end if arrayvalue is 'X'
        } //end for each value in array
    } //end if currentMove 'H'
    else if (currentMove == 'C')
    {
        //Check for human win code
        //Check all array slots for an occurence of 'X'
        for(USHORT i = 0; i < GridSize; i++)
        {   
            //Local stack variables, optimizations for iterations in loops and if statements,
            //also for readability, this is (only efficient and) done only when it is guaranteed
            //to be used in every for jump. 
            USHORT iModSide = i % Side;
            USHORT SideMinTwo = Side - 2;
            USHORT SidePlusTwo = Side + 2;
            USHORT iPlusSide = i + Side;
            USHORT iPlusSideTimesTwo = i + Side * 2;
            USHORT iPlusOne = i + 1;
            USHORT iPlusTwo = i + 2;

            //If an X is found evaluate a win scenario
            if (Grid_ptr[i] == 'O')
            {
                //For each row -->
                if (iModSide < SideMinTwo)
                {
                    //Check horizontal win from left to right
                    if (Grid_ptr[i + 1] == 'O' && Grid_ptr[i + 2] == 'O')
                    {
                        computerWin = true;
                        break;
                    }
                }

                //For the two values under the 'O' (colomn wise) check for 'O''O'
                if (iPlusSideTimesTwo < GridSize)
                {
                    if(Grid_ptr[iPlusSide] == 'O' && Grid_ptr[iPlusSideTimesTwo] == 'O')
                    {
                        computerWin = true; 
                        break;
                    }
                }

                //CHECK FOR DIAGONAL WIN FROM TOP LEFT TO DOWN RIGHT IN ALL POSSIBLE+LEGAL SLOTS!
                // [X] [X] [?] [?]   This illustration shows that checking only at X will suffice
                // [X] [X] [?] [?]   for this specific check in screening for all Top Left --> Down Right
                // [?] [?] [?] [?]   diagonal wins, similarly the Top Right --> Down Left is done mirrored
                // [?] [?] [?] [?]   All other wins using this vector are impossible!
                // Using this amount of conditions to find it saves a lot of searching and with it time
                if (iPlusSideTimesTwo < GridSize && iModSide < SideMinTwo)
                {
                    if (Grid_ptr[i+Side+1] == 'O' && Grid_ptr[iPlusSideTimesTwo+2] == 'O')
                    {
                        computerWin = true; 
                        break;
                    }
                }

                //CHECK FOR DIAGONAL WIN FROM TOP LEFT TO DOWN RIGHT IN ALL POSSIBLE+LEGAL SLOTS!
                // [?] [?] [Y] [Y]   This illustration shows that checking only at Y will suffice
                // [?] [?] [Y] [Y]   for this specific check in screening for all Top Right --> Down Left
                // [?] [?] [?] [?]   diagonal wins, similarly the Top Left --> Down Right is done mirrored
                // [?] [?] [?] [?]   This because all other wins using this vector are impossible!
                // Using this amount of conditions to find it saves a lot of searching and with it time
                if (iPlusSideTimesTwo+2 < GridSize && iModSide < SidePlusTwo)
                {
                    if (Grid_ptr[i+Side-1] == 'O' && Grid_ptr[i+Side*2-2] == 'O')
                    {
                        computerWin = true; 
                        break;
                    }
                }
            } //end if arrayvalue is 'O'
        } //end for each value in array
    }// else if currentMove 'C'
} //end method
//useAI(char* Grid_ptr) {  }

//weighGrid (char* Grid_ptr)  { for (USHORT i = 0; i < GridSize(find out); i++) {}  }


void PrintGrid(char* Grid_ptr, USHORT GridWidth, USHORT GridHeight, USHORT GridSize)
{
    //Abort this method if the Grid is not Square
    if (GridWidth != GridHeight)
    {
        cout << "Warning! \n\nGrid is not square. This method will likely fail!" << endl;
        cout << "Aborting method!" << endl;
        cout << "Press a key to return to program";         
    }
    else
    {
        //Since this code block's applicable to a square grid
        //Width or Height is not relevant, both should work
        //I have chosen to stick with Width everywhere.         

        USHORT rowStart = 0;
        USHORT rowEnd = GridWidth-1;
        USHORT passRowCounter = 1;
        USHORT Side = GridSize / GridHeight;

        for(USHORT i = 0; i < Side; i++)
        {   
            //GO TO NEXT ROW CODE
            rowEnd = Side * passRowCounter;
            passRowCounter++;               
            //PRINT ALL IN THIS ROW
            for (USHORT j = rowStart; j < rowEnd; j++)
            {
                cout << Grid_ptr[j];

            }
            rowStart = rowEnd;
            cout << "\n";
        }
    }
}

void useAI(char* Grid_ptr, USHORT GridSize, USHORT GridWidth)
{
    //Check all values in the array
    //If the value is '?' weigh the priority
    //else continue

    //Weighing the priority
    //If ('O' Present in legal ranges) add prio +1  

    //The AI Will function on this concept
    //All array slots have a weight, the highest weight means the best position
    //From top prio to lowest prio that means -->
    //WIN IN ONE MOVE (weight + 50)
    //NOT LOSE IN ONE MOVE (weight + 15) 
    //BLOCK ENEMY + LINK UP OWN ( Equal prio but stacks so both matter ) weight +1

    //These weights are determined using 8 directional vectors sprouting from all 'X' and 'O' locations in the grid
    //In it's path if it encounters on loc 1 'X' loc 2 + weight = 50 , and vice versa, else +1 for all 8 vectors

    //Create a weightgrid to store the data
    USHORT* WeightGrid_ptr = new USHORT[GridSize];  
    USHORT* fattest_ptr = new USHORT(0);
    USHORT* fattestIndex_ptr = new USHORT(0);

    USHORT Side = GridWidth;

    //Suggestion for optimization , make a forumula table to play all 8 vectors instead
    //Per vector u need Condition for the direction first space and next space. 24 statements in a list
    //A bit complex and harder to read so for now went the east 8 vectors copy pasting. But aware of the
    //solution none-the-less! Unfortunatly though it seems like a maze of code, it is well documented and
    //it's length is over 50% due to optimizations.

    for(USHORT i = 0; i < GridSize; i++)
    {
        if (Grid_ptr[i] == 'X')
        {
            //CHECK X --> Mid Right Vector
            //If within allowed parameters
            if(i % Side < Side-2)
            {
                if(Grid_ptr[i+1] == '?' && Grid_ptr[i+2] == '?')
                { 
                    WeightGrid_ptr[i+1] += 1; 
                    WeightGrid_ptr[i+2] += 1;
                }
                else if(Grid_ptr[i+1] == 'X')
                {
                    WeightGrid_ptr[i+2] += 15;
                }
                else if (Grid_ptr[i+2] == 'X')
                {
                    WeightGrid_ptr[i+1] += 15;
                }
            }
            //CHECK X --> Down Right Vector
            //If within allowed parameters
            if (i % Side < Side -2 && i + Side*2 < GridSize)
            {
                if (Grid_ptr[i+Side+1] == '?' && Grid_ptr[i+Side*2+2] == '?')
                { 
                    WeightGrid_ptr[i+Side+1] += 1;
                    WeightGrid_ptr[i+Side*2+2] += 1;
                }
                else if(Grid_ptr[i+Side+1] == 'X')
                {
                    WeightGrid_ptr[i+Side*2+2] += 15;
                }
                else if (Grid_ptr[i+Side*2+2] == 'X')
                {
                    WeightGrid_ptr[i+Side+1] += 15;
                }
            }
            //CHECK X --> Down Mid Vector
            //If within allowed paramaters
            if (i + Side*2 < GridSize)
            {
                if (Grid_ptr[i+Side] == '?' && Grid_ptr[i+Side*2] == '?')
                {
                    WeightGrid_ptr[i+Side] += 1;
                    WeightGrid_ptr[i+Side*2] += 1;
                }
                else if (Grid_ptr[i+Side] == 'X')
                {
                    WeightGrid_ptr[i+Side*2] += 15;
                }
                else if (Grid_ptr[i+Side*2] == 'X')
                {
                    WeightGrid_ptr[i+Side] += 15;
                }
            }
            //CHECK X --> Down Left Vector
            //If within allowed paramaters
            if(i % Side > 1 && i + Side*2 < GridSize)
            {
                if (Grid_ptr[i + Side*2-1] == '?' && i + Side*2-2 == '?')
                {
                    WeightGrid_ptr[i+Side*2-1] += 1;
                    WeightGrid_ptr[i+Side*2-2] += 1;
                }
                else if(Grid_ptr[i + Side*2-2] == 'X')
                {
                    WeightGrid_ptr[i+Side*2-1] += 15;
                }
                else if(Grid_ptr[i+Side*2-1] == 'X')
                {
                    WeightGrid_ptr[i+Side*2-2] += 15;
                }
            }
            //CHECK X --> Mid Left Vector
            //If within allowed parameters
            if(i % Side > 1)
            {
                if (Grid_ptr[i-1] == '?' && Grid_ptr[i-2] == '?')
                {
                    WeightGrid_ptr[i-1] += 1;
                    WeightGrid_ptr[i-2] += 1;
                }
                else if(Grid_ptr[i-1] == 'X')
                {
                    WeightGrid_ptr[i-2] += 15;
                }
                else if(Grid_ptr[i-2] == 'X')
                {
                    WeightGrid_ptr[i-1] += 15;
                }
            }
            //CHECK X --> Top Left Vector
            //If within allowed parameters
            if( (i) % (Side > 1) && i > Side*2)
            {
                if (Grid_ptr[i-Side-1] == '?' && Grid_ptr[i-Side*2-2] == '?') 
                {
                    WeightGrid_ptr[i-Side-1] += 1;
                    WeightGrid_ptr[i-Side*2-2] += 1;
                }
                else if (Grid_ptr[i-Side-1] == 'X') 
                {
                    WeightGrid_ptr[i-Side*2-2] += 15;
                }
                else if (Grid_ptr[i-Side*2-2] == 'X') 
                {
                    WeightGrid_ptr[i-Side-1] += 15;
                }
            }
            //CHECK X --> Mid Top Vector
            //If within allowed parameters
            if (i > Side*2)
            {
                if(Grid_ptr[i + Side] == '?' && Grid_ptr[i + Side*2] == '?')
                {
                    WeightGrid_ptr[i + Side] += 1;
                    WeightGrid_ptr[i + Side*2] += 1;
                }
                else if(Grid_ptr[i + Side] == 'X')
                {
                    WeightGrid_ptr[i + Side*2] += 15;
                }
                else if (Grid_ptr[i + Side*2] == 'X')
                {
                    WeightGrid_ptr[i + Side] += 15;
                }
            }
        } //end if 'X' detected
        else if (Grid_ptr[i] == 'O')
        {
            //CHECK 8 VECTORS
            //Add weights

            //CHECK O --> Mid Right Vector
            //If within allowed parameters
            if(i % Side < Side-2)
            {
                if(Grid_ptr[i+1] == '?' && Grid_ptr[i+2] == '?')
                { 
                    WeightGrid_ptr[i+1] += 1; 
                    WeightGrid_ptr[i+2] += 1;
                }
                else if(Grid_ptr[i+1] == 'O')
                {
                    WeightGrid_ptr[i+2] += 50;
                }
                else if (Grid_ptr[i+2] == 'O')
                {
                    WeightGrid_ptr[i+1] += 50;
                }

            }

            //CHECK O --> Down Right Vector
            //If within allowed parameters
            if (i % Side < Side -2 && i + Side*2 < GridSize)
            {
                if (Grid_ptr[i+Side+1] == '?' && Grid_ptr[i+Side*2+2] == '?')
                { 
                    WeightGrid_ptr[i+Side+1] += 1;
                    WeightGrid_ptr[i+Side*2+2] += 1;
                }
                else if(Grid_ptr[i+Side+1] == 'O')
                {
                    WeightGrid_ptr[i+Side*2+2] += 50;
                }
                else if (Grid_ptr[i+Side*2+2] == 'O')
                {
                    WeightGrid_ptr[i+Side+1] += 50;
                }
            }

            //CHECK O --> Down Mid Vector
            //If within allowed paramaters
            if (i + Side*2 < GridSize)
            {
                if (Grid_ptr[i+Side] == '?' && Grid_ptr[i+Side*2] == '?')
                {
                    WeightGrid_ptr[i+Side] += 1;
                    WeightGrid_ptr[i+Side*2] += 1;
                }
                else if (Grid_ptr[i+Side] == 'O')
                {
                    WeightGrid_ptr[i+Side*2] += 50;
                }
                else if (Grid_ptr[i+Side*2] == 'O')
                {
                    WeightGrid_ptr[i+Side] += 50;
                }
            }

            //CHECK O --> Down Left Vector
            //If within allowed paramaters
            if(i % Side > 1 && i + Side*2 < GridSize)
            {
                if (Grid_ptr[i + Side*2-1] == '?' && i + Side*2-2 == '?')
                {
                    WeightGrid_ptr[i+Side*2-1] += 1;
                    WeightGrid_ptr[i+Side*2-2] += 1;
                }
                else if(Grid_ptr[i + Side*2-2] == 'O')
                {
                    WeightGrid_ptr[i+Side*2-1] += 50;
                }
                else if(Grid_ptr[i+Side*2-1] == 'O')
                {
                    WeightGrid_ptr[i+Side*2-2] += 50;
                }
            }

            //CHECK O --> Mid Left Vector
            //If within allowed parameters
            if(i % Side > 1)
            {
                if (Grid_ptr[i-1] == '?' && Grid_ptr[i-2] == '?')
                {
                    WeightGrid_ptr[i-1] += 1;
                    WeightGrid_ptr[i-2] += 1;
                }
                else if(Grid_ptr[i-1] == 'O')
                {
                    WeightGrid_ptr[i-2] += 50;
                }
                else if(Grid_ptr[i-2] == 'O')
                {
                    WeightGrid_ptr[i-1] += 50;
                }
            }

            //CHECK O --> Top Left Vector
            //If within allowed parameters
            if( (i) & (Side > 1) && i > Side*2)
            {
                if (Grid_ptr[i-Side-1] == '?' && Grid_ptr[i-Side*2-2] == '?') 
                {
                    WeightGrid_ptr[i-Side-1] += 1;
                    WeightGrid_ptr[i-Side*2-2] += 1;
                }
                else if (Grid_ptr[i-Side-1] == 'O') 
                {
                    WeightGrid_ptr[i-Side*2-2] += 50;
                }
                else if (Grid_ptr[i-Side*2-2] == 'O') 
                {
                    WeightGrid_ptr[i-Side-1] += 50;
                }
            }

            //CHECK O --> Mid Top Vector
            //If within allowed parameters
            if (i > Side*2)
            {
                if(Grid_ptr[i + Side] == '?' && Grid_ptr[i + Side*2] == '?')
                {
                    WeightGrid_ptr[i + Side] += 1;
                    WeightGrid_ptr[i + Side*2] += 1;
                }
                else if(Grid_ptr[i + Side] == 'O')
                {
                    WeightGrid_ptr[i + Side*2] += 50;
                }
                else if (Grid_ptr[i + Side*2] == 'O')
                {
                    WeightGrid_ptr[i + Side] += 50;
                }
            }
        }
    } // end for scan 'X' 'O'

    //Get highest value from weightgrid, add an 'O' to that position, end method automatically
    for (USHORT q = 0; q < GridSize; q++)
    {
        if (Grid_ptr[q] == '?')
        {
            //If a better spot is found
            if (WeightGrid_ptr[q] > *fattest_ptr)
            {
                *fattest_ptr = WeightGrid_ptr[q];
                *fattestIndex_ptr = q;
            }
        }
    }

    Grid_ptr[*fattestIndex_ptr] = 'O';

    //SAFE DELETE POINTER WeightGrid_ptr
    if (WeightGrid_ptr != NULL)
    {
        delete[] WeightGrid_ptr;
        WeightGrid_ptr = NULL;      
    }
    //SAFE DELETE POINTER fattest_ptr
    if (fattest_ptr != NULL)
    {
        delete fattest_ptr;
        fattest_ptr = NULL;     
    }
    //SAFE DELETE POINTER fattestIndex_ptr
    if (fattestIndex_ptr != NULL)
    {
        delete fattestIndex_ptr;
        fattestIndex_ptr = NULL;        
    }

}

int _tmain(int argc, _TCHAR* argv[])
{
    //& adress off       |-|  &x  = 0x?
    //* value pointed by |-|  a = *b

    //Make the required variables on the heap
    USHORT GridHeight = 0;
    USHORT GridWidth  = 0;
    USHORT GridSize = 0;
    USHORT moveCounter = 0;



    char currentMove;

    USHORT input;
    //bool* humanWin_ptr = new bool(false);
    //bool* computerWin_ptr = new bool(false);

    bool humanWin_ptr = false;
    bool computerWin_ptr = false;

    bool Draw = false;

    cout << "A challanger has arrived!" << endl;

    //WARNING FOR THIS BLOCK! Special condition on for loop!
    for(;;)
    {
        cout << "Please state the width for the grid \n";
        scanf_s("%hu", &input);
        if (input > 2 && input < 20)
        {
            GridWidth = input;
            break; //CRITICAL CODE
        }
        else
        {
            cout << "Input was not correct, please state a number between 3 and 20 \n\n";
            cout << "Example of correct input '3' (without quotes) \n";         
        }
    }

    //WARNING FOR THIS BLOCK! Special condition on for loop!
    for(;;)
    {
        cout << "Please state the height for the grid \n";  
        scanf_s("%hu", &input);
        if (input > 2 && input < 20)
        {
            GridHeight = input;
            break; //CRITICAL CODE
        }
        else
        {
            cout << "Input was not correct, please state a number between 3 and 20 \n\n";
            cout << "Example of correct input '3' (without quotes) \n";
        }
    }

    cout << "You have succesfully filled in the paperwork to create the Grid" << endl;

    GridSize = GridHeight * GridWidth;
    cout << "The total GridSize is " << GridSize << " tiles in size" << endl;

    //if (GridWidth != GridHeigth)
    //{
    //  cout << "Warning! \n\nGrid is not square. Program may run irregularly!";
    //  cout << "Close the program or press a key to continue";
    //  scanf();
    //}

    //Note: pointer to a Grid object on the heap
    char* Grid_ptr = new char[GridSize];


    //Initialize Grid as empty
    for (USHORT i = 0; i < GridSize; i++)
    {
        Grid_ptr[i] = '?';      
    }



    //Visualize this step
    cout << "Grid created as empty Grid" << endl;
    cout << endl;

    cout << "Please read the following introduction if you wish for an explanation of the game" << endl;
    cout << "You will be reffered to as Player One equally so the opponent as AI" << endl;
    cout << "You always start with the first move" << endl;
    cout << "The condition for victory is a line of X X X (3 total) in a single line, colomn or a diagonal line across the Grid" << endl;
    cout << "Turns are exchanged per move 1 : 1, there are no time limits so use all you need" << endl;
    cout << "Player One can not lose this 3x3 Grid game when the best option is always chosen" << endl;
    cout << "Consider playing a larger field if you wish to win, Best of luck!" << endl;
    cout << "The grid is filled in like this!" << endl;

    PrintGrid(Grid_ptr, GridWidth, GridHeight, GridSize);

    while(humanWin_ptr == false && computerWin_ptr == false && Draw == false)
    {
        cout << "Players One's Turn! \n";
        cout << "Please fill in the number your X";     

        currentMove = 'H';
        for(;;)
        {
            scanf_s("%i" , &input);
            if (Grid_ptr[input] == 'X' || Grid_ptr[input] == 'O')
            {
                cout << "That space is already taken ,try another";
            }
            else
            {
                Grid_ptr[input] = 'X';
                moveCounter++;
                break;
            }
        }

        cout << '\n';
        PrintGrid(Grid_ptr, GridWidth, GridHeight, GridSize);
        CheckForWin(Grid_ptr, GridSize, GridWidth, humanWin_ptr, computerWin_ptr, currentMove);

        cout << "AI is making a move!" << endl;

        currentMove = 'C';
        useAI(Grid_ptr, GridSize, GridWidth);
        cout << '\n';
        PrintGrid(Grid_ptr, GridWidth, GridHeight, GridSize);
        CheckForWin(Grid_ptr, GridSize, GridWidth, humanWin_ptr, computerWin_ptr, currentMove);

        if (humanWin_ptr)
        {
            cout << "Congratulations you have won the game! \n";
            char c;
            puts ("Enter any text. Include a Space ('.') in a sentence to exit: \n");
            do 
            {
                c=getchar();
                putchar (c);
            } 
            while (c != ' ');   
        }
        else if (computerWin_ptr)
        {
            cout << "The computer won this match, better luck next time! \n";
            char c;
            puts ("Enter any text. Include a Space ('.') in a sentence to exit: \n");
            do 
            {
                c=getchar();
                putchar (c);
            } 
            while (c != ' ');               
        }

        if (moveCounter >= GridSize)
        {
            Draw = true;
            cout << "The game was a draw, good fighting!";
        }
    }

    //int ch = 0;
    //ch = _getch();
    //wint_t _getwch( void );


    //SAFE DELETE POINTER GRID
    if (Grid_ptr != NULL)
    { 
         delete[] Grid_ptr;
         Grid_ptr = NULL;       
    }
    /*
    //SAFE DELETE POINTER Human Win
    if (humanWin_ptr != NULL)
    {
        delete humanWin_ptr;
        humanWin_ptr = NULL;        
    }
    //SAFE DELETE POINTER Computer Win
    if (computerWin_ptr != NULL)
    {   
        delete computerWin_ptr;
        computerWin_ptr = NULL;     
    }*/



    return 0;
}

答案 4 :(得分:0)

你要求接缝是关于微优化的。首先正确实施,然后剖析/测量以找到瓶颈,然后思考如何改进。

由于问题是如此笼统(并且没有示例和代码),我认为不可能以不同的方式回答。