作为练习,我试图在Visual Studio中创建一个TicTacToe游戏作为控制台应用程序。首先,我创建了具有多维数组的3x3网格。我认为在网格的特定正方形中“写”“X”或“O”的直观方法是让玩家输入数字1-9,并且该数字将映射到特定正方形。下面是数字如何对应于网格中的点:

1   2   3

4   5   6

7   8   9

因此,我使用std::multimap将玩家输入映射到网格中的正方形以练习使用 map 和多图。由于我是std::multimap的新手,所以我想我在某个地方搞砸了:没有错误,游戏可以编译,但是输入似乎未正确映射到右方。

我不知道如何解决该错误,因为我不熟悉 map 和多图。

*如果有人可以告诉我如何使用我选择的映射方法解决问题,那就太好了!

*关于如何将玩家输入映射到特定方块,我也欢迎其他更好的想法!

对不起,长代码;我认为我再也削减不了什么了。感谢您抽出宝贵的时间!
#include <iostream>
#include <map>
using namespace std;


class TTTClass
{
private:
    static const int GRID_LENGTH = 3;
    char Grid[GRID_LENGTH][GRID_LENGTH] = {' '};

    int POInput;
    int PXInput;
    bool IsInputValid = false;

public:
    TTTClass()
{
    POInput = 1;
    PXInput = 1;
}


void EmptyGrid()
{
    for (int RowCounter = 0; RowCounter < GRID_LENGTH; RowCounter++)
    {
        for (int ColumnCounter = 0; ColumnCounter < GRID_LENGTH; ColumnCounter++)
        {
            Grid[RowCounter][ColumnCounter] = ' ';
        }
    }
}


void DisplayGrid()
{
    for (int RowCounter = 0; RowCounter < GRID_LENGTH; RowCounter++)
    {
        std::cout << "  ";
        for (int ColumnCounter = 0; ColumnCounter < GRID_LENGTH; ColumnCounter++)
        {
            std::cout << Grid[RowCounter][ColumnCounter];
            if (ColumnCounter != GRID_LENGTH - 1) {std::cout << " | ";}
        }
        if (RowCounter != GRID_LENGTH - 1)
        {
            std::cout << "\n  __|___|__ \n    |   |\n";
        }
    }
    std::cout << "\n\n";
}


void POTurn()
{
    std::multimap<int, int> Gridmm;

    Gridmm.insert(std::make_pair(1, 0)); Gridmm.insert(std::make_pair(1, 0));
    Gridmm.insert(std::make_pair(2, 0)); Gridmm.insert(std::make_pair(2, 1));
    Gridmm.insert(std::make_pair(3, 0)); Gridmm.insert(std::make_pair(3, 2));
    Gridmm.insert(std::make_pair(4, 1)); Gridmm.insert(std::make_pair(4, 0));
    Gridmm.insert(std::make_pair(5, 1)); Gridmm.insert(std::make_pair(5, 1));
    Gridmm.insert(std::make_pair(6, 1)); Gridmm.insert(std::make_pair(6, 2));
    Gridmm.insert(std::make_pair(7, 2)); Gridmm.insert(std::make_pair(7, 0));
    Gridmm.insert(std::make_pair(8, 2)); Gridmm.insert(std::make_pair(8, 1));
    Gridmm.insert(std::make_pair(9, 2)); Gridmm.insert(std::make_pair(9, 2));

    do
    {
        std::cout << "PlayerO, select a square: ";
        std::cin >> POInput;
        if (POInput < 1 || POInput > 9)
            IsInputValid = false;
        else
        {
            std::pair<std::multimap<int, int>::iterator, std::multimap<int, int>::iterator> RepeaterIterator;
            RepeaterIterator = Gridmm.equal_range(POInput);

            std::multimap<int, int>::iterator itr1 = RepeaterIterator.first;
            std::multimap<int, int>::iterator itr2 = RepeaterIterator.second;

            Grid[itr1->second][itr2->second] = 'O';
            std::cout << "Value at square " << POInput << "/ Coord. " << itr1->second << ", " << itr2->second;
            std::cout << " is: " << Grid[itr1->second][itr2->second] << "\n";
            IsInputValid = true;
        }
    } while (IsInputValid == false);
}

void PXTurn()
{
    std::multimap<int, int> Gridmm;

    Gridmm.insert(std::make_pair(1, 0)); Gridmm.insert(std::make_pair(1, 0));
    Gridmm.insert(std::make_pair(2, 0)); Gridmm.insert(std::make_pair(2, 1));
    Gridmm.insert(std::make_pair(3, 0)); Gridmm.insert(std::make_pair(3, 2));
    Gridmm.insert(std::make_pair(4, 1)); Gridmm.insert(std::make_pair(4, 0));
    Gridmm.insert(std::make_pair(5, 1)); Gridmm.insert(std::make_pair(5, 1));
    Gridmm.insert(std::make_pair(6, 1)); Gridmm.insert(std::make_pair(6, 2));
    Gridmm.insert(std::make_pair(7, 2)); Gridmm.insert(std::make_pair(7, 0));
    Gridmm.insert(std::make_pair(8, 2)); Gridmm.insert(std::make_pair(8, 1));
    Gridmm.insert(std::make_pair(9, 2)); Gridmm.insert(std::make_pair(9, 2));

    do
    {
        std::cout << "PlayerX, select a square: ";
        std::cin >> PXInput;
        if (PXInput < 1 || PXInput > 9)
            IsInputValid = false;
        else
        {
            std::pair<std::multimap<int, int>::iterator, std::multimap<int, int>::iterator> RepeaterIterator;
            RepeaterIterator = Gridmm.equal_range(PXInput);

            std::multimap<int, int>::iterator itr1 = RepeaterIterator.first;
            std::multimap<int, int>::iterator itr2 = RepeaterIterator.second;

            Grid[itr1->second][itr2->second] = 'X';
            std::cout << "Value at square " << POInput << "/ Coord. " << itr1->second << ", " << itr2->second;
            std::cout << " is: " << Grid[itr1->second][itr2->second] << "\n";
            IsInputValid = true;
        }
    } while (IsInputValid == false);
}
};

