I've tried two-dimensional arrays, varying prototype functions, and I can't seem to implement a score system for this game. Any ideas on what I can do? I want to take the output from this code, which are 6 varying numbers from 1-6, and assign them a value that I can add up to make a score. Ex. If I roll a 1, it would be worth 100 points. What's the quickest and most efficient way to assign a point value to the rolled value?
#include <stdio.h>
#include <time.h>
int main() {
int i, r, diceRoll;
char player1[20];
int temp, swapped;
int roll1[6];
srand(time(NULL));
printf("Enter name for Player 1:\n");
scanf(" %s", &player1);
for(i = 0; i < 6; i ++) {
r = ( rand() % 6 ) + 1;
diceRoll= r;
roll1[i] = diceRoll;
}
while(1) {
swapped = 0;
for( i = 0; i < 6-1; i++ ) {
if( roll1[i] > roll1[i + 1] ) {
temp = roll1[i];
roll1[i ] = roll1[i+1];
roll1[i+1] = temp;
swapped = 1;
}
}//for
if( swapped == 0) {
break;
}
}//while
printf("\n\n %s's Dice Roll:\n\n", player1); // prints out the dice rolls of player 1
return 0;
}//main
Why not do a straight aggregation of the values mapped to the corresponding point value? (Unless it is straight 100 * the roll value, in which case it is even easier.)
int score = 0;
for( i = 0; i < 6; ++i )
{
switch( roll1[i] )
{
case 1: score += 100; break;
case 2: score += 230; break;
case 3: score += 540; break;
case 4: score += 2320; break;
case 5: score += 13130; break;
case 6: score += 454260; break; /* Of course, change to the score you want for each value. */
}
}
printf("\n\n %s's Dice Roll:%d\n\n", player1, score);
"What I originally had in mind was to make the game like Farkle, where 1 is 100pts, 5 is 50pts, and everything else is 0 until you get 3 of a kind ( Three 3s = 300pts, Three 1s is 1000, etc). Any input would be greatly appreciated" There are many ways. You can do this easily and use Chux map approach for base and three of a kinds.
int score = 0;
int face_score = 0;
int base_points[6] = { 100, 0, 0, 0, 50, 0 };
int three_of_a_kind_points[6] = { 300, 200, 300, 400, 500, 600 };
int four_of_a_kind_points[6] = {
int repeat_counter[6] = { 0, 0, 0, 0, 0, 0 };
int kind_mask = 0;
int pair_count = 0;
int three_of_a_kind_count = 0;
int four_of_a_kind_count = 0;
for( i = 0; i < 6; ++i )
{
kind_mask |= 1 << ( roll1[i] - 1 );
switch( ++repeat_counter[roll1[i] - 1] )
{
case 1: break;
case 2: ++pair_count; break;
case 3: score = three_of_a_kind_points[rolli[i] - 1]; ++three_of_a_kind_count; break;
case 4: score = 1000; ++four_of_a_kind_count; break;
case 5: score = 2000; break;
case 6: score = 3000; break;
}
}
if( pair_count == 3 ) /* Three pairs */
score = 1500;
else if( three_of_a_kind_count == 2 ) /* Two three of a kinds */
score = 2500;
else if( four_of_a_kind && ( pair_count == 2 ) ) /* A four of a kind and one pair (2 because four of a kind counted as a pair in the aggregation phase) */
score = 1500;
else if( kind_mask = 0x2F ) /* One of each type */
score = 1500; /* Straight */
else if( !score ) /* score only 1's and 5's */
score = repeat_counter[0] * 100 + repeat_counter[4] * 50;
printf("\n\n %s's Dice Roll:%d\n\n", player1, score);
I have not compiled or run this code, so it may not be 100% correct.
Related
I can't use arrays or lists and I have to use C.
Duplicates mean if you have 975444579 it will show 25 or if you have 32111 it will show 6 and not 8.
Here is my code:
#include <stdio.h>
int main() {
int num = 0, sum = 0, i = 0, oNum = 0, nNum = 0, tNum = 0, e = 0;
printf("enter a number: ");
scanf("%d", &num);
oNum = num;
while (num != 0) {
e = 0;
i = 0;
nNum = oNum;
tNum = num % 10;
do {
if (nNum % 10 == tNum) {
i += 1;
}
nNum /= 10;
} while (nNum != 0);
sum += tNum;
i -= 1;
while (e < i) {
sum -= tNum;
e += 1;
}
num /= 10;
}
printf("%d", sum);
return 0;
}
Not being able to use an array is a silly requirement. It lends itself well to the problem:
Initial:
int seen[10] = { 0 };
Checking if a digit was encountered:
seen[d]
Marking a digit as encountered:
++seen[d];
These could even be combined.
if (!(seen[d]++))
sum += d;
But, we could use 10 bits of a number in a similar manner.
Initial:
uint16_t seen = 0;
Checking if a bit is set is done as follows:
seen & (1 << d)
Setting a bit is done as follows:
seen |= 1 << d;
finding the sum of a given Int but ignoring duplicate numbers digits?
Form a mask of allowed digits
Iterate once extracting one digit at a time (OP has that part)
If digit not used before, clear that a bit (per digit) and add digit to the sum.
Let us use an unsigned integer to avoid complications with negative values - we'll disallow them.
int digit_sum_no_repeat(unsigned i) {
int sum = 0;
unsigned allowed_digits_mask = 0x3FF; // All 10 digits allowed.
while (i) {
unsigned digit = i % 10; // Extract least significant digit
unsigned digit_mask = 1u << digit;
if (allowed_digits_mask & digit_mask) {
allowed_digits_mask ^= digit_mask; // clear the bit
sum += digit;
}
i /= 10;
}
return sum;
}
Here's a working example that uses the bits of a single unsigned int to find each digit in a number, and which then adds those found digits:
#include <stdio.h>
int main()
{
int num = 0, sum = 0, i;
unsigned int digits = 0u; // MUST be at least 10 bits in size (which is guaranteed)
printf("enter a number: ");
scanf("%d", &num);
while (num != 0) { // first loop - set bits for each digit present:
int dig = num % 10; // This gets us the value of the lowest digit...
digits |= (1u << dig); // Set the bit to indicate this digit.
num /= 10; // .. now remove the lowest digit and 'shift' the others.
}
for (i = 1; i < 10; ++i) { // second loop - sum all digits whose corresponding bit is set:
if (digits & (1u << i)) sum += i;
}
printf("%d", sum);
return 0;
}
unsigned int n = 1231;
unsigned int nsum = 0;
unsigned int bdigits = 0;
while( n ) {
bdigits |= 1 << (n%10);
n /= 10;
}
for( unsigned int x = 0; x < 10; x++ ) {
if( bdigits&(1<<x) ) nsum += x;
}
printf("Sum: %d\n", nsum);
I use switch loop two times ,but the code is so long
#include <stdio.h>
int main() {
int num=0,zero=0,one=0,two=0,three=0,four=0,five=0,six=0,seven=0,eight=0,nine=0,ten=0,s=0;
printf("enter a number: ");
scanf("%d", &num);
while(num != 0)
{
switch(num%10)
{
case 0:
{
zero++;
switch(zero)
{
case 1:
{
s=s+0;
}break;
}
}break;
case 1:
{
one++;
switch(one)
{
case 1:
{
s=s+1;
}break;
}
}break;
case 2:
{
two++;
switch(two)
{
case 1:
{
s=s+2;
}break;
}
}break;
case 3:
{
three++;
switch(three)
{
case 1:
{
s=s+3;
}break;
}
}break;
case 4:
{
four++;
switch(four)
{
case 1:
{
s=s+4;
}break;
}
}break;
case 5:
{
five++;
switch(five)
{
case 1:
{
s=s+5;
}break;
}
}break;
case 6:
{
six++;
switch(six)
{
case 1:
{
s=s+6;
}break;
}
}break;
case 7:
{
seven++;
switch(seven)
{
case 1:
{
s=s+7;
}break;
}
}break;
case 8:
{
eight++;
switch(eight)
{
case 1:
{
s=s+8;
}break;
}
}break;
case 9:
{
nine++;
switch(nine)
{
case 1:
{
s=s+9;
}break;
}
}break;
}
num /= 10;
}
printf("\nThe sum of the digits exepting repeated value : %d\n",s);
return 0;
}
You can do a trick using files and numbers, without needing to use array as follows:
int main()
{
int num;
char c;
FILE *fp = fopen("temp", "w");
if(!fp)
{
exit(1);
}
printf("enter a number: ");
scanf("%d", &num);
fprintf(fp, "%d", num);
fclose(fp);
int mask = 0;
fp = fopen("temp", "r");
while(fscanf(fp, "%1d", &num) != EOF) // reading 1 digit at a time
{
mask |= (1 << num); // here you will set the bit referent to the digit
}
fclose(fp);
int sum = 0;
for(int i = 1; i < 10; i++)
{
if(mask & (1 << i)) // here you check if the bit referent to number i was set
{
sum += i;
}
}
printf("sum is %d\n", sum);
}
Another way without the file is:
int main()
{
int num;
printf("enter a number: ");
scanf("%d", &num);
int mask = 0;
while(num)
{
mask |= (1 << (num%10));
num = num/10;
}
int sum = 0;
for(int i = 1; i < 10; i++)
if(mask & (1 << i))
sum += i;
printf("sum is %d\n", sum);
}
It's very hard to follow your program to debug it. You should choose more meaningful variable names or fill the code with all the required comments. Here's a program with better names.
#include <stdio.h>
int main() {
int num, check, copy, digit, notAdupe, sum = 0;
printf("enter a number: ");
scanf("%d", &num);
for(check = num; check; check /= 10 ) {
digit = check % 10;
notAdupe = 1;
for(copy = num; copy > check; copy /= 10) {
if( digit == copy % 10 ) {
notAdupe = 0;
break;
}
}
if( notAdupe ) sum += digit;
}
printf("\n%d", sum);
return 0;
}
in this block:
do {
if (nNum % 10 == tNum)
{
i += 1;
}
nNum /= 10;
} while (nNum != 0);
i -= 1;
you count how many times tNum appear in the digits that in his left side, so in the number 32111 for example you subtracting the most left 1 twice.
you need a way to find out if this the first time for seeing the digit in tNum.you can do it with bitwise of int variable with somethis like this
int flag = 0;
int is_first = 0;
...
tNum = num % 10;
is_first = flag ^ (tNum << 1) > flag;
flag |= (tNum << 1);
the flag will save in his bits which number you already saw
for example:
num = 121:
// you start with
flag = 0
...
tNum = 1, flag = 0 so
is_first = 0 ^ (1 << 1) > 0 = 1 > 0('true')
flag = 0 | 1 = 1
...
tNum = 2, flag = 1 so
is_first = 1 ^ (2 << 1) > 1 = 3 > 1('true')
flag = 2 | 1 = 3
...
tNum = 1, flag = 3 so
is_first = 3 ^ (1 << 1) > 3 = 2 > 3('false')
flag = 3 | 1 = 1
Here is a much simpler function to compute the sum of unique decimal digits in an integer:
int sum_unique_digits(unsigned n) {
int sum = 0, bits = 0;
do {
bits |= 1 << (n % 10);
} while (n /= 10);
do {
sum += (bits & 1) * n++;
} while (bits >>= 1);
return sum;
}
I have a coding assignment for my CIS class. The assignment is to write a program the will create an array of structures that will hold information on at max 10 dogs. At the end of the program, you are supposed to sort the array of dogs by either name or size. But I am unable to code the sorting of the array of dog. I was wondering how to sort the array of dogs for later use in the main function.
Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Dog{
char name[20];
int weight;
int age;
int ageDogYears;
char size[7];
};
typedef struct Dog DG;
void calc(DG[], int);
void sort(DG[], int);
void display();
int main(){
DG dArray[10];
int x = 0;
char str[80], *i;
FILE *inFile;
inFile = fopen("dogfile.txt", "r");
if (inFile == NULL){
printf("Error opening file");
exit(1);
}
while(fgets(str, 80,inFile) != NULL){
i = strtok(str, ", ");
strcpy(dArray[x].name, i);
puts(dArray[x].name);
i = strtok(NULL, ", ");
dArray[x].weight = atoi(i);
printf("%d\n", dArray[x].weight);
i = strtok(NULL, ", ");
dArray[x].age = atoi(i);
printf("%d\n", dArray[x].age);
x++;
}
calc(dArray, x);
sort(dArray, x);
return 0;
}
void calc(DG dog[], int numDogs){
int y, i, total;
for(i = 0; i < numDogs; ++i){
if(dog[i].weight <= 20){
//sets the dog size to small
strcpy(dog[i].size, "Small");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 15;
else if(y == 1)
total += 8;
else if(y == 2)
total += 5;
else
total += 4;
}
}
else if(dog[i].weight <= 50){
//sets the dog size to medium
strcpy(dog[i].size, "Medium");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 14;
else if(y == 1)
total += 9;
else if(y == 2)
total += 7;
else
total += 5;
}
}
else{
//sets the dog size to Large
strcpy(dog[i].size, "Large");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 12;
else if(y == 1)
total += 9;
else if(y == 2)
total += 8;
else
total += 7;
}
}
dog[i].ageDogYears = total;
total = 0;
}
}
void sort(DG dog[], int numDogs){
int sortType, i, y, temp;
printf("\n wlould you like to sort by name(N) or size(S): ");
scanf("%c", &sortType);
switch(sortType){
case 'N': case 'n':
for(i = 0; i < numDogs; ++i){
for(y = 0; y < (numDogs); ++y){
if(dog[y].weight > dog[y+1].weight){
temp = dog[y];
dog[y] = dog[y + 1];
dog[y + 1] = temp;
}
}
}
break;
default:
if((sortType != 's') && (sortType != 'S'))
printf("\n invalid input! Setting sort type to size.");
//sorting of dog names
}
}
Sample Input
Fluffy,23,6
Fido,65,7
Pepper,44,5
Bowser,75,10
Victor,10,2
Sassy,51,1
Any help would be much appretated! Thanks.
In my opinion, your error resides (despite of other comments I'll do below) in specifying %c as format descriptor to pass a pointer to int to match. You have to pass a pointer to char to make scanf(3) to select the proper place to put the character into. You probably are not getting the right character or no character at all (this leads to Undefined Behaviour in your program)
Some other problems are that you are using the weight field of the structure when requested to sort by name (on n input char) and other errors like this. This includes that you use y < (numDogs) in the inner loop limit condition (it must be y < (numDogs - 1), or you'll compare the y-esim with the y+1-esim element (out of array bounds)
Also, as you are using the same algorithm for both sorting options, I should include the switch statement inside the inner loop (where you do the comparison) as doing otherwise will force you to copy the same sorting code twice (for the overall sorting algorithm), as in:
for(i = 0; i < numDogs; ++i){
for(y = 0; y < (numDogs - 1); ++y){
int sortResultGreater;
switch (sortType) {
case 'n': case 'N':
sortResultGreater = strcmp(dog[y].name, dog[y+1].name) > 0;
break;
default: { /* this should be done as soon as you know the sorting type, not here inside the loop, of course */
static int not_already_printed = 1;
if (not_already_printed) {
printf("Error, sortType must be [nNsS], defaulting to n\n");
not_already_printed = 0; /* so we don't get here again */
}
} /* scope of not_already_printed finishes here */
/* no break used here to fallback to the next case */
case 's': case 'S':
sortResultGreater = dog[y].weight > dog[y+1].weight;
break;
} /* switch */
if(sortResultGreater){
temp = dog[y];
dog[y] = dog[y + 1];
dog[y + 1] = temp;
}
}
}
I am having trouble refining some code. My code takes a number "n" and calculates that many prime numbers. I need to display 10 primes per line of output data. Any tips would be appreciated.
#include <stdio.h>
int main()
{
int n, i = 3, count, c;
printf("How many primes would you like?");
scanf("%d",&n);
if ( n >= 1 )
{
printf("2");
}
for ( count = 2 ; count <= n ; )
{
for ( c = 2 ; c <= i - 1 ; c++ )
{
if ( i%c == 0 )
break;
}
if ( c == i )
{
printf(" %d",i);
count++;
}
i++;
}
return 0;
}
Just try
printf(" %5d", i);
/* ^ to help align the numbers
and
if ((count + 1) % 10 == 0)
fputc(stdout, '\n');
fix for the first time when you already print 2.
bool is_prime(int anyNum) //takes an integer array returns, is_prime
{
bool is_prime = true;
for (int c = 2; c <= anyNum - 1; c++)
{
if (anyNum % c == 0)
{
//printf("%d is not prime\r\n" , anyNum);
is_prime = false;
}
}
return is_prime;
}
int main()
{
int num_primes;
printf("How many primes would you like: ");
std::cin >> num_primes;
printf("\r\nScanned Primes Are---\r\n");
int foundPrimes = 0;
int x = 0;
for (; x <= num_primes; x++)
{
bool gotLuckyFindingPrime = is_prime( x );
if (gotLuckyFindingPrime)
{
if (foundPrimes % 10 == 0)
{
printf("\r\n");
}
printf(" %d", x);
foundPrimes = (foundPrimes + 1) % 10;
}
}
}
Does handle ten digit showing on cmd too, you can experiment with formatting
trying to learn about computer game players to familiarise myself with AI. I understand how minimax works in theory but cant get my head around how this code I found online works.
can someone explain the minimax fruction/computer move function (lines 38-78)to me.
credit: https://gist.github.com/MatthewSteel/3158579
thanks
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int minimax(int board[9], int player) {
//How is the position like for player (their turn) on board?
int winner = win(board);
if(winner != 0) return winner*player;
move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for(i = 0; i < 9; ++i) {//For all moves,
if(board[i] == 0) {//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player*-1);
if(thisScore > score) {
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if(move == -1) return 0;
return score;
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
Here is the essence of minimax:
int minimax(int board[9], int player) {
// ....
for(i = 0; i < 9; ++i) { //For all moves,
// ....
int thisScore = -minimax(board, player*-1);
}
}
Go through each possible move, and for each such possible move, turn the board around, pretend to be the other player (that's the player*-1 part), and try each possible move. thisScore is set to the negative return value from the recursive call to minimax, since good for the other player equals bad for ourselves.
computerMove just goes through all the possible moves, calls minimax for each such possible move, and uses the one with the best result.
I've written a program that generates 1,000 random numbers in the range of 1-10. What I then want it to do is tell me how many times each number was produced. But, for some reason why I run this program, I get 0 for every number.
Anyone know what I'm missing?
#include <stdio.h>
#include <stdlib.h>
void print(const int array[], int limit);
#define SIZE 1000
int main(void)
{
int i;
int arr[SIZE];
for (i = 0; i < SIZE; i++)
arr[i] = rand() % 10 + 1;
print(arr,SIZE);
return 0;
}
void print(const int array[], int limit)
{
int index, count1 = 0, count2 = 0, count3 = 0, count4 = 0, count5 = 0, count6 = 0,
count7 = 0, count8 = 0, count9 = 0, count10 = 0;
for (index = 0; index < limit; index++)
{
switch (array[index])
{
case '1' : count1++;
break;
case '2' : count2++;
break;
case '3' : count3++;
break;
case '4' : count4++;
break;
case '5' : count5++;
break;
case '6' : count6++;
break;
case '7' : count7++;
break;
case '8' : count8++;
break;
case '9' : count9++;
break;
case '10' : count10++;
break;
default : break;
}
}
printf("There were %d 10s, %d 9s, %d 8s, %d 7s, %d 6s, %d 5s, %d 4s, %d 3s, %d 2s, %d
1s.", count10, count9, count8, count7, count6, count5, count4, count3, count2, count1);
}
You do not need the single quotes around the numbers in the case statement. You are creating character literals by including the single quotes. Just take them off and you'll have integer literals, which is what you intend.
you are comparing numbers (stored in array) to character literals '1', '2', etc. In addition it would probably be easier to implement print using an array:
void print(const int array[], int limit)
{
int index;
int count[11] = {0};
for (index = 0; index < limit; index++)
{
count[array[index]]++;
}
printf("There were %d 10s", count[10]);
for (index = 10; index > 0; index--)
{
printf(" %d %ds%c", count[index], index, (index > 1)?',':'.');
}
}