Created
July 16, 2024 19:32
-
-
Save Ilchert/1fd3d49c41f625322ec3ed00a849f08c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
// define BowlingGame Class in a new file | |
// define Frame Class in a new file | |
class MainClass | |
{ | |
static void Main() | |
{ | |
SomeGame(); | |
SpareGame(); | |
PerfectGame(); | |
//RandomGame(); | |
// code goes here | |
} | |
private static void SomeGame() // 119 | |
{ | |
var game = new BowlingGame(); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(5); | |
game.Roll(4); | |
game.Roll(3); | |
game.Roll(2); | |
game.Roll(1); | |
game.Roll(0); | |
game.Roll(10); | |
game.Roll(10); | |
game.Roll(10); | |
game.Roll(0); | |
game.Roll(0); | |
PrintResults(game); | |
} | |
private static void SpareGame() //150 | |
{ | |
var game = new BowlingGame(); | |
while (!game.Ended) | |
game.Roll(5); | |
PrintResults(game); | |
} | |
private static void PerfectGame() // 300 | |
{ | |
var game = new BowlingGame(); | |
while (!game.Ended) | |
game.Roll(10); | |
PrintResults(game); | |
} | |
private static void RandomGame() | |
{ | |
var game = new BowlingGame(); | |
while (!game.Ended) | |
{ | |
var pins = Random.Shared.Next(11); | |
game.Roll(pins); | |
Console.WriteLine($"Pins: {pins}"); | |
PrintResults(game); | |
} | |
} | |
private static void PrintResults(BowlingGame game) | |
{ | |
Console.WriteLine($"Total score: {game.Score()}"); | |
Console.WriteLine($"Scope for all strikes: {game.ScoreStrikes()}"); | |
Console.WriteLine($"Scope for all spares: {game.ScoreSpares()}"); | |
Console.WriteLine(); | |
} | |
class BowlingGame | |
{ | |
private const int MaxFrames = 10; | |
private List<Frame> _frames = new() { new Frame() }; | |
public bool Ended { get; private set; } | |
public void Roll(int pins) | |
{ | |
if (pins < 0 || pins > 10) | |
throw new ArgumentOutOfRangeException(); | |
if (Ended) | |
throw new InvalidOperationException("Game over"); | |
var lastFrame = _frames[^1]; | |
if (lastFrame.Ended && _frames.Count < MaxFrames) | |
{ | |
lastFrame = new Frame(); | |
_frames.Add(lastFrame); | |
} | |
_frames.ForEach(f => f.Roll(pins)); | |
if (lastFrame.TotalCalculated && _frames.Count == MaxFrames) | |
Ended = true; | |
} | |
public int Score() | |
{ | |
return _frames.Sum(p => p.Total); | |
} | |
public int ScoreStrikes() | |
{ | |
return _frames.Where(p => p.Type == FrameType.Strike).Sum(p => p.Total); | |
} | |
public int ScoreSpares() | |
{ | |
return _frames.Where(p => p.Type == FrameType.Spare).Sum(p => p.Total); | |
} | |
} | |
internal class Frame | |
{ | |
public int Total { get; private set; } | |
public FrameType Type { get; private set; } | |
public bool Ended { get; private set; } | |
public bool TotalCalculated { get => _state == FrameState.Completed; } | |
private FrameState _state; | |
private const int MaxPins = 10; | |
public void Roll(int pins) | |
{ | |
switch (_state) | |
{ | |
case FrameState.Completed: | |
return; | |
case FrameState.FirstRoll: | |
if (pins == MaxPins) | |
{ | |
_state = FrameState.StrikeBall1; | |
Type = FrameType.Strike; | |
Ended = true; | |
} | |
else | |
{ | |
_state = FrameState.SecondRoll; | |
} | |
break; | |
case FrameState.SecondRoll: | |
if (pins + Total == MaxPins) | |
{ | |
_state = FrameState.Spare; | |
Type = FrameType.Spare; | |
} | |
else | |
{ | |
_state = FrameState.Completed; | |
} | |
Ended = true; | |
break; | |
case FrameState.Spare: | |
_state = FrameState.Completed; | |
break; | |
case FrameState.StrikeBall1: | |
_state = FrameState.StrikeBall2; | |
break; | |
case FrameState.StrikeBall2: | |
_state = FrameState.Completed; | |
break; | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
Total += pins; | |
} | |
private enum FrameState | |
{ | |
FirstRoll, | |
SecondRoll, | |
Spare, | |
StrikeBall1, | |
StrikeBall2, | |
Completed | |
} | |
} | |
public enum FrameType | |
{ | |
Regular, | |
Spare, | |
Strike | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment