Merge branch 'coding-horror:main' into main

This commit is contained in:
Steve Bosman
2022-02-06 22:41:14 +00:00
committed by GitHub
9 changed files with 498 additions and 0 deletions

View 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();
}
}
}
}

View 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;
}
}
}

View 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
View 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);
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bunny
{
internal class BasicData
{
private readonly int[] data;
private int index;
public BasicData(int[] data)
{
this.data = data;
index = 0;
}
public int Read()
{
return data[index++];
}
}
}

87
19_Bunny/csharp/Bunny.cs Normal file
View File

@@ -0,0 +1,87 @@
namespace Bunny
{
internal class Bunny
{
private const int asciiBase = 64;
private readonly int[] bunnyData = {
2,21,14,14,25,
1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1,
1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1,
5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1,
9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1,
13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1,
19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1,
8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1,
4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1,
2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1,
14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1,
14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1,
12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1,
10,11,17,18,22,22,24,24,29,29,-1,
22,23,26,29,-1,27,29,-1,28,29,-1,4096
};
public void Run()
{
PrintString(33, "BUNNY");
PrintString(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
PrintLines(3);
// Set up a BASIC-ish data object
BasicData data = new (bunnyData);
// Get the first five data values into an array.
// These are the characters we are going to print.
// Unlike the original program, we are only converting
// them to ASCII once.
var a = new char[5];
for (var i = 0; i < 5; ++i)
{
a[i] = (char)(asciiBase + data.Read());
}
PrintLines(6);
PrintLines(1);
var col = 0;
while (true)
{
var x = data.Read();
if (x < 0) // Start a new line
{
PrintLines(1);
col = 0;
continue;
}
if (x > 128) break; // End processing
col += PrintSpaces(x - col); // Move to TAB position x (sort of)
var y = data.Read(); // Read the next value
for (var i = x; i <= y; ++i)
{
// var j = i - 5 * (i / 5); // BASIC didn't have a modulus operator
Console.Write(a[i % 5]);
// Console.Write(a[col % 5]); // This works, too
++col;
}
}
PrintLines(6);
}
private static void PrintLines(int count)
{
for (var i = 0; i < count; ++i)
Console.WriteLine();
}
private static int PrintSpaces(int count)
{
for (var i = 0; i < count; ++i)
Console.Write(' ');
return count;
}
public static void PrintString(int tab, string value, bool newLine = true)
{
PrintSpaces(tab);
Console.Write(value);
if (newLine) Console.WriteLine();
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bunny
{
public static class Program
{
public static void Main()
{
new Bunny().Run();
}
}
}