Array, avoid pulling Duplicates, simple code, C++ - c++

Its a card game, I draw 2 cards from the deck (the array) with the help of two functions.
Each element of the array represent one card with a symbol Spades, Hearts, Diamonds or Clubs.
These numbers in the array \5 \4 \3 \6, represent Clubs, Dimaond, Heatrs, spades (just if ur curious)
The problem!
When I draw a card two times I sometimes get Duplicates.. The same card twice.
How do I make sure the same card cant be drawn twice?
How do I avoid getting duplicates??
This is how the code Looks like.
Some INFO about the array...
The further in, in the array, the higher value the element has.
I have shortened the array... for easy testing of a solution... later the array will be 52 elements.
array<string, 3> cards = { "Ess \5", "Ess \4", "Ess \3" };
//The function.
pair<string, int> draw_card()
{
int random_index = rand() % 52;
string card = cards[random_index];
return { card, random_index };
}
int main()
{
// Seed, random.
srand((unsigned int)time(NULL));
// Calling the function 2 times.
pair<string, int> you_drew = draw_card();
cout << "You drew: " << you_drew.first << endl;
pair<string, int> comp_drew = draw_card();
cout << "Computer drew: " << comp_drew.first << endl;
// Deciding the winner.
int your_score{ 0 };
int the_computers_score{ 0 };
if (you_drew.second > comp_drew.second) {
cout << "You Won!" << endl;
your_score++;
}
else if (you_drew.second < comp_drew.second) {
cout << "You Lost!" << endl;
the_computers_score++;
}
return 0;
}
Everything is working fine, EXCEPT sometimes I get duplicates... I want to make sure I can Not get that...
Somehow when I draw a card the element in the array should not be able to be drawn.. I want to avoid getting duplicates. Please help me!
Shouldnt something like this work? its not but.. shouldnt it?
pair<string, int> comp_drew = draw_card();
if (you_drew == comp_drew) {
bool run8 = true;
while (run8) {
pair<string, int> comp_drew = draw_card();
if (comp_drew != you_drew) {
cout << "Computer drew: " << comp_drew.first << endl;
run8 = false;
}
}
}
Or maybe another solution..
Perhaps after calling the function one time i can delete the return index from the array?

You can swap the drawn card to the end and only choose an index smaller than 51 the next time.
int array_len = 52; // global variables are not great, but it's easier here
pair<string, int> draw_card()
{
int random_index = rand() % array_len;
--array_len;
string card = cards[random_index];
std::swap(cards[random_index], cards[array_len]);
return { card, random_index };
}

