User defined values aren't honored in program at later points - c

In the code below, the user is supposed to be able to define what nurses won't be available for work that week. The user has a list of the names, and they are supposed to type a number that corresponds to the name. Once that value is stored into the slackers[4] array, it should be using those user supplied values to remove those nurses from being selected come making selections. It doesn't seem to be honoring those selected values, despite avail_nurses[9] having the correct values at any point in time (I tested using printf statements).
Everything seems to be in good shape except that essential piece of the puzzle. I would appreciate some constructive critique and useful suggestions. If you can avoid it, don't write the code for me--I gotta learn somehow. Thanks in advance!
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
char *names[] = { "Denise", "Inja", "Jane", "Karen", "Maggie", "Margaret", "MJ", "Queen", "Sherri", NULL }; //ptr for names, 9 nurses
/*0 = Denise, 1 = Inja, 2 = Jane, 3 = Karen, 4 = Maggie, 5 = Margaret, 6 = MJ, 7 = Queen, 8 = Sherri*/
const char days[5][10] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
int randomNurse();
#define total_nurses 9 //number of nurses on staff
#define days_in_week 5 //number of work days in a week
int main() {
srand(time(NULL));
int day, pos, rand_num, i, j;
int slackers[4] = { 0, 0, 0, 0 }; //array that holds the selections for who isn't working
int avail_nurses[total_nurses] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; //holds the status of each nurse, 0 = unavailable, 1 = available
/*this allows the user to repeat the program easily! flag determines if we run the program multiple times*/
while (char flag = 'y') {
/*prints names */
int temp_counter = 1; //counter
char **name_ptr = names;
while (*name_ptr) {
printf("%i) %s\n", temp_counter, *name_ptr);
name_ptr++;
temp_counter++;
}
/*this assumes that no more than FOUR nurses will be away on any given week*/
printf("\nEnter numbers that correspond to the nurses who won't be available for the week.\nType up to four numbers, each separated by a space.\n");
printf("When you are done, press \"Enter\".\n");
printf("If less than four nurses will be on leave, type a \"0\" in place of a selection.\n");
printf("Example: 1 2 5 0\n\n\n");
/*week selection of unavailable nurses*/
do {
printf("Who won't be here? ");
} while (scanf("%i %i %i %i", &slackers[0], &slackers[1], &slackers[2], &slackers[3]) != 4);
/*checks the selections made, and sets the available nurses to the correct value, zero if they are slacking||vacationing*/
for (int n = 0; n < 4; n++) {
int slacker = slackers[n];
if (slacker >= 1 && slacker <= 9)
avail_nurses[slacker - 1] = -1;
}
/*-----WEEKLY_ASSIGNMENT-----*/
int pos_per_day[days_in_week] = { 5, 9, 9, 8, 5 }; //number of nurses needed each day
int selection[days_in_week][total_nurses]; //the selected nurses per day
for (i = 0; i < days_in_week; i++) {
for (j = 0; j < total_nurses; j++) {
selection[i][j] = -1; //initialize to -1 which means no nurse is selected
}
}
//fill all the days of week
for (day = 0; day < days_in_week; day++) {
for (pos = 0; pos < pos_per_day[day]; pos++) { //for every position needed that day
do {
rand_num = randomNurse();
} while (!avail_nurses[rand_num]); //looks for available nurses (phrasing)
avail_nurses[rand_num] = 0; //change nurses status to not available
selection[day][pos] = rand_num; //fill the output array with appropriate nurse
}
for (i = 0; i < total_nurses; i++) {
avail_nurses[i] = 1; //initialize the nurses status for next day use
}
for (int n = 0; n < 4; n++) { //make sure we shame the slackers...
int slacker = slackers[n];
if (slacker >= 1 && slacker <= 9)
avail_nurses[slacker - 1] = -1;
}
/*DEBUGGING PRINTFs
printf("\n\nSELECTION:\n");
for (int x = 0; x < days_in_week; x++) {
for (int y = 0; y < total_nurses; y++) {
printf("%i\t", selection[x][y]);
}
printf("\n");
}*/
}
printf("\n");
/*-----PRINTS SCHEDULE FOR WEEK-----*/
for (i = 0; i < days_in_week; i++) {
printf("%-10s: ", days[i]);
for (j = 0; j < total_nurses; j++) {
if (selection[i][j] != -1)
printf("%-10s ", names[selection[i][j]]);
}
printf("\n");
}
fflush(stdin);
/*asks user if they want the program to run again*/
printf("\n\nDo you want to run the program again? (y/n) ");
scanf("%c", &flag);
if (flag == 'n' || flag == 'N') {
printf("\n");
break;
}
else {
printf("\n\n\n");
continue;
}
}
return 0;
}
/*function to generate random nurse*/
int randomNurse() {
return rand() % 9; //random number 0-8, to pick nurse
}

