这是我的第一篇文章,但我已经跟踪堆栈溢出了一段时间。我有一个任务来制作代表tic tac toe board的Board
课程。我还必须创建一个Reader
类来读取文件中的tic tac toe移动并将它们播放到棋盘上(而不是......你知道......玩家......实际上自己玩游戏)。
游戏板设置为2d阵列likeo
array[row][column]
00 01 02
10 11 12
20 21 22
分配的要求需要Reader
类中的bool函数从.txt文件中将值读入Board
对象并玩游戏。但是,如果文件尝试两次播放相同的动作,它应该返回false
。(nota bene:first move总是x)例如:
game.txt
01
11
12
01
应该返回false
,因为在x开始时,o无法在01中播放。
如果游戏已经完成,它还应该返回false
但是还有更多"播放"在文件中。例如:
game2.txt
00
10
11
12
22
02
o尝试播放02
,即使x
已赢了。这也应该返回false
(如果以某种方式胜出,则相同)。
现在,我无法正常返回任何内容。代码就在这个链接上(我知道,我知道......不是最好的分享方法,但我是初学者而且我无法弄清楚如何让堆栈接受它):
bool Reader::readGameFile(string fileName)
{
ifstream inputFile;
int row, column;
bool flagVar = true;
inputFile.open(fileName);
if (inputFile)
{
while(inputFile >> row >> column) //keep looping until the file runs out of input
{
if (board.checkOneBlank(row, column))
{
if(board.gameState() == X_WON)
flagVar = false;
if(board.gameState() == O_WON)
flagVar = false;
if(board.gameState() == UNFINISHED)
flagVar = true;
board.makeMove(row, column, playerTurn);
if(playerTurn == 'x')
{
playerTurn = 'o';
}
else
{
playerTurn = 'x';
}
}
}
}
if(flagVar)
return true;
else if(flagVar == false)
return false;
else if (board.gameState() == DRAW)
return true;
else
return true;
inputFile.close();
}
Board
类具有以下功能:
bool makeMove(int, int char); // which calls checkOneBlank and will record a move to the board if it is blank
void print(); // which prints the board
bool checkOneBlank(int, int); // checks to see if a value is blank
bool checkState(char); // checks to see if there are any horizontal, vertical, or diagonal wins
bool checkAllBlanks(); // checks to see if there are any blanks left on the board and counts them. if there are more than 0 then it returns false (used to check for a draw)
Game game(); // checks to see if the game has an x winner, an o winner, a draw, or is unfinished. is an enumerated data type due to the specifications of the project
所有这些功能都经过了彻底的测试。他们按预期工作。
我真的很感激任何帮助,让我上面发布的功能正常工作。这让我发疯了。谢谢!
编辑:我想知道如何确保bool值正确返回。我的问题是如何使这些循环功能。我必须让while循环运行到文件的末尾,即使播放器仍在播放。这是在项目规范中。
答案 0 :(得分:0)
我必须说很难理解你的实际问题是什么,但这是我的假设。 你的玩家继续采取行动,即使对方赢了......你想知道为什么他们这样做。
他们这样做是因为你永远不会打破while循环。我建议makeMove
方法只返回你的游戏状态。一旦执行该方法,检查返回值,如果x或y已经获胜,或者它是否为平局,请使用break
命令退出while循环。
这将删除对gameState
方法的任何需要,但是如果你真的需要你可以保留它而不是让makeMove
返回状态,你可以让它修改状态并检查它使用gameState
。
还有许多其他机会可以简化并使这些代码更好,但我会让你找到它们。
答案 1 :(得分:0)
获得所需结果后停止循环的最简单方法是return
该结果。
bool Reader::readGameFile(string fileName)
{
ifstream inputFile(fileName);
// Opens the file. When inputFile is destroyed, the file is closed
// The principle of doing an action at the end of a scope, by using
// some object's destructor is called RAII. It is one of the most important
// parts of idiomatic C++
for (int row, column; inputFile >> row >> column;)
{
// We only need row and column within the loop, so they are only defined here
if (board.checkOneBlank(row, column))
{
board.makeMove(row, column, playerTurn);
// move first, so that we check the state after the move
// otherwise we don't return the correct result if a win
// happens as the last move in a file
if(board.gameState() == X_WON)
return false;
if(board.gameState() == O_WON)
return false;
if(board.gameState() == DRAW)
return true;
// We are done with this function.
// Because our local objects tidy up after themselves,
// we don't need any "goto cleanup" etc.
if(playerTurn == 'x')
{
playerTurn = 'o';
}
else
{
playerTurn = 'x';
}
}
}
// always have to return a value.
return true;
}