使用goto语句时,代码不会在循环内的期望位置输出

问题描述

我正在尝试制作一个简单的井字游戏。现在,我正在尝试使计算机无法放置在二维阵列中的某些位置。将计算机设置为随机放置,我正在使用循环和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;
                    }
                }
            }

还有更多“优雅”的方法可以达到相同的结果,但是,希望您至少能够遵循(并理解)我对代码所做的相当小的更改。请随时要求进一步的澄清和/或解释。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...