This commit is contained in:
Christian Kauer 2023-12-22 18:30:41 +01:00
parent 64e009d401
commit 364223fdf5
6 changed files with 197 additions and 29 deletions

View File

@ -1,4 +1,6 @@
using System; using GameModel;
using GameModel.Exceptions;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -10,10 +12,50 @@ namespace GameHandler.UnitTests
internal class GameServiceTests internal class GameServiceTests
{ {
[Test] [Test]
public void Start_StartsANewGame() public void Start_InvalidStartStatusThrowInvalidGameStateExcpetion()
{ {
GameService service = new GameService(); GameService service = new GameService();
service.Start(); service.Start();
Assert.That(() => service.Start(), Throws.TypeOf<InvalidGameStateExcpetion>());
}
[Test]
public void Stop_InvalidStopStatusThrowInvalidGameStateExcpetion()
{
GameService service = new GameService();
Assert.That(() => service.Stop(), Throws.TypeOf<InvalidGameStateExcpetion>());
}
[Test]
public void HandleThrow_NotPossibleBeforeStart()
{
GameService service = new GameService();
Assert.That(() => service.HandleThrow(null), Throws.TypeOf<InvalidGameStateExcpetion>());
}
[Test]
public void HandleThrow_NotPossibleAfterStop()
{
GameService service = new GameService();
service.Start();
service.Stop();
Assert.That(() => service.HandleThrow(null), Throws.TypeOf<InvalidGameStateExcpetion>());
}
[Test]
public void HandleThrow_UpdateTheBoardState()
{
GameService service = new GameService();
var ts1 = service.Start();
var bs1 = ts1.BoardState;
var pinThrow = PinThrow.Create(1,PinPicture.Create(1,PinState.Down), false, false);
var ts2 = service.HandleThrow(pinThrow);
var bs2 = ts2.BoardState;
Assert.That(bs2, Is.Not.EqualTo(bs1));
} }
} }
} }

View File

@ -21,17 +21,17 @@ namespace GameHandler.UnitTests
[Test] [Test]
public void CreateFullPicAfterEachThrowInRepositionMode() public void CreateFullPicAfterEachThrowInRepositionMode()
{ {
var bs = _th.Init(ThrowMode.Reposition); var bs = _th.Init(ThrowMode.Reposition, 3);
var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2,PinState.Down),false,false)); var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2,PinState.Down),false,false));
Assert.That(bs.PinPicture.UpCount, Is.EqualTo(9)); Assert.That(bs.BoardState.PinPicture.UpCount, Is.EqualTo(9));
} }
[Test] [Test]
public void SinkThrowReturnsSameGameStateAsBefore() public void SinkThrowReturnsSameGameStateAsBefore()
{ {
var bs = _th.Init(ThrowMode.Reposition); var bs = _th.Init(ThrowMode.Reposition, 3);
var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, false)); var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, false));
var bs3 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, true)); var bs3 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, true));
@ -42,13 +42,42 @@ namespace GameHandler.UnitTests
[Test] [Test]
public void CreateFullPicAfterBoardIsClearedInDecreaseMode() public void CreateFullPicAfterBoardIsClearedInDecreaseMode()
{ {
var bs = _th.Init(ThrowMode.Decrease); var bs = _th.Init(ThrowMode.Decrease, 3);
var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, false)); var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, false));
Assert.That(bs2.PinPicture.DownCount, Is.EqualTo(1)); Assert.That(bs2.BoardState.PinPicture.DownCount, Is.EqualTo(1));
var bs3 = _th.Update(bs, new PinThrow(1, PinPicture.CreateAllPins(), false, false)); var bs3 = _th.Update(bs, new PinThrow(1, PinPicture.CreateAllPins(), false, false));
Assert.That(bs3.PinPicture.DownCount, Is.EqualTo(0)); Assert.That(bs3.BoardState.PinPicture.DownCount, Is.EqualTo(0));
}
[Test]
public void Update_ThrowCounterIncreasedAfterEachThrow()
{
var bs = _th.Init(ThrowMode.Decrease, 3);
Assert.That(bs.ThrowCount, Is.EqualTo(0));
var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, false));
Assert.That(bs2.ThrowCount, Is.EqualTo(1));
var bs3 = _th.Update(bs2, new PinThrow(1, PinPicture.CreateAllPins(), false, false));
Assert.That(bs3.ThrowCount, Is.EqualTo(2));
}
[Test]
public void Update_ThrowCounterResetToZeroAfterFullRound()
{
var bs = _th.Init(ThrowMode.Decrease, 3);
Assert.That(bs.ThrowCount, Is.EqualTo(0));
var bs2 = _th.Update(bs, new PinThrow(1, PinPicture.Create(2, PinState.Down), false, false));
Assert.That(bs2.ThrowCount, Is.EqualTo(1));
var bs3 = _th.Update(bs2, new PinThrow(1, PinPicture.CreateAllPins(), false, false));
Assert.That(bs3.ThrowCount, Is.EqualTo(2));
var bs4 = _th.Update(bs3, new PinThrow(1, PinPicture.CreateAllPins(), false, false));
Assert.That(bs4.ThrowCount, Is.EqualTo(0));
} }
} }
} }

