The concept I am trying to create is a guessing game where you have a randomly generated secret code that you have to guess in a few ties. If your answer is wrong the three hints it will give you are: 1) if your guess is too high or too low. 2) if there are digits that are right and in the right place. 3) if there are right digits in the wrong place.
So if the code was 803 and your guess was 837 the output would be
Too High, 1 digit(s) in the right place, 1 right digit(s) in the wrong place.
My problem comes with the function that checks to see if there are right digits in the wrong place.
#define DIGITS 4 // DIGITS repersents the amout of digits in the code.3♠
int wrongPlace(int num[], int code[]){
int n = 0 , i , j ,temp;
for(i=0; i < DIGITS; i ){
temp=num[0];
num[0]=num[i]; // checks each digits to see if there are equal but in a differnt
num[i]=temp; // place and adds one to n
for(j=1 ; j < DIGITS ; j )
if(code[i]==num[j])
n ;
}
return n; // n repersent the right digits that are in the wrong palce
}
My problem comes with a guess or code that has duplicate numbers and return a numbers that is not acuate.
So if the code was 2128 and your guess was 7249 the output would be
Too High, 0 digit(s) in the right place, 1 right digit(s) in the wrong place.
CodePudding user response:
You shouldn't be modifying any of the arrays.
We can make this simpler by working on one digit at a time, and splitting this up into two problems:
- Is the number in the correct spot in the array?
- If not, is it anywhere in the array?
The first is a simple loop with a counter.
int main() {
int code[] = {8, 0, 3};
int guess[] = {8, 3, 7};
int numRightPositions = 0;
for( size_t i = 0; i < numCodes; i ) {
if( code[i] == guess[i] ) {
numRightPositions ;
}
}
printf("%d right position\n", rightPosition);
}
If the guess isn't in the right position, we need to check if it's in the array at all. We can write a little function for that. Loop through the code to see if the guess is there.
// Don't use hard coded size, or anything, in a function.
// Pass them into the function.
bool rightNumber(const int *code, int guess, size_t size) {
for(size_t i = 0; i < size; i ) {
if( code[i] == guess ) {
return true;
}
}
return false;
}
And we can add that to our loop calling it if the code isn't in the right position.
int main() {
int code[] = {8, 0, 3};
int guess[] = {8, 3, 7};
size_t numCodes = sizeof(code)/sizeof(code[0]);
int numRightPositions = 0;
int numRightNumbers = 0;
for( size_t i = 0; i < numCodes; i ) {
if( code[i] == guess[i] ) {
numRightPositions ;
}
else if( rightNumber(code, guess[i], numCodes) ) {
numRightNumbers ;
}
}
printf(
"%d digit(s) in the right place, %d right digit(s) in the wrong place.\n",
numRightPositions, numRightNumbers
);
}
This can be optimized, but that's the basic implementation using functions to separate the problem into pieces.
CodePudding user response:
This swapping of elements of the array num
temp=num[0];
num[0]=num[i]; // checks each digits to see if there are equal but in a differnt
num[i]=temp;
does not make a sense. For example if the array num contains the following elements { 1, 1, 1, 1 } then what does the swapping do?
Also this inner for loop
for(j=1 ; j < DIGITS ; j )
if(code[i]==num[j])
n ;
never check the element code[0].
Also it is a bad idea to change the array num within the function.
I can suggest the following approach shown in the demonstration program below.
#include <stdio.h>
struct Pair
{
size_t right_place;
size_t wrong_place;
};
struct Pair count_places( const int num[], const int code[], size_t n )
{
struct Pair p = { 0, 0 };
for ( size_t i = 0; i < n; i )
{
if ( num[i] == code[i] )
{
p.right_place;
}
else
{
size_t k = 1;
for ( size_t j = 0; j < i; j )
{
if ( num[i] == num[j] ) k;
}
for ( size_t j = 0; k != 0 && j < n; j )
{
if ( num[i] == code[j] ) --k;
}
if ( k == 0 )
{
p.wrong_place;
}
}
}
return p;
}
int main( void )
{
enum { N = 4 };
int code1[N] = { 2, 1, 2, 8 };
int num1[N] = { 7, 2, 4, 9 };
struct Pair p;
p = count_places( num1, code1, N );
printf( "%zu digit(s) in the right place, %zu right digit(s) in the wrong place",
p.right_place, p.wrong_place );
}
The program output is
0 digit(s) in the right place, 1 right digit(s) in the wrong place100us
CodePudding user response:
This is a function that checks the two arrays and computes the output string that you want, then returns 0 if the guess is incorrect, and 1 if it is correct. It does however clobber the arrays with -1s to avoid double counting, so if that's a problem you may want to pass copies of the input and code arrays to this function
_Bool check(int input[] ,int code[]){
_Bool higher = 0;
int numCorrect = 0;
int numMisplaced = 0;
for(int i = 0; i < DIGITS; i)
if(input[i] != code[i]){ //First digit that is not the same tells us which is higher
higher = input[i] > code[i] ? 1 : 0;
break;
}
for(int i = 0; i < DIGITS; i)
if(input[i] == code[i]){ //Count the number of digits in the right spots
numCorrect;
input[i] = code[i] = -1; //Don't want to double count correct digits as misplaced
}
if(numCorrect == DIGITS){
printf("Correct!\n");
return 1;
}
for(int i = 0; i < DIGITS; i) //Check for the right digits in the wrong places
for(int j = 0; j < DIGITS; j){
if(j == i) //Skip cases where indices are the same
continue;
if(input[i] != -1 && code[i] != -1 && input[i] == code[j]){ //Skip all the negative ones because they have been counted as right number right place
numMisplaced;
input[i] = code[i] = -1; //Don't want to double count
}
}
printf("Too %s, %d digit%s in the right place, %d right digit%s in the wrong place\n",higher ? "High" : "Low", numCorrect, numCorrect == 1 ? "" : "s", numMisplaced, numMisplaced == 1 ? "" : "s");
return 0; //Codes are not equal
}
Your program may also benefit from using char[]
instead of int[]
to save a handful of bytes, since we only need to be able to represent digits from 0-9