Skip to content

Commit 78d1a8a

Browse files
refactor to GameManager
1 parent 59cf3ac commit 78d1a8a

18 files changed

Lines changed: 204 additions & 116 deletions

App.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
namespace CodeConcussion.KVL
22
{
3-
public partial class App {}
3+
public partial class App { }
44
}

CodeConcussion.KVL.csproj

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,12 @@
8484
<SubType>Designer</SubType>
8585
</ApplicationDefinition>
8686
<Compile Include="Entities\User.cs" />
87-
<Compile Include="Messages\ViewModelMessage.cs" />
88-
<Compile Include="Messages\MessageType.cs" />
87+
<Compile Include="Utilities\Messages\ViewModelMessage.cs" />
88+
<Compile Include="Utilities\Messages\MessageType.cs" />
8989
<Compile Include="Utilities\Container\AutoSubscriptionModule.cs" />
9090
<Compile Include="Utilities\Container\ContainerBootstrapper.cs" />
91+
<Compile Include="Utilities\Game\GameManager.cs" />
92+
<Compile Include="Utilities\Messages\MessageDispatch.cs" />
9193
<Compile Include="Utilities\Xaml\BoolToValueConverter.cs" />
9294
<Compile Include="Utilities\Xaml\BoolToVisibilityConverter.cs" />
9395
<Compile Include="Utilities\Game\Context.cs" />
@@ -97,9 +99,9 @@
9799
<Compile Include="Entities\Record.cs" />
98100
<Compile Include="Entities\Operation.cs" />
99101
<Compile Include="Utilities\Extensions.cs" />
100-
<Compile Include="Utilities\Game\GameMessage.cs" />
102+
<Compile Include="Utilities\Game\UserMessage.cs" />
101103
<Compile Include="Utilities\Game\UserStorage.cs" />
102-
<Compile Include="Utilities\Game\MessageConfiguration.cs" />
104+
<Compile Include="Utilities\Game\UserMessageConfiguration.cs" />
103105
<Compile Include="Utilities\Xaml\FocusExtension.cs" />
104106
<Compile Include="ViewModels\BaseViewModel.cs" />
105107
<Compile Include="ViewModels\CardViewModel.cs" />

