-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGamesFactory.cs
More file actions
140 lines (125 loc) · 5.88 KB
/
GamesFactory.cs
File metadata and controls
140 lines (125 loc) · 5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using Codebreaker.GameAPIs.Analyzers;
namespace Codebreaker.GameAPIs.Services;
/// <summary>
/// A factory class for creating instances of the <see cref="Game"/> class.
/// </summary>
public static class GamesFactory
{
private static readonly string[] s_colors6 = [Colors.Red, Colors.Green, Colors.Blue, Colors.Yellow, Colors.Purple, Colors.Orange];
private static readonly string[] s_colors8 = [Colors.Red, Colors.Green, Colors.Blue, Colors.Yellow, Colors.Purple, Colors.Orange, Colors.Pink, Colors.Brown];
private static readonly string[] s_colors5 = [Colors.Red, Colors.Green, Colors.Blue, Colors.Yellow, Colors.Purple];
private static readonly string[] s_shapes5 = [Shapes.Circle, Shapes.Square, Shapes.Triangle, Shapes.Star, Shapes.Rectangle];
/// <summary>
/// Creates a game object with specified gameType and playerName.
/// </summary>
/// <param name="gameType">The type of game to be created.</param>
/// <param name="playerName">The name of the player.</param>
/// <returns>The created game object.</returns>
public static Game CreateGame(string gameType, string playerName)
{
Game Create6x4SimpleGame() =>
new(Guid.NewGuid(), gameType, playerName, DateTime.UtcNow, 4, 12)
{
FieldValues = new Dictionary<string, IEnumerable<string>>()
{
{ FieldCategories.Colors, s_colors6 }
},
Codes = Random.Shared.GetItems(s_colors6, 4)
};
Game Create6x4Game() =>
new(Guid.NewGuid(), gameType, playerName, DateTime.UtcNow, 4, 12)
{
FieldValues = new Dictionary<string, IEnumerable<string>>()
{
{ FieldCategories.Colors, s_colors6 }
},
Codes = Random.Shared.GetItems(s_colors6, 4)
};
Game Create8x5Game() =>
new(Guid.NewGuid(), gameType, playerName, DateTime.UtcNow, 5, 12)
{
FieldValues = new Dictionary<string, IEnumerable<string>>()
{
{ FieldCategories.Colors, s_colors8 }
},
Codes = Random.Shared.GetItems(s_colors8, 5)
};
Game Create5x5x4Game() =>
new(Guid.NewGuid(), gameType, playerName, DateTime.UtcNow, 4, 14)
{
FieldValues = new Dictionary<string, IEnumerable<string>>()
{
{ FieldCategories.Colors, s_colors5 },
{ FieldCategories.Shapes, s_shapes5 }
},
Codes = Random.Shared.GetItems(s_shapes5, 4)
.Zip(Random.Shared.GetItems(s_colors5, 4), (shape, color) => (Shape: shape, Color: color))
.Select(item => string.Join(';', item.Shape, item.Color))
.ToArray()
};
Game Create5x3Game() =>
new(Guid.NewGuid(), gameType, playerName, DateTime.UtcNow, 3, 10)
{
FieldValues = new Dictionary<string, IEnumerable<string>>()
{
{ FieldCategories.Colors, s_colors5 }
},
Codes = Random.Shared.GetItems(s_colors5, 3)
};
return gameType switch
{
GameTypes.Game6x4Mini => Create6x4SimpleGame(),
GameTypes.Game6x4 => Create6x4Game(),
GameTypes.Game8x5 => Create8x5Game(),
GameTypes.Game5x5x4 => Create5x5x4Game(),
GameTypes.Game5x3 => Create5x3Game(),
_ => throw new CodebreakerException("Invalid game type") { Code = CodebreakerExceptionCodes.InvalidGameType }
};
}
/// <summary>
/// Applies a player's move to a game and returns a <see cref="Move"/> object that encapsulates the player's guess and the result of the guess.
/// Returns the Move and updates the Game
/// </summary>
/// <param name="game">The game to apply the move to.</param>
/// <param name="guesses">The player's guesses.</param>
/// <param name="moveNumber">The move number.</param>
/// <returns>A <see cref="Move"/> object that encapsulates the player's guess and the result of the guess.</returns>
public static Move ApplyMove(this Game game, string[] guesses, int moveNumber)
{
static TField[] GetGuesses<TField>(IEnumerable<string> guesses)
where TField : IParsable<TField> => guesses
.Select(g => TField.Parse(g, default))
.ToArray();
string[] GetColorGameGuessAnalyzerResult()
{
ColorGameGuessAnalyzer analyzer = new(game, GetGuesses<ColorField>(guesses), moveNumber);
return analyzer.GetResult().ToStringResults();
}
string[] GetSimpleGameGuessAnalyzerResult()
{
SimpleGameGuessAnalyzer analyzer = new(game, GetGuesses<ColorField>(guesses), moveNumber);
return analyzer.GetResult().ToStringResults();
}
string[] GetShapeGameGuessAnalyzerResult()
{
ShapeGameGuessAnalyzer analyzer = new(game, GetGuesses<ShapeAndColorField>(guesses), moveNumber);
return analyzer.GetResult().ToStringResults();
}
string[] results = game.GameType switch
{
GameTypes.Game6x4 => GetColorGameGuessAnalyzerResult(),
GameTypes.Game8x5 => GetColorGameGuessAnalyzerResult(),
GameTypes.Game6x4Mini => GetSimpleGameGuessAnalyzerResult(),
GameTypes.Game5x5x4 => GetShapeGameGuessAnalyzerResult(),
GameTypes.Game5x3 => GetColorGameGuessAnalyzerResult(),
_ => throw new CodebreakerException("Invalid game type") { Code = CodebreakerExceptionCodes.InvalidGameType }
};
Move move = new(Guid.NewGuid(), moveNumber)
{
GuessPegs = guesses,
KeyPegs = results
};
game.Moves.Add(move);
return move;
}
}