c++ - 如何使用 std::multimap 将整数键映射到用作多维数组坐标的两个整数值(对于井字游戏)?
问题描述
作为练习,我尝试在 Visual Studio 中创建一个井字游戏作为控制台应用程序。首先,我使用多维数组创建了 3x3 网格。我认为在网格的特定方格中“写”一个“X”或“O”的一种直观方法是让玩家输入一个数字 1-9,然后该数字将映射到一个特定的方格。以下是数字如何与网格中的点相对应:
1 2 3
4 5 6
7 8 9
因此,我使用 std::multimap 将玩家输入映射到网格中的一个正方形,以练习使用地图和多重地图。由于我是 std::multimap 的新手,我想我在某个地方搞砸了:没有错误,游戏编译,但输入似乎没有正确映射到正确的方块。
我不知道如何修复这个错误,因为我不熟悉地图和多地图。
*如果有人能告诉我如何使用我选择的映射方法解决问题,那就太好了!
*我也欢迎关于如何将玩家输入映射到特定方块的其他更好的想法!
抱歉,代码太长了;我想我不能再剪什么了。感谢您抽出宝贵的时间!
#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 错过了所需映射是int
→ int
×的点int
。
值类型必须是 egstd::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 真的想使用地图,那么std::map<int, std::pair<int, int> >
比多地图更有意义。
A是一个排序的关联容器,其中包含具有唯一键的键值对。(你有)。每个输入索引都映射到一个网格单元,并且没有重复的键。std::map
该值是一对int
s 无关紧要。它可以是具有最低属性要求的任何对象:
A是一个关联容器,其中包含键值对的排序列表,同时允许具有相同键的多个条目。(您不需要,因为您的密钥是唯一的)。std::multimap
在 OP 代码中:
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关于代码重复的提示。
推荐阅读
- java - 面对 java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
- go - 即使我得到一个着色器编译错误,所有着色器都可以正常工作。如何?
- css - 带有重复修饰符的 CSS 后代选择
- python - 如何在不更改任何默认值的情况下在 Ubuntu 上为 python 3.8 安装 pip?
- docker - 如何使用 docker compose 指定 GPU 限制 docker swarm?
- python - “is” Python 运算符是否可靠地测试可变对象的引用相等性?
- c++ - 为什么在我的程序中找不到 dll 的入口点?文件
- python - 当我尝试向用户添加 exp 时,我收到 KeyError: '563690668808208423'
- javascript - 无法使用 Firebase 云功能发送电子邮件
- c++ - 将openCV ROI保存到C++中的二进制文件