Entities/Record.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
namespace CodeConcussion.KVL.Entities
1+
using CodeConcussion.KVL.Utilities;
2+
3+
namespace CodeConcussion.KVL.Entities
24
{
35
public sealed class Record
46
{
5-
public Record() { }
7+
public Record() { } //needed for json serialization
68

79
public Record(Deck deck, decimal seconds)
810
{
@@ -22,13 +24,7 @@ public Record(Deck deck, decimal seconds)
2224

2325
public string DisplayTime
2426
{
25-
get
26-
{
27-
if (Seconds <= 0) return "";
28-
var minutes = (int)Seconds / 60;
29-
var seconds = Seconds - (minutes * 60);
30-
return string.Format("{0:D2}:{1:00.0}", minutes, seconds);
31-
}
27+
get { return Seconds.GetTiming(); }
3228
}
3329
}
3430
}

Utilities/Container/ContainerBootstrapper.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Windows;
66
using Autofac;
77
using Caliburn.Micro;
8+
using CodeConcussion.KVL.Utilities.Game;
9+
using CodeConcussion.KVL.Utilities.Messages;
810
using CodeConcussion.KVL.Utilities.Xaml;
911
using CodeConcussion.KVL.ViewModels;
1012

@@ -58,6 +60,10 @@ protected override void Configure()
5860
builder.Register<IEventAggregator>(x => new EventAggregator()).InstancePerLifetimeScope();
5961
builder.RegisterModule<AutoSubscriptionModule>();
6062

63+
//kvl
64+
builder.RegisterType<GameManager>().AsSelf().InstancePerLifetimeScope();
65+
builder.RegisterType<MessageDispatch>().AsSelf().InstancePerLifetimeScope();
66+
6167
_container = builder.Build();
6268

6369
ExtendBinder();
@@ -88,6 +94,8 @@ protected override void OnStartup(object sender, StartupEventArgs e)
8894
DisplayRootViewFor<ShellViewModel>();
8995

9096
Application.Current.MainWindow.SizeToContent = SizeToContent.Manual;
97+
Application.Current.MainWindow.Left = (SystemParameters.PrimaryScreenWidth - 650) / 2;
98+
Application.Current.MainWindow.Top = (SystemParameters.PrimaryScreenHeight - 650) / 2;
9199
Application.Current.MainWindow.Width = 650;
92100
Application.Current.MainWindow.Height = 650;
93101
Application.Current.MainWindow.MinWidth = 480;
@@ -102,13 +110,14 @@ private void ExtendBinder()
102110

103111
private IEnumerable<FrameworkElement> BindFocus(IEnumerable<FrameworkElement> controls, Type modelType)
104112
{
105-
var unmatched = _previousPropertyBinder(controls, modelType);
113+
var elements = controls.ToList();
114+
var unmatched = _previousPropertyBinder(elements, modelType);
106115
var properties = modelType.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public);
107116

108-
foreach (var control in controls)
117+
foreach (var element in elements)
109118
{
110-
var focusPropertyName = "Is" + control.Name + "Focused";
111-
FocusExtension.CheckForFocusProperty(focusPropertyName, properties, control);
119+
var focusPropertyName = "Is" + element.Name + "Focused";
120+
FocusExtension.CheckForFocusProperty(focusPropertyName, properties, element);
112121
}
113122

114123
return unmatched;

Utilities/Extensions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,14 @@ public static string GetSign(this Operation value)
2020
if (value == Operation.Multiplication) return "x";
2121
return "";
2222
}
23+
24+
[DebuggerStepThrough]
25+
public static string GetTiming(this decimal value)
26+
{
27+
if (value <= 0) return "";
28+
var minutes = (int)value / 60;
29+
var seconds = value - (minutes * 60);
30+
return string.Format("{0:D2}:{1:00.0}", minutes, seconds);
31+
}
2332
}
2433
}

