简体   繁体   中英

C++ - Class for list with 3 elements

I'm attempting to make a data type that is basically an associative array/map, but it would have 3 elements instead of 2. It would be implemented like this:

myTable rouletteBoard;
rouletteBoard.push.back(0, "Green", "Neither");
rouletteBoard.push.back(00, "Green", "Neither");
rouletteBoard.push.back(1, "Red", "Odd");

So really just a map or list with 3 elements, the first one being the unique key.

Yes this is a Roulette game. And I understand how to basically have a class for each number and make a separate instance for each number with the appropriate properties, but I feel that would be rather inefficient, since I could just have a list of each number with it's associated properties.

I've gotten pretty much nowhere on creating the class for this. I keep wondering if there is a better way to do it and trying that, then getting frustrated and quitting.

First let's talk about the data. Note that 0 must be distinguished from 00 so we cannot store them both naively as integers. Second, note that the color and parity (odd/even) can be derived instantly from the number. There is no need to store them as separate data. So we can do this:

struct Pocket {
    enum class Color { GREEN, RED, BLACK };
    enum class Parity { NONE, ODD, EVEN };

    Pocket(int8_t num) : number(num) {}

    int8_t number; // -1 for "00" on American style wheel

    Parity parity() const {
        if (number < 1) return Parity::NONE;
        if (number % 2) return Parity::ODD;
        return Parity::EVEN;
    }

    Color color() const {
        if (number < 1) return Color::GREEN;
        if (number % 2) return Color::RED;
        return Color::BLACK;
    }
};

Then you can make a simple container:

std::vector<Pocket> wheel;
for (int8_t ii = is_american ? -1 : 0; ii <= 36; ++ii) {
    wheel.emplace_back(ii);
}

Finally, you can add code for printing:

std::ostream& operator <<(std::ostream& out, Pocket pocket) {
    if (pocket.number == -1) return out << "00";
    return out << pocket.number;
}

const char* to_string(Pocket::Color color) {
    switch (color) {
        case Pocket::Color::GREEN: return "Green";
        case Pocket::Color::RED: return "Red";
        case Pocket::Color::BLACK: return "Black";
        default: return "?";
    }
}

If you want an associative array with multiple data, you create a map between a key and a data-structure.

For example here, if you only wanted to store strings, I'd suggest using a map between a key and a vector. Then you can add as many or as few strings as needed to each key, so it's a flexible system.

std::map<int,std::vector<std::string>> rouletteBoard;

Or, have that structure inside your "rouletteBoard" class.

As for the key, if you use literal ints, then you have a problem, as 0 and 00 would be the same int, you either need string keys, or to specify "00" interally with a special value such as -1. You can then create an enum relating to the different fields of the vector, a working prototype could look like:

#include<iostream>
#include<map>
#include<string>
#include<vector>

std::map<int, std::vector<std::string>> rouletteBoard;

enum
{
    name,
    color,
    oddeven,
    property_count
};

std::string colors[] = { "Green", "Black", "Red"};

std::string roulette_color(int i)
{
    if (i < 1) return colors[0]; // Green
    if (i < 11) return colors[1 + (i & 1)]; // Black=Even Red=Odd
    if (i < 19) return colors[2 - (i & 1)]; // Black=Odd Red=Even
    if (i < 29) return colors[1 + (i & 1)]; // Black=Even Red=Odd
    return colors[2 - (i & 1)]; // Black=Even Red=Odd
}
int main()
{
    rouletteBoard[-1] = {"00", roulette_color(-1), "Neither"};
    rouletteBoard[ 0] = { "0", roulette_color(0), "Neither" };

    for(int i = 1; i <=36; ++i)
    {
        rouletteBoard[i] = { std::to_string(i), roulette_color(i), (i & 1) ? "Odd" : "Even" };
    }

    for (int i = -1; i <= 36; ++i)
    {
        std::cout << rouletteBoard[i][name] << ": " << rouletteBoard[i][color] << ", " << rouletteBoard[i][oddeven] << "\n";
    }

    std::cin.get();
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM