Я пытаюсь создать текстовую версию этой игры:
http://www.cse.nd.edu/java/SameGame.html
Вот код, который у меня есть:
#include <iostream>
#include <vector>
#include <ctime>
class Clickomania
{
public:
Clickomania();
std::vector<std::vector<int> > board;
int move(int, int);
bool isSolved();
void print();
void pushDown();
bool isValid();
};
Clickomania::Clickomania()
: board(12, std::vector<int>(8,0))
{
srand((unsigned)time(0));
for(int i = 0; i < 12; i++)
{
for(int j = 0; j < 8; j++)
{
int color = (rand() % 3) + 1;
board[i][j] = color;
}
}
}
void Clickomania::pushDown()
{
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 12; j++)
{
if (board[j][i] == 0)
{
for(int k = j; k > 0; k--)
{
board[k][i] = board[k-1][i];
}
board[0][i] = 0;
}
}
}
}
int Clickomania::move(int row, int col)
{
bool match = false;
int totalMatches = 0;
if (row > 12 || row < 0 || col > 8 || col < 0)
{
return 0;
}
int currentColor = board[row][col];
board[row][col] = 0;
if ((row + 1) < 12)
{
if (board[row+1][col] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row+1, col);
}
}
if ((row - 1) >= 0)
{
if (board[row-1][col] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row-1, col);
}
}
if ((col + 1) < 8)
{
if (board[row][col+1] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row, col+1);
}
}
if ((col - 1) >= 0)
{
if (board[row][col-1] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row, col-1);
}
}
return totalMatches;
}
void Clickomania::print()
{
for(int i = 0; i < 12; i++)
{
for(int j = 0; j < 8; j++)
{
std::cout << board[i][j];
}
std::cout << "\n";
}
}
int main()
{
Clickomania game;
game.print();
int row;
int col;
std::cout << "Enter row: ";
std::cin >> row;
std::cout << "Enter col: ";
std::cin >> col;
int numDestroyed = game.move(row,col);
game.print();
std::cout << "Destroyed: " << numDestroyed << "\n";
}
Метод, который доставляет мне неприятности, - это мой метод "перемещения". Этот метод, учитывая пару координат, должен удалить все квадраты по этой координате с одинаковым номером, а также со всеми квадратами с одинаковым номером, подключенными к нему.
Если вы перейдете по ссылке, которую я дал выше, вы увидите, как удаление выполняется одним кликом.
int Clickomania::move(int row, int col)
{
bool match = false;
int totalMatches = 0;
if (row > 12 || row < 0 || col > 8 || col < 0)
{
return 0;
}
int currentColor = board[row][col];
board[row][col] = 0;
if ((row + 1) < 12)
{
if (board[row+1][col] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row+1, col);
}
}
if ((row - 1) >= 0)
{
if (board[row-1][col] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row-1, col);
}
}
if ((col + 1) < 8)
{
if (board[row][col+1] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row, col+1);
}
}
if ((col - 1) >= 0)
{
if (board[row][col-1] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row, col-1);
}
}
return totalMatches;
}
Мой метод move (), описанный выше, работает нормально, так как он удалит соответствующие «блоки» и заменит их нулями. Однако количество уничтоженных (возвращаемое значение) всегда однозначно (слишком мало). Я считаю, что это потому, что первый вызов move () не учитывается, но я не знаю, как различить первый вызов или последующие вызовы в этом рекурсивном методе.
Как я могу изменить свой метод move (), чтобы он возвращал правильное количество уничтоженных блоков?