mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-21 23:00:43 -08:00
Bowling in csharp
This commit is contained in:
198
14_Bowling/csharp/Bowling.cs
Normal file
198
14_Bowling/csharp/Bowling.cs
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bowling
|
||||||
|
{
|
||||||
|
public class Bowling
|
||||||
|
{
|
||||||
|
private readonly Pins pins = new();
|
||||||
|
|
||||||
|
private int players;
|
||||||
|
|
||||||
|
public void Play()
|
||||||
|
{
|
||||||
|
ShowBanner();
|
||||||
|
MaybeShowInstructions();
|
||||||
|
Setup();
|
||||||
|
GameLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShowBanner()
|
||||||
|
{
|
||||||
|
Utility.PrintString(34, "BOWL");
|
||||||
|
Utility.PrintString(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||||
|
Utility.PrintString();
|
||||||
|
Utility.PrintString();
|
||||||
|
Utility.PrintString();
|
||||||
|
Utility.PrintString("WELCOME TO THE ALLEY");
|
||||||
|
Utility.PrintString("BRING YOUR FRIENDS");
|
||||||
|
Utility.PrintString("OKAY LET'S FIRST GET ACQUAINTED");
|
||||||
|
Utility.PrintString();
|
||||||
|
}
|
||||||
|
private static void MaybeShowInstructions()
|
||||||
|
{
|
||||||
|
Utility.PrintString("THE INSTRUCTIONS (Y/N)");
|
||||||
|
if (Utility.InputString() == "N") return;
|
||||||
|
Utility.PrintString("THE GAME OF BOWLING TAKES MIND AND SKILL.DURING THE GAME");
|
||||||
|
Utility.PrintString("THE COMPUTER WILL KEEP SCORE.YOU MAY COMPETE WITH");
|
||||||
|
Utility.PrintString("OTHER PLAYERS[UP TO FOUR].YOU WILL BE PLAYING TEN FRAMES");
|
||||||
|
Utility.PrintString("ON THE PIN DIAGRAM 'O' MEANS THE PIN IS DOWN...'+' MEANS THE");
|
||||||
|
Utility.PrintString("PIN IS STANDING.AFTER THE GAME THE COMPUTER WILL SHOW YOUR");
|
||||||
|
Utility.PrintString("SCORES .");
|
||||||
|
}
|
||||||
|
private void Setup()
|
||||||
|
{
|
||||||
|
Utility.PrintString("FIRST OF ALL...HOW MANY ARE PLAYING", false);
|
||||||
|
var input = Utility.InputInt();
|
||||||
|
players = input < 1 ? 1 : input;
|
||||||
|
Utility.PrintString();
|
||||||
|
Utility.PrintString("VERY GOOD...");
|
||||||
|
}
|
||||||
|
private void GameLoop()
|
||||||
|
{
|
||||||
|
GameResults[] gameResults = InitGameResults();
|
||||||
|
var done = false;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
ResetGameResults(gameResults);
|
||||||
|
for (int frame = 0; frame < GameResults.FramesPerGame; ++frame)
|
||||||
|
{
|
||||||
|
for (int player = 0; player < players; ++player)
|
||||||
|
{
|
||||||
|
pins.Reset();
|
||||||
|
int pinsDownThisFrame = pins.GetPinsDown();
|
||||||
|
|
||||||
|
int ball = 1;
|
||||||
|
while (ball == 1 || ball == 2) // One or two rolls
|
||||||
|
{
|
||||||
|
Utility.PrintString("TYPE ROLL TO GET THE BALL GOING.");
|
||||||
|
_ = Utility.InputString();
|
||||||
|
|
||||||
|
int pinsDownAfterRoll = pins.Roll();
|
||||||
|
ShowPins(player, frame, ball);
|
||||||
|
|
||||||
|
if (pinsDownAfterRoll == pinsDownThisFrame)
|
||||||
|
{
|
||||||
|
Utility.PrintString("GUTTER!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ball == 1)
|
||||||
|
{
|
||||||
|
// Store current pin count
|
||||||
|
gameResults[player].Results[frame].PinsBall1 = pinsDownAfterRoll;
|
||||||
|
|
||||||
|
// Special handling for strike
|
||||||
|
if (pinsDownAfterRoll == Pins.TotalPinCount)
|
||||||
|
{
|
||||||
|
Utility.PrintString("STRIKE!!!!!\a\a\a\a");
|
||||||
|
// No second roll
|
||||||
|
ball = 0;
|
||||||
|
gameResults[player].Results[frame].PinsBall2 = pinsDownAfterRoll;
|
||||||
|
gameResults[player].Results[frame].Score = FrameResult.Points.Strike;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ball = 2; // Roll again
|
||||||
|
Utility.PrintString("ROLL YOUR SECOND BALL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ball == 2)
|
||||||
|
{
|
||||||
|
// Store current pin count
|
||||||
|
gameResults[player].Results[frame].PinsBall2 = pinsDownAfterRoll;
|
||||||
|
ball = 0;
|
||||||
|
|
||||||
|
// Determine the score for the frame
|
||||||
|
if (pinsDownAfterRoll == Pins.TotalPinCount)
|
||||||
|
{
|
||||||
|
Utility.PrintString("SPARE!!!!");
|
||||||
|
gameResults[player].Results[frame].Score = FrameResult.Points.Spare;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utility.PrintString("ERROR!!!");
|
||||||
|
gameResults[player].Results[frame].Score = FrameResult.Points.Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Utility.PrintString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShowGameResults(gameResults);
|
||||||
|
Utility.PrintString("DO YOU WANT ANOTHER GAME");
|
||||||
|
var a = Utility.InputString();
|
||||||
|
done = a.Length == 0 || a[0] != 'Y';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameResults[] InitGameResults()
|
||||||
|
{
|
||||||
|
var gameResults = new GameResults[players];
|
||||||
|
for (int i = 0; i < gameResults.Length; i++)
|
||||||
|
{
|
||||||
|
gameResults[i] = new GameResults();
|
||||||
|
}
|
||||||
|
return gameResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowPins(int player, int frame, int ball)
|
||||||
|
{
|
||||||
|
Utility.PrintString($"FRAME: {frame + 1} PLAYER: {player + 1} BALL: {ball}");
|
||||||
|
var breakPins = new bool[] { true, false, false, false, true, false, false, true, false, true };
|
||||||
|
var indent = 0;
|
||||||
|
for (int pin = 0; pin < Pins.TotalPinCount; ++pin)
|
||||||
|
{
|
||||||
|
if (breakPins[pin])
|
||||||
|
{
|
||||||
|
Utility.PrintString(); // End row
|
||||||
|
Utility.PrintString(indent++, false); // Indent next row
|
||||||
|
}
|
||||||
|
var s = pins[pin] == Pins.State.Down ? "+ " : "o ";
|
||||||
|
Utility.PrintString(s, false);
|
||||||
|
}
|
||||||
|
Utility.PrintString();
|
||||||
|
Utility.PrintString();
|
||||||
|
}
|
||||||
|
private void ResetGameResults(GameResults[] gameResults)
|
||||||
|
{
|
||||||
|
foreach (var gameResult in gameResults)
|
||||||
|
{
|
||||||
|
foreach (var frameResult in gameResult.Results)
|
||||||
|
{
|
||||||
|
frameResult.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void ShowGameResults(GameResults[] gameResults)
|
||||||
|
{
|
||||||
|
Utility.PrintString("FRAMES");
|
||||||
|
for (int i = 0; i < GameResults.FramesPerGame; ++i)
|
||||||
|
{
|
||||||
|
Utility.PrintString(Utility.PadInt(i, 3), false);
|
||||||
|
}
|
||||||
|
Utility.PrintString();
|
||||||
|
foreach (var gameResult in gameResults)
|
||||||
|
{
|
||||||
|
foreach (var frameResult in gameResult.Results)
|
||||||
|
{
|
||||||
|
Utility.PrintString(Utility.PadInt(frameResult.PinsBall1, 3), false);
|
||||||
|
}
|
||||||
|
Utility.PrintString();
|
||||||
|
foreach (var frameResult in gameResult.Results)
|
||||||
|
{
|
||||||
|
Utility.PrintString(Utility.PadInt(frameResult.PinsBall2, 3), false);
|
||||||
|
}
|
||||||
|
Utility.PrintString();
|
||||||
|
foreach (var frameResult in gameResult.Results)
|
||||||
|
{
|
||||||
|
Utility.PrintString(Utility.PadInt((int)frameResult.Score, 3), false);
|
||||||
|
}
|
||||||
|
Utility.PrintString();
|
||||||
|
Utility.PrintString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
14_Bowling/csharp/FrameResult.cs
Normal file
23
14_Bowling/csharp/FrameResult.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bowling
|
||||||
|
{
|
||||||
|
public class FrameResult
|
||||||
|
{
|
||||||
|
public enum Points { None, Error, Spare, Strike };
|
||||||
|
|
||||||
|
public int PinsBall1 { get; set; }
|
||||||
|
public int PinsBall2 { get; set; }
|
||||||
|
public Points Score { get; set; }
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
PinsBall1 = PinsBall2 = 0;
|
||||||
|
Score = Points.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
14_Bowling/csharp/GameResults.cs
Normal file
23
14_Bowling/csharp/GameResults.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bowling
|
||||||
|
{
|
||||||
|
public class GameResults
|
||||||
|
{
|
||||||
|
public static readonly int FramesPerGame = 10;
|
||||||
|
public FrameResult[] Results { get; set; }
|
||||||
|
|
||||||
|
public GameResults()
|
||||||
|
{
|
||||||
|
Results = new FrameResult[FramesPerGame];
|
||||||
|
for (int i = 0; i < FramesPerGame; ++i)
|
||||||
|
{
|
||||||
|
Results[i] = new FrameResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
14_Bowling/csharp/Pins.cs
Normal file
56
14_Bowling/csharp/Pins.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bowling
|
||||||
|
{
|
||||||
|
public class Pins
|
||||||
|
{
|
||||||
|
public enum State { Up, Down };
|
||||||
|
public static readonly int TotalPinCount = 10;
|
||||||
|
private readonly Random random = new();
|
||||||
|
|
||||||
|
private State[] PinSet { get; set; }
|
||||||
|
|
||||||
|
public Pins()
|
||||||
|
{
|
||||||
|
PinSet = new State[TotalPinCount];
|
||||||
|
}
|
||||||
|
public State this[int i]
|
||||||
|
{
|
||||||
|
get { return PinSet[i]; }
|
||||||
|
set { PinSet[i] = value; }
|
||||||
|
}
|
||||||
|
public int Roll()
|
||||||
|
{
|
||||||
|
// REM ARK BALL GENERATOR USING MOD '15' SYSTEM
|
||||||
|
for (int i = 0; i < 20; ++i)
|
||||||
|
{
|
||||||
|
var x = random.Next(100) + 1;
|
||||||
|
int j;
|
||||||
|
for (j = 1; j <= 10; ++j)
|
||||||
|
{
|
||||||
|
if (x < 15 * j)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var pindex = 15 * j - x;
|
||||||
|
if (pindex > 0 && pindex <= TotalPinCount)
|
||||||
|
PinSet[--pindex] = State.Down;
|
||||||
|
}
|
||||||
|
return GetPinsDown();
|
||||||
|
}
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < PinSet.Length; ++i)
|
||||||
|
{
|
||||||
|
PinSet[i] = State.Up;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int GetPinsDown()
|
||||||
|
{
|
||||||
|
return PinSet.Count(p => p == State.Down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
14_Bowling/csharp/Program.cs
Normal file
16
14_Bowling/csharp/Program.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bowling
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
new Bowling().Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
14_Bowling/csharp/Utility.cs
Normal file
54
14_Bowling/csharp/Utility.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bowling
|
||||||
|
{
|
||||||
|
internal static class Utility
|
||||||
|
{
|
||||||
|
public static string PadInt(int value, int width)
|
||||||
|
{
|
||||||
|
return value.ToString().PadLeft(width);
|
||||||
|
}
|
||||||
|
public static int InputInt()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (int.TryParse(InputString(), out int i))
|
||||||
|
return i;
|
||||||
|
else
|
||||||
|
PrintString("!NUMBER EXPECTED - RETRY INPUT LINE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static string InputString()
|
||||||
|
{
|
||||||
|
PrintString("? ", false);
|
||||||
|
var input = Console.ReadLine();
|
||||||
|
return input == null ? string.Empty : input.ToUpper();
|
||||||
|
}
|
||||||
|
public static void PrintInt(int value, bool newLine = false)
|
||||||
|
{
|
||||||
|
PrintString($"{value} ", newLine);
|
||||||
|
}
|
||||||
|
public static void PrintString(bool newLine = true)
|
||||||
|
{
|
||||||
|
PrintString(0, string.Empty);
|
||||||
|
}
|
||||||
|
public static void PrintString(int tab, bool newLine = true)
|
||||||
|
{
|
||||||
|
PrintString(tab, string.Empty, newLine);
|
||||||
|
}
|
||||||
|
public static void PrintString(string value, bool newLine = true)
|
||||||
|
{
|
||||||
|
PrintString(0, value, newLine);
|
||||||
|
}
|
||||||
|
public static void PrintString(int tab, string value, bool newLine = true)
|
||||||
|
{
|
||||||
|
Console.Write(new String(' ', tab));
|
||||||
|
Console.Write(value);
|
||||||
|
if (newLine) Console.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user