CS106B Assignment #4:Boggle

The game of Boggle

任务地址:https://see.stanford.edu/materials/icspacs106b/H22-Assign4Boggle.pdf

一个人机比赛的拼字游戏

It's time for a CS106 classic, the venerable word game Boggle!

核心部分还是递归,写多了真感觉大同小异;

比较难的是九宫格移动时的条件设计,采用双重循环省去类很多重复代码。

还有新的递归结构 :递归结构:if(递归条件) { 标记; 递归; 解除标记;}

和迷宫回溯一样的理念,标记递归过的地方,递归结束时再解除标记,以前为采用的是set类存储递归过的地方

代码:

#include <iostream>
#include "strutils.h"
#include "random.h"
#include "lexicon.h"
#include "simpio.h"
#include "grid.h"
#include "vector.h"
#include "set.h"
#include <string>

using namespace std;
const int Bordsize = 4;
//stanford定义的字符串
string StandardCubes[16]  =
        {"AAEEGN", "ABBJOO", "ACHOPS", "AFFKPS", "AOOTTW", "CIMOTU", "DEILRX", "DELRVY",
         "DISTTY", "EEGHNW", "EEINSU", "EHRTVW", "EIOSST", "ELRTTY", "HIMNQU", "HLNNRZ"};

//board二维数组的建立部分//
Vector<string> StringArrayToVector(string arr[], int boardSize)
{
    Vector<string> vec;
    int size = boardSize * boardSize;
    for (int i = 0; i < size; i++)
    {
        vec.add(arr[i]);
    }
    return vec;
}
void FillBoard(Grid<string> &board, Vector<string> &letters)
{
    int count = 0;
    for (int row = 0; row < board.numRows(); row++)
    {
        for (int col = 0; col < board.numCols(); col++)
        {
            board.setAt(row,col,letters[count]);
            count++;
        }
    }
}
void ShuffleBoardCubes(Grid<string> &board)
{
    for (int row = 0; row < board.numRows(); row++)
    {
        for (int col = 0; col < board.numCols(); col++)
        {
            int randomRow = RandomInteger(row, board.numRows()-1);
            int randomCol = RandomInteger(col, board.numCols()-1);
            string tmp = board.getAt(row,col);
            board.setAt(row,col,board.getAt(randomRow,randomCol));
            board.setAt(randomRow,randomCol,tmp);
        }
    }
}
void ShuffleCubeLetters(Grid<string> &board)
{
    for (int row = 0; row < board.numRows(); row++)
    {
        for (int col = 0; col < board.numCols(); col++)
        {
            string cubeString = board.getAt(row,col);
            int randomChar = RandomInteger(0,cubeString.size()-1);
            string letter = cubeString.substr(randomChar, 1);
            board.setAt(row,col,letter);
        }
    }
}

Grid<string> BoardSetup(){
    int boardSize = Bordsize;  //设定board大小
    Grid<string> board(boardSize, boardSize);
    Vector<string> cube;
    cube = StringArrayToVector(StandardCubes, boardSize);//获取填充用的vector
    FillBoard(board, cube);//将cube填入board中, 得到二维数组, 内容为6字符的字符串
    ShuffleBoardCubes(board);  //打乱次序
    ShuffleCubeLetters(board); //从字符串中随机选择一个字符填入
    return  board;
}
/核心找答案部分/
//递归函数
void FindCompWords(Grid<string> &board, Lexicon &lex, int row, int col,
                   string soFar, Set<string> & allsoultions)
{
    string letter = board.getAt(row,col); // 取出单词
    string current = soFar + letter.substr(0,1); // 加入current
    // 如果找到单词结束递归
    if (current.length() >= 4 && lex.containsWord(current))
    {
        if(!(allsoultions.contains(current))){
            string temp = ConvertToLowerCase(current);
            allsoultions.add(temp);
        }
        return;
    }
    // 如果不含前缀结束递归
    if (!lex.containsPrefix(soFar))
    {
        return;
    }
    // 递归结构:条件{  标记; 递归; 解除标记;}
    for (int vert = -1; vert <= 1; vert++)
    {
        for (int horiz = -1; horiz <= 1; horiz++)
        {
            // 递归条件:不超过边界 && 没被标记 && 不同时为0(本身)
            if (row + vert >= 0 && row + vert < board.numRows() &&
                col + horiz >= 0 && col + horiz < board.numCols() &&
                board.getAt(row + vert, col + horiz) != "~" &&
                !(horiz == 0 && vert == 0))
            {
                board.setAt(row,col,"~"); //  标记
                FindCompWords(board,lex,row+vert,col+horiz,current,allsoultions);//递归
                board.setAt(row,col,letter); // 递归结束后取消标记
            }
        }
    }
}
//递归主函数
Set<string> getallsolution(Grid<string> board, Lexicon lex){
    int boardSize = board.numRows();
    Set<string> allsolutions;
    //设定递归传入参量:首字母的行列,初始量soFar, 判别量allsolution
    for (int row = 0; row < boardSize; row++)
    {
        for (int col = 0; col < boardSize; col++)
        {
            string soFar = "";
            FindCompWords(board,lex,row,col,soFar,allsolutions);
        }
    }
    return allsolutions;
}
用户输入部分//
void ParseGuess(string word, Set<string> &guesses,Set<string> & allsolutions )
{

    if (guesses.contains(word))//判断是否录过该单词
    {
        cout << "You've already guessed that word!" << endl;
        return;
    }
    if (word.length() < 4)
    {
        cout << "Not a valid word!" << endl;
        return;
    }
    // 找到单词
    bool haveword = false;
    if(allsolutions.contains(word)){
        guesses.add(word);
        allsolutions.remove(word);
        haveword = true;
        }
    if(!haveword)
        cout << "Couldn't find word on board." << endl;
}

