Hangman C ++从字符串数组打印形状

时间:2017-03-03 02:50:14

标签: c++ arrays string

我正在编写一个刽子手游戏。我有一个字符串数组,由10个不同的hangman形状组成。让我说我的字符串数组叫做myHangmanPics:

std::string myHangmanPics[9];

以下是一个索引中包含的内容的示例:

Example of a text shape (pistol) which I've stored in myHangmanPics[0]

数组的每个索引(大小为10)包含不同的hangman形状,例如上面的那个。我使用随机数生成器为hangman形状数组随机选择一个索引(从0到9),因此是一个随机的hangman形状。

好的,现在问题。

我想从所选索引中为每个错误的用户猜测打印出一行挂起形状(连续)。第一个猜测将打印第一行,这只是下图中的下划线。第二个错误的猜测将打印第二行,依此类推,直到整个形状被打印出来。这是我的意思的一个例子:

Desired output after 1-5 wrong guesses.

我已成功地弄清楚如何注册错误的猜测,但我一次难以打印出一行。形状确实有一个换行符' \ n'在每一行形状的末尾,如第一张图片所示。

鉴于此信息,实现此最简单的方法是什么?非常感激。

1 个答案:

答案 0 :(得分:0)

这里的Merge函数将两个字符串组合为2D图像,将空格视为透明。两个字符串中的第一个字符将位于结果的左上角位置。 main中的示例演示了如何使用换行和空格填充在合并结果中定位字符串。

已修改为包含不使用自动

的相同代码的版本
#include <iostream>
#include <string>

// NextLine returns the substring in s starting at pos and ending
// in a newline character (not included).
// pos is set to the beginning of the next line, or the
// length of the string if the end is reached.
std::string NextLine(const std::string &s, std::size_t &pos) {
    if(pos >= s.length()) { return {}; }
    const auto start = pos;
    const auto nlpos = s.find('\n', start);
    if(nlpos == std::string::npos) {
        pos = s.length();
        return s.substr(start); 
    } else {
        pos = nlpos + 1;
        return s.substr(start, nlpos - start);
    }
}

// Merge creates a compisition of two strings
// The space character is treated as transparent
// If two non-transparent characters occupy the same
// position, the character from string b is used.
std::string Merge(std::string a, std::string b) {
    std::size_t pos_a=0, pos_b=0;
    std::string result;
    while(pos_a < a.length() || pos_b < b.length()) {
        if(!result.empty()) { result += '\n'; }
        auto line_a = NextLine(a, pos_a);
        auto line_b = NextLine(b, pos_b);
        auto len = line_a.length();
        if(len > line_b.length()) {
            line_b += std::string(len - line_b.length(), ' ');
        }
        else if(len < line_b.length()) {
            len = line_b.length();
            line_a += std::string(len - line_a.length(), ' ');
        }
        for(std::size_t i=0; i<len; ++i) {
            result += line_b[i] == ' ' ? line_a[i] : line_b[i];
        }
    }
    return result;
}

int main() {
    std::string parts[] = {
        " O ",
        "\n | ",
        "\\ /",
        "\n\n/ \\"
    };
    std::string man;
    bool first = true;
    for(auto p : parts) {
        if(first) { first = false; }
        else      { std::cout << "---\n"; }
        man = Merge(man, p);
        std::cout << man << '\n';
    }
}

输出

 O 
---
 O 
 | 
---
\O/
 | 
---
\O/
 | 
/ \

这是一个不使用auto的版本:

#include <iostream>
#include <string>

std::string NextLine(const std::string &s, std::size_t &pos) {
    if(pos >= s.length()) { return {}; }
    const std::size_t start = pos;
    const std::size_t nlpos = s.find('\n', start);
    if(nlpos == std::string::npos) {
        pos = s.length();
        return s.substr(start); 
    } else {
        pos = nlpos + 1;
        return s.substr(start, nlpos - start);
}   }
std::string Merge(std::string a, std::string b) {
    std::size_t pos_a=0, pos_b=0;
    std::string result;
    while(pos_a < a.length() || pos_b < b.length()) {
        if(!result.empty()) { result += '\n'; }
        std::string line_a = NextLine(a, pos_a);
        std::string line_b = NextLine(b, pos_b);
        std::size_t len = line_a.length();
        if(len > line_b.length()) {
            line_b += std::string(len - line_b.length(), ' ');
        } else if(len < line_b.length()) {
            len = line_b.length();
            line_a += std::string(len - line_a.length(), ' ');
        }
        for(std::size_t i=0; i<len; ++i) {
            result += line_b[i] == ' ' ? line_a[i] : line_b[i];
    }   }
    return result;
}
int main() {
    std::string parts[] = {" O ", "\n | ", "\\ /", "\n\n/ \\" };
    std::string man;
    for(std::size_t i=0; i<sizeof(parts)/sizeof(parts[0]); ++i) {
        if(i) { std::cout << "---\n"; }
        man = Merge(man, parts[i]);
        std::cout << man << '\n';
}   }