-1

I wrote a simple program for League that generates a random role (AP, AD, Hybrid, Tank), lane, and champion. You can see the code here:

#include <iostream>
#include <string>
#include <random>
#include <ctime>

using namespace std;

int main()
{
    mt19937 RNG(time(0));
    uniform_int_distribution<int> championRoll(1, 128);
    uniform_int_distribution<int> roleRoll(1, 4);
    uniform_int_distribution<int> laneRoll(1, 5);


    int iChampion, iRole, iLane;
    string Champion, Role, Lane;

    iChampion = championRoll(RNG);
    iRole = roleRoll(RNG);
    iLane = laneRoll(RNG);

    switch (iChampion)
    {
    case 1: Champion = "Aatrox"; break;
    case 2: Champion = "Ahri"; break;
    case 3: Champion = "Akali"; break;
    case 4: Champion = "Alistar"; break;
    case 5: Champion = "Amumu"; break;
    case 6: Champion = "Anivia"; break;
    case 7: Champion = "Annie"; break;
    case 8: Champion = "Ashe"; break;
    case 9: Champion = "Azir"; break;
    case 10: Champion = "Bard"; break;
    case 11: Champion = "Blitzcrank"; break;
    case 12: Champion = "Brand"; break;
    case 13: Champion = "Braum"; break;
    case 14: Champion = "Caitlyn"; break;
    case 15: Champion = "Cassiopeia"; break;
    case 16: Champion = "Cho'Gath"; break;
    case 17: Champion = "Corki"; break;
    case 18: Champion = "Darius"; break;
    case 19: Champion = "Diana"; break;
    case 20: Champion = "Dr. Mundo"; break;
    case 21: Champion = "Draven"; break;
    case 22: Champion = "Ekko"; break;
    case 23: Champion = "Elise"; break;
    case 24: Champion = "Evelynn"; break;
    case 25: Champion = "Ezreal"; break;
    case 26: Champion = "Fiddlesticks"; break;
    case 27: Champion = "Fiora"; break;
    case 28: Champion = "Fizz"; break;
    case 29: Champion = "Galio"; break;
    case 30: Champion = "Gangplank"; break;
    case 31: Champion = "Garen"; break;
    case 32: Champion = "Gnar"; break;
    case 33: Champion = "Gragas"; break;
    case 34: Champion = "Graves"; break;
    case 35: Champion = "Hecarim"; break;
    case 36: Champion = "Heimerdinger"; break;
    case 37: Champion = "Illaoi"; break;
    case 38: Champion = "Irelia"; break;
    case 39: Champion = "Janna"; break;
    case 40: Champion = "Jarvan IV"; break;
    case 41: Champion = "Jax"; break;
    case 42: Champion = "Jayce"; break;
    case 43: Champion = "Jinx"; break;
    case 44: Champion = "Kalista"; break;
    case 45: Champion = "Karma"; break;
    case 46: Champion = "Karthus"; break;
    case 47: Champion = "Kassadin"; break;
    case 48: Champion = "Katarina"; break;
    case 49: Champion = "Kayle"; break;
    case 50: Champion = "Kennen"; break;
    case 51: Champion = "Kha'zix"; break;
    case 52: Champion = "Kindred"; break;
    case 53: Champion = "Kog'Maw"; break;
    case 54: Champion = "Leblanc"; break;
    case 55: Champion = "Lee Sin"; break;
    case 56: Champion = "Leona"; break;
    case 57: Champion = "Lissandra"; break;
    case 58: Champion = "Lucian"; break;
    case 59: Champion = "Lulu"; break;
    case 60: Champion = "Lux"; break;
    case 61: Champion = "Malphite"; break;
    case 62: Champion = "Malzahar"; break;
    case 63: Champion = "Maokai"; break;
    case 64: Champion = "Master Yi"; break;
    case 65: Champion = "Miss Fortune"; break;
    case 66: Champion = "Mordekaiser"; break;
    case 67: Champion = "Morgana"; break;
    case 68: Champion = "Nami"; break;
    case 69: Champion = "Nasus"; break;
    case 70: Champion = "Nautilus"; break;
    case 71: Champion = "Nidalee"; break;
    case 72: Champion = "Nocturne"; break;
    case 73: Champion = "Nunu"; break;
    case 74: Champion = "Olaf"; break;
    case 75: Champion = "Orianna"; break;
    case 76: Champion = "Pantheon"; break;
    case 77: Champion = "Poppy"; break;
    case 78: Champion = "Quinn"; break;
    case 79: Champion = "Rammus"; break;
    case 80: Champion = "Rek'Sai"; break;
    case 81: Champion = "Renekton"; break;
    case 82: Champion = "Rengar"; break;
    case 83: Champion = "Riven"; break;
    case 84: Champion = "Rumble"; break;
    case 85: Champion = "Ryze"; break;
    case 86: Champion = "Sejuani"; break;
    case 87: Champion = "Shaco"; break;
    case 88: Champion = "Shen"; break;
    case 89: Champion = "Shyvana"; break;
    case 90: Champion = "Singed"; break;
    case 91: Champion = "Sion"; break;
    case 92: Champion = "Sivir"; break;
    case 93: Champion = "Skarner"; break;
    case 94: Champion = "Sona"; break;
    case 95: Champion = "Soraka"; break;
    case 96: Champion = "Swain"; break;
    case 97: Champion = "Syndra"; break;
    case 98: Champion = "Tahm Kench"; break;
    case 99: Champion = "Talon"; break;
    case 100: Champion = "Taric"; break;
    case 101: Champion = "Teemo"; break;
    case 102: Champion = "Thresh"; break;
    case 103: Champion = "Tristana"; break;
    case 104: Champion = "Trundle"; break;
    case 105: Champion = "Tryndamere"; break;
    case 106: Champion = "Twisted Fate"; break;
    case 107: Champion = "Twitch"; break;
    case 108: Champion = "Udyr"; break;
    case 109: Champion = "Urgot"; break;
    case 110: Champion = "Varus"; break;
    case 111: Champion = "Vayne"; break;
    case 112: Champion = "Veigar"; break;
    case 113: Champion = "Vel'Koz"; break;
    case 114: Champion = "Vi"; break;
    case 115: Champion = "Viktor"; break;
    case 116: Champion = "Vladimir"; break;
    case 117: Champion = "Volibear"; break;
    case 118: Champion = "Warwick"; break;
    case 119: Champion = "Wukong"; break;
    case 120: Champion = "Xerath"; break;
    case 121: Champion = "Xin Zhao"; break;
    case 122: Champion = "Yasuo"; break;
    case 123: Champion = "Yorick"; break;
    case 124: Champion = "Zac"; break;
    case 125: Champion = "Zed"; break;
    case 126: Champion = "Ziggs"; break;
    case 127: Champion = "Zilean"; break;
    case 128: Champion = "Zyra"; break;
    }

    switch (iRole)
    {
    case 1: Role = "AD"; break;
    case 2: Role = "AP"; break;
    case 3: Role = "Hybrid"; break;
    case 4: Role = "Tank"; break;
    }

    switch (iLane)
    {
    case 1: Lane = "Top"; break;
    case 2: Lane = "Mid"; break;
    case 3: Lane = "ADC"; break;
    case 4: Lane = "Support"; break;
    case 5: Lane = "Jungle"; break;
    }

    cout << Role << " " << Champion << " " << Lane << endl;

    system("PAUSE");
    return 0;
}

