我正在尝试确定一种合理的方法来为每行和每列查找 3、4 或 5 个匹配项。玩家在游戏板上寻找相同的“宝石”区域(行或列),在交换两个相邻的块(每轮交换一个)后,重复 3-5 个连续点。
这是一个匹配移动的示例场景:
玩家移动前的棋盘(粗体是必要的交换):
ACBBC
DDBAD
DAACC
工商管理硕士
DCDAA
玩家移动后棋盘(粗体为结果匹配):
ACBBC
D DBAD
DAACC _
D阿巴
D CDAA
在此示例中,第一行之后的第一列中有 4 个匹配的“D”。我试图弄清楚如何在 1.) 游戏开始时创建棋盘并且棋盘随机化多次以消除即时匹配,以及 2.) 在玩家移动之后找到这样的匹配。如果工作正常,程序将能够在程序本身或玩家进行正确交换后检测到匹配。
我尝试的每个算法都导致循环超出范围和/或在交换后不正确地找到所有结果匹配。我的意思是,程序有时会尝试在数组之外搜索,因为我没有成功地告诉程序如何根据当前位置的位置“调整”其数组搜索。即使它不会导致运行时错误,它仍然会显示不正确的结果。例如,玩家会看到棋盘上至少显示了一场完整的比赛,这是不好的。
以下是我尝试过的两个程序的解释:
以下空格。从当前位置,向前检查同一行中的四个空格(如果该行中剩余的空格少于四个,则检查更少)。首先检查五个匹配,包括当前位置;如果没有,检查四个(减去一个点);如果没有,检查三个(减去一个点);如果没有,则找不到匹配项。对下面的列重复相同的检查。
前面的空格。从 当前位置开始,检查同一行中的四个空格(如果行中的第一个位置和当前位置之间的空格少于四个,则检查更少)。首先检查五个匹配,包括当前位置;如果没有,检查四个(减去一个点);如果没有,检查三个(减去一个点);如果没有,则找不到匹配项。对上列重复相同的检查。
这是需要这种工作算法的主要功能。此处使用我的 Gem 类(当前已损坏)可能对请求并不重要,因此除非有帮助,否则我不会添加它。
bool Board::findMatches(bool scoringMove) // false if board is being setup before game
{
bool matchesFound = false;
// loops through entire board, where "size" is the width, not the number of spots
for (int i = 0; i < size.getSize()*size.getSize(); i++)
{
// loops for each type of Gem, six total (_not identical to given example_)
for (int k = 0; k < gems.getNumGems(); k++)
{
Gem traverseGems(k); // next Gem (in sequence)
char nextGem = traverseGems.getGem(); // next Gem set to a char
// ROWS check
// default match search for 3-match
if ((i < (size.getSize()*size.getSize())-4)
&& (board[i]->getGem() == nextGem)
&& (board[i+1]->getGem() == nextGem)
&& (board[i+2]->getGem() == nextGem))
{
// if the player is making a move
if (!scoringMove)
return true;
matchesFound = true;
// just adds points to score; irrelevant to algorithm
scoreMatches(3, 'R', i, 3);
// no 4-match, but a 3-match
if (board[i+3]->getGem() != nextGem)
scoreMatches(3, 'R', i, 3);
else
scoreMatches(4, 'R', i, 4);
// 5-match found
if (board[i+3]->getGem() == nextGem && board[i+4]->getGem() == nextGem)
scoreMatches(5, 'R', i, 5);
}
// COLUMNS check (comments for rows check apply here as well)
if ((i <= (size.getSize()-1))
&& (board[i]->getGem() == nextGem)
&& (board[i+size.getSize()]->getGem() == nextGem)
&& (board[i+(size.getSize()*2)]->getGem() == nextGem))
{
if (!scoringMove)
return true;
matchesFound = true;
scoreMatches(3, 'C', i, 3);
if (board[i+(size*3)]->getGem() != nextGem)
scoreMatches(3, 'C', i, 3);
else
scoreMatches(4, 'C', i, 4);
if (board[i+(size*3)]->getGem() == nextGem && board[i+(size*4)]->getGem() == nextGem)
scoreMatches(5, 'C', i, 5);
}
}
}
return matchesFound;
}
板子.h
#ifndef BOARD_H
#define BOARD_H
#include "Size.h"
#include "Score.h"
#include "Move.h"
#include "Gem.h"
#include <iostream>
#include <iomanip>
#include <ctime>
class Board
{
private:
Size size;
Score score;
Gem **board;
bool moreSwaps;
void swapGems(Move);
void swapGems(int, int);
void setNewRandGem(int);
void findMoreSwaps();
void scoreMatches(int, char, int, int);
bool findMatches(bool);
public:
Board();
Board(Size, Score&);
~Board();
void displayBoard() const;
bool isMatch(Move);
bool moreMovesFound() const;
};
#endif
板构造器
Board::Board(Size size, Score &score)
{
srand((unsigned int)time(NULL)); // I can always move this to main()
this->size = size;
this->score = score;
board = new Gem *[size.getSize()*size.getSize()];
for (int i = 0; i < size.getSize()*size.getSize(); i++)
board[i] = new Gem;
//This is the "pre-game" block.
//As long as the program finds a new match after performing its
//own swaps, it'll randomize the entire board and start over again.
//This is incredibly unefficient, but I will try to fix it later.
do
{
for (int i = 0; i < size.getSize()*size.getSize(); i++)
setNewRandGem(i);
} while (findMatches(false));
}