Skip to content

Commit bba18b3

Browse files
Merge pull request #313 from CodebreakerApp/copilot/fix-312
Update Codebreaker.Bot to Support Additional Game Types (Game8x5, Game5x5x4)
2 parents dec3a3f + 5233eec commit bba18b3

9 files changed

Lines changed: 589 additions & 166 deletions

File tree

src/services/bot/CodeBreaker.Bot.Tests/CodeBreakerAlgorithmsTests.cs

Lines changed: 114 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections;
2+
using Codebreaker.GameAPIs.Client.Models;
23

34
using Xunit;
45

@@ -7,25 +8,62 @@ namespace CodeBreaker.Bot.Tests;
78
public class CodeBreakerAlgorithmsTests
89
{
910
[Fact]
10-
public void SelectPeg_Should_ThrowException()
11+
public void SelectPeg_Should_ThrowException_ForGame6x4()
1112
{
1213
Assert.Throws<InvalidOperationException>(() =>
13-
CodeBreakerAlgorithms.SelectPeg(44, 4));
14+
CodeBreakerAlgorithms.SelectPeg(44, GameType.Game6x4, 4));
15+
}
16+
17+
[Fact]
18+
public void SelectPeg_Should_ThrowException_ForGame8x5()
19+
{
20+
Assert.Throws<InvalidOperationException>(() =>
21+
CodeBreakerAlgorithms.SelectPeg(44, GameType.Game8x5, 5));
22+
}
23+
24+
[Fact]
25+
public void SelectPeg_Should_ThrowException_ForGame5x5x4()
26+
{
27+
Assert.Throws<InvalidOperationException>(() =>
28+
CodeBreakerAlgorithms.SelectPeg(44, GameType.Game5x5x4, 4));
29+
}
30+
31+
[Theory]
32+
[InlineData(0b_000100_000100_000100_000100, 0, 0b_000100)]
33+
[InlineData(0b_000100_000100_000100_000100, 1, 0b_000100)]
34+
[InlineData(0b_000100_000100_000100_000100, 2, 0b_000100)]
35+
[InlineData(0b_000100_000100_000100_000100, 3, 0b_000100)]
36+
public void SelectPegTest_Game6x4(int code, int number, int expected)
37+
{
38+
int actual = CodeBreakerAlgorithms.SelectPeg(code, GameType.Game6x4, number);
39+
Assert.Equal(expected, actual);
40+
}
41+
42+
[Theory]
43+
[InlineData(0b_000100_000100_000100_000100_000100, 0, 0b_000100)]
44+
[InlineData(0b_000100_000100_000100_000100_000100, 1, 0b_000100)]
45+
[InlineData(0b_000100_000100_000100_000100_000100, 2, 0b_000100)]
46+
[InlineData(0b_000100_000100_000100_000100_000100, 3, 0b_000100)]
47+
[InlineData(0b_000100_000100_000100_000100_000100, 4, 0b_000100)]
48+
public void SelectPegTest_Game8x5(int code, int number, int expected)
49+
{
50+
int actual = CodeBreakerAlgorithms.SelectPeg(code, GameType.Game8x5, number);
51+
Assert.Equal(expected, actual);
1452
}
1553

1654
[Theory]
1755
[InlineData(0b_000100_000100_000100_000100, 0, 0b_000100)]
1856
[InlineData(0b_000100_000100_000100_000100, 1, 0b_000100)]
1957
[InlineData(0b_000100_000100_000100_000100, 2, 0b_000100)]
2058
[InlineData(0b_000100_000100_000100_000100, 3, 0b_000100)]
21-
public void SelectPegTest(int code, int number, int expected)
59+
public void SelectPegTest_Game5x5x4(int code, int number, int expected)
2260
{
23-
int actual = CodeBreakerAlgorithms.SelectPeg(code, number);
61+
int actual = CodeBreakerAlgorithms.SelectPeg(code, GameType.Game5x5x4, number);
2462
Assert.Equal(expected, actual);
2563
}
2664

2765
[Fact]
28-
public void HandleBlackMatches_Should_Find1BlackMatch()
66+
public void HandleBlackMatches_Should_Find1BlackMatch_Game6x4()
2967
{
3068
List<int> toMatch =
3169
[
@@ -35,12 +73,27 @@ public void HandleBlackMatches_Should_Find1BlackMatch()
3573
];
3674
int selection = 0b_000001_010000_000001_000001;
3775

38-
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, 1, selection);
76+
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, GameType.Game6x4, 1, selection);
3977
Assert.Equal(2, actual.Count);
4078
}
4179

4280
[Fact]
43-
public void HandleBlackMatches_Should_Find2BlackMatches()
81+
public void HandleBlackMatches_Should_Find1BlackMatch_Game8x5()
82+
{
83+
List<int> toMatch =
84+
[
85+
0b_100000_010000_100000_100000_100000, // hit
86+
0b_100000_010000_010000_100000_100000, // hit
87+
0b_000100_000100_000100_000100_000100 // miss
88+
];
89+
int selection = 0b_000001_010000_000001_000001_000001;
90+
91+
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, GameType.Game8x5, 1, selection);
92+
Assert.Equal(2, actual.Count);
93+
}
94+
95+
[Fact]
96+
public void HandleBlackMatches_Should_Find2BlackMatches_Game6x4()
4497
{
4598
List<int> toMatch =
4699
[
@@ -50,12 +103,12 @@ public void HandleBlackMatches_Should_Find2BlackMatches()
50103
];
51104
int selection = 0b_000001_010000_010000_000001;
52105

53-
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, 2, selection);
106+
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, GameType.Game6x4, 2, selection);
54107
Assert.Equal(2, actual.Count);
55108
}
56109

