Skip to content

Commit 116481b

Browse files
Merge pull request #321 from CodebreakerApp/copilot/fix-320
Create comprehensive benchmark comparison for CodeBreaker.Bot vs CodeBreaker.BotWithString algorithms
2 parents f6929de + 8e12583 commit 116481b

10 files changed

Lines changed: 1430 additions & 194 deletions

src/services/bot/CodeBreaker.Bot.Benchmarks/AlgorithmBenchmarks.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using BenchmarkDotNet.Attributes;
22
using BenchmarkDotNet.Diagnosers;
3-
using Codebreaker.GameAPIs.Client.Models;
43

54
namespace CodeBreaker.Bot.Benchmarks;
65

@@ -56,7 +55,7 @@ public void Setup()
5655
[BenchmarkCategory("BlackMatches", "Game6x4", "FullList")]
5756
public List<int> HandleBlackMatches_Game6x4_FullList()
5857
{
59-
return _fullGame6x4Values.HandleBlackMatches(GameType.Game6x4, 2, _testSelection6x4);
58+
return BinaryCodeBreakerAlgorithms.HandleBlackMatches(_fullGame6x4Values, GameType.Game6x4, 2, _testSelection6x4);
6059
}
6160

6261
[Benchmark]
Lines changed: 83 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using Codebreaker.GameAPIs.Client.Models;
2-
31
namespace CodeBreaker.Bot.Benchmarks;
42

53
/// <summary>
@@ -12,83 +10,49 @@ public static class BenchmarkTestData
1210
/// </summary>
1311
public static List<int> CreateGame6x4PossibleValues()
1412
{
15-
static List<int> CreateColors(int colorCount, int shift)
16-
{
17-
List<int> pin = [];
18-
for (int i = 0; i < colorCount; i++)
19-
{
20-
int x = 1 << i + shift;
21-
pin.Add(x);
22-
}
23-
return pin;
24-
}
25-
26-
static List<int> AddColorsToList(List<int> list1, List<int> list2)
27-
{
28-
List<int> result = new(capacity: 1300);
29-
for (int i = 0; i < list1.Count; i++)
30-
{
31-
for (int j = 0; j < list2.Count; j++)
32-
{
33-
int x = list1[i] ^ list2[j];
34-
result.Add(x);
35-
}
36-
}
37-
return result;
38-
}
39-
40-
var digits1 = CreateColors(6, 0);
41-
var digits2 = CreateColors(6, 6);
42-
var list2 = AddColorsToList(digits1, digits2);
43-
var digits3 = CreateColors(6, 12);
44-
var list3 = AddColorsToList(list2, digits3);
45-
var digits4 = CreateColors(6, 18);
46-
var list4 = AddColorsToList(list3, digits4);
47-
list4.Sort();
48-
return list4;
13+
return BinaryCodeBreakerAlgorithms.GenerateAllPossibleCombinations(GameType.Game6x4, 6);
4914
}
5015

5116
/// <summary>
5217
/// Creates a list of possible values for Game8x5
5318
/// </summary>
5419
public static List<int> CreateGame8x5PossibleValues()
5520
{
56-
static List<int> Create8Colors(int shift)
57-
{
58-
List<int> pin = [];
59-
for (int i = 0; i < 8; i++)
60-
{
61-
int x = 1 << (i + shift);
62-
pin.Add(x);
63-
}
64-
return pin;
65-
}
21+
return BinaryCodeBreakerAlgorithms.GenerateAllPossibleCombinations(GameType.Game8x5, 8);
22+
}
6623

67-
static List<int> AddColorsToList(List<int> list1, List<int> list2)
68-
{
69-
List<int> result = new(capacity: list1.Count * list2.Count);
70-
for (int i = 0; i < list1.Count; i++)
71-
{
72-
for (int j = 0; j < list2.Count; j++)
73-
{
74-
int x = list1[i] ^ list2[j];
75-
result.Add(x);
76-
}
77-
}
78-
return result;
79-
}
24+
/// <summary>
25+
/// Creates string-based possible values for Game6x4
26+
/// </summary>
27+
public static List<string[]> CreateGame6x4StringPossibleValues()
28+
{
29+
string[] colors = ["Red", "Blue", "Green", "Yellow", "Orange", "Purple"];
30+
return StringCodeBreakerAlgorithms.GenerateAllPossibleCombinations(GameType.Game6x4, colors);
31+
}
8032

81-
var digits1 = Create8Colors(0);
82-
var digits2 = Create8Colors(6);
83-
var list2 = AddColorsToList(digits1, digits2);
84-
var digits3 = Create8Colors(12);
85-
var list3 = AddColorsToList(list2, digits3);
86-
var digits4 = Create8Colors(18);
87-
var list4 = AddColorsToList(list3, digits4);
88-
var digits5 = Create8Colors(24);
89-
var list5 = AddColorsToList(list4, digits5);
90-
list5.Sort();
91-
return list5;
33+
/// <summary>
34+
/// Creates string-based possible values for Game8x5
35+
/// </summary>
36+
public static List<string[]> CreateGame8x5StringPossibleValues()
37+
{
38+
string[] colors = ["Red", "Blue", "Green", "Yellow", "Orange", "Purple", "Pink", "Brown"];
39+
return StringCodeBreakerAlgorithms.GenerateAllPossibleCombinations(GameType.Game8x5, colors);
40+
}
41+
42+
/// <summary>
43+
/// Creates string-based possible values for Game5x5x4
44+
/// </summary>
45+
public static List<string[]> CreateGame5x5x4StringPossibleValues()
46+
{
47+
string[] shapeColors =
48+
[
49+
"RedCircle", "RedSquare", "RedTriangle", "RedDiamond", "RedStar",
50+
"BlueCircle", "BlueSquare", "BlueTriangle", "BlueDiamond", "BlueStar",
51+
"GreenCircle", "GreenSquare", "GreenTriangle", "GreenDiamond", "GreenStar",
52+
"YellowCircle", "YellowSquare", "YellowTriangle", "YellowDiamond", "YellowStar",
53+
"OrangeCircle", "OrangeSquare", "OrangeTriangle", "OrangeDiamond", "OrangeStar"
54+
];
55+
return StringCodeBreakerAlgorithms.GenerateAllPossibleCombinations(GameType.Game5x5x4, shapeColors);
9256
}
9357

