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.