admin管理员组

文章数量:1297135

I'm working on a dice project that rolls dice until the target number is rolled. I'm trying to figure out how to print the dice side by side instead of in a line. I've attached an image of the current output when I run the code.

using namespace std;

#include <iostream>
#include <cstdlib> // rand and srand
#include <ctime> // time

void diceImage(int value) { // Dice 1 through 6
    switch (value) {
    case 1: cout << " ------- " << endl << "|       |\n" << "|   *   |\n" << "|          |" << endl << " ------- " << endl; break;
    case 2: cout << " ------- " << endl << "|*      |\n" << "|       |\n" << "|      *|" << endl << " ------- " << endl; break;
    case 3: cout << " ------- " << endl << "|*      |\n" << "|   *   |\n" << "|      *|" << endl << " ------- " << endl; break;
    case 4: cout << " ------- " << endl << "|*     *|\n" << "|       |\n" << "|*     *|" << endl << " ------- " << endl; break;
    case 5: cout << " ------- " << endl << "|*     *|\n" << "|   *   |\n" << "|*     *|" << endl << " ------- " << endl; break;
    case 6: cout << " ------- " << endl << "|*     *|\n" << "|*     *|\n" << "|*     *|" << endl << " ------- " << endl; break;
    }
    using namespace std;

}

int main() {
    srand(time(0));

    int target_number;
    int die1, die2, die3, die4, die5, total_roll;
    int num_tries = 0;

    // Get user input and validate
    do {
        cout << "Enter a number between 5 and 30: ";
        cin >> target_number;
        if (target_number < 5 || target_number > 30) {
            cout << "Invalid input. Please enter a number between 5 and 30." << endl;
        }
    } while (target_number < 5 || target_number > 30);

    // Roll dice until the total matches the target
    do {
        die1 = rand() % 6 + 1; // Generate random number between 1 and 6 for die 1
        diceImage(die1); // Generate image for die 1
        die2 = rand() % 6 + 1; // Generate random number between 1 and 6 for die 2
        diceImage(die2); // Generate image for die 2
        die3 = rand() % 6 + 1;
        diceImage(die3);
        die4 = rand() % 6 + 1;
        diceImage(die4);
        die5 = rand() % 6 + 1;
        diceImage(die5);
        total_roll = die1 + die2 + die3 + die4 + die5;
        cout << "Die 1: " << die1 << ", Die 2: " << die2 << ", Die 3: " << die3 << ", Die 4: " << die4 << ", Die 5: " << die5 << ", Total: " << total_roll << endl;
        num_tries++;
    } while (total_roll != target_number);

    cout << "It took " << num_tries << " rolls to get " << target_number << "." << endl;

    return 0;
}

I'm working on a dice project that rolls dice until the target number is rolled. I'm trying to figure out how to print the dice side by side instead of in a line. I've attached an image of the current output when I run the code.

using namespace std;

#include <iostream>
#include <cstdlib> // rand and srand
#include <ctime> // time

void diceImage(int value) { // Dice 1 through 6
    switch (value) {
    case 1: cout << " ------- " << endl << "|       |\n" << "|   *   |\n" << "|          |" << endl << " ------- " << endl; break;
    case 2: cout << " ------- " << endl << "|*      |\n" << "|       |\n" << "|      *|" << endl << " ------- " << endl; break;
    case 3: cout << " ------- " << endl << "|*      |\n" << "|   *   |\n" << "|      *|" << endl << " ------- " << endl; break;
    case 4: cout << " ------- " << endl << "|*     *|\n" << "|       |\n" << "|*     *|" << endl << " ------- " << endl; break;
    case 5: cout << " ------- " << endl << "|*     *|\n" << "|   *   |\n" << "|*     *|" << endl << " ------- " << endl; break;
    case 6: cout << " ------- " << endl << "|*     *|\n" << "|*     *|\n" << "|*     *|" << endl << " ------- " << endl; break;
    }
    using namespace std;

}

