Thread: How to write a Mastermind game without using array and pointer?

  1. #16
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    Quote Originally Posted by Salem View Post
    When you've matched a near value, you need to mark it in some way as being matched already.

    Eg. code = 1223 guess = 1322

    If for example zero is never used, then when the 3 is matched as a near guess, the guess becomes say 1022 to prevent the 3 from being matched again.
    I've tried this method but the problem is that if the programme reaches the near value faster than the exact value, the near value increases by 1 and makes the near match being calculated wrongly.

    e.g.
    code = 1 2 3 4
    guess = 4 5 6 4

    As the program compares the 1st "4" with the code "1 2 3 4" 1st, near match will be increased by 1 because the exact value increases in the 4th turn, when the 4th "4" in guess matches the 4th "4" in code, which leads to a wrong answer.

    Correct ans: Exact: 1, Near: 0
    Ans displayed in my program: Exact: 1, Near: 1

  2. #17
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Match (and remove) all the exact matches first, then look for near matches.

    So after the exact scan, you're left with 1 2 3 0 and 4 5 6 0 to compare with one another for near matches (of which there is zero).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #18
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    I still don't know what's wrong with my program, someone pls tell me
    Last edited by wtxwt; 10-22-2007 at 05:04 AM.

  4. #19
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Your test for "near" will still have to run through 4 digits, since you are putting the digits back in the place where they were.

    I'm only guessing what's wrong from looking at the code - and that looks wrong to me. It is very helpful in posts like this if you (the original poster) posts what the "failure" is [e.g. "It doesn't calculate 'exact' the right way, it comes up with X when Y is the right result for guesses 1 2 3 4 where the correct answer is 4 7 3 5"].

    --
    Mats
    Last edited by matsp; 10-22-2007 at 03:02 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #20
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    Quote Originally Posted by matsp View Post
    Your test for "near" will still have to run through 4 digits, since you are putting the digits back in the place where they were.

    I'm only guessing what's wrong from looking at the code - and that looks wrong to me. It is very helpful in posts like this if you (the original poster) posts what the "failure" is [e.g. "It doesn't calculate 'exact' the right way, it comes up with X when Y is the right result for guesses 1 2 3 4 where the correct answer is 4 7 3 5"].

    --
    Mats
    Actually if I reset the reduced code in the near part, (after near++ but outside the inner for loop) the near match can be calculated nearly correct but numbers are counted repeatedly, if I don't reset the reduced number, it just counts as 0 or 1 near match.

    Someone in another forum suggests me to accomplish the task using "mask", but I haven't learned anything about mask, I've done a little research on that, is it sth like a array of boolean?

    Is it good to use maske to do that? If so, how? Thank You

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, you could use a mask. A mask would be a bit per value in the array. Start out with 0xF (1111 in binary), and clear the bits (and with ~(1 << n) ) when you "use the digit".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #22
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    Quote Originally Posted by matsp View Post
    Yes, you could use a mask. A mask would be a bit per value in the array. Start out with 0xF (1111 in binary), and clear the bits (and with ~(1 << n) ) when you "use the digit".

    --
    Mats
    But I know nothing about mask, I even don't know how to start, is the "mask" method better than the original one?

    What is the meaning of "0xF" and "clear the bits when I use that digit"?

  8. #23
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by wtxwt View Post
    But I know nothing about mask, I even don't know how to start, is the "mask" method better than the original one?

    What is the meaning of "0xF" and "clear the bits when I use that digit"?
    I don't think you need a mask - using a "marker" digit like the zero value should work just fine.

    You probably need to check the "newguess" extracted number for zero before you check if it's a match or not - otherwise you'll count the 0's as matches, which they are not.

    Code:
    		for (i = 1; i <= 4-exact; i++)
    		{
    			g = newguess % 10;
    			newguess /= 10;
    			for (j = 1; j <= 4-exact; j++)
    You should remove the red code.

    You will also need to adjust the inner loop to start over with the original numer, as you will certainly have it zero when it's run through one loop. When you find a near match, however, you need to zero that digit out, so that it doesn't count again for another number of same colour.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #24
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    The highlighted part has already kicked all the 0s out, but I still can't be able to correct the repeated numbers problem. You just compile it and play it for a while and you know what the problem is.

    Try to enter some combinations with repeated numbers or let the program chooses some repeated numbers and the problem appears. I don't know how to solve it.
    Last edited by wtxwt; 10-22-2007 at 05:04 AM.

  10. #25
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It takes me enough time to write answers to questions here, without actually trying to compile someone elses code, and "playing with it" until I figure out what the problem is.

    You still need to remove the "color" when it's been "used" for a near match.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #26
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    Quote Originally Posted by matsp View Post
    It takes me enough time to write answers to questions here, without actually trying to compile someone elses code, and "playing with it" until I figure out what the problem is.

    You still need to remove the "color" when it's been "used" for a near match.

    --
    Mats
    I don't know how, as the checking run for 16 turns, if I don't reset the number, the near match will just become "1" from the 5th check to 16th check, but if I reset the number, some combinations will be counted repeatedly, sometimes the near match can be calculated as more than 4

    e.g.
    Answer: 3 6 3 1
    Guess: 6 6 1 3
    Number of near match: 3
    The "3" is counted for two times, therefore 3 near match is displayed
    Last edited by wtxwt; 10-22-2007 at 04:13 AM.

  12. #27
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, so you set colorreset for the first three to zero. You also need to break the inner loop so you don't check more digits with the digit you've already used.

    By the way, to make it easier to test a specific case, why not (for now) ask for the answer as well as the guess - so you can _SET_ your answer to any combination you like. If you still want the "random" version, if you enter zero at the first position [and any 3 other numbers], it generates the random variety as the existing code does. That way, you don't have to "play until the particular combination comes up" - it could take quite some time to get three of one or four of one, which is probably some of the more difficult cases.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #28
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    I finally figure out the way to remove the numbers which have been already compared. See if it is a good way to achieve it, thank you

    Code:
    		for (i = 1; i <= 4; i++)
    		{
    			g = newguess &#37; 10;
    			newguess /= 10;
    	
    			tempnear = near;
    			
    			for (j = 1; j <= 4; j++)
    			{
    				c = newcolor % 10;
    				newcolor /= 10;
    				if (g==c && g!=0)
    				{
    					near++;
    					g = 0;
    					temp = c;
    					place = j;
    				}
    			}
    			//printf("%d\n",near);
    			
    			newcolor = colorreset;
    			if (near>tempnear)
    			{newcolor = newcolor - temp*pow(10,place-1);}
    			colorreset = newcolor;
    			//printf("%d\n",newcolor);
    		}

  14. #29
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Does that work for you when there are two same digits in the "color"?

    I would expect it not to work correctly for the example you gave above.

    Why not just do the "colorreset" modification inside the if-statement. Something like this:
    Code:
                                    if (g==c && g!=0)
    				{
    					near++;
                                            colorreset = colorreset - c*pow(10,j-1);
                                            break;
    				}
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #30
    Registered User
    Join Date
    Oct 2007
    Posts
    18
    Quote Originally Posted by matsp View Post
    Does that work for you when there are two same digits in the "color"?

    I would expect it not to work correctly for the example you gave above.

    Why not just do the "colorreset" modification inside the if-statement. Something like this:
    Code:
                                    if (g==c && g!=0)
    				{
    					near++;
                                            colorreset = colorreset - c*pow(10,j-1);
                                            break;
    				}
    --
    Mats
    It works for the example I hv given to you, exact = 1, near = 2, but I will try your method to see if the code can be further reduced. Thank you very much for your help these days.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting the matrix question..
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-22-2008, 03:17 PM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM