【问题标题】:C++ iterate through a 2D vector to find 3 in a rowC++ 遍历一个 2D 向量以连续找到 3 个
【发布时间】:2010-11-04 21:39:36
【问题描述】:

大家好,正在开发一款 C++ 小游戏“Connect 3”。这就像Connect 4 一样,只是我们只需要一场 3 场比赛就可以赢得比赛。我将我的电路板存储在一个包含整数的 2D 向量中。

vector< vector<int> > vector2d;

我有一个“X”存储为 1,一个“O”存储为 -1,其中 0 是一个空格。到目前为止,它似乎工作正常。

因此,在我与计算机对战的算法中,它会找到可能的最佳移动。我已经完成了算法,但它需要知道何时遇到“基本情况”。 (它是递归的。)基本情况是:

  1. 有人连续获得 3 个,或
  2. 董事会已满

检查板是否已满很容易。我只是遍历并查看是否有任何空格是“0”。如果是,则董事会未满。但在我检查之前,我需要看看是否有人连续获得 3 个,这就是我遇到问题的地方。我能想到的唯一方法是大而复杂的,通过3次不同的时间,寻找3的水平匹配,3的垂直匹配和3的对角匹配。我什至不知道从哪里开始这样做,我希望有更好的方法来做到这一点。非常感谢您的帮助!

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

编辑:板不需要是 3 x 3。它可以是 1 x 7、7 x 7 或任何尺寸。如果它不是合法大小 (0,0),我的代码会告诉用户,但任何其他板都应该可以工作。我已经使用矢量大小来查看板有多大。

【问题讨论】:

  • 有人已经问过这个问题,但是关于井字游戏。找不到确切的链接,但要点是您从最后播放的乐曲开始,并从中检查 3 个方向。提示:mod (%) 是你的朋友。

标签: c++ vector iterator iteration


【解决方案1】:

您不必每次都检查整个电路板。只有新作品会有所不同,因此您只需检查包含新作品的最终条件。您需要检查8个不同的方向,但每两个都在同一条线上,应该一起检查。方向可以定义为 (delta_X, delta_Y) 对:(1,0),(0,1),(1,1),(1,-1)。您的代码应该在每个方向上遍历(如 Leonid 中的代码),并尝试计算与新片段具有相同值的片段数量。然后它应该从当前方向以相反的方向(-x,-y)遍历,并计算这些碎片。如果计数的件数为 N-1(新件已计数),那么您就有赢家了。

【讨论】:

    【解决方案2】:

    假设您使用的是 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 个值进行测试。

    所以假设 2 名玩家有以下位置:

      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 个,并且由于“and”不是 0 而有一个。

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

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

    无论如何...我就是这样做的:D

    【讨论】:

    • 当然......将上面的内容转换为汇编程序将是众所周知的 micturate 的一部分。
    • 很酷的解决方案! ^^ 但是在决定了棋盘大小后,初始化计算中奖号码不是需要蛮力方法吗?
    • @Moberg:是的……但是你有这样的优势,你可以缓存获胜线,这样你就可以玩一千场比赛,而仍然只需要暴力破解一次。不像其他系统,你必须在每场比赛中多次暴力破解!
    【解决方案3】:

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

    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;
                }
            }
        }
    }
    

    【讨论】:

    • 找到 bool 的逻辑似乎有点不对劲。
    • 这是一个很好的例子,说明为什么你应该为变量使用实名。
    • 虽然这可能很接近,但中间似乎有点混乱。 “iii”是否被声明了两次?
    • @Wayfarer:已修复,20% 的时间在思考这个问题,80% 的时间在思考如何正确缩进 :)))
    • @Leonid,如果您使用正确的变量名,那么 cmets 将完全没有必要。读 'board[column,row]' 比读 'x[i,j] //get column i and row j from board' 容易得多
    【解决方案4】:

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

    每个人都可以根据需要使用它。

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

    哦,差点忘了提,这是一个控制台应用程序(黑屏 DOS envi,不管它叫什么)。它有一个人工智能(如果这是我的最新版本)应该做得很好。并且网格是动态构建的(这是最难的部分)U 可以连续玩 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;
    }
    

    【讨论】:

      【解决方案5】:

      您所要求的接缝是关于微优化的。首先正确实施,然后分析/衡量以发现瓶颈,然后思考如何改进。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-03
        • 2015-08-08
        • 2023-01-22
        • 1970-01-01
        • 2020-06-09
        • 2010-12-07
        • 1970-01-01
        相关资源
        最近更新 更多