57110
[Fact]
58-
public void HandleBlackMatches_Should_Find3BlackMatches()
111+
public void HandleBlackMatches_Should_Find3BlackMatches_Game6x4()
59112
{
60113
List<int> toMatch =
61114
[
@@ -65,24 +118,24 @@ public void HandleBlackMatches_Should_Find3BlackMatches()
65118
];
66119
int selection = 0b_000001_100000_010000_000001;
67120

68-
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, 3, selection);
121+
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, GameType.Game6x4, 3, selection);
69122
Assert.Single(actual);
70123
}
71124

72125
[Fact]
73-
public void HandleBlackMatches_Should_BeEmpty()
126+
public void HandleBlackMatches_Should_BeEmpty_Game6x4()
74127
{
75128
List<int> toMatch =
76129
[
77130
0b_000100_010000_001000_000010
78131
];
79132
int selection = 0b_000001_010000_001000_001000;
80-
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, 1, selection);
133+
List<int> actual = CodeBreakerAlgorithms.HandleBlackMatches(toMatch, GameType.Game6x4, 1, selection);
81134
Assert.Empty(actual);
82135
}
83136

84137
[Fact]
85-
public void HandleWhiteMatches_Should_Find1WhiteMatches()
138+
public void HandleWhiteMatches_Should_Find1WhiteMatches_Game6x4()
86139
{
87140
List<int> toMatch =
88141
[
@@ -92,21 +145,64 @@ public void HandleWhiteMatches_Should_Find1WhiteMatches()
92145
];
93146
int selection = 0b_000001_010000_000001_000001;
94147

95-
List<int> actual = CodeBreakerAlgorithms.HandleWhiteMatches(toMatch, 1, selection);
148+
List<int> actual = CodeBreakerAlgorithms.HandleWhiteMatches(toMatch, GameType.Game6x4, 1, selection);
96149
Assert.Equal(2, actual.Count);
97150
}
98151

99152
[Fact]
100-
public void IntToColors_Should_ConvertToCorrectColor()
153+
public void IntToColors_Should_ConvertToCorrectColor_Game6x4()
101154
{
102155
int value = 0b_000100_010000_000001_100000;
156+
Dictionary<int, string> colorNames = new()
157+
{
158+
{ 0b_000001, "Black" },
159+
{ 0b_000010, "White" },
160+
{ 0b_000100, "Red" },
161+
{ 0b_001000, "Green" },
162+
{ 0b_010000, "Blue" },
163+
{ 0b_100000, "Yellow" }
164+
};
103165
string[] expected = ["Red", "Blue", "Black", "Yellow"];
104-
string[] actual = CodeBreakerAlgorithms.IntToColors(value);
166+
string[] actual = CodeBreakerAlgorithms.IntToColors(value, GameType.Game6x4, colorNames);
105167
Assert.Equal(expected, actual);
106168
}
107169

108170
[Fact]
109-
public void HandleNoMatches_Should_MatchOneResult()
171+
public void HandleBlueMatches_Should_Find1BlueMatch_Game5x5x4()
172+
{
173+
List<int> toMatch =
174+
[
175+
0b_000100_000100_000100_000100, // potential hit
176+
0b_000010_000010_000010_000010, // potential hit
177+
0b_001000_001000_001000_001000 // miss
178+
];
179+
int selection = 0b_000001_000001_000001_000001;
180+
181+
List<int> actual = CodeBreakerAlgorithms.HandleBlueMatches(toMatch, GameType.Game5x5x4, 1, selection);
182+
// Should filter based on blue match logic
183+
Assert.True(actual.Count <= toMatch.Count);
184+
}
185+
186+
[Fact]
187+
public void HandleBlueMatches_Should_ReturnUnfiltered_ForOtherGameTypes()
188+
{
189+
List<int> toMatch =
190+
[
191+
0b_000100_000100_000100_000100,
192+
0b_000010_000010_000010_000010
193+
];
194+
int selection = 0b_000001_000001_000001_000001;
195+
196+
List<int> actual6x4 = CodeBreakerAlgorithms.HandleBlueMatches(toMatch, GameType.Game6x4, 1, selection);
197+
List<int> actual8x5 = CodeBreakerAlgorithms.HandleBlueMatches(toMatch, GameType.Game8x5, 1, selection);
198+
199+
// Should return all values unfiltered for non-Game5x5x4 types
200+
Assert.Equal(toMatch.Count, actual6x4.Count);
201+
Assert.Equal(toMatch.Count, actual8x5.Count);
202+
}
203+
204+
[Fact]
205+
public void HandleBlueMatches_ShouldHandleNoMatches()
110206
{
111207
List<int> toMatch =
112208
[
@@ -115,7 +211,7 @@ public void HandleNoMatches_Should_MatchOneResult()
115211
0b_001000_001000_001000_001000 // hit
116212
];
117213
int selection = 0b_000100_010000_000001_100000;
118-
List<int> actual = CodeBreakerAlgorithms.HandleNoMatches(toMatch, selection);
214+
List<int> actual = CodeBreakerAlgorithms.HandleNoMatches(toMatch, GameType.Game6x4, selection);
119215
Assert.Single(actual);
120216
}
121217

0 commit comments

Comments
 (0)