mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 07:29:02 -08:00
Ported Depth Charge to C#
This commit is contained in:
25
31 Depth Charge/csharp/DepthCharge.sln
Normal file
25
31 Depth Charge/csharp/DepthCharge.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.31129.286
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Game", "Game.csproj", "{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{CBC9D8D9-9EDE-4D34-A20E-C90D929ABF8F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {738F08DD-89E9-44C5-B5AC-3F21C6AEEFA1}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
9
31 Depth Charge/csharp/Game.csproj
Normal file
9
31 Depth Charge/csharp/Game.csproj
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<RootNamespace>DepthCharge</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
85
31 Depth Charge/csharp/src/Controller.cs
Normal file
85
31 Depth Charge/csharp/src/Controller.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DepthCharge
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains functions for reading input from the user.
|
||||||
|
/// </summary>
|
||||||
|
static class Controller
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Retrives a dimension for the play area from the user.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Note that the original BASIC version would allow dimension values
|
||||||
|
/// of 0 or less. We're doing a little extra validation here in order
|
||||||
|
/// to avoid strange behaviour.
|
||||||
|
/// </remarks>
|
||||||
|
public static int InputDimension()
|
||||||
|
{
|
||||||
|
View.PromptDimension();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!Int32.TryParse(Console.ReadLine(), out var dimension))
|
||||||
|
View.ShowInvalidNumber();
|
||||||
|
else
|
||||||
|
if (dimension < 1)
|
||||||
|
View.ShowInvalidDimension();
|
||||||
|
else
|
||||||
|
return dimension;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a set of coordinates from the user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trailNumber">
|
||||||
|
/// The current trail number.
|
||||||
|
/// </param>
|
||||||
|
public static (int x, int y, int depth) InputCoordinates(int trailNumber)
|
||||||
|
{
|
||||||
|
View.PromptGuess(trailNumber);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var coordinates = Console.ReadLine().Split(',');
|
||||||
|
|
||||||
|
if (coordinates.Length < 3)
|
||||||
|
View.ShowTooFewCoordinates();
|
||||||
|
else
|
||||||
|
if (coordinates.Length > 3)
|
||||||
|
View.ShowTooManyCoordinates();
|
||||||
|
else
|
||||||
|
if (!Int32.TryParse(coordinates[0], out var x) ||
|
||||||
|
!Int32.TryParse(coordinates[1], out var y) ||
|
||||||
|
!Int32.TryParse(coordinates[2], out var depth))
|
||||||
|
View.ShowInvalidNumber();
|
||||||
|
else
|
||||||
|
return (x, y, depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the user's intention to play again (or not).
|
||||||
|
/// </summary>
|
||||||
|
public static bool InputPlayAgain()
|
||||||
|
{
|
||||||
|
View.PromptPlayAgain();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch (Console.ReadLine())
|
||||||
|
{
|
||||||
|
case "Y":
|
||||||
|
return true;
|
||||||
|
case "N":
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
View.ShowInvalidYesOrNo();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
31 Depth Charge/csharp/src/Program.cs
Normal file
47
31 Depth Charge/csharp/src/Program.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DepthCharge
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var random = new Random();
|
||||||
|
|
||||||
|
View.ShowBanner();
|
||||||
|
|
||||||
|
var dimension = Controller.InputDimension();
|
||||||
|
var maximumGuesses = CalculateMaximumGuesses();
|
||||||
|
|
||||||
|
View.ShowInstructions(maximumGuesses);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
View.ShowStartGame();
|
||||||
|
|
||||||
|
var submarineCoordinates = PlaceSubmarine();
|
||||||
|
var trailNumber = 1;
|
||||||
|
var guess = (0, 0, 0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
guess = Controller.InputCoordinates(trailNumber);
|
||||||
|
if (guess != submarineCoordinates)
|
||||||
|
View.ShowGuessPlacement(submarineCoordinates, guess);
|
||||||
|
}
|
||||||
|
while (guess != submarineCoordinates && trailNumber++ < maximumGuesses);
|
||||||
|
|
||||||
|
View.ShowGameResult(submarineCoordinates, guess, trailNumber);
|
||||||
|
}
|
||||||
|
while (Controller.InputPlayAgain());
|
||||||
|
|
||||||
|
View.ShowFarewell();
|
||||||
|
|
||||||
|
int CalculateMaximumGuesses() =>
|
||||||
|
(int)Math.Log2(dimension) + 1;
|
||||||
|
|
||||||
|
(int x, int y, int depth) PlaceSubmarine() =>
|
||||||
|
(random.Next(dimension), random.Next(dimension), random.Next(dimension));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
121
31 Depth Charge/csharp/src/View.cs
Normal file
121
31 Depth Charge/csharp/src/View.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DepthCharge
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains methods for displaying information to the user.
|
||||||
|
/// </summary>
|
||||||
|
static class View
|
||||||
|
{
|
||||||
|
public static void ShowBanner()
|
||||||
|
{
|
||||||
|
Console.WriteLine(" DEPTH CHARGE");
|
||||||
|
Console.WriteLine(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowInstructions(int maximumGuesses)
|
||||||
|
{
|
||||||
|
Console.WriteLine("YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER");
|
||||||
|
Console.WriteLine("AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR");
|
||||||
|
Console.WriteLine($"MISSION IS TO DESTROY IT. YOU HAVE {maximumGuesses} SHOTS.");
|
||||||
|
Console.WriteLine("SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A");
|
||||||
|
Console.WriteLine("TRIO OF NUMBERS -- THE FIRST TWO ARE THE");
|
||||||
|
Console.WriteLine("SURFACE COORDINATES; THE THIRD IS THE DEPTH.");
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowStartGame()
|
||||||
|
{
|
||||||
|
Console.WriteLine("GOOD LUCK !");
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowGuessPlacement((int x, int y, int depth) actual, (int x, int y, int depth) guess)
|
||||||
|
{
|
||||||
|
Console.Write("SONAR REPORTS SHOT WAS ");
|
||||||
|
if (guess.y > actual.y)
|
||||||
|
Console.Write("NORTH");
|
||||||
|
if (guess.y < actual.y)
|
||||||
|
Console.Write("SOUTH");
|
||||||
|
if (guess.x > actual.x)
|
||||||
|
Console.Write("EAST");
|
||||||
|
if (guess.x < actual.x)
|
||||||
|
Console.Write("WEST");
|
||||||
|
if (guess.y != actual.y || guess.x != actual.y)
|
||||||
|
Console.Write(" AND");
|
||||||
|
if (guess.depth > actual.depth)
|
||||||
|
Console.Write (" TOO LOW.");
|
||||||
|
if (guess.depth < actual.depth)
|
||||||
|
Console.Write(" TOO HIGH.");
|
||||||
|
if (guess.depth == actual.depth)
|
||||||
|
Console.Write(" DEPTH OK.");
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowGameResult((int x, int y, int depth) submarineLocation, (int x, int y, int depth) finalGuess, int trailNumber)
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
if (submarineLocation == finalGuess)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"B O O M ! ! YOU FOUND IT IN {trailNumber} TRIES!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!");
|
||||||
|
Console.WriteLine($"THE SUBMARINE WAS AT {submarineLocation.x}, {submarineLocation.y}, {submarineLocation.depth}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowFarewell()
|
||||||
|
{
|
||||||
|
Console.WriteLine ("OK. HOPE YOU ENJOYED YOURSELF.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowInvalidNumber()
|
||||||
|
{
|
||||||
|
Console.WriteLine("PLEASE ENTER A NUMBER");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowInvalidDimension()
|
||||||
|
{
|
||||||
|
Console.WriteLine("PLEASE ENTER A VALID DIMENSION");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowTooFewCoordinates()
|
||||||
|
{
|
||||||
|
Console.WriteLine("TOO FEW COORDINATES");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowTooManyCoordinates()
|
||||||
|
{
|
||||||
|
Console.WriteLine("TOO MANY COORDINATES");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowInvalidYesOrNo()
|
||||||
|
{
|
||||||
|
Console.WriteLine("PLEASE ENTER Y OR N");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PromptDimension()
|
||||||
|
{
|
||||||
|
Console.Write("DIMENSION OF SEARCH AREA? ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PromptGuess(int trailNumber)
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.Write($"TRIAL #{trailNumber}? ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PromptPlayAgain()
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.Write("ANOTHER GAME (Y OR N)? ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user