9458
/// <summary>
@@ -111,6 +75,26 @@ public static List<int> CreateReducedPossibleValues(List<int> fullList, int targ
11175
return reducedList;
11276
}
11377

78+
/// <summary>
79+
/// Creates a reduced string list simulating a game in progress
80+
/// </summary>
81+
public static List<string[]> CreateReducedStringPossibleValues(List<string[]> fullList, int targetSize)
82+
{
83+
if (fullList.Count <= targetSize)
84+
return fullList;
85+
86+
// Create a reduced list by taking every nth element
87+
var step = fullList.Count / targetSize;
88+
var reducedList = new List<string[]>(targetSize);
89+
90+
for (int i = 0; i < fullList.Count && reducedList.Count < targetSize; i += step)
91+
{
92+
reducedList.Add(fullList[i]);
93+
}
94+
95+
return reducedList;
96+
}
97+
11498
/// <summary>
11599
/// Creates typical selection values for testing
116100
/// </summary>
@@ -126,42 +110,48 @@ public static int CreateTestSelection(GameType gameType)
126110
}
127111

128112
/// <summary>
129-
/// Creates color name mappings for testing
113+
/// Creates typical string selection values for testing
130114
/// </summary>
131-
public static Dictionary<int, string> CreateColorNames(GameType gameType)
115+
public static string[] CreateTestStringSelection(GameType gameType)
132116
{
133-
var colorNames = new Dictionary<int, string>();
134-
int key = 1;
117+
return gameType switch
118+
{
119+
GameType.Game6x4 => ["Red", "Red", "Red", "Red"],
120+
GameType.Game8x5 => ["Red", "Red", "Red", "Red", "Red"],
121+
GameType.Game5x5x4 => ["RedCircle", "RedCircle", "RedCircle", "RedCircle"],
122+
_ => ["Red", "Red", "Red", "Red"]
123+
};
124+
}
135125

126+
/// <summary>
127+
/// Creates color name mappings for algorithms that need them
128+
/// </summary>
129+
public static Dictionary<int, string> CreateColorNames(GameType gameType)
130+
{
136131
if (gameType == GameType.Game5x5x4)
137132
{
138-
// Create shape+color combinations
139-
var colors = new[] { "Red", "Green", "Blue", "Yellow", "Orange" };
140-
var shapes = new[] { "Circle", "Square", "Triangle", "Diamond", "Star" };
141-
142-
foreach (var shape in shapes)
133+
// For Game5x5x4, use shape+color combinations
134+
return new Dictionary<int, string>
143135
{
144-
foreach (var color in colors)
145-
{
146-
colorNames[key] = $"{shape};{color}";
147-
key <<= 1;
148-
}
149-
}
136+
{ 1, "RedCircle" }, { 2, "RedSquare" }, { 3, "RedTriangle" }, { 4, "RedDiamond" }, { 5, "RedStar" },
137+
{ 6, "BlueCircle" }, { 7, "BlueSquare" }, { 8, "BlueTriangle" }, { 9, "BlueDiamond" }, { 10, "BlueStar" },
138+
{ 11, "GreenCircle" }, { 12, "GreenSquare" }, { 13, "GreenTriangle" }, { 14, "GreenDiamond" }, { 15, "GreenStar" },
139+
{ 16, "YellowCircle" }, { 17, "YellowSquare" }, { 18, "YellowTriangle" }, { 19, "YellowDiamond" }, { 20, "YellowStar" },
140+
{ 21, "OrangeCircle" }, { 22, "OrangeSquare" }, { 23, "OrangeTriangle" }, { 24, "OrangeDiamond" }, { 25, "OrangeStar" }
141+
};
150142
}
151143
else
152144
{
153-
// Color-only games
154145
var colors = gameType == GameType.Game8x5
155-
? new[] { "Red", "Green", "Blue", "Yellow", "Orange", "Purple", "Pink", "White" }
156-
: new[] { "Red", "Green", "Blue", "Yellow", "Orange", "Purple" };
146+
? new[] { "Red", "Blue", "Green", "Yellow", "Orange", "Purple", "Pink", "Brown" }
147+
: new[] { "Red", "Blue", "Green", "Yellow", "Orange", "Purple" };
157148

158-
foreach (var color in colors)
149+
var colorMap = new Dictionary<int, string>();
150+
for (int i = 0; i < colors.Length; i++)
159151
{
160-
colorNames[key] = color;
161-
key <<= 1;
152+
colorMap[i + 1] = colors[i]; // Map 1-based indices to color names
162153
}
154+
return colorMap;
163155
}
164-
165-
return colorNames;
166156
}
167157
}

0 commit comments

Comments
 (0)