//返回用户输入的得到的正确单词组
Set<string> PlayerTurn(Set<string> & allsolutions){
    Set<string> guesses;
    string word;
    while(true)
    {
        cout << endl << "Enter a word: ";
        word = GetLine();
        word = ConvertToLowerCase(word);
        if (word == "") break;
        ParseGuess(word, guesses, allsolutions);
    }
    return guesses;
}
///画图打印部分/
//把board画出
void DrawBoard(Grid<string> board){
    system("clear");
    for (int i = 0; i < Bordsize; i++) {
        cout << "+---";
    }
    cout << "+" << endl;

    for (int i = 0; i < Bordsize; i++) {
        for (int j = 0; j < Bordsize; j++) {
            cout << "| " << board[i][j] << " ";
        }
        cout << "|" << endl;
        for (int k = 0; k < Bordsize; k++) {
            cout << "+---";
        }
        cout << "+" << endl;
    }
}
//打印成绩和单词
void printset(Set<string> set){
    int score =0;
    int i = 0;
    Set<string>::Iterator It = set.iterator();
    while(It.hasNext()){
        string temp = It.next();
        score += temp.size();
        cout << temp <<" ";
        if((++i)%10 == 0)
            cout <<" "<<endl;
    }
    cout <<endl;
    cout <<"\nthe scores are : "<<score<<endl;
    cout << "---------------------------------------------------------"<<endl;

}
//游戏结构部分//
//欢迎
void Welcome() {
    cout << "Welcome to my Game ! "<< endl;
    cout << "Hit return when you're ready...";
    GetLine();
    cout << endl;
}
//游戏开始
void StartGame(Lexicon &lex){
    Grid<string> board = BoardSetup();  //得到board
    DrawBoard(board);
    Set<string> allsolutions = getallsolution(board, lex);//找出所有可能的单词


    Set<string> playersoltuion = PlayerTurn(allsolutions);
    cout << "-- Your sollution is :\n"<<endl;
    printset(playersoltuion);

    Set<string> computersolution = allsolutions;
    cout << "-- The computer's sollution is :\n"<<endl;
    printset(computersolution);

}
//设定是否继续
bool PlayAgain()
{
    bool rerun = false;
    while(true)
    {
        cout << endl << "Play again? (Y/N) ";
        string answer = GetLine();
        answer = ConvertToUpperCase(answer);
        if (answer == "Y" || answer == "YES")
        {
            rerun = true;
            break;
        }
        else if (answer == "N" || answer == "NO")
        {
            rerun = false;
            break;
        }
    }
    return rerun;
}
///

int main()
{
    Randomize();
    Welcome();
    Lexicon lex("/Users/elwg/ClionProjects/myboggle/lexicon.dat");
    StartGame(lex);

    while(true)
    {
        if(PlayAgain())
        {
            cout << endl;
            StartGame(lex);
        }
        else
            break;
    }
    return 0;
}

结果展示:

Welcome to my Game ! 
Hit return when you're ready...

+---+---+---+---+
| I | H | E | A |
+---+---+---+---+
| O | N | T | R |
+---+---+---+---+
| D | G | C | R |
+---+---+---+---+
| O | R | M | N |
+---+---+---+---+

Enter a word: neat

Enter a word: 
-- Your sollution is :

neat 

the scores are : 4
---------------------------------------------------------
-- The computer's sollution is :

crate doing done dong dorm earth eath ethion gone hear  
heat hent hind hint hone hong inearth inert inter near  
odor ohing ordo rate rath rend rent tare tear tend  
then thin thio thong trend 

the scores are : 153
---------------------------------------------------------

Play again? (Y/N) 

 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!对于 CS106B 的环境搭建,您可以按照以下步骤进行操作: 1. 首先,确保您的计算机上已经安装了 C++ 的编译器。推荐使用 g++ 或者 clang++,您可以在终端中输入 `g++ --version` 或者 `clang++ --version` 来检查是否已经安装。 2. 接下来,您需要下载并安装 Stanford 的 C++ 标准库。您可以在 Stanford 的官方网站上找到这个库的下载链接。下载完成后,将其解压到您自定义的目录中。 3. 现在,您可以下载 CS106B 的课程代码。您可以在 Stanford 的官方网站上找到这些代码的下载链接。下载完成后,将其解压到您自定义的目录中。 4. 打开您喜欢的集成开发环境(IDE),例如 Visual Studio Code、Xcode 或者 Eclipse。创建一个新的项目,并将 CS106B 的课程代码添加到该项目中。 5. 配置项目的编译选项,确保编译器能够找到 Stanford 的 C++ 标准库。具体操作方式取决于您使用的 IDE。通常情况下,您需要添加标准库的路径和头文件的路径。 6. 现在,您可以开始编写和运行 CS106B 的代码了!根据课程要求,您可以选择运行命令行程序或者图形化界面程序。 请注意,这些步骤可能会因为您使用的操作系统和开发工具而略有不同。如果您遇到任何问题,建议您查阅课程文档或者向您的教师或同学寻求帮助。祝您在 CS106B 中取得好成绩!如果您还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值