Utilities/Game/GameManager.cs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using System;
2+
using CodeConcussion.KVL.Entities;
3+
using CodeConcussion.KVL.Utilities.Messages;
4+
5+
namespace CodeConcussion.KVL.Utilities.Game
6+
{
7+
public sealed class GameManager
8+
{
9+
public GameManager(MessageDispatch dispatcher)
10+
{
11+
_dispatcher = dispatcher;
12+
}
13+
14+
private readonly MessageDispatch _dispatcher;
15+
16+
public Deck Deck { get; private set; }
17+
public Card CurrentCard { get; private set; }
18+
public Card PreviewCard { get; private set; }
19+
public bool IsPlaying { get; private set; }
20+
public DateTime? StartedAt { get; private set; }
21+
public decimal Elapsed { get; private set; }
22+
public int Progress { get; private set; }
23+
24+
public bool CheckAnswer(string guess)
25+
{
26+
var answer = int.Parse("0" + guess.Trim());
27+
return answer == CurrentCard.Answer;
28+
}
29+
30+
public void Deal()
31+
{
32+
Progress++;
33+
if (PreviewCard == null) CurrentCard = null;
34+
35+
if (CurrentCard != null)
36+
{
37+
_dispatcher.PublishMessage(MessageType.DealCard);
38+
CurrentCard = PreviewCard;
39+
PreviewCard = Deck.Deal();
40+
}
41+
else
42+
{
43+
FinishGame();
44+
}
45+
}
46+
47+
public void StartGame(Deck deck)
48+
{
49+
Deck = deck;
50+
Deck.Shuffle();
51+
CurrentCard = Deck.Deal();
52+
PreviewCard = Deck.Deal();
53+
54+
Elapsed = 0;
55+
Progress = 1;
56+
IsPlaying = true;
57+
StartedAt = DateTime.Now;
58+
_dispatcher.PublishMessage(MessageType.StartGame);
59+
}
60+
61+
public void StopGame()
62+
{
63+
if (!IsPlaying) return;
64+
Elapsed = (decimal)(DateTime.Now - StartedAt.GetValueOrDefault()).TotalSeconds;
65+
Progress = 0;
66+
IsPlaying = false;
67+
StartedAt = null;
68+
_dispatcher.PublishMessage(MessageType.StopGame);
69+
}
70+
71+
public void FinishGame()
72+
{
73+
StopGame();
74+
75+
var seconds = decimal.Round(Elapsed, 1, MidpointRounding.AwayFromZero);
76+
var record = new Record(Deck, seconds);
77+
var isNewRecord = Context.User.UpdateRecord(record);
78+
if (isNewRecord) UserStorage.SaveUser(Context.User);
79+
80+
var type = isNewRecord ? MessageType.NewRecord : MessageType.NoRecord;
81+
_dispatcher.PublishMessage(type, record);
82+
}
83+
}
84+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace CodeConcussion.KVL.Utilities.Game
22
{
3-
internal enum GameMessage
3+
internal enum UserMessage
44
{
55
NoRecord,
66
NewRecord

Utilities/Game/MessageConfiguration.cs renamed to Utilities/Game/UserMessageConfiguration.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@
55

66
namespace CodeConcussion.KVL.Utilities.Game
77
{
8-
internal static class MessageConfiguration
8+
internal static class UserMessageConfiguration
99
{
10-
private static Dictionary<GameMessage, string> _messages;
11-
public static Dictionary<GameMessage, string> Messages
10+
private static Dictionary<UserMessage, string> _messages;
11+
public static Dictionary<UserMessage, string> Messages
1212
{
1313
get { return _messages ?? (_messages = GetMessages()); }
1414
}
1515

16-
private static Dictionary<GameMessage, string> GetMessages()
16+
private static Dictionary<UserMessage, string> GetMessages()
1717
{
1818
var settings = ConfigurationManager.AppSettings.AllKeys.Where(x => x.StartsWith("Message."));
1919
var messages = settings
20-
.Select( x => new KeyValuePair<GameMessage, string>(KeyToGameMessage(x), ConfigurationManager.AppSettings[x]))
20+
.Select( x => new KeyValuePair<UserMessage, string>(KeyToGameMessage(x), ConfigurationManager.AppSettings[x]))
2121
.ToDictionary(x => x.Key, x => x.Value);
2222
return messages;
2323
}
2424

25-
private static GameMessage KeyToGameMessage(string key)
25+
private static UserMessage KeyToGameMessage(string key)
2626
{
27-
return (GameMessage)Enum.Parse(typeof(GameMessage), key.Replace("Message.", ""));
27+
return (UserMessage)Enum.Parse(typeof(UserMessage), key.Replace("Message.", ""));
2828
}
2929
}
3030
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Caliburn.Micro;
2+
3+
namespace CodeConcussion.KVL.Utilities.Messages
4+
{
5+
public sealed class MessageDispatch
6+
{
7+
public MessageDispatch(IEventAggregator eventAggregator)
8+
{
9+
_eventAggregator = eventAggregator;
10+
}
11+
12+
private readonly IEventAggregator _eventAggregator;
13+
14+
public void PublishMessage(MessageType type, dynamic data = null)
15+
{
16+
_eventAggregator.Publish(new ViewModelMessage(type, data), x => x());
17+
}
18+
}
19+
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
namespace CodeConcussion.KVL.Messages
1+
namespace CodeConcussion.KVL.Utilities.Messages
22
{
33
public enum MessageType
44
{
55
CloseMessage,
66
CloseRecords,
77
CloseUser,
8-
CorrectAnswer,
9-
FinishGame,
8+
DealCard,
109
NewRecord,
1110
NoRecord,
1211
OpenRecords,

0 commit comments

Comments
 (0)