7

行と列ごとに、3、4、または 5 の一致を見つける賢明な方法を決定しようとしています。プレーヤーはゲーム ボード内の領域 (行または列) を探し、同じ「宝石」が 2 つの隣接するピースを交換した後 (ターンごとに 1 つの交換)、3 ~ 5 の連続するスポットを繰り返します。

マッチメイキングの動きのシナリオの例を次に示します。

  • プレイヤーが移動する前のボード (太字はスワップが必要) :

    ACBBC

    DDBAD

    DAACC

    AD BBA

    DCDAA

  • プレイヤーの移動後のボード (太字は結果の一致) :

    ACBBC

    DDBAD _

    D AACC

    Dアバ

    DCDAA _

この例では、最初の行の後の最初の列に "D" の 4 つの一致があります。1.) ボードはゲームの開始時に作成され、ボードは即時の一致を排除するために何度もランダム化され、2.) プレーヤーが移動した後、そのような一致を見つける方法を見つけようとしています。正しく動作している場合、プログラム自体またはプレーヤーによって正しいスワップが行われた後、プログラムは一致を検出できます。

私が試みたすべてのアルゴリズムは、ループが範囲外になったり、スワップ後に結果として得られたすべての一致を不適切に見つけたりする原因となりました。これは、現在のスポットがどこにあるかに基づいて配列検索を「調整」する方法をプログラムに伝えることに失敗したため、プログラムが配列の外側を検索しようとする場合があることを意味します。実行時エラーが発生しない場合でも、不適切な結果が表示されます。たとえば、プレイヤーは、ボードに少なくとも 1 つの完全な一致が表示されていることがわかりますが、これは良くありません。

私が試みた2つの手順の説明は次のとおりです。

  • 次のスペース。現在のスポットから、同じ行の 4 つのスペース (または、行に残っているスペースが 4 つ未満の場合はそれ以下) を先に確認します。最初に、現在のスポットを含む 5 つの一致を確認します。ない場合は、4 (スポットを引いたもの) をチェックします。ない場合は、3 つ (スポットを引いたもの) を確認します。ない場合は、一致が見つかりません。以下の列についても同じチェックを繰り返します。

  • 先行スペース。 現在のスポットから、同じ行にある 4 つのスペース (または、行の最初のスポットと現在のスポットの間に 4 つ未満のスペースがある場合はそれ以下) を確認します。最初に、現在のスポットを含む 5 つの一致を確認します。ない場合は、4 (スポットを引いたもの) をチェックします。ない場合は、3 つ (スポットを引いたもの) を確認します。ない場合は、一致が見つかりません。上記の列についても同じチェックを繰り返します。

これは、そのような作業アルゴリズムが必要な主要な機能です。ここでの 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));
}
4

1 に答える 1