Your avail_nurses array uses the value 1 to indicate a nurse that's available, the value 0 to indicate a nurse that's not available as that nurse has already been assigned, and -1 to indicate a nurse that's not available because that nurse is a slacker. You then test whether or not a nurse is available with !avail_nurses[rand_num]. This statement is true if avail_nurses[rand_num] is 0 and is false if it's any other value. The means when avail_nurses[rand_num] is -1 it will exit the loop just like it does when it's 1.
To fix this bug either change the test to avail_nurses[rand_num] <= 0 or use only 0 to indicate unavailable nurses regardless of the reason why.

Related

Algorithm in C - who is the winner team

I need to store data from a tournament. I need to know how many teams will play(n) and the number of games they will play (n!). Then, the team's names and their results. Something like this:
Input:
3 6
TeamX
TeamY
TeamZ
TeamX 0 - TeamY 3
TeamX 1 - TeamZ 0
TeamY 1 - TeamX 0
TeamY 0 - TeamZ 0
TeamZ 0 - TeamX 0
TeamZ 3 - TeamY 1
The output will be something like:
This winner is TeamY, with 7 point(s)
Won 2 game(s), tied 1 game(s) e lost 1 game(s)
Scored 5 goal(s) e suffered 3 goal(s)
EDIT2:
THIS is what I have until now. But it won't work at the scanf.... I can't type the team's names after the number of teams and games. Can you run it and try to understand?
Guide: I have game and team structs, first I add team names to theTeams array of structs, then I add the games to the games array of structs. Then, if/else blocks to do the maths of wins, losses, etc and finally see and printf the winner.
#include <stdio.h>
#include <string.h>
struct game {
const char *teamA;
int scoreA;
const char *teamB;
int scoreB;
};
struct team {
const char *teamA;
int score;
int wins;
int losses;
int ties;
int scored;
int suff;
};
struct team team_new(const char *teamA, int score, int wins, int losses, int ties, int scored, int suff)
{
struct team t;
t.teamA = strdup(teamA);
t.score = score;
t.wins = wins;
t.losses = losses;
t.ties = ties;
t.scored = scored;
t.suff = suff;
return t;
};
struct game game_new(const char *teamA, int scoreA, const char *teamB, int scoreB)
{
struct game g;
g.teamA = strdup(teamA);
g.scoreA = scoreA;
g.teamB = strdup(teamB);
g.scoreB = scoreB;
return g;
};
int main(void)
{
int i, j, teams, nrgames, biggestScore, whichTeam;
scanf("Teams and number of games %d %d", &teams, &nrgames);
//add team names to theTeamss struct
struct team theTeams[teams];
size_t num_teams = 0;
for (i = 0; i < teams; ++i)
{
char teamA[20];
if (scanf("%s", teamA) != 1)
exit(0);
theTeams[++num_teams] = team_new(teamA, 0, 0, 0, 0, 0, 0);
}
struct game games[nrgames]; //add games
size_t num_games = 0;
for (i = 0; i < sizeof games / sizeof *games; ++i)
{
char teamA[20], teamB[20];
int scoreA, scoreB;
if (scanf(" %s %d - %s %d", teamA, &scoreA, teamB, &scoreB) != 4)
exit(0);
games[++num_games] = game_new(teamA, scoreA, teamB, scoreB);
}
//run through games[] to change values of theTeams[] scores
//games - A against B
for (i = 0; i < sizeof games / sizeof *games; ++i)
{
for (j = 0; j < sizeof theTeams / sizeof *theTeams; ++j)
{
if ((games[i].teamA == theTeams[j].teamA)) //team(A)
{
//if A wins
if(games[i].scoreA > games[i].scoreB)
{
theTeams[j].score += 3;
theTeams[j].wins += 1;
theTeams[j].scored = games[i].scoreA;
}
//if A loses
else if (games[i].scoreA < games[i].scoreB)
{
theTeams[j].score += 0;
theTeams[j].losses += 1;
theTeams[j].suff = games[i].scoreB;
}
else //tied
{
theTeams[j].score += 1;
theTeams[j].ties += 1;
theTeams[j].suff = games[i].scoreA;
}
}
if ((games[i].teamB == theTeams[j].teamA))//team(B)
{
//if B wins
if(games[i].scoreB > games[i].scoreA)
{
theTeams[j].score += 3;
theTeams[j].wins += 1;
theTeams[j].scored = games[i].scoreB;
}
//if B loses
else if (games[i].scoreB < games[i].scoreA)
{
theTeams[j].score += 0;
theTeams[j].losses += 1;
theTeams[j].suff = games[i].scoreA;
}
else //tied
{
theTeams[j].score += 1;
theTeams[j].ties += 1;
theTeams[j].suff = games[i].scoreB;
}
}
}
}
//accessing to the winner team
biggestScore = theTeams[0].score;
whichTeam = 0;
for (i = 0; i < sizeof theTeams / sizeof *theTeams; ++i){
if (theTeams[i].score > biggestScore){
biggestScore = theTeams[i].score;
whichTeam = i;
}
}
//output
printf("\n This winner is %s, with %d point(s), Won %d game(s), tied %d game(s) and lost %d game(s), Scored %d goal(s) e suffered %d goal(s)\n", theTeams[whichTeam].teamA, theTeams[whichTeam].score, theTeams[whichTeam].wins, theTeams[whichTeam].losses, theTeams[whichTeam].ties, theTeams[whichTeam].scored, theTeams[whichTeam].suff);
return 0;
}
There are no "problems" with C language and strings; you can do whatever you want. It's just a bit more responsibility than in other languages.
You seem to need an array of structures, yes. I would recommend modelling it as just an array of games played, where each game records the teams that took part, and their scores. No need to first record a list of "available" teams, it's easier to just extract that from the game data afterwards.
struct game {
const char *teamA;
int scoreA;
const char *teamB;
int scoreB;
};
struct game game_new(const char *teamA, int scoreA, const char *teamB, int scoreB)
{
struct game g;
g.teamA = strdup(teamA);
g.scoreA = scoreA;
g.teamB = strdup(teamB);
g.scoreB = scoreB;
return g;
}
and then in the man program:
int main(void)
{
struct game games[100];
size_t num_games = 0;
for (size_t i = 0; i < sizeof games / sizeof *games; ++i)
{
char teamA[100], teamB[100];
int scoreA, scoreB;
if (scanf(" %s %d - %s %d", teamA, &scoreA, teamB, &scoreB) != 4)
break;
games[++num_games] = game_new(teamA, scoreA, teamB, scoreB);
}
}
C like all programming languages is only as good as the plan you have laid out to model the data
For this, an array of arrays that stores the data can work.
Might want to also consider a database for relationships based on teams. Then you can also add metadata and the like (for example, timestamps). Though its only good if you don't mind externalising application beyond C.

