[英]C++ iterate through a 2D vector to find 3 in a row
大家好,我們正在開發一款C ++小游戲“ Connect 3”。 就像Connect 4一樣 ,除了我們只需要匹配3即可贏得比賽。 我將板保存在2D向量中,該向量具有整數。
vector< vector<int> > vector2d;
我將“ X”存儲為1,將“ O”存儲為-1,其中0為空白。 到目前為止,它似乎一直在工作。
因此,在我與計算機對抗的算法中,它找到了可能的最佳移動方式。 我已經完成了算法,但是它需要知道什么時候遇到了“基本情況”。 (這是遞歸的。)一個基本情況是:
檢查電路板是否已滿很容易。 我只是遍歷,看看是否有任何空格為“ 0”。 如果是,則說明板未滿。 但是在檢查之前,我需要查看是否有人連續獲得3個,這就是我遇到的問題。 我能想到的唯一方法是又大又復雜,要經過3次不同的董事會,尋找水平比賽3,垂直比賽3和對角線比賽3。我什至不知道從哪里開始這樣做,我希望有一個更好的方法。 幫助將不勝感激!
另外,不確定是否允許使用Boost,但到目前為止還沒有,我不想使用它。 (不確定學校計算機是否裝有)。
編輯:董事會不需要是3 x3。它可以是1 x 7、7 x 7或任何大小。 如果不是合法大小(0,0),我的代碼會告訴用戶,但是其他任何板都可以工作。 我使用矢量大小來查看電路板有多大。
您不必每次都檢查整個電路板。 只有新零件會有所作為,因此您只需要檢查包括新零件在內的那些最終條件。 您需要檢查8個不同的方向,但是每兩個方向都在同一行,應該一起檢查。 方向可以定義為(delta_X,delta_Y)對:(1,0),(0,1),(1,1),(1,-1)。 您的代碼應在各個方向上遍歷(例如Leonid的代碼),並嘗試計算與新片段具有相同值的盡可能多的片段。 然后,它應該以與當前方向成(-x,-y)的相反方向來回移動,並且還要對這些部分進行計數。 如果計件數為N-1(已經計入新件數),那么您就有贏家。
因此,假設您使用的是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
因此,我們知道勝出線是1 | 8 | 64 = 73行,因此我們可以使用以下方法進行測試
331 & 73 = 73
180 & 73 = 0
因此,我們可以輕松地檢測到玩家1連續有3個,並且由於“與”不為0而有一個。
這意味着您最多可以計算8個步驟的贏家(即對照8個可能的答案檢查兩位選手的總成績)。
顯然,復雜度會隨着您變大而增加,並且用完所有位(似乎要看一下std :: bitset,例如如何處理該問題)時,它看起來會變得復雜得多,但是最終游戲要比進行一次迭代檢查的迭代次數更少蠻力法。 顯然,這需要花費更多的時間來設置,但每種板型僅計算一次最終游戲條件,這樣就可以在多個游戲中分攤時間。
無論如何...那就是我會怎么做:D
從算法復雜性的角度來看,以下C ++ O(N*M)
解決方案是最好的選擇,因為我們需要檢查最壞情況下的電路板上的每個單元。 它遍歷所有細胞在板( i
和j
),嘗試在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;
}
}
}
}
我做了這樣的游戲,這實際上是我用C ++所做的第一件事(誰需要打招呼:P)
每個人都可以根據需要使用它。
只是不要忘了這是我的第一篇C ++東西,它肯定沒有正確編碼:P,但其中包含一些不錯的C ++東西。 但是,這里有一個100%優化的搜索算法,可以檢查所需排列的絕對數量最少,以確保連續三場獲勝條件具有豐富的注釋和ASCII藝術。 那可能很有用。
哦,幾乎忘了提及,這是一個控制台應用程序(黑屏DOS envi,無論它叫什么)。 它具有一個AI(如果這是我的最新版本),應該做得很好。 並且網格是動態構建的(這是最困難的部分),U可以連續播放3個,但是最大可以播放20x20網格(我發現la腳的游戲,在重力作用下連續播放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;
}
您要問的是關於微優化的。 首先正確地實施它,然后概要分析/測量以發現瓶頸,然后思考如何改進。
由於問題是如此籠統(並且沒有示例和代碼),所以我認為不可能以不同的方式回答。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.