Problems with a forloop never returning true

I am making a program that gennerates a code, as a string of number, then the user inputs a number of the same lenght and the program compares the two sets of numbers.
The programme then generates a guitext for each number and colors it according to wether the number is the correct number and place in the code(green), the number is in the code but not at the given place (yellow), or the number is not pressent in the code (red).
I want the code to only return as manny yellows of a number as times that the number is prsent in the code.
I coded it in c# and I’m using three forloops, but for a reason i can not figur out the innermost forloop never returns true even though it should.

any ideas, solutions are welcome.
I’m posten the funtion where the comparring is happening.
the var line is used for controlling the spacing of the guiTexts
teh var n is the lenght of the code being checked.

void hack () {
	//sets input=the player indput
	input = codeIn.text;
	line++;
	//transforms code and input to char arrays
	code.ToCharArray(0, n);
	input.ToCharArray(0, n);
	//creating array for storing the number of used instances of number
 	numberUsed=new int[10];
	//setting each int to 0
	for (int i = 0; i < n; i++){
		numberUsed*=0;*
  •   }*
    
  •   //tjekking input against code*
    
  •   if (input==code){*
    
  •   	//if the code is correct the output is "code accepted"*
    
  •   	//resets input guiText*
    
  •   	codeIn.text="";*
    
  •   	//prints the correct code in a guiText*
    
  •   	GameObject test01 = new GameObject("GUIText");*
    
  •   	test03 = (GUIText)test01.AddComponent(typeof(GUIText));*
    
  •   	test03.text = input;*
    
  •   	test03.material.color = Color.green;*
    

_ test03.transform.position = new Vector3(0.1f,0.8f-line*0.025f,0f);_

  •   	line++;*
    
  •   	//prints the "code accepted" in a guiText*
    
  •   	GameObject test04 = new GameObject("GUIText");*
    
  •   	test03 = (GUIText)test04.AddComponent(typeof(GUIText));*
    
  •   	test03.text = "code accepted";*
    

_ test03.transform.position = new Vector3(0.1f,0.8f-line*0.025f,0f);_

  •   	Log(timer.ToString());*
    
  •   }else{*
    
  •   	for (int i = 0; i < n; i++){*
    
  •   		string[] inputCorrectness = new string[n];*
    
  •   		for (int j = 0; j < n; j++){*
    
  •   			//if the number is correct the code returns green*
    

if (code_==input*){
inputCorrectness = “green”;
//raises the count of uses of the number by one*

numberUsed[input*-48]++;
break;*_

_ //if the number(input*) is present at another location in the code
}else if(code[j]==input){*_

* //cheks the number of used instances of the digit*
if (numberUsed[input_-48]>=numberCount[input*-48]){
inputCorrectness = “red”;
break;
} else {
for (int k=0; k<n; k++){
print(“derp”);
/if the input is also input at another place in the code (input[k])
and that input is equal to the code, set current inputcolor to red/

if (code[k]==input[k] && input[k]==input){
inputCorrectness = “red”;
print(“herp”);
break;
//else set current inputcolor to yellow
}else{
inputCorrectness = “yellow”;
numberUsed[input-48]++;
break;
}
}
//breaks outer forloop else the texts turns back to red.
break;
}
//if the number is not in the code it returns red
} else {*_

_ inputCorrectness = “red”;
* } *_

* } *
_ //print(numberCount[input*-48]);
//print(numberUsed[input-48]);*_

//print(input_+inputCorrectness*);
codeIn.text=“”;
//prints the number with the earlyer given color*

* GameObject test01 = new GameObject("GUIText " + i);
test02 = (GUIText)test01.AddComponent(typeof(GUIText));
test02.text = “”+input;
test02.transform.position = new Vector3(0.1f+i0.01f,0.8f-line0.025f,0f);
switch(inputCorrectness){
case “green”:
test02.material.color = Color.green;
break;
case “yellow”:
test02.material.color = Color.yellow;
break;
case “red”:
test02.material.color = Color.red;
break;
}
}
}
} *_

I would suggest you re-approach the way you’ve got this programed. I’ve been looking at it for a few minutes and I’m reminded that usually I get myself to rethink how I’ve approached a problem if I’ve got 3 loops nested. The only time I’d allow myself to do this is for a pre-runtime (in-editor) function.

I would suggest using either a custom datatype that would allow you to store a number value and all of the indexes where it occurs. Or a Dictionary where your number is the key and you have a string value that you could parse for indexes of all of the occurrences.

I needed a break from what I was working on tonight, so I wrote a Dictionary based solution. I think you’ll find it pretty easy to read, but let me know if you have any questions. :). I almost always use Lists too for my collections, as I believe they’re faster than just an ArrayList.

    using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MasterMind : MonoBehaviour {

	int itemCount = 8;
	
	int minValue = 0;
	int maxValue = 10;
	
	int numTries = 0;
	bool hasSolution = false;
	
	Dictionary<int, int> masterItemIndex = new Dictionary<int, int>();
	
	//If this flag is true, we'll store our correct answers
	bool storeCorrects = true;
	List<int> correctItems = new List<int>();
	
	void Awake()
	{
		for( int i = 0; i < itemCount; i++ ) {
			bool goodValue = false;
			while( !goodValue ) {
				int newInt = Random.Range(minValue, maxValue);
				if( !masterItemIndex.ContainsKey(newInt) ) {
					masterItemIndex.Add(newInt, i);
					goodValue = true;
				}
			}
		}
		
		//verify Dictionary
		foreach (var element in masterItemIndex)
	    	Debug.Log(element);
	}

	List<int> SimulateGuess()
	{
		List<int> output = new List<int>();
		for( int i=0; i < itemCount; i++ )
		{
			if( storeCorrects && correctItems.Count > i ) {
				if( correctItems *!= -999 ) {*

_ output.Add( correctItems );_
* continue;*
* }*
* }*
* //roll a unique number for our simulated guess*
* bool isUnique = false;*
* while( !isUnique ) {*
* int newInt = Random.Range( minValue, maxValue );*
* if( !output.Contains(newInt) ) {*
* output.Add(newInt);*
* isUnique = true;*
* }*
* }*
* }*

* return output;*
* }*

* // Update is called once per frame*
* void Update () {*
* if( hasSolution ) return;*

* //Simulate our guesses*
* List guesses = SimulateGuess();*

* //Check to see how well we did*
* CheckGuess(guesses);*
* }*

* void CheckGuess (List inGuesses)*
* {*
* List guessFeedback = new List();*

* //loop through guesses*
* int numberCorrect = 0;*
* for(int i=0; i < inGuesses.Count; i++ )*
* {*
_ int currentNumber = inGuesses*;
if( masterItemIndex.ContainsKey(currentNumber) ) {
if( (int)masterItemIndex[currentNumber] == i ) {
guessFeedback.Add(“green”);
++numberCorrect;
}
else {
guessFeedback.Add (“yellow”);
}
}
else {
guessFeedback.Add(“red”);
}
}*_

* //Assess how we did*
* ++numTries;*
* if( numberCorrect == itemCount ) {*
* hasSolution = true;*
* string solution = “”;*

* for( int i=0; i < inGuesses.Count; i++ ) {*
_ solution += inGuesses*;
if( i < inGuesses.Count - 1 ) solution += ", ";
}
Debug.Log("A WINNER IS YOU! It took you " + numTries + " tries. The correct solution was: " + solution);
}
else if( numberCorrect > 0 ){
Debug.Log(“You got " + numberCorrect + " correct. Go again.”);
}
else {
Debug.Log(“Um. Not. Even. Close…”);
}*_

* if( !storeCorrects ) return;*
* //show guessFeedback List and store green ones (not optimal, but it will get us there eventually)*
* correctItems = new List();*
* for( int i=0; i < guessFeedback.Count; i++ ) {*
_ if( guessFeedback == “green” ) {
correctItems.Add(inGuesses*);
}
else {
correctItems.Add(-999);
}
}
}
}*_

Hey Burton

Thank you for your reply. I can see its a cleaner and more clear method, so I have rewriten my code based on your solution.

But it dosn’t sovle my problem with the returns of more yellows of a number than there is instances in the code.

ex. if the random code contains two instances of the number 7 and the user inputs 7 three times, the returning 7’s should be, 2 green and one red, 2 yellow and one red or one green one yellow and one red. But as it is, it return 3 yellow, 2 yellow and one green or 2 green and one yellow.

anyone got an solution for this?
code inserted below

using UnityEngine;

using System.Collections;
using System.Collections.Generic;

public class hacking : MonoBehaviour {

//used to calculate line spaces
float line = 0;
//GUItext containing the user intput
public GUIText codeIn;
public float timer = 0;
private GUIText outNumber = new GUIText[8];
private GUIText outText = new GUIText();

int n;
//used to generate a random number for the code
float a;
int itemCount = 8;

int minValue = 0;
int maxValue = 10;

int numTries = 0;
bool hasSolution = false;

Dictionary<int, int> masterItemIndex = new Dictionary<int, int>();

//If this flag is true, we’ll store our correct answers
bool storeCorrects = true;
List correctItems = new List();
List guesses = new List();

 void Awake()
{
   for( int i = 0; i < itemCount; i++ ) {
     bool goodValue = false;
     while( !goodValue ) {
      int newInt = Random.Range(minValue, maxValue);
      if( !masterItemIndex.ContainsKey(newInt) ) {
          masterItemIndex.Add(newInt, i);
          goodValue = true;
      }
     }
   }

   //verify Dictionary
   foreach (var element in masterItemIndex)
       Debug.Log(element);
}


void Start() {

	//n = code.Length;
	//Creating log if none exists and makes an entry in log
	if(!System.IO.File.Exists("C://dataLog/log.txt")){
		System.IO.File.WriteAllText("C://dataLog/log.txt", " New Test Participant:");
	}else{
		string existingText = System.IO.File.ReadAllText("C://dataLog/log.txt");
		System.IO.File.WriteAllText("C://dataLog/log.txt", existingText + " New Test Participant:");
	}
	//sets timer
	timer = 0;
}

