問題描述
我的井字遊戲理論上是個大問題,但對我來說一切似乎都很好 (Theoretically big problem with my Tic tac toe game , but for me all seems good)
所以我進入了學習 c++ 的下一步,那是一個矩陣。我嘗試做一個簡單的井字遊戲,但我的遊戲無法正確檢查遊戲是否結束。如果您在第一輪中輸入 height = 2 和 width = 2,則表示您贏了...我看不出我在哪裡搞砸了,在我看來一切都很好...
int map[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
map[i][j] = 0;
}
}
bool finished = false;
int player = 1;
while (!finished) {
//attack
cout << "player " << player << " it is your turn"<< endl;
cout << "The map looks like this:" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << map[i][j] << " ";
}
cout << endl;
}
bool correctMove;
int height, width;
do
{
correctMove = true;
cout << "Where do you want to attack?" << endl;
cout << "height = "; cin >> height;
cout << "width = "; cin >> width;
if (map[height][width] != 0 || width > 2 || height > 2) {
correctMove = false;
}
} while (!correctMove);
map[height][width] = player;
//check finish game
bool foundSequenceLine = true;
for (int i = 0; i < 3; i++) {
if (map[height][i] != player) {
foundSequenceLine = false;
}
}
bool foundSequenceColumn = true;
for (int i = 0; i < 3; i++) {
if (map[i][width] != player) {
foundSequenceColumn = false;
}
}
bool foundSequenceDiag1 = true;
if (height == width) {
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
}
}
}
bool foundSequenceDiag2 = true;
if (height + width == 2) {
for (int i = 0; i < 3; i++) {
if (map[2‑i][i] != player) {
foundSequenceDiag2 = false;
}
}
}
if (foundSequenceColumn || foundSequenceLine || foundSequenceDiag1 || foundSequenceDiag2) {
finished = true;
cout << "Congrats player " << player << " you won!!!";
}
//change turn
if (player == 1) {
player++;
}
else {
player‑‑;
}
}
}
參考解法
方法 1:
code makes an assumption, then avoids checking it.
Your code assumes the player has won unless you can exhaustively prove they haven't. The problem is that you then short‑circuit two of the tests that prove a move is not a winning move.
Look at what this code is doing:
bool foundSequenceDiag1 = true;
if (height == width) {
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
}
}
}
First, you say "the player has won" foundSequenceDiag1=true;
. Then you say, "was the move on a diagonal?", and only then do you run code that can set foundSequenceDiag1
to false.
If the player makes a move that isn't on the diagonal, the check won't run.
to fix:
bool foundSequenceDiag1 = (height==width); // true if the player played on diagonal
if (foundSequenceDiag1) { // loop code now only executes if player played on diagonal
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
}
}
}
when you've found something, stop looking.
If I were writing your checks, I'd make use of the break
keyword to stop looking once I found an answer.
for (int i = 0; i < 3; i++) {
if (map[i][i] != player) {
foundSequenceDiag1 = false;
break; // can't be true now, so stop checking.
}
}
(by Victor Bînzar、KrisW)