Home > Software engineering >  What is frong with this approach in comparing two row in mastermind?
What is frong with this approach in comparing two row in mastermind?

Time:01-23

Created a function with two int and two lists. This approach still double counts. Example: row 1: 1,2,2,3 row 2: 1,4,2,5

It shows wrongPosition: 1 and samePlace: 2 instead of samePlace: 2 and wrongPosition:0. Also, do you have any suggestion as to how to optimise this code?

private void CompareRows()
{
if (\_resaultPawns.Length != \_actualRowPawns.Length)
{
Debug.LogError("Arrays have different length");
return;
}
int swrongPosition = 0;
int samePlace = 0;
List\<int\> alreadyCounted = new List\<int\>();
List\<int\> alreadyCountedColors = new List\<int\>();

        // Check for same position with same color
        for (int i = 0; i < _resaultPawns.Length; i  )
        {
            if (_resaultPawns[i].GetComponent<MeshRenderer>().material.color == _actualRowPawns[i].GetComponent<MeshRenderer>().material.color)
            {
                if (!alreadyCounted.Contains(i))
                {
                    samePlace  ;
                    alreadyCounted.Add(i);
                }
            }
        }
    
        // Check for wrong position with same color
        for (int i = 0; i < _resaultPawns.Length; i  )
        {
            for (int j = 0; j < _actualRowPawns.Length; j  )
            {
                if (_resaultPawns[i].GetComponent<MeshRenderer>().material.color == _actualRowPawns[j].GetComponent<MeshRenderer>().material.color && !alreadyCounted.Contains(i) && !alreadyCountedColors.Contains(j))
                {
                    if (!alreadyCounted.Contains(i) && !alreadyCountedColors.Contains(j))
                    {
                        swrongPosition  ;
                        alreadyCountedColors.Add(j);
                        alreadyCounted.Add(i);
                    }
                }
            }
        }

}```

CodePudding user response:

It seems pretty simple to just do this:

var hidden = new[] { 1, 2, 2, 3 };
var first = new[] { 1, 4, 2, 5 };

int sp = 0;
int wp = 0;
for (int i = 0; i < 4; i  )
{
    if (first[i] == hidden[i])
        sp  ;
    else
        for (int j = 0; j < 4; j  )
            if (first[i] == hidden[j] && first[j] != hidden[j])
            {
                wp  ;
                break;
            }
}

Console.WriteLine($"Same Place: {sp}, Wrong Place: {wp}");

That outputs Same Place: 2, Wrong Place: 0.

CodePudding user response:

See https://dotnetfiddle.net/91GVVe

I looked at this from optimizations/maintainability first and refactoring the code a bit seems to already have solved the issue as well ^^

    var samePlace = new List<int>(4);
    var wrongPosition = new List<int>(4);

    for (var i = 0; i < _resaultPawns.Length; i  )
    {
        if (_resaultPawns[i].GetComponent<MeshRenderer>().material.color == _actualRowPawns[i].GetComponent<MeshRenderer>().material.color)
        {
            // Check for 'alreadyCounted.Contains' is redundan at this stage
            
            // No additional counter needed - simply add items and use the list Count later on
            samePlace.Add(i);
        }
    }

    for (var i = 0; i < _resaultPawns.Length; i  )
    {
        // Can directly skip as already counted
        if (samePlace.Contains(i)) continue;
        
        for (var j = 0; j < _actualRowPawns.Length; j  )
        {
            // can directly skip as would have been upper loop match
            // slightly chaper though than using the 'samePlace.Contains(j)' below
            if (i == j) continue;
            
            // skip as well to not re-use already exact matches 
            if (samePlace.Contains(j)) continue;
            
            // skip to not use twice
            if (wrongPosition.Contains(j)) continue;
            
            if (_resaultPawns[i].GetComponent<MeshRenderer>().material.color == _actualRowPawns[j].GetComponent<MeshRenderer>().material.color)
            {
                wrongPosition.Add(j);
                break;
            }
        }
    }

    var wrongPositionCount = wrongPosition.Count;
    var samePlaceCount = samePlace.Count;

I guess the main bit I added was

if (samePlace.Contains(j)) continue;

=> you also want to ignore if a j index was already seen before by the first loop as it is already an exact match.

In your example

1,2,2,3 

1,4,2,5

even though the index 3 (=value 2) was already counted as an exact match it was used again as an alternative position for index 1, a case you didn't check for as it is neither in your alreadyCounted nor in alreadyCountedColour

  • Related