dev
This commit is contained in:
parent
a69a8f450d
commit
c451a67b8c
|
|
@ -13,29 +13,42 @@ namespace GameData.Repository
|
||||||
{
|
{
|
||||||
public class ExpenseRepository : IExpenseRepository
|
public class ExpenseRepository : IExpenseRepository
|
||||||
{
|
{
|
||||||
readonly ILogger<ExpenseRepository> _log;
|
readonly ILogger<ExpenseRepository>? _log;
|
||||||
private ApiClient _client;
|
private ApiClient _apiClient;
|
||||||
|
|
||||||
string UrlExpense => "items/expense";
|
string UrlExpense => "items/expense";
|
||||||
string UrlPlayerExpense => "items/playerexpense";
|
string UrlPlayerExpense => "items/playerexpense";
|
||||||
List<PlayerExpense> _memberExpenses = new List<PlayerExpense>();
|
List<PlayerExpense> _memberExpenses = new List<PlayerExpense>();
|
||||||
|
|
||||||
|
private List<Expense> _expenses = null;
|
||||||
|
|
||||||
public ExpenseRepository(ILogger<ExpenseRepository> log, ApiClient apiClient)
|
public ExpenseRepository(ILogger<ExpenseRepository> log, ApiClient apiClient)
|
||||||
{
|
{
|
||||||
_log = log;
|
_log = log;
|
||||||
_client = apiClient;
|
_apiClient = apiClient;
|
||||||
|
|
||||||
_log?.LogDebug("creating ExpenseRepository");
|
_log?.LogDebug("creating ExpenseRepository");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Expense>> GetAll()
|
public async Task<IEnumerable<Expense>> GetAll()
|
||||||
{
|
{
|
||||||
return await _client.Get<Expense>(UrlExpense);
|
if (_expenses == null)
|
||||||
|
{
|
||||||
|
_log?.LogDebug("loading expenses from api");
|
||||||
|
var res = await _apiClient.Get<Expense>(UrlExpense);
|
||||||
|
_expenses = new List<Expense> { };
|
||||||
|
_expenses.AddRange(res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_log?.LogDebug("returning expenses from cache");
|
||||||
|
}
|
||||||
|
return _expenses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PlayerExpense> Save(PlayerExpense memberExpense)
|
public async Task<PlayerExpense> Save(PlayerExpense memberExpense)
|
||||||
{
|
{
|
||||||
return await _client.Post<PlayerExpense>(memberExpense, UrlPlayerExpense);
|
return await _apiClient.Post<PlayerExpense>(memberExpense, UrlPlayerExpense);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Delete(IEnumerable<PlayerExpense> items)
|
public async Task Delete(IEnumerable<PlayerExpense> items)
|
||||||
|
|
@ -43,7 +56,7 @@ namespace GameData.Repository
|
||||||
dynamic keys = new JObject();
|
dynamic keys = new JObject();
|
||||||
keys.keys = new JArray(items.Select(_ => _.Id));
|
keys.keys = new JArray(items.Select(_ => _.Id));
|
||||||
|
|
||||||
await _client.Delete(keys, UrlPlayerExpense);
|
await _apiClient.Delete(keys, UrlPlayerExpense);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,11 @@ namespace GameData.Repository
|
||||||
TypeNameHandling = TypeNameHandling.Auto
|
TypeNameHandling = TypeNameHandling.Auto
|
||||||
});
|
});
|
||||||
var gameStateDo = new GameStateDo(gameState.Id, gameState.GameId, gameState.GameName, str, gameState.Counter);
|
var gameStateDo = new GameStateDo(gameState.Id, gameState.GameId, gameState.GameName, str, gameState.Counter);
|
||||||
var res = await _client.Post<GameStateDo>(gameStateDo,UrlGameState);
|
var res = await _client.Post<GameStateDo>(gameStateDo,UrlGameState).ConfigureAwait(false);
|
||||||
|
|
||||||
if (res == null)
|
if (res == null)
|
||||||
{
|
{
|
||||||
var msg = "error saviong gamestate - save rsult cannot be null - repo not online, or game deleted";
|
var msg = "error saving gamestate - save rsult cannot be null - repo not online, or game deleted";
|
||||||
_log.LogError(msg);
|
_log.LogError(msg);
|
||||||
throw new InvalidOperationException(msg);
|
throw new InvalidOperationException(msg);
|
||||||
}
|
}
|
||||||
|
|
@ -72,19 +72,19 @@ namespace GameData.Repository
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Update(Game game)
|
public Task Update(Game game)
|
||||||
{
|
{
|
||||||
await _client.Put<Game>(game, UrlGame);
|
return _client.Put<Game>(game, UrlGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Game> Create(Game game)
|
public Task<Game> Create(Game game)
|
||||||
{
|
{
|
||||||
return await _client.Post<Game>(game, UrlGame);
|
return _client.Post<Game>(game, UrlGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Game> LoadGame(Guid gameId)
|
public Task<Game> LoadGame(Guid gameId)
|
||||||
{
|
{
|
||||||
return await _client.GetSingle<Game>(UrlGame + "/" + gameId);
|
return _client.GetSingle<Game>(UrlGame + "/" + gameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Game> Create(string gameName)
|
public async Task<Game> Create(string gameName)
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ namespace GameHandler.UnitTests
|
||||||
public void CheckThrow_SinkCausesMultipleSinkExpsenses()
|
public void CheckThrow_SinkCausesMultipleSinkExpsenses()
|
||||||
{
|
{
|
||||||
var bs = BoardState.Create();
|
var bs = BoardState.Create();
|
||||||
var model = _eh.CheckThrow(bs, PinThrow.Create(1, PinPicture.Create(), false, true), _player);
|
var model = _eh.CheckThrow(bs, PinThrow.Create(1, PinPicture.Create(), false, true), _player).Result;
|
||||||
var expense1 = model.MemberExpenses.First();
|
var expense1 = model.First();
|
||||||
var expense2 = model.MemberExpenses.Skip(1).First();
|
var expense2 = model.Skip(1).First();
|
||||||
Assert.That(expense1.Name, Is.EqualTo("Gosse"));
|
Assert.That(expense1.Name, Is.EqualTo("Gosse"));
|
||||||
Assert.That(expense2.Name, Is.EqualTo("Gosse2"));
|
Assert.That(expense2.Name, Is.EqualTo("Gosse2"));
|
||||||
}
|
}
|
||||||
|
|
@ -37,20 +37,20 @@ namespace GameHandler.UnitTests
|
||||||
public void CheckThrow_NinePinsCausesExpenseForAllOthers()
|
public void CheckThrow_NinePinsCausesExpenseForAllOthers()
|
||||||
{
|
{
|
||||||
var bs = BoardState.Create();
|
var bs = BoardState.Create();
|
||||||
var model = _eh.CheckThrow(bs, PinThrow.Create(1, PinPicture.CreateAllPins(), false, false), _player);
|
var model = _eh.CheckThrow(bs, PinThrow.Create(1, PinPicture.CreateAllPins(), false, false), _player).Result;
|
||||||
Assert.That(model.MemberExpenses.Count, Is.EqualTo(_player.Count()-1));
|
Assert.That(model.Count, Is.EqualTo(_player.Count()-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CheckThrow_NoWoodAndBellCausesSinkAndBellExpsense()
|
public void CheckThrow_NoWoodAndBellCausesSinkAndBellExpsense()
|
||||||
{
|
{
|
||||||
var bs = BoardState.Create();
|
var bs = BoardState.Create();
|
||||||
var model = _eh.CheckThrow(bs, PinThrow.Create(1, true, true), _player);
|
var model = _eh.CheckThrow(bs, PinThrow.Create(1, true, true), _player).Result;
|
||||||
var expense1 = model.MemberExpenses.First();
|
var expense1 = model.First();
|
||||||
var expense2 = model.MemberExpenses.Skip(2).First(); // there are two triggers for sink in testdata
|
var expense2 = model.Skip(2).First(); // there are two triggers for sink in testdata
|
||||||
Assert.That(expense1.Name, Is.EqualTo("Gosse"));
|
Assert.That(expense1.Name, Is.EqualTo("Gosse"));
|
||||||
Assert.That(expense2.Name, Is.EqualTo("Klingel"));
|
Assert.That(expense2.Name, Is.EqualTo("Klingel"));
|
||||||
Assert.That(model.MemberExpenses.Count, Is.EqualTo(3));
|
Assert.That(model.Count, Is.EqualTo(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace GameHandler.UnitTests.Extensions
|
||||||
[Test]
|
[Test]
|
||||||
public void GetGameHandler_ThrowsExceptionWhenGamenameIsNotValid()
|
public void GetGameHandler_ThrowsExceptionWhenGamenameIsNotValid()
|
||||||
{
|
{
|
||||||
var gs = new GameService();
|
var gs = new GameService(null);
|
||||||
Assert.That(() => gs.GetGameHandler("unknown"), Throws.TypeOf<InvaildGameNameException>());
|
Assert.That(() => gs.GetGameHandler("unknown"), Throws.TypeOf<InvaildGameNameException>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace GameHandler.UnitTests.DeathGame
|
||||||
var gm = _gh.InitGameModel(_players, _settings);
|
var gm = _gh.InitGameModel(_players, _settings);
|
||||||
int failedCoffinPlayerId = 0;
|
int failedCoffinPlayerId = 0;
|
||||||
ExpenseTrigger[] failed = Array.Empty<ExpenseTrigger>();
|
ExpenseTrigger[] failed = Array.Empty<ExpenseTrigger>();
|
||||||
_gh.GameExpenseOccured += (sender, arg) =>
|
_gh.GameExpenseOccured += async (sender, arg) =>
|
||||||
{
|
{
|
||||||
failed = ((GameExenseEventArgs)arg).Triggers;
|
failed = ((GameExenseEventArgs)arg).Triggers;
|
||||||
failedCoffinPlayerId = ((GameExenseEventArgs)arg).PlayerId;
|
failedCoffinPlayerId = ((GameExenseEventArgs)arg).PlayerId;
|
||||||
|
|
@ -92,7 +92,7 @@ namespace GameHandler.UnitTests.DeathGame
|
||||||
var gm = _gh.InitGameModel(_players, _settings);
|
var gm = _gh.InitGameModel(_players, _settings);
|
||||||
int failedCoffinPlayerId = 0;
|
int failedCoffinPlayerId = 0;
|
||||||
ExpenseTrigger[] failed = Array.Empty<ExpenseTrigger>();
|
ExpenseTrigger[] failed = Array.Empty<ExpenseTrigger>();
|
||||||
_gh.GameExpenseOccured += (sender, arg) =>
|
_gh.GameExpenseOccured += async (sender, arg) =>
|
||||||
{
|
{
|
||||||
failed = ((GameExenseEventArgs)arg).Triggers;
|
failed = ((GameExenseEventArgs)arg).Triggers;
|
||||||
failedCoffinPlayerId = ((GameExenseEventArgs)arg).PlayerId;
|
failedCoffinPlayerId = ((GameExenseEventArgs)arg).PlayerId;
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,21 @@ namespace GameHandler.UnitTests.Mocks
|
||||||
{
|
{
|
||||||
public class FakeExpenseRepository : IExpenseRepository
|
public class FakeExpenseRepository : IExpenseRepository
|
||||||
{
|
{
|
||||||
|
public Task Delete(IEnumerable<PlayerExpense> enumerable)
|
||||||
|
|
||||||
public IEnumerable<Expense> GetAll()
|
|
||||||
{
|
{
|
||||||
return IExpenseRepository.TestData;
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<PlayerExpense> Save(PlayerExpense data)
|
public Task<PlayerExpense> Save(PlayerExpense data)
|
||||||
{
|
{
|
||||||
return Task.FromResult(data);
|
return Task.FromResult(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<Expense>> GetAll()
|
||||||
|
{
|
||||||
|
IEnumerable<Expense> res = IExpenseRepository.TestData;
|
||||||
|
return Task.FromResult(res);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using GameModel;
|
using GameHandler.GameHandler;
|
||||||
|
using GameModel;
|
||||||
using GameModel.Contracts;
|
using GameModel.Contracts;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -12,7 +13,17 @@ namespace GameHandler.UnitTests.Mocks
|
||||||
{
|
{
|
||||||
public Task<Game> Create(Game game)
|
public Task<Game> Create(Game game)
|
||||||
{
|
{
|
||||||
return Task.FromResult(Game.Create());
|
return Task.FromResult(Game.Create(FreeGameHandler.GAMENAME_FREETRAINING));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Game> Create(string gameName)
|
||||||
|
{
|
||||||
|
return Task.FromResult(Game.Create(gameName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Delete(IEnumerable<GameState> gameStates)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameState Load(Guid gameId)
|
public GameState Load(Guid gameId)
|
||||||
|
|
@ -20,6 +31,16 @@ namespace GameHandler.UnitTests.Mocks
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<Game> LoadGame(Guid gameId)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<GameState>> LoadStates(Guid gameId)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Task<GameState> Save(GameState gameState)
|
public Task<GameState> Save(GameState gameState)
|
||||||
{
|
{
|
||||||
return Task.FromResult(gameState);
|
return Task.FromResult(gameState);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AsyncAwaitBestPractices" Version="7.0.0" />
|
||||||
<PackageReference Include="Autofac" Version="7.1.0" />
|
<PackageReference Include="Autofac" Version="7.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace GameHandler.DeathGame
|
||||||
public const string GAMENAME_DEATHBOX = "Totenkiste";
|
public const string GAMENAME_DEATHBOX = "Totenkiste";
|
||||||
|
|
||||||
public event CoffinCompleted CoffinCompleted;
|
public event CoffinCompleted CoffinCompleted;
|
||||||
public event EventHandler GameExpenseOccured;
|
public event AsyncEventHandler<EventArgs>? GameExpenseOccured;
|
||||||
|
|
||||||
private static Random random = new Random();
|
private static Random random = new Random();
|
||||||
|
|
||||||
|
|
@ -50,6 +50,7 @@ namespace GameHandler.DeathGame
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IGameModel InitGameModel(int[] playerIds, IGameSettings gameSettings)
|
public IGameModel InitGameModel(int[] playerIds, IGameSettings gameSettings)
|
||||||
{
|
{
|
||||||
return InitGameModel(playerIds, gameSettings as DeathGameSettings);
|
return InitGameModel(playerIds, gameSettings as DeathGameSettings);
|
||||||
|
|
@ -217,9 +218,12 @@ namespace GameHandler.DeathGame
|
||||||
|
|
||||||
public int ThrowsPerRount() => IGameHandler.INFINIT_THROWS;
|
public int ThrowsPerRount() => IGameHandler.INFINIT_THROWS;
|
||||||
|
|
||||||
protected virtual void OnGameExpenseOccured(GameExenseEventArgs e)
|
protected async virtual Task OnGameExpenseOccured(GameExenseEventArgs e)
|
||||||
{
|
{
|
||||||
GameExpenseOccured?.Invoke(this, e);
|
if (GameExpenseOccured is not null)
|
||||||
|
{
|
||||||
|
await GameExpenseOccured(this, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ namespace GameHandler.GameHandler
|
||||||
public class FreeGameHandler : IGameHandler
|
public class FreeGameHandler : IGameHandler
|
||||||
{
|
{
|
||||||
public const string GAMENAME_FREETRAINING = "Freies Spiel";
|
public const string GAMENAME_FREETRAINING = "Freies Spiel";
|
||||||
|
|
||||||
public event EventHandler GameExpenseOccured;
|
public event AsyncEventHandler<EventArgs>? GameExpenseOccured;
|
||||||
|
|
||||||
|
|
||||||
public static string GameName()
|
public static string GameName()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,25 +16,26 @@ using System.Data;
|
||||||
using Autofac.Core;
|
using Autofac.Core;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using static System.Formats.Asn1.AsnWriter;
|
using static System.Formats.Asn1.AsnWriter;
|
||||||
|
using AsyncAwaitBestPractices;
|
||||||
|
|
||||||
namespace GameHandler
|
namespace GameHandler
|
||||||
{
|
{
|
||||||
public class GameService
|
public class GameService
|
||||||
{
|
{
|
||||||
private readonly IContainer? _rootContainer;
|
private readonly IContainer _rootContainer;
|
||||||
private bool _isStarted = false;
|
private bool _isStarted = false;
|
||||||
private ILifetimeScope? _scope;
|
private ILifetimeScope _scope;
|
||||||
private IGameHandler? _gh;
|
private IGameHandler _gh;
|
||||||
private ThrowHandler? _th;
|
private ThrowHandler _th;
|
||||||
private ExpenseHandler? _eh;
|
private ExpenseHandler _eh;
|
||||||
private GameStateHandler? _gameStateHandler;
|
private GameStateHandler _gameStateHandler;
|
||||||
private Game? _game;
|
private Game? _game;
|
||||||
|
|
||||||
public GameState? GameModel { get => _gameStateHandler?.GameState; }
|
public GameState? GameModel { get => _gameStateHandler?.GameState; }
|
||||||
|
|
||||||
public bool FreePlayerSelection => _gh != null && _gh.FreePlayerSelection();
|
public bool FreePlayerSelection => _gh != null && _gh.FreePlayerSelection();
|
||||||
|
|
||||||
public GameService(IContainer? rootContainer = null)
|
public GameService(IContainer rootContainer)
|
||||||
{
|
{
|
||||||
this._rootContainer = rootContainer;
|
this._rootContainer = rootContainer;
|
||||||
}
|
}
|
||||||
|
|
@ -53,9 +54,9 @@ namespace GameHandler
|
||||||
|
|
||||||
static int[] defaultPlayerIds => new[] {1,2,3,4};
|
static int[] defaultPlayerIds => new[] {1,2,3,4};
|
||||||
|
|
||||||
public async Task<GameState> Start(string gameName = FreeGameHandler.GAMENAME_FREETRAINING)
|
public Task<GameState> Start(string gameName = FreeGameHandler.GAMENAME_FREETRAINING)
|
||||||
{
|
{
|
||||||
return await Start(defaultPlayerIds, new DeathGameSettings(6), gameName);
|
return Start(defaultPlayerIds, new DeathGameSettings(6), gameName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<GameState> Start(int[] playerIds, IGameSettings gameSettings, string gameName = FreeGameHandler.GAMENAME_FREETRAINING)
|
public async Task<GameState> Start(int[] playerIds, IGameSettings gameSettings, string gameName = FreeGameHandler.GAMENAME_FREETRAINING)
|
||||||
|
|
@ -92,15 +93,15 @@ namespace GameHandler
|
||||||
{
|
{
|
||||||
_scope = _rootContainer?.BeginLifetimeScope();
|
_scope = _rootContainer?.BeginLifetimeScope();
|
||||||
_gh = this.GetGameHandler(gameName);
|
_gh = this.GetGameHandler(gameName);
|
||||||
_gh.GameExpenseOccured += _gh_GameExpenseOccured;
|
_gh.GameExpenseOccured += _gh_GameExpenseOccured1; ;
|
||||||
_th = new ThrowHandler();
|
_th = new ThrowHandler();
|
||||||
_eh = new ExpenseHandler(_scope.Resolve<IExpenseRepository>());
|
_eh = new ExpenseHandler(_scope.Resolve<IExpenseRepository>());
|
||||||
_gameStateHandler = new GameStateHandler(_scope.Resolve<IGameRepository>(), _scope.Resolve<IExpenseRepository>());
|
_gameStateHandler = new GameStateHandler(_scope.Resolve<IGameRepository>(), _scope.Resolve<IExpenseRepository>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _gh_GameExpenseOccured(object? sender, EventArgs e)
|
private async Task _gh_GameExpenseOccured1(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var items = _eh.HandleGameExenseEventArgs(e as GameExenseEventArgs).Result;
|
var items = await _eh.HandleGameExenseEventArgs(e as GameExenseEventArgs);
|
||||||
_gameStateHandler.Add(items);
|
_gameStateHandler.Add(items);
|
||||||
//_lastState = _lastState with { ExpenseModel = expenseModel };
|
//_lastState = _lastState with { ExpenseModel = expenseModel };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace GameModel.UnitTests
|
||||||
public void PinPicture_IndexTest(int pinNumber, PinState pinState)
|
public void PinPicture_IndexTest(int pinNumber, PinState pinState)
|
||||||
{
|
{
|
||||||
var p = PinPicture.Create(pinNumber, pinState);
|
var p = PinPicture.Create(pinNumber, pinState);
|
||||||
Assert.That(p[pinNumber],Is.EqualTo(PinState.Down));
|
Assert.That(p.Index(pinNumber),Is.EqualTo(PinState.Down));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
@ -35,7 +35,7 @@ namespace GameModel.UnitTests
|
||||||
public void Get_Invalid_PinNumber_ThrowsException(int pinNumber)
|
public void Get_Invalid_PinNumber_ThrowsException(int pinNumber)
|
||||||
{
|
{
|
||||||
var p = PinPicture.Create();
|
var p = PinPicture.Create();
|
||||||
Assert.That(() => p[pinNumber],Throws.TypeOf<InvalidPinIndexException>());
|
Assert.That(() => p.Index(pinNumber),Throws.TypeOf<InvalidPinIndexException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Test]
|
//[Test]
|
||||||
|
|
@ -79,10 +79,10 @@ namespace GameModel.UnitTests
|
||||||
{
|
{
|
||||||
var p = PinPicture.Create();
|
var p = PinPicture.Create();
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var item in p)
|
foreach (var item in p.Take())
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
Assert.That(item, Is.EqualTo(p[i]));
|
Assert.That(item, Is.EqualTo(p.Index(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -92,21 +92,21 @@ namespace GameModel.UnitTests
|
||||||
{
|
{
|
||||||
var p = new PinPicture(PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down);
|
var p = new PinPicture(PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down);
|
||||||
Assert.That(p.First, Is.EqualTo(PinState.Down));
|
Assert.That(p.First, Is.EqualTo(PinState.Down));
|
||||||
Assert.That(p.Skip(1).First, Is.EqualTo(PinState.Up));
|
Assert.That(p.PinState2, Is.EqualTo(PinState.Up));
|
||||||
Assert.That(p.Last, Is.EqualTo(PinState.Down));
|
Assert.That(p.Last, Is.EqualTo(PinState.Down));
|
||||||
|
|
||||||
var items = p.Take(9).ToArray();
|
var items = p.Take(9).ToArray();
|
||||||
CollectionAssert.AreEqual(items, new[] { PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down });
|
CollectionAssert.AreEqual(items, new[] { PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down });
|
||||||
|
|
||||||
var enumerator = p.GetEnumerator();
|
//var enumerator = p.GetEnumerator();
|
||||||
enumerator.MoveNext();
|
//enumerator.MoveNext();
|
||||||
enumerator.MoveNext();
|
//enumerator.MoveNext();
|
||||||
Assert.That(enumerator.Current, Is.EqualTo(PinState.Up));
|
//Assert.That(enumerator.Current, Is.EqualTo(PinState.Up));
|
||||||
|
|
||||||
// cover GetEnumerator method https://stackoverflow.com/questions/1510031/how-do-you-test-the-ienumerable-getenumerator-method
|
//// cover GetEnumerator method https://stackoverflow.com/questions/1510031/how-do-you-test-the-ienumerable-getenumerator-method
|
||||||
IEnumerable weak = p.AsWeakEnumerable();
|
//IEnumerable weak = p.AsWeakEnumerable();
|
||||||
var sequence = weak.Cast<PinState>().Take(9).ToArray();
|
//var sequence = weak.Cast<PinState>().Take(9).ToArray();
|
||||||
CollectionAssert.AreEqual(sequence, new[] { PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down });
|
//CollectionAssert.AreEqual(sequence, new[] { PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down, PinState.Up, PinState.Down });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GameModel.Contract
|
namespace GameModel.Contract
|
||||||
{
|
{
|
||||||
|
public delegate Task AsyncEventHandler<TEventArgs>(object? sender, TEventArgs e);
|
||||||
|
|
||||||
public interface IGameHandler
|
public interface IGameHandler
|
||||||
{
|
{
|
||||||
public const int INFINIT_THROWS = 9999;
|
public const int INFINIT_THROWS = 9999;
|
||||||
|
|
@ -25,7 +27,7 @@ namespace GameModel.Contract
|
||||||
IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate,
|
IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate,
|
||||||
ThrowState throwStateAfterUpdate);
|
ThrowState throwStateAfterUpdate);
|
||||||
|
|
||||||
event EventHandler GameExpenseOccured;
|
event AsyncEventHandler<EventArgs>? GameExpenseOccured;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Reflection;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Reflection.Metadata.Ecma335;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -145,6 +146,51 @@ namespace GameModel
|
||||||
return DownCount == 0;
|
return DownCount == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PinState First => PinState1;
|
||||||
|
|
||||||
|
public PinState Last => PinState9;
|
||||||
|
|
||||||
|
public IEnumerable<PinState> Take()
|
||||||
|
{
|
||||||
|
return Take(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<PinState> Take(int count)
|
||||||
|
{
|
||||||
|
if (count <= 1 || count > 9)
|
||||||
|
{
|
||||||
|
throw new InvalidPinIndexException();
|
||||||
|
}
|
||||||
|
var res = new List<PinState>
|
||||||
|
{
|
||||||
|
PinState1,
|
||||||
|
PinState2,
|
||||||
|
PinState3,
|
||||||
|
PinState4,
|
||||||
|
PinState5,
|
||||||
|
PinState6,
|
||||||
|
PinState7,
|
||||||
|
PinState8,
|
||||||
|
PinState9
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.Take(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">one-based number of a pin</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public PinState Index(int index)
|
||||||
|
{
|
||||||
|
if (index < 1 || index > 9)
|
||||||
|
{
|
||||||
|
throw new InvalidPinIndexException();
|
||||||
|
}
|
||||||
|
return Take(9).ToArray()[index-1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record PinPictureEnum : PinPicture, IEnumerable<PinState>, IEnumerable
|
public record PinPictureEnum : PinPicture, IEnumerable<PinState>, IEnumerable
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AsyncAwaitBestPractices" Version="7.0.0" />
|
||||||
<PackageReference Include="AutofacSerilogIntegration" Version="5.0.0" />
|
<PackageReference Include="AutofacSerilogIntegration" Version="5.0.0" />
|
||||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ async Task ShowMainMenu()
|
||||||
|
|
||||||
void ContinueGame()
|
void ContinueGame()
|
||||||
{
|
{
|
||||||
StartGameAction("", new Guid("33869054-811f-49cb-940b-be582ee5d8a5"));
|
StartGameAction("", new Guid("4dd49b5e-7060-467a-8f79-a2e96b1b4c32"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MasterDataAction()
|
void MasterDataAction()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue