-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWordGameService.cs
executable file
·106 lines (82 loc) · 3.09 KB
/
WordGameService.cs
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
using System.Linq;
using System.Collections.Generic;
namespace WordGame
{
using System;
public class WordGameService : IWordGameService
{
private const int maxLeaderBoardCount = 10;
private readonly object submissionLock = new();
private readonly IValidWords validWords;
private char[] initialWordCharArray;
private SortedList<LeaderBoardScore, (string PlayerName, string Word, int Points)> leaderBoard = new();
private HashSet<string> usedWordsSet = new();
public WordGameService(string letters, IValidWords validWords) :
this(letters.ToCharArray(), validWords)
{ }
public WordGameService(char[] letters, IValidWords validWords)
{
this.validWords = validWords;
initialWordCharArray = letters;
}
public string GetPlayerNameAtPosition(int position) =>
GetLeaderBoardEntry(position)?.PlayerName;
public int? GetScoreAtPosition(int position) =>
GetLeaderBoardEntry(position)?.Points;
public string GetWordEntryAtPosition(int position) =>
GetLeaderBoardEntry(position)?.Word;
private (string PlayerName, string Word, int Points)? GetLeaderBoardEntry(int position)
{
if (position < 0 || position >= leaderBoard.Values.Count)
return null;
lock (submissionLock)
{
return leaderBoard.Values[position];
}
}
public int? SubmitWord(string playerName, string word)
{
if (string.IsNullOrWhiteSpace(playerName) || string.IsNullOrWhiteSpace(word))
return null;
if (!IsWordValid(word))
return null;
var points = CalculatePoints(word);
AddWord(playerName, word, points);
return points;
}
private bool IsWordValid(string word)
{
var wrongChars = word.ToList();
foreach (var ch in initialWordCharArray) {
wrongChars.Remove(ch);
}
if (wrongChars.Count > 0)
return false;
lock (submissionLock)
{
if (usedWordsSet.Contains(word))
return false;
}
if (!validWords.Contains(word))
return false;
return true;
}
private void AddWord(string playerName, string word, int points)
{
lock (submissionLock)
{
usedWordsSet.Add(word);
leaderBoard.Add(
new LeaderBoardScore(points, DateTime.Now),
(playerName, word, points)
);
if (leaderBoard.Count > maxLeaderBoardCount)
{
leaderBoard.RemoveAt(maxLeaderBoardCount);
}
}
}
private int CalculatePoints(string word) =>
word.Length;
}
}