int main()
{
    TTTClass MyGame;

    MyGame.EmptyGrid();
    MyGame.DisplayGrid();

    MyGame.PXTurn();
    MyGame.DisplayGrid();

    MyGame.POTurn();
    MyGame.DisplayGrid();

    return 0;
}


顺便说一句,我知道游戏只运行了两个回合,但是无论如何都会出现问题。

最佳答案

(评论太长,实际上可能是答案。)

我相信,OP忽略了所需的映射是intint×int的观点。

值类型必须为std::pair<int, int>或需要两个映射–一个将输入映射到行,另一个将输入映射到列。

但是,输入索引和网格坐标之间存在非常简单的线性关系:

 1 -> 0, 0 | 2 -> 0, 1 | 3 -> 0, 2
 ----------+-----------+----------
 4 -> 1, 0 | 5 -> 1, 1 | 6 -> 1, 2
 ----------+-----------+----------
 7 -> 2, 0 | 8 -> 2, 1 | 9 -> 2, 2

即用于输入int i:int col = (i - 1) % 3, row = (i - 1) / 3;

除了:如果OP确实要使用 map ,那么std::map<int, std::pair<int, int> >比multimap更有意义。

std::map 是一个排序的关联容器,其中包含具有唯一键的键值对。 (您拥有)。每个输入索引都精确地映射到一个网格单元,并且没有重复的键。

该值是一对int无关紧要。可以是对属性要求最低的任何对象:
  • CopyInsertable
  • EqualityComparable
  • Destructible

  • std::multimap 是一个关联容器,其中包含键-值对的排序列表,同时允许具有相同键的多个条目。 (您不需要,因为您的键是唯一的)。

    在OPs代码中:
    std::cin >> i;
    if (i >= 1 && i <= 9) {
      Grid[/* row: */(i - 1) / 3, /* col: */(i - 1) % 3] = mark;
    } else {
      // harass user
    }
    

    因此,char mark可以具有'X''O'来考虑PaulMcKenzie关于代码重复的提示。

    关于c++ - 如何使用std::multimap将整数键映射到两个用作多维数组坐标的整数值(用于Tic Tac Toe)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57121819/

    10-11 22:47
    查看更多