int main() {
    srand(time(0));

    int target_number;
    int die1, die2, die3, die4, die5, total_roll;
    int num_tries = 0;

    // Get user input and validate
    do {
        cout << "Enter a number between 5 and 30: ";
        cin >> target_number;
        if (target_number < 5 || target_number > 30) {
            cout << "Invalid input. Please enter a number between 5 and 30." << endl;
        }
    } while (target_number < 5 || target_number > 30);

    // Roll dice until the total matches the target
    do {
        die1 = rand() % 6 + 1; // Generate random number between 1 and 6 for die 1
        diceImage(die1); // Generate image for die 1
        die2 = rand() % 6 + 1; // Generate random number between 1 and 6 for die 2
        diceImage(die2); // Generate image for die 2
        die3 = rand() % 6 + 1;
        diceImage(die3);
        die4 = rand() % 6 + 1;
        diceImage(die4);
        die5 = rand() % 6 + 1;
        diceImage(die5);
        total_roll = die1 + die2 + die3 + die4 + die5;
        cout << "Die 1: " << die1 << ", Die 2: " << die2 << ", Die 3: " << die3 << ", Die 4: " << die4 << ", Die 5: " << die5 << ", Total: " << total_roll << endl;
        num_tries++;
    } while (total_roll != target_number);

    cout << "It took " << num_tries << " rolls to get " << target_number << "." << endl;

    return 0;
}

Share Improve this question edited Feb 11 at 19:40 Remy Lebeau 598k36 gold badges503 silver badges848 bronze badges asked Feb 11 at 16:13 semajamossemajamos 412 bronze badges 10
  • 1 Please add output and expected output as text in the question – 463035818_is_not_an_ai Commented Feb 11 at 16:17
  • 2 Standard C++ only allows streamed output. Unless you want to use external libraries, the only way would be for function to get all values and print it row by row – Yksisarvinen Commented Feb 11 at 16:20
  • Instead of displaying directly, you might feeds 5 lines, and display them once the 5 dice has been added. – Jarod42 Commented Feb 11 at 16:21
  • 2 Side note: instead of naming those dice die1, die2, etc., create an array: int dice[5]; and then you can write a loop: for (int i = 0; i < 5; ++i) { dice[i] = rand() % 6 + 1; diceimage(dice[i]); } instead of writing the same code five times. – Pete Becker Commented Feb 11 at 16:32
  • 2 Is it enough/fine to just use single Unicode character: symbl/en/unicode/blocks/miscellaneous-symbols/#subblock-2680. ⚀ ⚁ ⚂ ⚃ ⚄ ⚅ – Marek R Commented Feb 11 at 16:43
 |  Show 5 more comments

4 Answers 4

Reset to default 10

You have to just print consecutive lines of dice for all dices at once. Whole line for all dices at once and iterate over each line.

using namespace std::literals;

constexpr size_t DiceHight = 5;
constexpr auto DicesView = std::to_array<std::array<std::string_view, DiceHight>>({
    {
        "+-------+"sv,
        "|       |"sv,
        "|   *   |"sv,
        "|       |"sv,
        "+-------+"sv,
    },
    {
        "+-------+"sv,
        "| *     |"sv,
        "|       |"sv,
        "|     * |"sv,
        "+-------+"sv,
    },
    {
        "+-------+"sv,
        "| *     |"sv,
        "|   *   |"sv,
        "|     * |"sv,
        "+-------+"sv,
    },
    {
        "+-------+"sv,
        "| *   * |"sv,
        "|       |"sv,
        "| *   * |"sv,
        "+-------+"sv,
    },
    {
        "+-------+"sv,
        "| *   * |"sv,
        "|   *   |"sv,
        "| *   * |"sv,
        "+-------+"sv,
    },
    {
        "+-------+"sv,
        "| *   * |"sv,
        "| *   * |"sv,
        "| *   * |"sv,
        "+-------+"sv,
    },
});

void printDiceSequnce(std::span<const int> sequence, std::string_view separator = " "sv)
{
    for (size_t i = 0; i < DiceHight; ++i) {
        std::string_view sep;
        for (auto x : sequence) {
            std::cout << sep << DicesView[x - 1][i];
            sep = separator;
        }
        std::cout << '\n';
    }
}

void printDiceSequnce(std::initializer_list<int> sequence, std::string_view separator = " "sv)
{
    printDiceSequnce(std::span<const int> { sequence.begin(), sequence.size() }, separator);
}

https://godbolt./z/n9K6crGE6

Instead of displaying directly, you might feeds 5 lines, and display them once all the dice have been added, something like

struct Output
{
    std::string lines[5];
};