What I want to do is have this program generate 5 lines at once. There's two problems with this though.

First problem is that I need the champions and lanes to be unique values, because you can't have two of those in the same game. So I'm not really sure how to do that. Is there a way to put a set of integers into an array, and if there are duplicate numbers, swap delete them and generate new ones instantly? That's just a guess.

The second problem is that my seed is time, so is there a way to make the program wait 1 second each time it generates a line?

Riggs
  • 11
  • 2
  • you may want to look into using a "set" data structure to hold unique values of integers.http://en.cppreference.com/w/cpp/container/set – Beed Jan 07 '16 at 00:59
  • Why do you think you need to wait a second? You only need to set a random seed once and then it generates a random sequence without needing to be re-seeded. Also, what is a "line" in your terminology? I'm not familiar with "League" or most of your other terms, and most of this information seems unnecessary anyway. Are you basically just asking how to generate n random numbers such that there are no repeats? – Ryan Stout Jan 07 '16 at 01:01
  • Look up the `random_shuffle()` algorithm. – Peter Jan 07 '16 at 01:01
  • 2
    Both questions have been asked and answered countless times. Please show some research effort. Also, please post exactly one question per question. This should be closed as duplicate, but your double question prevents people from choosing a single dupe target. – Baum mit Augen Jan 07 '16 at 01:02
  • @BaummitAugen You're right. I'll delete my answer and vote to close as “too broad”. – 5gon12eder Jan 07 '16 at 01:13