    void CheckGuess (List<int> inGuesses)
{
   List<string> guessFeedback = new List<string>();
	line++;
   //loop through guesses
   int numberCorrect = 0;
   for(int i=0; i < inGuesses.Count; i++ )
   {
     int currentNumber = inGuesses*;*

if( masterItemIndex.ContainsKey(currentNumber) ) {
if( (int)masterItemIndex[currentNumber] == i ) {
guessFeedback.Add(“green”);
++numberCorrect;
}
else {
guessFeedback.Add (“yellow”);
}
}
else {
guessFeedback.Add(“red”);
}
}

  •   codeIn.text="";*
    
  •   for (int i= 0; i < itemCount; i++){*
    
  •   	//prints the number with the earlyer given color*
    
  •   	GameObject test01 = new GameObject("GUIText " + i);*
    

_ outNumber = (GUIText)test01.AddComponent(typeof(GUIText));_
outNumber_.text = “”+inGuesses*;
outNumber.transform.position = new Vector3(0.1f+i0.01f,0.8f-line0.025f,0f);
switch(guessFeedback){
case “green”:
outNumber.material.color = Color.green;
break;
case “yellow”:
outNumber.material.color = Color.yellow;
break;
case “red”:
outNumber.material.color = Color.red;
break;
}
}
//Assess how we did*

++numTries;
if( numberCorrect == itemCount ) {
hasSolution = true;
string solution = “”;
for( int i=0; i < inGuesses.Count; i++ ) {
solution += inGuesses*;*
if( i < inGuesses.Count - 1 ) solution += ", ";
}
* line++;
//prints the “code accepted” in a guiText*

* GameObject test04 = new GameObject(“GUIText”);
outText = (GUIText)test04.AddComponent(typeof(GUIText));
outText.text = “code accepted”;
outText.transform.position = new Vector3(0.1f,0.8f-line0.025f,0f);

}
else if( numberCorrect > 0 ){
Debug.Log(“You got " + numberCorrect + " correct. Go again.”);
}
else {
Debug.Log(“Um. Not. Even. Close…”);
}
if( !storeCorrects ) return;
//show guessFeedback List and store green ones (not optimal, but it will get us there eventually)
correctItems = new List();
for( int i=0; i < guessFeedback.Count; i++ ) {
if( guessFeedback == “green” ) {
correctItems.Add(inGuesses*);*
}
else {
correctItems.Add(-999);
}
}
* guesses.Clear();
}*_

* // Update is called once per frame*
* void Update () {*
* //starts timer*
* timer += Time.deltaTime;*
* //Simulate our guesses*

* codeIn.enabled = true;*
* //int n = code.Length;*
* string c = Input.inputString;*
* //testing input*
* switch (Input.inputString){*
* //if input is a backspace and the inputstring isn’t zero, delete the last number in the string*
* //need looking at, doesn’t delete the right entry*
* case (“\b”):*
* if (codeIn.text.Length != 0){*
codeIn.text = codeIn.text.Substring(0, codeIn.text.Length - 1);
* guesses.Remove(guesses.Count);*
* print(guesses.Count);*
* }*
* break;*
* //if the input is enter, run the hacking system *
* case (“\r”):*
* //Check to see how well we did*
* CheckGuess(guesses);*
* break;*
* //if the input is a nu ber, ad the number to the input string if the string is shorter than n *
* case “0”:*
* case “1”:*
* case “2”:*
* case “3”:*
* case “4”:*
* case “5”:*
* case “6”:*
* case “7”:*
* case “8”:*
* case “9”:*
* if (codeIn.text.Length<itemCount){*
* guesses.Add(int.Parse(c));*
* codeIn.text+=c;*
* print(guesses.Count);*
* }*
* break; *
* } *
* }*
* //adding timer to log*
* public void Log(string text){*
* if(System.IO.File.Exists(“C://dataLog/log.txt”)){*
* string existingText = System.IO.File.ReadAllText(“C://dataLog/log.txt”);*
* System.IO.File.WriteAllText(“C://dataLog/log.txt”, existingText + " " + text + " " + timer.ToString() + “;”);*
* }*
* }*
}

Sorry I missed the point a bit there, hehe. This is hardly a full solution, but you might want to make another table as you go through and store uniques. When you get a duplicate, you pass over it.

Only issue there is you’re not giving them feedback from every number. I think the type of 1:1 feedback you’re trying to give is at odds with the duplicates issue. If you give them feedback for each number, you’ll have duplicate feedback. If you don’t give feedback for duplications, they’ll likely ascertain that the number (they’ll end up spamming multiples of) exists in the set, actually making the code easier to crack in some regards.

I was going to suggest another color to indicate “correct, but duplicates”, but the user can just do 012344456 and if they see the other color they know 4 is there. Maybe that’s the point, but it seems like a solution for this case might break the integrity of the challenge.

That’s all I’ve got and it’s not much of an answer, but maybe it will give you some things to think about.