void Print(const Output& output)
{
    for (const auto& line : output.lines) {
        std::cout << line << std::endl;
    }
}

void AppendDiceImage(Output& output, int value) { // Dice 1 through 6
    output.lines[0] += " -------  ";
    switch (value) {
    case 1: {
        output.lines[1] += "|       | ";
        output.lines[2] += "|   *   | ";
        output.lines[3] += "|       | ";
        break;
    }
    case 2: {
        output.lines[1] += "|*      | ";
        output.lines[2] += "|       | ";
        output.lines[3] += "|      *| ";
        break;
    }
    case 3: {
        output.lines[1] += "|*      | ";
        output.lines[2] += "|   *   | ";
        output.lines[3] += "|      *| ";
        break;
    }
    case 4: {
        output.lines[1] += "|*     *| ";
        output.lines[2] += "|       | ";
        output.lines[3] += "|*     *| ";
        break;
    }
    case 5: {
        output.lines[1] += "|*     *| ";
        output.lines[2] += "|   *   | ";
        output.lines[3] += "|*     *| ";
        break;
    }
    case 6: {
        output.lines[1] += "|*     *| ";
        output.lines[2] += "|*     *| ";
        output.lines[3] += "|*     *| ";
        break;
    }
    }
    output.lines[4] += " -------  ";
}

Demo

I'd suggest some library for more sophisticated output. What you can do yourself without too much effort is accumulate lines and only print them when you have all output ready.

As a first step, consider this code:

#include <iostream>
#include <string>
#include <array>

std::array<std::string,2> foo(int i) {
    return {std::string(i,'*')+"x",std::string(i,'x')+"*"};
}

int main() {
    std::array<std::string,2> output;
    for (int i=0;i<3;++i) {
        auto lines = foo(i);
        for (const auto& line : lines) std::cout << line << "\n";
    }
}

foo returns one "block" of output. It's two lines, first i-times * followed by a x and i-times x followed by a *. The output is:

x
*
*x
x*
**x
xx*

If you want to have all block printed horizontally rather than vertically you just have to store the lines to print them when all output is available:

#include <iostream>
#include <string>
#include <array>

std::array<std::string,2> foo(int i) {
    return {std::string(i,'*')+"x",std::string(i,'x')+"*"};
}

int main() {
    std::array<std::string,2> output;
    for (int i=0;i<3;++i) {
        auto lines = foo(i);
        for (size_t i=0;i<output.size();++i) output[i] += lines[i];
    }
    for (const auto& line : output) std::cout << line << "\n";
}

It prints:

x*x**x
*x*xx*

Concatenating strings can be rather expensive. You could use std::stringstreams to accumulate the output and only construct the string before printing it.

The logical error in your code is that you mix up representation with display logic.

Instead of having cout and endl inside diceImage, create an array of lines, which will be an array of strings and then you will end up having the proper structure for your dice. So this is how you can display multiple dices into the same row (I replaced my code with the one @463035818_is_not_an_ai provided in the fiddle he linked to in the comment-section, kudos to this person):

#include <iostream>
#include <string>
#include <array>
#include <vector>

std::array<std::string,5> diceImage(int value) {
    
    switch (value) {
        case 1: return std::array<std::string,5> {" ------- ","|       |", "|   *   |","|       |"," ------- "}; break;
        //Implement case 2, case 3, etc. in similar fasion
    }
    return {};
}

void displayMultipleDice(const std::vector<std::array<std::string,5>>& dice, std::string diceSeparator, std::string lineSeparator) {
    std::array<std::string,5> lines{};    
    for (size_t d = 0; d < dice.size(); d++) {
        for (int line = 0; line < 5; line++) {
            lines[line] += dice[d][line] + diceSeparator;
        }
    }
    for (size_t line = 0; line < 5; line++) {
        if (line > 0) {
            std::cout << lineSeparator;
        }
        std::cout << lines[line];
    }
}

int main() {
    std::vector<std::array<std::string,5>> die;
    die.push_back(diceImage(1));
    die.push_back(diceImage(1));
    die.push_back(diceImage(1));
    displayMultipleDice(die," - ", "\n");
}

The idea is that you build an array of lines for each dice, then you merge each cluster of corresponding lines into a single line and do the displaying.

本文标签: cMulti Dice Rolling GameStack Overflow