1 Answers1

3

First problem is that I need the champions and lanes to be unique values, because you can't have two of those in the same game.

You can solve this problem by creating an array/vector containing all the required lanes, then shuffling it:

std::vector<lane> lanes{lane::top, lane::bot, lane::jng, lane::mid};
std::shuffle(std::begin(lanes), std::end(lanes), RNG);

Afterwards, you can iterate over the lanes vector and it is guaranteed you will get all the lanes in a random fashion.

I suggest creating an helper make_shuffled_vector<T>(...) function to avoid boilerplate.


The second problem is that my seed is time, so is there a way to make the program wait 1 second each time it generates a line?

You should use std::random_device.

std::random_device rd;
std::mt19937_64 gen(rd());

If hardware support is available, a seed is generated using it. Otherwise, the default seed is implementation defined.

I suggest reading this article for more information about default seeding.


Optionally, you could avoid cumbersome and error-prone switch constructs for this problem.

Here's a possible way of solving it cleanly, making use of variadic templates:

template<typename T, typename... Ts>
auto make_shuffled_vector(Ts... xs)
{
    // Note: perfect-forwarding intentionally omitted to 
    // enhance example readability.

    std::vector<T> v{xs...};
    std::shuffle(std::begin(v), std::end(v), RNG);
    return v;
} 

auto champions = make_shuffled_vector<string>(
    "Vayne (best champion.)", "Caitlyn", "Lulu", 
    "Teemo (Satan)", ...);

auto lanes = make_shuffled_vector<string>(
    "mid", "top", "bot(adc)", "bot(sup)", "jng"); 

// You may want roles to be duplicated (not shuffled). 
// This is just an example.
auto roles = make_shuffled_vector<string>(
    "ad", "ap", "tank", "hybrid");

// Get the `i-th` element from `vec`, cycling if end is reached.
auto get_cycled = [](const auto& vec, auto i)
{
    return vec[i % vec.size()];
};

// Get 5 champions:
for(int i = 0; i < 5; ++i) 
{
    std::cout 
        << lanes[i]      // Assumes there always are >=5 lanes.
        << champions[i]  // Assumes there always are >=5 champions.
        << get_cycled(roles, i) 
        << "\n";
}

If you want to go down this route, you can find a real implementation of make_vector here, which can be used to implement make_shuffled_vector.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • While variadic templates are cool, I'm not sure whether this is a good use-case. Accepting a `std::vector` would require you to type two additional braces in the function call but the function would be more general and a single instantiation would do for any number of items. – 5gon12eder Jan 07 '16 at 01:18
  • I've looked over this line of code `std::vector lanes{lane::top, lane::bot, lane::jng, lane::mid};` so many times, and I've googled about vectors and asked other people, but I don't get what I'm supposed to put where you have "lane::top, lane::bot," etc. What numbers go there? – Riggs Jan 10 '16 at 18:38
  • @Riggs: `enum class lane {top, bot, jng, mig};` - look into enums and enum classes – Vittorio Romeo Jan 10 '16 at 18:55