问题描述
我正在尝试制作一个简单的井字游戏。现在,我正在尝试使计算机无法放置在二维阵列中的某些位置。将计算机设置为随机放置,我正在使用循环和goto将其随机放置,直到获得合适的位置为止。
#include <iostream>
#include <string>
#include <ctime>
#include <Windows.h>
using namespace std;
string team;
string a = " ";
const int rows = 5;
const int elements = 5;
string Board[rows][elements] = { a,"| ",a,"- ","+ ",a };
void showBoard()
{
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
cout << Board[i][j];
}
cout << endl;
}
}
int main()
{
int nonFilled = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
if (Board[i][j] == a && a == " ")
nonFilled++;
}
}
int circleFilled = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
if (Board[i][j] == a && a == "0 ")
circleFilled++;
}
}
int crossFilled = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < elements; j++) {
if (Board[i][j] == a && a == "X ")
crossFilled++;
}
}
cout << "Welcome to tic-tac-toe game." << endl;
cout << endl;
showBoard();
cout << "Please select team if circle or cross: (0/X)" << endl;
cin >> team;
if (team == "0") {
int ifCircle = 1;
cout << "You have selected circle." << endl;
while (nonFilled > circleFilled + crossFilled) {
srand(time(NULL));
int x,y = 0;
int xx,xy = 0;
cout << "Select square: " << endl;
cout << "Y cord (0-4): ";
cin >> x;
cout << endl;
cout << "X cord (0-4): ";
cin >> y;
if (x == 0 || y == 0)
return 0;
/*if (Board[x - 1][y - 1] = "| ","- ")
{
cout << "You cannot place one there. " << endl;
nonFilled = 100;
}*/
int b = 1;
if (Board[x - 1][y - 1] == a)
b = 1;
else
b = 2;
switch (b) {
case 1:
Board[x - 1][y - 1] = "0 ";
break;
case 2:
cout << "You cannot place one there. " << endl;
continue;
}
/* if (Board[x - 1][y - 1] == a)
{
Board[x - 1][y - 1] = "0 ";
}
else
{
cout << "You cannot place one there." << endl;
}*/
cout << endl;
showBoard();
cout << "The opponent will Now pick a square:" << endl;
system("pause");
xx = rand() % rows;
xy = rand() % elements;
int c = 1;
if (Board[xx][xy] == a)
c = 1;
else if (Board[xx][xy] == "| ","- ")
c = 2;
switch (c) {
case 1:
Board[xx][xy] = "X ";
break;
case 2: {
LOOP: // here is my label for the goto statement
while (true) // this loop
{
xx = rand() % rows;
xy = rand() % elements;
if (Board[xx][xy] == "| ","- ") {
goto LOOP; // goto statement
}
else {
Board[xx][xy] = "X ";
}
}
}
}
cout << endl;
cout << "The opponent has picked:" << endl;
showBoard();
}
}
else if (team == "X") {
int ifCircle = 0;
}
system("pause");
return 0;
}
所讨论的循环位于最底部,我不确定这是关于如何放置标签或如何使用语句的问题,还是与代码的其他部分有关的问题。 / p>
我在while循环中查看了关于goto语句的大量问题,但找不到任何东西。
解决方法
眼前的问题既不在于您的LOOP:
标签的位置,也不在于goto
语句的使用(我不是将参与到有关是否应在C ++程序中使用 ever 的争论)。
问题在以下行中:
if (Board[xx][xy] == "| ","+ ","- ") {
(以及前面几行中类似的if else...
语句)。
这不会不做您可能想要的事情!实际上,它会始终返回一个true
值,因为表达式的最终结果是if ("- ")
-它将始终为非null(即非零)的字符串文字地址。
您需要的内容(如果要使索引的Board[][]
字符串与三个文字之一匹配)
if (Board[xx][xy] == "| " || Board[xx][xy] == "+ " || Board[xx][xy] == "- ") {
//...
您拥有的代码使用comma operator来评估每个逗号分隔的表达式(从左到右的顺序),并丢弃除最后一个(最右边)的值之外的每个表达式;总体结果就是最右边的表达式。
编辑:应用了我在上文中建议的修复程序之后,我注意到了另一个问题:您的while
循环按现状将从不退出(它将goto
移至LOOP:
或继续运行)。这是修复循环的一种(快速)方法,它也消除了对goto
语句的需要:
case 2:
{
bool done = false;
while (!done)
{
xx = rand() % rows;
xy = rand() % elements;
if (Board[xx][xy] == "| " || Board[xx][xy] == "+ " || Board[xx][xy] == "- ") {
continue;
}
else {
Board[xx][xy] = "X ";
done = true;
}
}
}
还有更多“优雅”的方法可以达到相同的结果,但是,希望您至少能够遵循(并理解)我对代码所做的相当小的更改。请随时要求进一步的澄清和/或解释。