There are many different ways to do this.
std::random_shuffle
#include <iostream>
#include <algorithm>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
int cards[DECK_SIZE] = {1,2,3,4};
int lastUsedCardIndex = -1;
public:
int getCard() {
if (lastUsedCardIndex == DECK_SIZE - 1)
shuffle();
return cards[++lastUsedCardIndex];
}
void shuffle() {
random_shuffle(begin(cards), end(cards));
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "unhsuffled - 1,2,3,4 without duplicates:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // or call getCard which can shuffle
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
Mark Card as Taken
#include <iostream>
#include <random>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
inline static int constexpr cards[DECK_SIZE] = {1,2,3,4};
bool cardIsGone[DECK_SIZE] = {false, false, false, false};
public:
int getCard() {
while(true) {
int const RANDOM_INDEX = rand()%DECK_SIZE;
if(!cardIsGone[RANDOM_INDEX]) {
cardIsGone[RANDOM_INDEX] = true;
return cards[RANDOM_INDEX];
}
}
}
void shuffle() {
for(bool &isGone : cardIsGone)
isGone = false;
lastUsedCardIndex = -1;
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "Shuffled - Random order, and still no duplicates:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // Causes infinite loop if you call getCard DECK_SIZE + 1 times
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
It's not the most efficient solution, but with small values like 52, it should be instant.
Swap Used Cards to Back and Keep Track of Range
#include <iostream>
#include <random>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
int cards[DECK_SIZE] = {1,2,3,4};
int lastCardIndexExlusive = DECK_SIZE;
public:
int getCard() {
int const RANDOM_INDEX = rand()%lastCardIndexExlusive;
swap(cards[RANDOM_INDEX],cards[lastCardIndexExlusive - 1]);
return cards[--lastCardIndexExlusive];
}
void shuffle() {
lastCardIndexExlusive = DECK_SIZE;
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "Shuffled - Random order, and still no duplicates:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // Causes exception if getCard DECK_SIZE + 1 times
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
Remember Last Card
#include <iostream>
#include <random>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
int cards[DECK_SIZE] = {1,2,3,4};
int lastCard = -1;
public:
int getCard() {
int const RANDOM_INDEX = rand()%DECK_SIZE;
if (lastCard == RANDOM_INDEX) {
return getCard();
}
lastCard = cards[RANDOM_INDEX];
return lastCard;
}
void shuffle() {
lastCard = -1;
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "Shuffled - Random order, and still no duplicates, but only able to produce 2:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // Causes potential duplicates if getCards 3+ times
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
All of these solutions make use of a class to hold state for use in getCard to make sure we get the right behavior.

Related

Clarification about function calls in cout needed

i'm doing an online c++ learning course with quiz. The last output line of this snippet is to be determined (comments added by me). Correct answer: 10. My question: why 10 and not 11?
Calling a(b) swaps the two variables, so why is the last a.a.b 0 and not 1? / Why does the a.b() in cout not affect the a.a.b?
#include <iostream>
using namespace std;
class classA {
public:
classA() { st.f = st.p = 1; }
struct { int f, p; } st;
int bfunc(void);
};
int classA::bfunc(void) { int x = st.f; st.f = st.p; st.p = x; return x; };
int main()
{
classA a;
a.st.f = 0;
cout << a.st.f << a.st.p << endl; //01
a.bfunc();
cout << a.st.f << a.st.p << endl; //10
a.bfunc();
cout << a.st.f << a.st.p << endl; //01
a.bfunc();
cout << a.st.f << a.st.p << endl; //10
cout << a.bfunc() << a.st.p << endl; //10
return 0;
}

How can I use struct efficiently in my quiz?

I'm trying to create a simple quiz with struct. But my program here is very repetitive. How can I modify it and make it more efficient? Especially to check if the answers are correct I do not want to declare a separate variable and store it as int correct. Thank You.
#include <iostream>
using namespace std;
struct Quiz{
string question;
string answers[3];
};
struct Quiz2{
string question2;
string answers2[3];
};
int correct;
int main()
{
Quiz Question;
Question.question = "What is the smallest county?";
cout << Question.question << endl;
Question.answers[0] = "1. USA";
cout << Question.answers[0] << endl;
Question.answers[1] = "2. India";
cout << Question.answers[1] << endl;
Question.answers[2] = "3. Vatican City";
cout << Question.answers[2] << endl;
cout << endl;
cout << "Choose 1-3: ";
cin >> correct;
if(correct == 3)
cout << "Correct!";
else
cout << "Incorrect!";
cout << endl;
cout << endl;
// Question 2
Quiz2 Question2;
Question2.question2 = "What is the biggest animal in the world?";
cout << Question2.question2 << endl;
Question2.answers2[0] = "1. Elephant";
cout << Question2.answers2[0] << endl;
Question2.answers2[1] = "2. Blue Whale";
cout << Question2.answers2[1] << endl;
Question2.answers2[2] = "3. Great white shark";
cout << Question2.answers2[2] << endl;
cout << endl;
cout << "Choose 1-3: ";
cin >> correct;
if(correct == 2)
cout << "Correct!";
else
cout << "Incorrect!";
return 0;
}
That's as much as non-repetitive as I can imagine after a few minutes of thinking. Maybe it can become smaller, but for my taste this looks alright.
You basically rely on std::vector class, instead of a typical array, because vectors can be of dynamic size. This allows us to use only one struct, but make as many answers as we want (3, 5, 10, whatever). We then create the whole quiz as another vector of questions. We're only left with printing to the console - for that we use loops, as our quiz structure is very simple and self-repetitive.
#include <iostream>
#include <vector>
using namespace std;
struct Question{
string question;
int correct_idx;
vector<string> answers;
Question(string question, int correct_idx, vector<string> answers)
:question(question), correct_idx(correct_idx), answers(answers)
{}
};
int main()
{
vector<Question> whole_quiz = {
Question{
"What is the smallest country?",
2, // indexes start from 0, e.g. 0, 1, 2. So 2 is correct
{"USA", "India", "Vatican City"}
},
Question{
"What is the biggest animal in the world?",
1,
{"Elephant", "Blue Whale", "Great white shark"}
},
};
for(auto question : whole_quiz) {
cout << question.question << endl;
for(int i = 0; i < question.answers.size(); ++i) {
cout << i+1 << ". " << question.answers[i] << endl;
}
cout << "Choose 1-" << question.answers.size() << endl << endl;
int guess;
cin >> guess;
if (guess-1 == question.correct_idx) {
cout << "Correct!" << endl << endl;
} else {
cout << "Incorrect!" << endl << endl;
}
}
return 0;
}
I would propose a more complicated, but also a more fun solution. Have a huge list of answers, like 100, or 1000, or as many as you like. Then in your struct have a std::string question, and std::vector<int> possible answers that are indexes in the huge list. First answer in the list is the correct one. So when you ask a question you pick first index, and three more indexes at random, and you shuffle them up, and present this to the user. The quiz will be different every time.
struct acts as a template, not a single variable. so there's no need to create 2 different struct. Also, a correct variable can be added to the struct for ease of checking.
Code (I split it into different functions for clearer understanding):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct quiz
{
int correct;
string question;
vector<string> answers;
};
vector<quiz> questionsToAsk;
void addNewQuestion(string ques, vector<string>ans, int cor)
{
quiz q1;
q1.question = ques;
q1.answers = ans;
q1.correct = cor;
questionsToAsk.push_back(q1);
}
void displayQuestion(int idx)
{
quiz cur = questionsToAsk[idx];
cout << cur.question << '\n';
for (int i = 0; i < cur.answers.size(); i++)
{
cout << cur.answers[i] << '\n';
}
cout << "Choose 1-3: "; int inp; cin >> inp;
if (inp == cur.correct) {cout << "Correct";} else {cout << "Incorrect";} cout << '\n';
}
int main()
{
vector<string> ans1({"1. USA", "2. India", "3. Vatican City"});
vector<string> ans2({"1. Elephant", "2. Blue Whale", "3. Great white shark"});
addNewQuestion("What is the smallest county?", ans1, 3);
addNewQuestion("What is the biggest animal in the world?", ans2, 2);
for (int i = 0; i < questionsToAsk.size(); i++)
{
displayQuestion(i);
}
}
Result:
What is the smallest county?
1. USA
2. India
3. Vatican City
Choose 1-3: 1
Incorrect
What is the biggest animal in the world?
1. Elephant
2. Blue Whale
3. Great white shark
Choose 1-3: 2
Correct
You can use a template like
<typename T = int>
T get_answer(std::istream& in) {
T res;
in >> res;
return res;
}
...
if(get_answer(std::cin) == 3)
cout << "Correct!";
else
cout << "Incorrect!";
You can also overload operator<<.
#include <iostream>
#include <string>
template<typename T = int>
T get_answer(std::istream& in) {
T res;
in >> res;
return res;
}
class Quiz{
public:
Quiz(const std::string& q, const std::string& a1, const std::string& a2, const std::string& a3, unsigned correct)
: question(q), answers{a1, a2, a3}{
CheckAnswer(correct);
}
friend std::ostream& operator<<(std::ostream& os, const Quiz& quiz) {
os << quiz.question << "\n";
unsigned i = 1;
for (const auto & answer : quiz.answers) {
os << i++ << ". " << answer << "\n";
}
os << "\n";
return os;
}
void CheckAnswer(unsigned correct) {
std::cout << *this << "Choose 1-3: ";
if(get_answer(std::cin) == correct)
std::cout << "Correct!";
else
std::cout << "Incorrect!";
std::cout << std::endl;
std::cout << std::endl;
}
private:
std::string question;
std::string answers[3];
};
int main()
{
Quiz Question("What is the smallest county?", "USA", "India", "Vatican City", 3);
// Question 2
Quiz Question2("What is the biggest animal in the world?", "Elephant", "Blue Whale", "Great white shark", 2);
return 0;
}
The only thing you can do is define the correct variable in the struct itself. You can use a loop for decreasing the repetitiveness but obviously the question and the answers will have to be stored, it cannot be simplified further.

c++ vector of structs inside class

hello all i am working on a school prject called inventory inquisitor. the specifications are as follows:
enter image description here
so far i have created a class in which contains a struct and a vector of this struct.
all im trying to do so far is get the class to display the struct just to know it works but when i compile it and run it nothing happens. here is the code. excuse whatever rookie mistakes i have made i am very new with classes, and vectors. thanks you in advance!
//Inventory Inquisitor.cpp
#include <iostream>
#include <string>
#include <cctype> //for toupper
#include <fstream>
#include <vector>
using namespace std;
class Inventory
{
private:
struct item
{
string Description = " ";
double Quantity = 0;
double Wholesalescost = 0;
double Retailcost = 0;
string Dateadded = " ";
};
vector<item> Inv;
public:
void Display();
};
void Inventory::Display()
{
Inv[0].Description = "english";
Inv[0].Quantity = 1;
Inv[0].Wholesalescost = 100;
Inv[0].Retailcost = 200;
Inv[0].Dateadded = "3/8/2018";
cout << Inv[0].Description << endl;
cout << Inv[0].Quantity << endl;
cout << Inv[0].Wholesalescost << endl;
cout << Inv[0].Retailcost << endl;
cout << Inv[0].Dateadded << endl;
}
int main()
{
Inventory inst1;
inst1.Display();
}
You have to put something into the vector before accessing it:
// Create an item
item i;
i.Description = "english";
i.Quantity = 1;
i.Wholesalescost = 100;
i.Retailcost = 200;
i.Dateadded = 3/8/2018;
// The vector is empty, size() == 0
// Add it to the vector
Inv.push_back(i);
// Now the vector has 1 item, size() == 1
// Now you can print it
cout << Inv.at(0).Description << endl;
cout << Inv.at(0).Quantity << endl;
cout << Inv.at(0).Wholesalescost << endl;
cout << Inv.at(0).Retailcost << endl;
cout << Inv.at(0).Dateadded << endl;
According to your assignment, you will most likely change to function to print an existing item. You will have another function to add items to the vector.
void Inventory::Display(int index)
{
// Print an item already in the vector
if (index >= 0 && index < Inv.size()) {
cout << Inv.at(index).Description << endl;
cout << Inv.at(index).Quantity << endl;
cout << Inv.at(index).Wholesalescost << endl;
cout << Inv.at(index).Retailcost << endl;
cout << Inv.at(index).Dateadded << endl;
}
}

C++ Method won't call correct information from variable

I am working a a text adventure and have come across an error when I try to call a method from another method. The method returns the private int player_health and private int player_attack this work when I call it in main but when I call it in my combat_handler class it just give me a random number. I call it the exact same way in both class. Here is my code
Main.cpp
#include <iostream>
#include "player_handler.h"
#include "enemy_handler.h"
#include "combat_handler.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
player_handler phobj;
enemy_handler ehobj;
combat_handler cbobj;
phobj.test_player_systems();
ehobj.test_enemy_stats();
cbobj.player_turn();
phobj.get_player_stats();
return 0;
}
player_handler header
#ifndef PLAYER_HANDLER_H
#define PLAYER_HANDLER_H
class player_handler
{
public:
player_handler();
int get_player_health();
int get_player_attack();
void get_player_stats();
void add_player_health(int x);
void remove_player_health(int x);
void add_player_attack(int y);
void set_player_stats(int x, int y);
int test_player_systems();
private:
int player_health;
int player_attack;
};
#endif // PLAYER_HANDLER_H
player_handler.cpp
#include "player_handler.h"
#include <iostream>
using namespace std;
player_handler::player_handler()
{
//cout << "working"<< endl;
}
//Getting the players stats
int player_handler::get_player_health()
{
return player_health;
}
int player_handler::get_player_attack()
{
return player_attack;
}
void player_handler::get_player_stats()
{
cout << "the players health is " << get_player_health()<<endl;
cout << "The players attack is " << get_player_attack() <<endl;
}
//setting the player stats
void player_handler::set_player_stats(int x, int y)
{
player_handler::player_health = x;
player_attack = y;
//cout << "player health is " << player_health << endl;
//cout << "player attack is " << player_attack << endl;
}
//Player health control
void player_handler::add_player_health(int x)
{
//cout << "The old player health was " << player_health << endl;
player_health = player_health + x;
//cout << "Your health is now " << player_health << endl;
}
void player_handler::remove_player_health(int x)
{
//cout << "you lost " << x << " health" << endl;
player_health = player_health - x;
//cout << "Your new health is " << player_health << endl;
}
//player attack control
void player_handler::add_player_attack(int y)
{
//cout << "Your attack has been upgraded by " << y << " points" << endl;
player_attack = player_attack+y;
//cout << "You attack is now " << player_attack <<endl;
}
//test all player systems
int player_handler::test_player_systems()
{
set_player_stats(10,10);
cout <<"The player health is " << get_player_health()<<endl;
cout <<"the player attack is " << get_player_attack() << endl;
add_player_health(5);
remove_player_health(5);
add_player_attack(5);
get_player_stats();
return 0;
}
Now keep in mind that all this works it returns the right value for player_health and player_attack. now here is my problem it just gives me a random number
combat_handler header
#ifndef COMBAT_HANDLER_H
#define COMBAT_HANDLER_H
class combat_handler
{
public:
combat_handler();
int player_turn();
int enemy_turn();
private:
int player_input;
int player_dmg_given;
int enemy_dmg_given;
};
#endif // COMBAT_HANDLER_H
combat_handler.cpp
#include "combat_handler.h"
#include <iostream>
#include "player_handler.h"
using namespace std;
combat_handler::combat_handler()
{
cout << "combat handler on-line\n";
}
int combat_handler::player_turn()
{
player_handler phobj;
cout << "Would you like to (1)check stats (2) Enter the room?\n";
cin >> player_input;
switch(player_input){
case 1:
cout << "one"<<endl;
phobj.get_player_stats();
break;
default:
cout << "entering the room.\n";
break;
}
return 0;
}
The error happens when I call get_player_stats from the phobj in the combat handler class.
player_handler phobj;
This would call default constructor for player_handler( from your code it seems you are doing nothing in default constructor). And then you are calling get_player_stats() without setting the values. So, it would surely give you random values.
Earlier in main,
phobj.test_player_systems(); <<<< This is setting values.
phobj.get_player_stats(); <<<< Then you are querying on values already set.

C++ class and function output issue

I'm having problems with my program's output. It keeps spitting out 12345.
Here's the details:
It's split in three files: program8.cpp (the part that runs tests), myRandom.cpp (implementation of the class), and myRandom.h (specification of the class).
myRandom.h:
#ifndef MYRANDOM_H_
#define MYRANDOM_H_
class myRandom
{
public:
myRandom(); //Constructor
~myRandom(); //Destructor
void seed(unsigned long theSeed); //Mutator for current
unsigned long next(); //Mutator or Accessor for current
int randInt(int start, int end); //Scales result to a range
double randNormal(); //Future expansion
private:
unsigned long current; //Current random #
static const unsigned long a = 1103515245; //Multiplier for LGC
static const unsigned long c = 12345; //Increment for LGC
static const unsigned long m = 2147483648; //Modulus for LGC
};
#endif /* MYRANDOM_H_ */
myRandom.cpp:
#include <iostream>
#include <cstdlib>
#include "myRandom.h"
using namespace std;
myRandom::myRandom() //Constructor
{
current = 0;
}
myRandom::~myRandom() //Destructor
{
}
void myRandom::seed(unsigned long theSeed) //Mutator for current
{
if (theSeed < 0 || theSeed > m-1)
{
// ERROR
return;
}
else
current = theSeed;
}
unsigned long myRandom::next() //Mutator or Accessor for current
{
if (current < 0)
{
cout << "Error: cannot set seed to a negative number" << endl;
return 0;
}
else
{
current = (m*current+c)%m; //Formula
return current;
}
}
int myRandom::randInt(int start, int end) //Scales result to a range
{
if (start >= end)
{
cout << "Error: cannot set start greater than or equal to end" << endl;
return 0;
}
else
{
return ((this->next() % (end - start)) + start);
}
}
double myRandom::randNormal() //Future expansion
{
cout << "Warning: randNormal not implemented" << endl;
return 0;
}
program8.cpp:
#include <iostream>
#include <cstdlib>
#include "myRandom.h"
using namespace std;
int main()
{
myRandom theRand;
unsigned long theSeed;
cout << "Verify that the sequence generated by next() is the same on each run" << endl;
for (int i = 0; i < 5; i++)
{
cout << theRand.next() << endl;
}
cout << "Verify that you can set the seed to 0 and 1" << endl;
theSeed = 0;
cout << theRand.next() << endl;
theSeed = 1;
cout << theRand.next() << endl;
cout << "Verify that attempting to set the seed to -1 generates an error" << endl;
theSeed = -1;
cout << theRand.next() << endl;
cout << "Verify that you can set the seed to m-2 and m-1" << endl;
theSeed = 2147483648-2;
cout << theRand.next() << endl;
theSeed = 2147483648-1;
cout << theRand.next() << endl;
cout << "Verify that attempting to set the seed to m generates and error" << endl;
theSeed = 2147483648;
cout << theRand.next() << endl;
cout << "Verify that next() produces a sequence predicted by hand/calc for the chosen seed" << endl;
cout << "Please enter a seed: ";
cin >> theSeed;
cout << theRand.next() << endl;
cout << "Verify that using start == end generates and error. Set both to 10." << endl;
theRand.randInt(10,10);
cout << theRand.next() << endl;
cout << "Verify that using start > end generates and error. Set start to 10 and end to 5." << endl;
theRand.randInt(10,5);
cout << theRand.next() << endl;
theRand.seed(theSeed);
cout << "Testing randInt for start=0 end=1,000" << endl;
for (int i = 0; i < 5; i++)
{
cout << theRand.randInt(0 , 1000) << endl;
}
return 0;
}
I think the problem lies in the next() function, since that's what gets called all those times in program8.cpp cout statements. I could understand getting 12345 once, but it should be updated once that function runs successive times. I apologize if it's a dumb question. Thank you for your time and patience.
Your problem isn't a code specific one - it is Math-related from here:
current = (m*current+c)%m;
This always returns the value of c if c < m, otherwise (or more generally) it returns c % m. Why? From this theorem:
(m*n + a)%m = a
Example:
m = 10
n = 3
a = 7
(10*3 + 7)%10 = 7
See this for more:
http://en.wikipedia.org/wiki/Modulo_operation