I am making a clock-driven simulation program and, among other issues, my main while loop, while(jobsCompleted < jobsToComplete) is looping more times than expected/wanted. For example, if I were to assign 500 to jobsToComplete, the output at the end of the program would tell me that there were 505 jobs completed. I have tried to debug this one issue for at least an hour now, but to no avail. Any help is appreciated. Thanks!
#include <iostream>
#include <string>
#include <stdlib.h>
#include <queue>
#include <fstream>
#include "job.cpp"
using namespace std;
int main()
{
ofstream cpuSim;
cpuSim.open("cpuSim.out.txt");
int clock = 0, jobsCompleted = 0, jobsToComplete = 0, probUser = 0, probability, id = 0;
jobType_t job_type;
int inWQ, outWQ, inCPUQ, outCPUQ, required, given, jobTypeInt, timeSpentInCPUqueue = 0, timeSpentInWaitQueue = 0, CPUidle = 0;
queue<job> CPUqueue, waitQueue;
int numIO = 0, numCPU = 0;
srand(time(NULL));
cout << "Enter how many jobs need to be completed: ";
cin >> jobsToComplete;
cout << endl << "Enter the probability that a new job is created: ";
cin >> probUser;
cout << endl;
while(jobsCompleted < jobsToComplete)
{
clock++;
probability = rand() % 100 + 1;
if(probability > probUser)
{
for(int i=0; i<jobsToComplete; i++)
{
id = rand() % 1000 + 1;
jobTypeInt = rand() % 100 + 1;
if(jobTypeInt >= 50)
job_type = IO_bound;
else
job_type = CPU_bound;
required = rand() % 10;
job *newJob = new job(id, job_type, inWQ, outWQ, inCPUQ, outCPUQ, required, given);
waitQueue.push(*newJob);
}
while((CPUqueue.size() <= 10) && waitQueue.empty() == false)
{
waitQueue.front();
job temp = waitQueue.back();
waitQueue.pop();
temp.setTimeExitedWQueue(clock);
temp.setTimeEnteredCPUQueue(clock);
CPUqueue.push(temp);
}
double oneSecond = 1.0, timeSpent = 0;
while((oneSecond > 0.0) && (!CPUqueue.empty()))
{
job top = CPUqueue.front();
CPUqueue.pop();
if(top.getJobType() == IO_bound)
{
top.setTimeGiven(top.getTimeGiven() + .1);
timeSpent = .1;
numIO++;
}
else
{
top.setTimeGiven(top.getTimeGiven() + .2);
timeSpent = .2;
numCPU++;
}
if(top.getTimeRequired() <= top.getTimeGiven())
{
top.setTimeExitedCPUQueue(clock);
jobsCompleted++;
timeSpentInWaitQueue += (top.getTimeExitedWQueue() - top.getTimeEnteredWQueue());
timeSpentInCPUqueue += (top.getTimeExitedCPUQueue() - top.getTimeEnteredCPUQueue());
}
else
CPUqueue.push(top);
oneSecond -= timeSpent;
if((clock%60 == 0) && (clock > 600)) //every 60 seconds after the first 10 minutes
{
cout << "After the first 10 minutes:" << endl;
cout << "Time: " << clock << endl;
cout << "Number of jobs in the wait queue: " << waitQueue.size() << endl;
cout << "Number of jobs in the CPU queue: " << CPUqueue.size() << endl;
job temp1 = waitQueue.front();
job temp2 = CPUqueue.front();
cout << "Job number of front wait job: " << temp1.getID() << endl;
cout << "Job number of front CPU job: " << temp2.getID() << endl;
}
else
{
cout << "Job Number: " << jobsCompleted << endl;
cout << "Job ID: " << top.getID() << endl;
cout << "Job Type: " << top.getJobType() << endl;
cout << "Time in CPU Queue: " << timeSpentInCPUqueue << endl;
cout << "Time Entered CPU Queue: " << top.getTimeEnteredCPUQueue() << endl << endl;
}
}
if((oneSecond > 0) && (CPUqueue.empty()))
CPUidle += oneSecond;
}
}
cout << "I/O_bound jobs: " << numIO << endl;
cout << "CPU_bound jobs: " << numCPU << endl;
cout << "*****JOBS COMPLETED: " << jobsCompleted << " *****" << endl << endl;
return 0;
}
And as a less pertinent question, I cannot get my enumerated data types to print out correctly nor my IDs at the very begging to pass into *newJob correctly...
Let's say it's been looping for a while and now jobsCompleted is 499 (and your jobsToComplete is 500). Okay, so this is the last loop right? Yes! But the incrementing of jobsCompleted happens within another nested while loop. So if that nested loop occurs 6 times, jobsCompleted will be 505 and then the outer while loop will end, leaving you with a total number of jobs completed at 505.
Telling you how to fix it would require understanding the logic of your code, but there's a bit too much for me to figure out. Maybe this will help you.
By looking at the code it's clear that this happens because you have a situation like the following
while (x < y) {
...
while (condition) {
...
if (condition) {
++x;
}
}
}
This means that for every outer iteration it may happen that you are incrementing x more than once, so you enter the last iteration (x == 499) and then increment it 6 times while inside the inner loop. You should debug that part of code to understand why it happens, explicitly you should check these two conditions:
while((oneSecond > 0.0) && (!CPUqueue.empty()))
if(top.getTimeRequired() <= top.getTimeGiven())
because on last iteration the are both true at least 6 times.
Related
I'm student in high school and I wanna to make simple game with guessing random number and I had problem with user inputed array while I need to check the condition.
When it comes to checking condition it says there wasn't declared i.
Below I leave code.
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
int PlayerAns[200];
int iNumSecret, iNumGuess;
int iWrongAns = 0;
srand(time(NULL));
int iNumMax = 100;
iNumSecret = rand() % iNumMax + 1;
cout << "========== Simple Game =========== "
<< "\n";
do
{
for (int i = 0; i < 100; i++)
{
cout << "Guess the number od 1 do " << iNumMax << "\n";
cin >> PlayerAns[i];
if (iNumSecret < PlayerAns[i] && PlayerAns[i] >= 0 && PlayerAns[i] <= 100)
{
cout << " - Secret number is lower ! "
<< "\n";
}
else if (iNumSecret > PlayerAns[i] && PlayerAns[i] >= 0 && PlayerAns[i] <= 100)
{
cout << " - Secret number is higher ! "
<< "\n";
}
else if (PlayerAns[i] < 0 || PlayerAns[i] > 100)
{
cout << " - Number is out of scope ! "
<< "\n";
iWrongAns++;
}
}
}
while (iNumSecret != PlayerAns[i]);
{
cout << "--- You get it !!!"
<< "\n";
cout << PlayerAns << "\n";
cout << "You guess number out of scope that many times: " << iWrongAns << "\n";
}
return 0;
}
The variable i is defined only inside the for loop in that case.
If you wanted to, you can define i before the do while loop, and then use it in the for loop like so:
for(i = 0; i < 100; i++) {
...
}
Suggestion:
You can try not using the for loop and make the PlayerAns an integer instead of an array.
If the generated random number to look for does not exist in hashtable array, then programm gets stuck in endless loop in function void hashSearch(),
whereas it should just get out of the loop and output that search item is not found. The exact place in code is where these to outputs are:
cout << "stuck in else loop \n"; and cout << "stuck in while loop end \n";.
I've googled around, but can't find similar examples.
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <chrono>
using namespace std;
int arr [1000];
int arr2 [1000];
int randArrayInt, n, randSearchItem, searchInt, address, size2;
void printZeroArr();
void linearSentinelSearch();
void printHashArray();
void hashSearch();
int main ()
{
srand (time(nullptr)); //initialize random seed:
n = rand() % 900 + 100; //random integer number from 100 - 1000, length of the array
//n = rand() % 10; // random number in the range 1-10 for sanity tests, length of the array
//randSearchItem = rand() % 10 + 1;
randSearchItem = rand() % 900 + 100; //this is the number to search for
cout << "Array length is " << n << endl;
cout << "[";
for (int i = 0; i <= n; i++)
{
randArrayInt = rand() % 900 + 100;
//randArrayInt = rand() % 10 + 1; // generate random 1-10 number for for sanity tests
arr[i] = randArrayInt; // insert into array position the generated random number
cout<< " " << arr[i]; // print out array element at current loop position
}
cout << " ]\n" << endl;
printZeroArr();
}
void printZeroArr()
{
size2 = n + 1; //length of hashed array
cout << "This is the random key to search for in array: " << randSearchItem << endl;
cout << "This is the size2 length " << size2 << endl;
cout << "This is the hasharray with zeros" << endl;
cout << "[";
for (int i = 0; i <= size2; i++)
{
arr2[i] = 0; // insert into hasharray number 0
cout<< " " << arr2[i]; // print out hasharray element at current loop position
}
cout << " ]\n" << endl;
linearSentinelSearch();
}
void linearSentinelSearch()
{
auto start = std::chrono::high_resolution_clock::now();
arr[n + 1] = randSearchItem;
//cout << "testing arr[n + 1] is " << arr[n + 1] << endl;
int i = 0;
while (arr[i] != randSearchItem) i++;
if (i == n + 1)
cout << "Sentinel search did not found the searchitem in random array" << "\n" << endl;
else
cout << "Searchitem found in array with linearsearch at position " << i << "\n" << endl;
auto finish = std::chrono::high_resolution_clock::now();
chrono::duration<double> elapsed = finish - start;
cout << "Elapsed time: " << elapsed.count() << " s\n";
printHashArray();
}
void printHashArray()
{
//cout << "printing out 'address' value, or the modulo result: " << endl;
//cout << "[";
for (int i = 0; i <= n; i++)
{
address = arr[i] % size2;
//cout << " " << address;
while (arr2[address] != 0)
{
if (address == size2 - 1)
{
address = 0;
} else
{
address++;
}
}
arr2[address] = arr[i];
}
//cout << " ]\n" << endl;
cout << "This is the hasharray with hashitems" << endl;
cout << "[";
for (int i = 0; i <= size2; i++)
{
cout << " " << arr2[i];
}
cout << " ]\n" << endl; hashSearch();
}
void hashSearch()
{
auto start = std::chrono::high_resolution_clock::now();
int searchInt = randSearchItem % size2;
while ((arr2[searchInt] != 0) && (arr2[searchInt] != randSearchItem))
{
if (searchInt == size2 - 1)
{
searchInt = 0;
cout << "if loop \n";
}
else
{
searchInt++;
cout << " stuck in else loop \n";
}
cout << " stuck in while loop end \n";
}
if (searchInt == 0) {
cout << "Search item not found using hashSearch" << endl;
} else {
cout << "Search item " << randSearchItem << " found using hashSearch at position " << searchInt << " in arr2." << endl;
}
auto finish = std::chrono::high_resolution_clock::now();
chrono::duration<double> elapsed = finish - start;
cout << "Elapsed time: " << elapsed.count() << " s\n";
}
Whereas it should just get out of the loop and output that search item is not found.
Search for cout << " stuck in else loop \n"; and cout << " stuck in while loop end \n";.
You want to stop your loop when you hit the end of the array: To that effect, you set the item to search for to zero:
if (searchInt == size2 - 1)
{
searchInt = 0;
cout << "if loop \n";
}
But in the loop control, you don't test that. You only test the array element at the current index for zero (not found) or the item to search (found):
while ((arr2[searchInt] != 0) && (arr2[searchInt] != randSearchItem)) ...
You need an additional test:
while ((searchInt != 0) && ...) ...
It took me a while to see that you want to code an open-address hastable where a zero marks unused slots. The hash value is just the number itself. Using zero as indicator for an empty slot is not ideal: You cannot store numbers whose hash code modulo the table size is zero.
I'd also code this with a non-void function where the return value is the index or some unambiguous value meaning "not found", perhaps -1. (Alternatively, you can return a pointer to the found item or NULL if the item isn't found -- after all, the index in the hash array is part of the hash table's internals and non concern to the caller.)
Then you can use early returns:
int hashSearch(const int *arr2, int size2, int item)
{
int i = item % size2;
for (; i < size2; i++) {
if (arr2[i] == -1) break; // -1 indicated unused space
if (arr2[i] == item) return i; // return index of item
}
return -1; // not found!
}
But what do you do if there is no room for a further element when you have a hash code close to the array size? You will need to add extra space at the end or you'll need to wrap around. Perhaps that is what you wanted to achieve by setting the index back to zero. In your case, ther array is full, so there are no zeros that could serve as loop-breaking criterion. You will have to find another criterion. You could ensure that there are zeros by making the hash table 30% or so bigger than the number of entries. Or you could try to detect whether the index has come full circle to the original index.
As already pointed out to you in comments: Try to use function arguments and local variables rather than puttin everything into global space. Also, the chaining of function calls, where the last thing in a function is to call the next one is strange. It's probably better to put all sequential calls into main.
I'm writing a trivial program that doubles the amount of rice grains per each square on a chess board. I'm trying to work out the amount of squares required for at least 1 000 000 000 grains of rice. The problem is, what ever I try, the second if statement gets skipped even though 'test' is false after first iteration.
I've tried an else after the if statement, but the else is skipped when 'test' variable is false.
constexpr int max_rice_amount = 1000000000;
int num_of_squares = 0;
int rice_grains = 0;
bool test = true; // so we can set rice_grains amount to 1
for (int i = 0; i <= max_rice_amount; i++)
{
if (test == true)
{
rice_grains = 1; // This will only happen once
test = false;
}
else if (test == false)
rice_grains *= 2;
++num_of_squares;
std::cout << "Square " << num_of_squares << " has " << rice_grains << " grains of rice\n";
}
The else causes the issue. But C++ is more powerful than you can imagine. Rework your loop to
for (
int rice_grains = 1, num_of_squares = 1;
rice_grains <= max_rice_amount;
rice_grains *= 2, ++num_of_squares
){
with
std::cout << "Square " << num_of_squares << " has " << rice_grains << " grains of rice\n";
as the loop body; and weap at the beauty.
Looking at the problem description, this looks a good fit for a while loop or a do-while loop.
#include <iostream>
void f()
{
constexpr int max_rice_amount = 1000000000;
int num_of_squares = 1;
int rice_grains = 1;
while (rice_grains < max_rice_amount)
{
std::cout << "Square " << num_of_squares << " has " << rice_grains << " grains of rice\n";
rice_grains *= 2;
++num_of_squares;
}
}
Code at compiler explorer
Here you recognize 3 big blocks:
Initialization
The 'until' condition in the while
The manipulation
I'm creating a program where a user tries to guess the amount of times two dice have to roll to reach the totalsum of 100.
I've finished the loop but now I'm stuck on the point where I want the program to compare the two variables. I've googled but nothing has been coming up regarding the issue.
In regards to the code, here's what I have:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
const int min_value=1;
const int max_value=6;
int die1,die2,sum,totalRolls, totalSum, prediction;
unsigned seed = time(0);
srand(seed);
sum=0;
totalRolls=0;
totalSum=0;
cout << "How many rolls will it take to reach a total of 100?\n";
cin >> prediction;
while (totalSum <= 100)
{
cout << "Rolling the die\n";
die1=(rand() % (max_value - min_value + 1) + min_value);
die2=(rand() % (max_value - min_value + 1) + min_value);
cout << die1 << endl;
cout << die2 << endl;
sum=die1+die2;
totalSum+=sum;
cout << "Your current total is " << totalSum << endl;
totalRolls++;
cout << "Last roll number = " << totalRolls << endl;
}
if (totalRolls <= 5)
{
cout << "Amazing!\n";
}
else if (totalRolls <=10)
{
cout << "Good\n";
}
else if (totalRolls <= 15)
{
cout << "Okay\n";
}
else if (totalRolls <= 20)
{
cout << "Try harder\n";
}
system("Pause");
return 0;
}
I honestly just don't know how to compare the predicted total number of rolls compared to the actual rolls it took.
This question already has answers here:
Why do I get an infinite loop if I enter a letter rather than a number? [duplicate]
(4 answers)
Closed 5 years ago.
I decided to try to make a little game. It's a simple survival game. Part of it has people try to survive as long as they can by choosing options. I've scaled down the game as much as possible from 1000 lines to this for the minimum case.
At one part of the game it asks, "You were visited by a gifting clown. On a scale of 0-10, how badly do you want a gift?"
If they answer 0-10, the loop works fine. If they answer with a character, like y or n, the loop basically forces the game to execute where it no longer asks players for input on any other choices.
A previous while loop works, one where it will continue so long as the player is alive. This clown while loop is nested inside of it. I have broken up the while loop with the clown section to where I think the problem is... And also included the full code just in case it's not inside there.
My goal is simply if a character is put into it, that it doesn't break this game.
main.cpp - clown section
encounterHurt = 0;
randomEncounter = rand() % 8;
cin.ignore(1, '\n');
if (randomEncounter == 1 && clown == true){
encounterChoice = 1;
cout << "\n\nYou were visited by a gifting clown. \nOn a scale of 0-10, how badly do you want a gift? ";
while (encounterChoice >= 0 && encounterChoice <= 10){
cin >> encounterChoice;
encounterFood = (rand() % 3) + encounterChoice / 2;
encounterWood = (rand() % 3) + encounterChoice / 2;
encounterMedicine = (rand() % 2);
encounterBullets = (rand() % 2);
if (encounterChoice > 0){
encounterHurt = (rand() % 10) - encounterChoice;
if (encounterHurt <= 1){
health--;
cout << "The crazy clown stabs you, but still provides gifts.";
}
}
if (encounterFood > 0) {
cout << "\nYou were provided with " << encounterFood << " food." << endl;
food += encounterFood;
}
if (encounterWood > 0) {
cout << "\nYou were provided with " << encounterWood << " wood." << endl;
wood += encounterWood;
}
if (encounterMedicine > 0) {
cout << "\nYou were provided with " << encounterMedicine << " medicine." << endl;
medicine += encounterMedicine;
}
if (encounterBullets > 0) {
cout << "\nYou were provided with " << encounterBullets << " bullets." << endl;
bullets += encounterBullets;
}
encounterChoice = 11;
}
main.cpp - Condensed code
#include <iostream>
#include <iomanip>
#include <random>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main() {
srand (time(NULL));
int randNumber = 0;
int food = 4;
int wood = 4;
int medicine = 2;
int bullets = 8;
int money = 25;
int randomEncounter = 0;
int hunt = 0;
bool axe = false;
int axeTemp = 0;
int axeBonus = 0;
int lumberTemp = 0;
int lumber = 0;
int findStore = 0;
int storeChoice = 0;
bool gun = false;
int gunSearch;
int gunTemp;
int gunBonus = 0;
int gunFind = 0;
// int searches;
// int searchesBonus;
int farmFind = 0;
int farmFood = 0;
int farmSearch = 0;
bool farm = false;
string description;
int foodTemp = 0;
int woodTemp = 0;
int medicineTemp = 0;
int bulletsTemp = 0;
int moneyTemp = 0;
int huntTemp = 0;
int huntSuccess = 0;
char huntChoice;
int encounterFood = 0;
int encounterWood = 0;
int encounterBullets = 0;
int encounterMedicine = 0;
int encounterHurt = 0;
unsigned int encounterChoice = 0;
int hurt = 0;
int health = 3;
int healthMax = 3;
int days = 1;
char action = '0';
char pause = '1';
char classChoice;
char mainChoice;
bool clown = true;
int clownHealth = 5;
char clownChoice;
int yourShot = 0;
int clownShot = 0;
string place;
//Food 1 per day per person. Can expand to include more people.
//Fuel 1 per day, takes that much to stay warm even if fewer people
//Medicine used one per wound
//Bullets 1 to hunt, though can spend more to increase chance of success.
//Days how many days that they have survied.
//Health, everyone starts with three health. Good, okay, bad, dead.
cout << "\nFood: " << food << " Wood: " << wood << " Medicine: " << medicine << " Bullets: " << bullets << " Health: " << health << endl;
while (health > 0){
cout << "\nDay: " << days;
cout << "\nFood: " << food
<< "\nWood: " << wood
<< "\nMedicine: " << medicine
<< "\nBullets: " << bullets
<< "\nHealth: " << health
<< "\nMoney: " << money << endl;
if (food >= 1){
food--;
}
if (wood >= 1){
wood--;
}
if (food <= 0){
health--;
cout << "Health lost due to lack of food" << endl;
}
if (health < healthMax && medicine > 0){
health++;
medicine--;
cout << "Health pack used to heal your character\nHealth : " << health << endl;
}
action = '0';
cout << "\n1: Find food" << endl;
cout << "What's your action? ";
cin >> action;
cout << endl;
if (action == '1'){
//
//Section for random sites to search.
//
//
randNumber = rand() % 4;
description = "";
//Maybe + days at the end, and subtract some, so that they eventually run out of places to check.
if (randNumber >= 0 && randNumber < 2) {
place = "supermarket";
foodTemp = (rand() % 4) + 1;
woodTemp = (rand() % 2) + 0;
bulletsTemp = (rand() % 2) + 0;
medicineTemp = (rand() % 2) + 1;
moneyTemp = (rand() % 5) + 5;
}
if (randNumber >= 2 && randNumber < 4) {
place = "boat house";
foodTemp = (rand() % 2) + 1;
woodTemp = (rand() % 4) + 1;
bulletsTemp = (rand() % 2) + 0;
medicineTemp = (rand() % 2) + 0;
moneyTemp = (rand() % 3) + 0;
}
cout << "You have come to the " << place << "." << endl;
cout << description << endl;
food += foodTemp;
wood += woodTemp;
bullets += bulletsTemp;
medicine += medicineTemp;
money += moneyTemp;
if (foodTemp > 0)
cout << "You have found " << foodTemp << " food." << endl;
if (woodTemp > 0)
cout << "You have found " << woodTemp << " wood." << endl;
if (medicineTemp > 0)
cout << "You have found " << medicineTemp << " medicine." << endl;
if (bulletsTemp > 0)
cout << "You have found " << bulletsTemp << " bullets." << endl;
if (moneyTemp > 0)
cout << "You have found " << moneyTemp << " money." << endl;
cout << "\nFood: " << food << " Wood: " << wood << " Medicine: " << medicine << " Bullets: " << bullets
<< " Health: " << health << " Money: " << money << endl;
//End of search rooms.
}
//Random encounter chance to see if they can gain additional items.
encounterHurt = 0;
randomEncounter = rand() % 8;
cin.ignore(1, '\n');
if (randomEncounter == 1 && clown == true){
encounterChoice = 1;
cout << "\n\nYou were visited by a gifting clown. \nOn a scale of 0-10, how badly do you want a gift? ";
while (encounterChoice >= 0 && encounterChoice <= 10){
cin >> encounterChoice;
encounterFood = (rand() % 3) + encounterChoice / 2;
encounterWood = (rand() % 3) + encounterChoice / 2;
encounterMedicine = (rand() % 2);
encounterBullets = (rand() % 2);
if (encounterChoice > 0){
encounterHurt = (rand() % 10) - encounterChoice;
if (encounterHurt <= 1){
health--;
cout << "The crazy clown stabs you, but still provides gifts.";
}
}
if (encounterFood > 0) {
cout << "\nYou were provided with " << encounterFood << " food." << endl;
food += encounterFood;
}
if (encounterWood > 0) {
cout << "\nYou were provided with " << encounterWood << " wood." << endl;
wood += encounterWood;
}
if (encounterMedicine > 0) {
cout << "\nYou were provided with " << encounterMedicine << " medicine." << endl;
medicine += encounterMedicine;
}
if (encounterBullets > 0) {
cout << "\nYou were provided with " << encounterBullets << " bullets." << endl;
bullets += encounterBullets;
}
encounterChoice = 11;
}
//Option to attack clown
//
//
}
//End of random encounter from the clown.
//Pause mechanic to prevent the game from cycling.
// pause = 'b';
// while (pause != 'a'){
// cout << "\nEnter a to continue: ";
// cin >> pause;
// }
//End of game message
cout << endl;
if (days == 100){
cout << "You have made it to 100 days. You have beaten this game. You can quit now, or try to see how long you'll last." << endl;
}
//Add day at end of while loop.
days++;
}
cout << "You have died after " << days << " days" << endl;
}
From another Stack Overflow question...
When an error occurs when reading from a stream, an error flag gets
set and no more reading is possible until you clear the error flags.
That's why you get an infinite loop.
cin.clear(); // clears the error flags
// this line discards all the input waiting in the stream
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');