View File

@ -10,11 +10,25 @@ namespace GameHandler
{ {
public class GameService public class GameService
{ {
public const int INFINIT_THROWS = 9999;
private bool _isStarted = false; private bool _isStarted = false;
private ThrowHandler _th; private ThrowHandler _th;
private BoardState _lastState; private ThrowState _lastState;
public BoardState Start() public string ThrowModeName
{
get
{
if (_lastState != null)
{
return _lastState.BoardState.ThrowMode == ThrowMode.Decrease ? "Abräumen" : "Volle";
}
return string.Empty;
}
}
public ThrowState Start(int GameTypeId=0)
{ {
if (_isStarted) if (_isStarted)
{ {
@ -27,11 +41,14 @@ namespace GameHandler
_th = new ThrowHandler(); _th = new ThrowHandler();
_lastState = BoardState.Create(ThrowMode.Decrease); var throwMode = GameTypeId == 0 ? ThrowMode.Reposition : ThrowMode.Decrease;
var throwsPerRount = GameTypeId == 0 ? INFINIT_THROWS : 3;
_lastState = ThrowState.Create(throwMode, throwsPerRount);
return _lastState; return _lastState;
} }
public BoardState HandleThrow(PinThrow pinThrow) public ThrowState HandleThrow(PinThrow pinThrow)
{ {
if (!_isStarted) if (!_isStarted)
{ {

View File

@ -4,11 +4,11 @@ namespace GameHandler
{ {
public class ThrowHandler public class ThrowHandler
{ {
public BoardState Init(ThrowMode throwMode) public ThrowState Init(ThrowMode throwMode, int ThrowsPerRound)
{ {
var picture = PinPicture.Create(); var picture = PinPicture.Create();
return new BoardState(throwMode,picture); return new ThrowState(new BoardState(throwMode, picture), ThrowsPerRound, 0);
} }
/// <summary> /// <summary>
@ -18,7 +18,7 @@ namespace GameHandler
/// <param name="throwMode"></param> /// <param name="throwMode"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public BoardState SetBoardstatePicture(PinPicture boardstate, ThrowMode throwMode) public ThrowState SetBoardstatePicture(PinPicture boardstate, ThrowMode throwMode)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -29,18 +29,28 @@ namespace GameHandler
/// <param name="currentState"></param> /// <param name="currentState"></param>
/// <param name="pinThrow"></param> /// <param name="pinThrow"></param>
/// <returns></returns> /// <returns></returns>
public BoardState Update(BoardState currentState, PinThrow pinThrow) public ThrowState Update(ThrowState throwState, PinThrow pinThrow)
{ {
if (currentState.ThrowMode == ThrowMode.Reposition) var resetBoard = throwState.ThrowCount + 1 == throwState.ThrowsPerRount;
var newBoardState = UpdateBoardState(throwState, pinThrow, resetBoard);
var throwCount = resetBoard ? 0 : throwState.ThrowCount + 1;
return throwState with { BoardState = newBoardState, ThrowCount = throwCount };
}
private static BoardState UpdateBoardState(ThrowState throwState, PinThrow pinThrow, bool resetBoard)
{
var boardState = throwState.BoardState;
if (boardState.ThrowMode == ThrowMode.Reposition)
{ {
return currentState with { PinPicture = PinPicture.Create() }; return boardState with { PinPicture = PinPicture.Create() };
} }
else else
{ {
var result = currentState with { PinPicture = currentState.PinPicture + pinThrow }; var result = boardState with { PinPicture = boardState.PinPicture + pinThrow };
if (result.PinPicture.UpCount == 0) if (result.PinPicture.UpCount == 0 || resetBoard)
{ {
return currentState with { PinPicture = PinPicture.Create() }; return boardState with { PinPicture = PinPicture.Create() };
} }
else else
{ {

16
GameModel/ThrowState.cs Normal file
View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameModel
{
public record ThrowState(BoardState BoardState, int ThrowsPerRount, int ThrowCount)
{
public static ThrowState Create(ThrowMode throwMode, int throwsPerRount)
{
return new ThrowState(BoardState.Create(throwMode), throwsPerRount, 0);
}
}
}

View File

@ -39,15 +39,15 @@ GameService _gs;
void NewGameAction() void NewGameAction()
{ {
_gs = new GameService(); _gs = new GameService();
var bs = _gs.Start(); var bs = _gs.Start(1);
ShowBoard(bs); Show(bs);
do do
{ {
var stringData = AnsiConsole.Prompt( var stringData = AnsiConsole.Prompt(
new TextPrompt<string>("Wurf?") new TextPrompt<string>($"Wurf [yellow]{bs.ThrowCount + 1}[/]?")
.PromptStyle("green") .PromptStyle("green")
.ValidationErrorMessage("[red]That's not a valid throw[/]") .ValidationErrorMessage("[red]That's not a valid throw[/]")
.Validate(data => .Validate(data =>
@ -71,16 +71,67 @@ void NewGameAction()
} }
bs = _gs.HandleThrow(PinThrow.Create(throwData.Pindata, throwData.Bell, throwData.Sink, throwData.PlayerId)); bs = _gs.HandleThrow(PinThrow.Create(throwData.Pindata, throwData.Bell, throwData.Sink, throwData.PlayerId));
ShowBoard(bs); Show(bs);
} while (true) ; } while (true) ;
} }
void ShowBoard(BoardState board) void Show(ThrowState throwState)
{ {
AnsiConsole.Clear(); AnsiConsole.Clear();
ShowPlayer();
ShowThrow(throwState);
ShowBoard(throwState.BoardState);
}
void ShowThrow(ThrowState throwState)
{
int throwCount = throwState.ThrowCount;
int throwsPerRount = throwState.ThrowsPerRount;
Text text1;
if (throwsPerRount == GameService.INFINIT_THROWS)
{
text1 = new Text($"Würfe: {throwCount}", new Style(Color.Red, Color.Black));
}
else
{
text1 = new Text($"Würfe: {throwCount}/{throwsPerRount}", new Style(Color.Red, Color.Black));
}
var text1_2 = new Text($"Modus: {_gs.ThrowModeName}", new Style(Color.Red, Color.Black));
// Create three text elements
var paddedText_II = new Text("Spieler: ", new Style(Color.Green, Color.Black));
var paddedText_III = new Text("Spielzeit: ", new Style(Color.Blue, Color.Black));
// Apply padding to the three text elements
var pad1_1 = new Padder(text1).PadRight(16).PadBottom(0).PadTop(2);
var pad1_2 = new Padder(text1_2).PadRight(0).PadBottom(0).PadTop(2);
var pad_II = new Padder(paddedText_II).PadBottom(0).PadTop(2);
var pad_III = new Padder(paddedText_III).PadLeft(16).PadBottom(0).PadTop(0);
// Insert padded elements within single-row grid
var grid = new Grid();
grid.AddColumn();
grid.AddColumn();
grid.AddColumn();
grid.AddRow(pad1_2);
grid.AddRow(pad1_1, pad_II, pad_III);
// Write grid and it's padded contents to the Console
AnsiConsole.Write(grid);
}
void ShowBoard(BoardState board)
{
var grid = new Grid(); var grid = new Grid();
grid.AddColumn(); grid.AddColumn();
@ -106,10 +157,13 @@ void ShowBoard(BoardState board)
GetRow(5, out pad_1, out pad_2, out pad_3, out pad_4, out pad_5, board); GetRow(5, out pad_1, out pad_2, out pad_3, out pad_4, out pad_5, board);
grid.AddRow(pad_1, pad_2, pad_3, pad_4, pad_5); grid.AddRow(pad_1, pad_2, pad_3, pad_4, pad_5);
// Write grid and it's padded contents to the Console // Write grid and it's padded contents to the Console
AnsiConsole.Write(grid); AnsiConsole.Write(grid);
}
void ShowPlayer()
{
}; };
static void GetRow(int row, out Padder pad_1, out Padder pad_2, out Padder pad_3, out Padder pad_4, out Padder pad_5, BoardState board) static void GetRow(int row, out Padder pad_1, out Padder pad_2, out Padder pad_3, out Padder pad_4, out Padder pad_5, BoardState board)