Skip to content

Commit

Permalink
Merge pull request #239 from CodebreakerApp/235-analyzer5x5x4
Browse files Browse the repository at this point in the history
fix analyzer for 5x5x4 games
  • Loading branch information
christiannagel authored Sep 7, 2024
2 parents 1ef368d + a4f8715 commit 06045fc
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,34 @@ namespace Codebreaker.GameAPIs.Analyzer.Tests;

public class ShapeGame5x5x4AnalyzerTests
{
[Fact]
public void SetMove_ShouldNotReturnBlueWithOneWhite()
{
ShapeAndColorResult expectedKeyPegs = new(0, 1, 0);
ShapeAndColorResult? resultKeyPegs = AnalyzeGame(
["Rectangle;Green", "Triangle;Blue", "Square;Blue", "Triangle;Green"],
["Circle;Red", "Square;Green", "Triangle;Blue", "Star;Yellow"]
);
// Position 3: Triangle.Blue is correct, but should be in the 2nd position
// all the other pegs are incorrect

Assert.Equal(expectedKeyPegs, resultKeyPegs);
}

[Fact]
public void SetMove_ShouldReturnOneWhiteAndOneBlue()
{
ShapeAndColorResult expectedKeyPegs = new(0, 1, 1);
ShapeAndColorResult? resultKeyPegs = AnalyzeGame(
["Rectangle;Purple", "Square;Purple", "Star;Red", "Circle;Yellow"],
["Triangle;Purple", "Star;Green", "Circle;Blue", "Square;Purple"]
);
// position 4: Square;Purple is correct but in an incorrect position (should be 2) - white
// position 1: Purple correct - blue

Assert.Equal(expectedKeyPegs, resultKeyPegs);
}

[Fact]
public void SetMove_ShouldReturnTwoBlack()
{
Expand Down Expand Up @@ -111,7 +139,7 @@ public void SetMove_ShouldReturnTwoBlueForMatchingShapes()
[Fact]
public void SetMove_ShouldReturnOneBlackAndOneWhite()
{
// the first and second guess have a correct shape, but both in the wrong positon
// the first and second guess have a correct shape, but both in the wrong position
// all the colors are incorrect
ShapeAndColorResult expectedKeyPegs = new(1, 1, 0);
ShapeAndColorResult? resultKeyPegs = AnalyzeGame(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ protected override void ValidateGuessValues()
protected override ShapeAndColorResult GetCoreResult()
{
// Check black, white and blue keyPegs
List<ShapeAndColorField> codesToCheck = [.._game.Codes.ToPegs<ShapeAndColorField>() ];
List<ShapeAndColorField> guessPegsToCheck = [.. Guesses ];
List<ShapeAndColorField> remainingCodesToCheck = [];
List<ShapeAndColorField> remainingGuessPegsToCheck = [];
List<ShapeAndColorField> codesToCheck = [.._game.Codes.ToPegs<ShapeAndColorField>() ]; // all the codes that need to be verified with the actual check
List<ShapeAndColorField> guessPegsToCheck = [.. Guesses ]; // all the guesses that need to be verified with the actual check
List<ShapeAndColorField> remainingCodesToCheck = []; // the codes that need to be checked with the check following - filled by the actual check
List<ShapeAndColorField> remainingGuessPegsToCheck = []; // the guesses that need to be checked with the check following - filled by the actual check

byte black = 0;
byte white = 0;
byte blue = 0;

// check for black (correct color and shape at the correct position)
// first check for black (correct color and shape at the correct position)
// add the remaining codes and guess pegs to the remaining lists to check for white and blue keyPegs
for (int i = 0; i < guessPegsToCheck.Count; i++)
{
Expand All @@ -44,36 +44,40 @@ protected override ShapeAndColorResult GetCoreResult()
}
}

// next check for white (correct pair at a wrong position)
// add the remaining codes and guess pegs to the remaining lists to check for blue keyPegs
codesToCheck = remainingCodesToCheck;
remainingCodesToCheck = new(codesToCheck);
guessPegsToCheck = remainingGuessPegsToCheck;
remainingGuessPegsToCheck = [];
remainingCodesToCheck = new(codesToCheck);
remainingGuessPegsToCheck = Enumerable.Repeat(ShapeAndColorField.Empty, guessPegsToCheck.Count).ToList();

// check for white (correct pair at a wrong position)
// and add the remaining codes and guess pegs to the remaining lists to check for blue keyPegs
for (int i = 0; i < guessPegsToCheck.Count; i++)
{
ShapeAndColorField? codeField = codesToCheck.FirstOrDefault(c => c == guessPegsToCheck[i]);
if (codeField is not null)
{
white++;
codesToCheck.Remove(codeField); // remove for the white check
remainingCodesToCheck.Remove(codeField); // remove for the blue check

var ix = codesToCheck.IndexOf(codeField);
codesToCheck[ix] = ShapeAndColorField.Empty; // this code is a match and thus no longer is used when checking for white
remainingCodesToCheck[ix] = ShapeAndColorField.Empty; // this code is also not used with the next blue check
}
else
{
remainingGuessPegsToCheck.Add(guessPegsToCheck[i]); // add for the blue check
remainingGuessPegsToCheck[i] = guessPegsToCheck[i]; // not a match for the guess, thus it needs to be added for the blue check
}
}

// check blue (either the shape or the color is in the correct position but with a wrong paired element)
codesToCheck = remainingCodesToCheck;
guessPegsToCheck = remainingGuessPegsToCheck;

// check blue (either the shape or the color is in the correct position but with a wrong paired element)
for (int i = 0; i < guessPegsToCheck.Count; i++)
{
if (guessPegsToCheck[i].Shape == codesToCheck[i].Shape ||
guessPegsToCheck[i].Color == codesToCheck[i].Color)
if ((guessPegsToCheck[i] != ShapeAndColorField.Empty ||
codesToCheck[i] != ShapeAndColorField.Empty) &&
(guessPegsToCheck[i].Shape == codesToCheck[i].Shape ||
guessPegsToCheck[i].Color == codesToCheck[i].Color))
{
blue++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<VersionPrefix>3.7.1</VersionPrefix>
<PackageTags>
Codebreaker;CNinnovation;GameAnalyzers
</PackageTags>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

public partial record class ShapeAndColorField(string Shape, string Color)
{
internal static ShapeAndColorField Empty => new ShapeAndColorField(string.Empty, string.Empty);

private const char Separator = ';';
public override string ToString() => $"{Shape}{Separator}{Color}";

Expand Down

0 comments on commit 06045fc

Please sign in to comment.