Finding the largest difference between multiple sets of numbers

I've attempted to create a program which processes a list of outcomes for football games while also processing the results.
The way my program works is you input the number of matches that have been played then you list the results of each match.
Each row in the list has the form of HOME_TEAM_ID | AWAY_TEAM_ID | HOME_TEAM_GOALS | AWAY_TEAM_GOALS
So for example if the user entered (the first line is the number of matches):
2
0 1 5 0
2 3 0 5
My program will then output a row containing: team id, win ratio, win ratio on home games, average point difference in won games ( -1 in case of no home games.) The largest (in terms of point difference) win in a single game and then the ID of that opponent.
0 1.000 1.000 5.000
1 0.000 -1 -1
2 0.000 0.000 -1
3 1.000 -1 5.000
I've completed most of my program but I'm having difficulty implementing one last part. I want to find out the the largest (in terms of goal difference) win in a single game for each team and then the ID of the opponent which they had their largest win in terms of goal difference. (If there aren't any wins then it should simply output -1.)
My first thought was to just loop through the array, setting a variable to the largest win. For each element, check if its point difference is higher than the variable. If it is, replace the variable with the current element's difference.
However I'm getting a compiler error.
1079.c: In function 'main':
1079.c:153:11: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
maximum = resultTable[0];
^
1079.c:157:24: warning: comparison between pointer and integer
if (resultTable[n] > maximum)
^
1079.c:159:17: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
maximum = resultTable[n];
Any help about how to find the largest average point difference, over multiple games, against one particular opponent, would be greatly appreciated.
Here's my full code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//My local variables
int n;
int i;
int input = 0;
int TEAM_ID = 0, NUM_OF_GAMES = 1, WINS = 3, HOME_GAMES = 2, HOME_WINS = 4, HOME_WIN_RATIO = 6, WIN_RATIO = 5, GD = 7;
int homeTeamID, awayTeamID, homeGoals, awayGoals;
static const int NUM_COLUMNS = 10;
static const int NUM_TEAMS = 30;
double resultTable[30][10];
int BEST_WIN_DIFF = 8, BEST_WIN_OPPONENT = 9;
void takeInput();
void sortData();
void printer();
//This method takes the input from the user for homeTeamID, awayTeamID,homeGoals and awayGoals
void takeInput()
{
scanf("%d", &input);
for (n = 0; n < input; n++) {
scanf("%d %d %d %d", &homeTeamID, &awayTeamID, &homeGoals, &awayGoals);
//calls the sortData function
sortData();
}
}
//The table fnction which uses the resultTable variable to put the infomation in a table
void sortData()
{
int goalDiff = homeGoals - awayGoals;
//This will increment the home games,home game counter and the away game
resultTable[homeTeamID][NUM_OF_GAMES]++;
resultTable[homeTeamID][HOME_GAMES]++;
resultTable[awayTeamID][NUM_OF_GAMES]++;
//If the awaygoals is larger than the homegoals then it will set the winner in the results table
if (homeGoals < awayGoals) {
resultTable[awayTeamID][WINS]++; //increment away wins
}
//If the homegoals is larger than the awaygoals then it will set the winner in the results table
else if (homeGoals > awayGoals) {
resultTable[homeTeamID][WINS]++;
resultTable[homeTeamID][HOME_WINS]++; //increment home wins
}
//The goal difference for home and away
resultTable[homeTeamID][GD] = resultTable[homeTeamID][GD] + (homeGoals - awayGoals);
resultTable[awayTeamID][GD] = resultTable[awayTeamID][GD] + (awayGoals - homeGoals);
if (goalDiff > resultTable[homeTeamID][BEST_WIN_DIFF]) {
resultTable[homeTeamID][BEST_WIN_DIFF] = goalDiff;
resultTable[homeTeamID][BEST_WIN_OPPONENT] = awayTeamID;
}
if (-goalDiff > resultTable[awayTeamID][BEST_WIN_DIFF]) {
resultTable[awayTeamID][BEST_WIN_DIFF] = -goalDiff;
resultTable[awayTeamID][BEST_WIN_OPPONENT] = homeTeamID;
}
}
//Calculates the win ratio
void winRatio()
{
for (n = 0; n < 30; n++) {
//This if determines the home win ratio
if (resultTable[n][HOME_GAMES] > 0) {
resultTable[n][HOME_WIN_RATIO] = resultTable[n][HOME_WINS]
/ resultTable[n][HOME_GAMES];
}
if (resultTable[n][NUM_OF_GAMES] > 0) {
resultTable[n][GD] = resultTable[n][GD] / resultTable[n][NUM_OF_GAMES];
}
//This if determines the win ratio
if (resultTable[n][NUM_OF_GAMES] > 0) {
resultTable[n][WIN_RATIO] = resultTable[n][WINS]
/ resultTable[n][NUM_OF_GAMES];
}
}
}
//This method prints out the results
void printer()
{
for (n = 0; n < NUM_TEAMS; n++) {
if (resultTable[n][NUM_OF_GAMES] != 0) {
if (resultTable[n][HOME_WIN_RATIO] == -1) {
printf("%d %.3f %.0f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
else {
printf("%d %.3f %.3f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
}
}
}
//My main function which will be used to call everyother function
int main(void)
{
for (n = 0; n < NUM_TEAMS; n++) {
for (i = 1; i < NUM_COLUMNS; i++) {
resultTable[n][i] = 0;
}
resultTable[n][TEAM_ID] = n;
resultTable[n][HOME_WIN_RATIO] = -1;
resultTable[n][BEST_WIN_DIFF] = -HUGE_VAL;
}
int maximum, location = 1;
for (n = 0; n < 30; n++)
scanf("%d", &resultTable[n]);
maximum = resultTable[0];
for (n = 0; n < 30; n++)
{
if (resultTable[n] > maximum)
{
maximum = resultTable[n];
location = n+1;
}
}
printf("Maximum element is present at location %d and it's value is %d.\n", location, maximum);
return 0;
takeInput();
winRatio();
printer();
return EXIT_SUCCESS;
}
You can't get the information you want (the largest etcetera) from the data you enter into the array because you throw away information you need later to calculate this.
You need to store the input data unchanged into the array, then you can calculate anything from it you want.
In particular, with
//The goal difference for home and away
resultTable[homeTeamID][GD] = resultTable[homeTeamID][GD] + (homeGoals - awayGoals);
resultTable[awayTeamID][GD] = resultTable[awayTeamID][GD] + (awayGoals - homeGoals);
you remember the difference, but that is not enough to calculate the largest win in a single game for each team. Instead, store both homeGoals and awayGoalsand then later calculate the information you want.
Include math.h for HUGE_VAL.
#include <math.h>
Add two extra columns.
static const int NUM_COLUMNS = 10;
static const int NUM_TEAMS = 30;
double resultTable[NUM_TEAMS][NUM_COLUMNS];
int BEST_WIN_DIFF = 8, BEST_WIN_OPPONENT = 9;
Add them to the table function.
void table()
{
int i;
for (n = 0; n < NUM_TEAMS; n++) {
for (i = 1; i < NUM_COLUMNS; i++) {
resultTable[n][i] = 0;
}
resultTable[n][TEAM_ID] = n;
resultTable[n][HOME_WIN_RATIO] = -1;
resultTable[n][BEST_WIN_DIFF] = -HUGE_VAL;
}
}
Add the new code to the end of sortData.
void sortData()
{
...
int goalDiff = homeGoals - awayGoals;
if (goalDiff > resultTable[homeTeamID][BEST_WIN_DIFF]) {
resultTable[homeTeamID][BEST_WIN_DIFF] = goalDiff;
resultTable[homeTeamID][BEST_WIN_OPPONENT] = awayTeamID;
}
if (-goalDiff > resultTable[awayTeamID][BEST_WIN_DIFF]) {
resultTable[awayTeamID][BEST_WIN_DIFF] = -goalDiff;
resultTable[awayTeamID][BEST_WIN_OPPONENT] = homeTeamID;
}
}
and finally update printer to include the extra columns.
void printer()
{
for (n = 0; n < NUM_TEAMS; n++) {
if (resultTable[n][NUM_OF_GAMES] != 0) {
if (resultTable[n][HOME_WIN_RATIO] == -1) {
printf("%d %.3f %.0f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
else {
printf("%d %.3f %.3f %.3f %.0f %.0f\n", n,
resultTable[n][WIN_RATIO],
resultTable[n][HOME_WIN_RATIO],
resultTable[n][GD],
resultTable[n][BEST_WIN_DIFF],
resultTable[n][BEST_WIN_OPPONENT]);
}
}
}
}
double resultTable[30][10];
resultTable[x] is a pointer to double [10]
resultTable[x] is a pointer of double *
resultTable[x][y] is double
That is the reason you get the warning
You have more problems in your code
you scanf integers, but pass pointer to double etc etc.

Specific dice to reroll in C

I am working on a game of Yahtzee and one part of the game is the user can choose which dice out of 5 they wish to re-roll. I don't really know how to approach this besides writing a ton of if if-else statements, but there has to be a more efficient way to re-roll the specific die/ dice. I wrote out a snippet of what I am trying to accomplish, its not exactly like this in my actual code, but hopefully it is enough to answer the question :)
#include<stdio.h>
int main(void)
{
int die1 = 0, die2 = 0, die3 = 0, die4 = 0, die5 = 0;
int *ptr_die1 = &die1, *ptr_die2 = &die2, *ptr_die3 = &die3, *ptr_die4 = &die4, *ptr_die5 = &die5;
int choice = 0;
int die[5] = { 0 };
for (int i = 0; i < 5; i++)
{
die[i] = rand() % 6 + 1;
}
printf("Die[1] = %d\n", die[0]);
printf("Die[2] = %d\n", die[1]);
printf("Die[3] = %d\n", die[2]);
printf("Die[4] = %d\n", die[3]);
printf("Die[5] = %d\n", die[4]);
choice = printf("Please select which die to reroll\n");
scanf("%d", &choice);
printf("%d\n", choice);
for (int i = 0; i < 5; i++)
{
die[choice-1] = rand() % 6 + 1;
}
printf("Die[1] = %d\n", die[0]);
printf("Die[2] = %d\n", die[1]);
printf("Die[3] = %d\n", die[2]);
printf("Die[4] = %d\n", die[3]);
printf("Die[5] = %d\n", die[4]);
return 0;
}
after this I am really lost on how to change the die because the user could want to change just 1, or all 5 or any combination in between...
You have way too many variables that are not really needed.
int main(int argc, char **argv)
{
int i;
int choice;
int dices[5];
srand(time(NULL));
while(1){
for (i = 0; i < 5; i++)
dices[i] = rand() % 6 + 1;
choice = printf("Please select which die to reroll (or enter 0 to quit)");
scanf("%d", &choice);
if (choice == 0) // end the game
break;
if (choice < 1 || choice > 5 ){ // make sure that input is valid
fprintf(stderr, "error, input should be between 1 to 5 (inclusive)\n");
return -1;
}
printf("dice shows: %d", dices[choice-1]);
}
return 0;
}
You need to ask the user for the ending it, e.g. "Enter 0 to end the game". Otherwise it would be an infinite loop.
You could have the user input a comma-separatd list of die, instead of a single integer, which it looks like you're doing now. Then just parse the input, check that you have between 1 and 5 valid integers less than 6, and index into each die.
Or you could do like kaylum suggested and loop until the user inputs a special string indicating they're done, or prompt for 1, 2, ... 5 and ask for a yes or no answer to each.
Just use an array of int values to represent the set of dice:
#define DICE_COUNT 6
void rollDice(int* diceArray, size_t diceIndex) {
assert( 0 <= diceIndex && diceIndex < DICE_COUNT );
diceArray[ diceIndex ] = rand() % 6 + 1;
}
int main(int argc, char* argv[]) {
// Seed the RNG:
srand( (unsigned)time(&t) );
int dice[DICE_COUNT];
for(size_t i = 0; i < DICE_COUNT; i++) {
rollDice( dice, i );
}
while( true ) {
printf("Please select which die to reroll. Enter -2 to quit. (%d to %d inclusive)", 1, DICE_COUNT);
int selection = -1;
scanf("%d", &selection);
if( selection == -2 ) break;
if( 1 <= selection && selection <= DICE_COUNT ) {
selection--; // convert from 1-6 to 0-5.
rollDice( dice, selection );
}
}
return EXIT_SUCCESS;
}
I don't see any if..else statements in your code above. I will say, in this chunk of code:
for (int i = 0; i < 5; i++)
{
die[choice-1] = rand() % 6 + 1;
}
You don't need the for loop. You are not using the index, and rand() should work the first time through. I know rand() isn't the best written function, but if you seed it first, it should give you a pseudo-random number.
#include <time.h>
...
/* initialize random seed: */
srand ( time(NULL) );
...
die[choice-1] = rand() % 6 + 1;
Hope this was helpful, if you are still even working on that project!

Loop to create random numbers, read from existing array, then create new array -- Stuck in While-Loop

I have a doozy of a conundrum. Conceptually, I think I know what I need to do. Code-wise, I'm not so sure.
I want to go through the AVAIL_NURSE_W1[] array (which holds the number that corresponds to which nurse is available on Week_1), generate a random number to decide on a slot in that array (if the slot holds a zero value, then generate another random number and try again), take that number (which is a nurse), and put it into the MONDAY[] array.
Related-code:
int main() {
int randomNurse();
srand(time_t(NULL));
/*0 = Denise, 1 = Inja, 2 = Jane, 3 = Karen, 4 = Maggie, 5 = Margaret, 6 = MJ, 7 = Queen, 8 = Sherri*/
/*-----WEEKLY_ASSIGNMENT-----*/
int AVAIL_NURSE_W1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //holds the numerical values of the nurses that CAN work each week
/*scans in first week*/
for (int column = 0; column < 4; column++) {
for (int num = 0; num < 9; num++) {
if (AVAIL_NURSE_W1[num] == select[0][column])
AVAIL_NURSE_W1[num] = 0;
}
}
/*-----MONDAY-----*/
int MONDAY[5]; //days of the week, number of jobs on a given day
for (int e = 0; e < 5; e++) { //loop for positions on monday
while (MONDAY[e] == 0) {
int temp_assign = randomNurse();
if (AVAIL_NURSE_W1[temp_assign] != 0) { //if the nurse IS available...
MONDAY[e] = AVAIL_NURSE_W1[temp_assign];
AVAIL_NURSE_W1[temp_assign] = 0; //we don't want to repeat nurses
} else {
continue;
}
}
}
return 0;
}
/*function to generate random nurse*/
int randomNurse() {
return rand() % 9; //random number 0-8, to pick nurse
}
My Question:
How do I take care of getting the available nurses from the AVAIL_NURSE_W1[] array, generate a random number which decides which slot to take a value from, takes that value, stores it in a new array MONDAY[]; if the value in the AVAIL_NURSE_W1[] array is a ZERO, then repeat the above process until it's selected a non-zero value; after I've selected a value, I will change the selected value to a ZERO and then go through the loop again.
Desired result
The MONDAY[] array should contain five non-zero integers. No repeats.
So far, it seems the while loop condition never changes.
Let me know if there is anything else that needs saying. I hope I've given enough information.
Here you go :
#include<stdio.h>
#include <stdlib.h>
const char names[9][10] = {"Denise", "Inja", "Jane", "Karen", "Maggie", "Margaret", "MJ", "Queen", "Sherri"};
const char days[5][10] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
int randomNurse();
int main() {
srand(time(NULL));
int day, e, pos, candidate;
int i,j;
/*0 = Denise, 1 = Inja, 2 = Jane, 3 = Karen, 4 = Maggie, 5 = Margaret, 6 = MJ, 7 = Queen, 8 = Sherri*/
/*-----WEEKLY_ASSIGNMENT-----*/
int AVAIL_NURSE_W1[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1}; //holds the status of each nurse, 1:available 0:unavailable
int pos_per_day[5] = {2, 5, 7, 4, 3}; // number of needed nurses per day, Monday:2 nurses, tuesday: 5 nurses ...
int select[5][9]; // the selected nurses per day
for(i=0; i<5; i++)
for(j=0; j<9;j++) select[i][j] = -1; // initialize to -1 which means no nurse is selected
// fill all the days of week
for (day = 0; day<5; day++) // for every day
{
for(pos = 0; pos<pos_per_day[day]; pos++ ) // for every position needed that day
{
do
{
candidate = randomNurse();
}while(!AVAIL_NURSE_W1[candidate]); // look for available nurse
AVAIL_NURSE_W1[candidate] = 0; // change her status to not available
select[day][pos] = candidate; // fill the output array with appropriate nurse
}
for(i=0; i< 9; i++)
{
AVAIL_NURSE_W1[i] = 1; // initialize the nurses status for next day use
}
}
for(i=0; i<5; i++) // display
{
printf("%-10s: ", days[i]);
for(j=0; j<9;j++)
{
if(select[i][j] != -1) printf("%-10s ", names[select[i][j]]);
}
printf("\n");
}
return 0;
}
/*function to generate random nurse*/
int randomNurse() {
return rand() % 9; //random number 0-8, to pick nurse
}

Switch-Case statement seems to freeze my loops

Here are a few loops from my program I'm working on. The program seems to stop advancing after printf("TEST2");. Everything checks out at a glance. Is there something I'm missing?
I'm expecting the loop to repeat after setting the values in the switch-statement. I know it's getting through it at least once.
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
char *names[] = { "Denise", "Inja", "Jane", "Karen", "Maggie", "Margaret", "MJ", "Queen", "Sherri", NULL }; //ptr for names, 9 nurses
const char days[5][10] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
int randomNurse();
#define total_nurses 9 //number of nurses on staff
#define days_in_week 5 //number of work days in a week
int main() {
srand(time(NULL));
int day, pos, candidate, i, j;
int slackers[4] = { 1, 1, 1, 1 }; //array that holds the selections for who isn't working
char **name_ptr = names;
/*0 = Denise, 1 = Inja, 2 = Jane, 3 = Karen, 4 = Maggie, 5 = Margaret, 6 = MJ, 7 = Queen, 8 = Sherri*/
int avail_nurses[total_nurses] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; //holds the status of each nurse, 0 = unavailable, 1 = available
/*prints names */
int temp_counter = 1; //counter
while (*name_ptr) {
printf("%i) %s\n", temp_counter, *name_ptr);
name_ptr++;
temp_counter++;
}
/*this assumes that no more than FOUR nurses will be away on any given week*/
printf("\nEnter numbers that correspond to the nurses who won't be available for the week.\nType up to four numbers, each separated by a space.\n");
printf("When you are done, press \"Enter\".\n");
printf("If less than four nurses will be on leave, type a \"0\" in place of a selection.\n");
printf("Example: 1 2 5 0\n\n\n");
/*week selection of unavailable nurses*/
do {
printf("Who won't be here? ");
} while (scanf("%i %i %i %i", &slackers[0], &slackers[1], &slackers[2], &slackers[3]) != 4);
/*checks the selections made, and sets the available nurses to the correct value, zero if they are slacking||vacationing*/
for (int n = 0; n < 4; n++) {
int slacker = slackers[n];
if (slacker >= 1 && slacker <= 9)
avail_nurses[slacker] = -1;
}
/*-----WEEKLY_ASSIGNMENT-----*/
int pos_per_day[days_in_week] = { 5, 9, 9, 8, 5 }; //number of nurses needed each day
int selection[days_in_week][total_nurses]; //the selected nurses per day
for (i = 0; i < days_in_week; i++) {
for (j = 0; j < total_nurses; j++) {
selection[i][j] = -1; //initialize to -1 which means no nurse is selected
}
}
//fill all the days of week
for (day = 0; day < days_in_week; day++) {
for (pos = 0; pos < pos_per_day[day]; pos++) { //for every position needed that day
do {
candidate = randomNurse();
} while (!avail_nurses[candidate]); //looks for available nurses (phrasing)
avail_nurses[candidate] = 0; //change nurses status to not available
selection[day][pos] = candidate; //fill the output array with appropriate nurse
}
for (i = 0; i < total_nurses; i++) {
avail_nurses[i] = 1; //initialize the nurses status for next day use
}
for (int n = 0; n < 4; n++) { //make sure we shame the slackers...
int slacker = slackers[n];
if (slacker >= 1 && slacker <= 9)
avail_nurses[slacker] = -1;
}
}
/*-----PRINTS SCHEDULE FOR WEEK-----*/
for (i = 0; i < days_in_week; i++) {
printf("%-10s: ", days[i]);
for (j = 0; j < total_nurses; j++) {
if (selection[i][j] != -1)
printf("%-10s ", names[selection[i][j]]);
}
printf("\n");
}
return 0;
}
/*function to generate random nurse*/
int randomNurse() {
return rand() % 9; //random number 0-8, to pick nurse
}
You have Undefined Behaviour. The second value in pos_per_day is 9, which is outside the bounds of the select array. Subtracting one from each value in that array may be enough to fix it.
Other bad problems:
you need to validate the input data after scanf.
the switch statement is completely unnecessary. Replace it by a calculation.
don't use UPPER CASE for variables. By convention, that's only for defined constants.
don't hard code numbers like 5 and 9. Replace them by DEFINED CONSTANTS.
You must learn how to debug simple programs like this, using the debugger available to you.

Resources