Boggle回溯算法

时间:2019-04-23 18:44:36

标签: recursion backtracking

不确定如何编写Word查找类来为我的Boggle C ++程序做回溯,实际上只是一起迷路了,可以使用一些帮助。此类负责查找玩家可以从棋盘上猜到的所有可能单词并将其存储在集合中。至此,我已经添加了所有已完成的工作以及wordfind类本身的测试用例。

除了构造函数之外,此类还应具有以下方法:

GetAllWords(GameBoard g) 负责设置参数以调用查找所有可能单词的递归回溯帮助器函数。提示:您可以调用递归帮助器函数16次,每个起始位置一次。

AppendDFSWords(GameBoard g,std :: string stringPrefix,std :: set&foundWords,bool已选中[16],int currentCell) 这是运行递归回溯算法的辅助函数。它接收一个板g,当前构建的单词stringPrefix,当前在板上找到的所有单词的集合,一个表示板上字符是否已被使用的数组以及网格中的当前位置。请注意,位置是单个整数,您可以根据行主格式将其转换为网格中的行和列。请记住,此功能应该在黑板上找到所有可能的单词,而不仅仅是一个单词。

测试用例

#define CATCH_CONFIG_MAIN

#include "catch/catch.hpp"
#include "../word_find.hpp"
#include "../gameboard.hpp"

TEST_CASE("Checking word list finder")
{
    WordFind wordFinder; // need instance to house an instance of a lookup dictionary
    GameBoard g("GGGGGGGGGGGGGGGG"); // No words
    REQUIRE(wordFinder.GetAllWords(g).size() == 0);

    GameBoard g2("AAAAAAAAAAAAAAAH"); // AHA should be only word

    REQUIRE(wordFinder.GetAllWords(g2).size() == 1);

    GameBoard g3("ABHGDGEINSGEHTAC");
    REQUIRE(wordFinder.GetAllWords(g3).size() == 38);
}

// Compile & run:
// make clean test

dictionary.hpp

#ifndef DICTIONARY_HPP
#define DICTIONARY_HPP
#include <iostream>
#include <string>
#include <unordered_set>
#include <fstream>
#include <sstream>

class Dictionary
{
    private:
        std::unordered_set<std::string> dictionary;
    public:
        Dictionary();
        bool IsWord(std::string word);
};
#endif

dictionary.cpp

#include "dictionary.hpp"

/*
 This class holds all possible words that could appear in any game. 
 This class will read from words.txt to get all possible words, and then 
 allow the program to check for whether a word exists. 
 Note that we are using a set in this case for quick access 
 (an array would be O(n) which in this case could be substantially longer). 
 The constructor will load the words, while IsWord will return whether or not a 
 string is a word.
*/

Dictionary::Dictionary()
{
    std::ifstream infile;
    infile.open("words.txt");
    std::string line = "";
    while (!infile.eof())//std::getline(infile, line)
    {
        infile >> line;
        dictionary.insert(line);
    }
    infile.close();
}

bool Dictionary::IsWord(std::string word)
{
    bool isWord = false;

    if(dictionary.find(word) != dictionary.end())
    {
        isWord = true;
    }
    return isWord;
}

gameboard.hpp

#ifndef GAMEBOARD_HPP
#define GAMEBOARD_HPP
#include "die.hpp"
#include <iostream>
#include <string>

class GameBoard
{
    private:
        char letters[4][4];
    public:
        GameBoard(std::string letters);
        char GetLetterByRowCol(int row, int col);
        std::string ShowBoard();
};
#endif

gameboard.cpp

#include "gameboard.hpp"

GameBoard::GameBoard(std::string letters)
{
    for(int i = 0; i < 4; ++i)
    {
        for(int j = 0; j < 4; ++j)
        {
            this->letters[i][j] = letters[i * 4 + j];

        }
    }
}

char GameBoard::GetLetterByRowCol(int row, int col)
{
    /*
     *Returns the character at the specified row and column.
    */
    return this->letters[row][col];
}

std::string GameBoard::ShowBoard()
{
    /*
     *Returns a string representation of the board (should include new lines as needed).
    */
    std::string output = "";
    for(int i = 0; i < 4; ++i) 
    {
        for(int j = 0; j < 4; ++j) 
        {
            output += letters[i][j];
            if(j < 3 )
            {
                output += " ";
            }
        }
        output += "\n";
    }
    return output;
}

die.hpp

#ifndef DIE_HPP
#define DIE_HPP
#include <iostream>
#include <string>
#include <cstdlib>

class Die
{
    private:
        char possibleLetters[6];
    public:
        Die(std::string possibleLetters);
        char Roll();
};
#endif

die.cpp

#include "die.hpp"
/*
* This class is responsible for handling a die (singular of dice) in the game. 
* You need to pass in a string of 6 possible characters. Each character represents 
* one possible side of the die. The roll method will randomly select one of the 
* six characters and return the result.
*/

Die::Die(std::string possibleLetters)
{
    for(int i = 0; i < 6; ++i)
    {
        this->possibleLetters[i] = possibleLetters.at(i);
    }
}

char Die::Roll()
{
    int roll = rand()%6;
    return possibleLetters[roll];
}

wordfind.hpp

#ifndef WORDFIND_HPP
#define WORDFIND_HPP
#include "dictionary.hpp"
#include "gameboard.hpp"
#include "die.hpp"
#include <iostream>
#include <unordered_set>
#include <string>

class WordFind
{
    private:
        Dictionary dictionary;
        void AppendDFSWords(GameBoard g, std::string stringPrefix, 
                std::set<std::string>& foundWords, bool alreadyChosen[16], int currentCell);
    public:
        WordFind();
        std::set<std::string> GetAllWords(GameBoard g);
};
#endif

wordfind.cpp

#include "wordfind.hpp"

WordFind::WordFind()
{

}

void WordFind::AppendDFSWords(GameBoard g, std::string stringPrefix, 
    std::set<std::string>& foundWords, bool alreadyChosen[16], int currentCell)
{
    /*
        This is the helper function that runs the recursive backtracking algorithm. 
        It takes in a board g, the currently built word stringPrefix, the set of all 
        words currently found on the board, an array denoting whether a character on 
        the board has already been used, and the current position in the grid. 
        Note, that positions are as a single integer which you can convert to a row and
        column in the grid based on row major form. Keep in mind that this function 
        should find ALL possible words in the board, and not just a single word.
    */

}

std::set<std::string> WordFind::GetAllWords(GameBoard g)
{
    /*
     * Responsible for setting up the arguments to call the recursive 
     * backtracking helper function that finds all possible words. Hint: you can call 
     * the recursive helper function 16 times, once for each starting location.
    */
}

0 个答案:

没有答案