mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
Merge branch 'coding-horror:main' into main
This commit is contained in:
@@ -17,3 +17,4 @@ http://www.vintage-basic.net/games.html
|
||||
|
||||
#### External Links
|
||||
- Common Lisp: https://github.com/koalahedron/lisp-computer-games/blob/master/01%20Acey%20Ducey/common-lisp/acey-deucy.lisp
|
||||
- PowerShell: https://github.com/eweilnau/basic-computer-games-powershell/blob/main/AceyDucey.ps1
|
||||
|
||||
48
15_Boxing/csharp/AttackStrategy.cs
Normal file
48
15_Boxing/csharp/AttackStrategy.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace Boxing;
|
||||
|
||||
public abstract class AttackStrategy
|
||||
{
|
||||
protected const int KnockoutDamageThreshold = 35;
|
||||
protected readonly Boxer Other;
|
||||
protected readonly Stack<Action> Work;
|
||||
private readonly Action _notifyGameEnded;
|
||||
|
||||
public AttackStrategy(Boxer other, Stack<Action> work, Action notifyGameEnded)
|
||||
{
|
||||
Other = other;
|
||||
Work = work;
|
||||
_notifyGameEnded = notifyGameEnded;
|
||||
}
|
||||
|
||||
public void Attack()
|
||||
{
|
||||
var punch = GetPunch();
|
||||
if (punch.IsBestPunch)
|
||||
{
|
||||
Other.DamageTaken += 2;
|
||||
}
|
||||
|
||||
Work.Push(punch.Punch switch
|
||||
{
|
||||
Punch.FullSwing => FullSwing,
|
||||
Punch.Hook => Hook,
|
||||
Punch.Uppercut => Uppercut,
|
||||
_ => Jab
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract AttackPunch GetPunch();
|
||||
protected abstract void FullSwing();
|
||||
protected abstract void Hook();
|
||||
protected abstract void Uppercut();
|
||||
protected abstract void Jab();
|
||||
|
||||
protected void RegisterKnockout(string knockoutMessage)
|
||||
{
|
||||
Work.Clear();
|
||||
_notifyGameEnded();
|
||||
Console.WriteLine(knockoutMessage);
|
||||
}
|
||||
|
||||
protected record AttackPunch(Punch Punch, bool IsBestPunch);
|
||||
}
|
||||
45
15_Boxing/csharp/Boxer.cs
Normal file
45
15_Boxing/csharp/Boxer.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace Boxing;
|
||||
|
||||
public class Boxer
|
||||
{
|
||||
private int _wins;
|
||||
|
||||
private string Name { get; set; } = string.Empty;
|
||||
|
||||
public Punch BestPunch { get; set; }
|
||||
|
||||
public Punch Vulnerability { get; set; }
|
||||
|
||||
public void SetName(string prompt)
|
||||
{
|
||||
Console.WriteLine(prompt);
|
||||
string? name;
|
||||
do
|
||||
{
|
||||
name = Console.ReadLine();
|
||||
} while (string.IsNullOrWhiteSpace(name));
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public int DamageTaken { get; set; }
|
||||
|
||||
public void ResetForNewRound() => DamageTaken = 0;
|
||||
|
||||
public void RecordWin() => _wins += 1;
|
||||
|
||||
public bool IsWinner => _wins >= 2;
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
|
||||
public class Opponent : Boxer
|
||||
{
|
||||
public void SetRandomPunches()
|
||||
{
|
||||
do
|
||||
{
|
||||
BestPunch = (Punch) GameUtils.Roll(4); // B1
|
||||
Vulnerability = (Punch) GameUtils.Roll(4); // D1
|
||||
} while (BestPunch == Vulnerability);
|
||||
}
|
||||
}
|
||||
10
15_Boxing/csharp/Boxing.csproj
Normal file
10
15_Boxing/csharp/Boxing.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
22
15_Boxing/csharp/Boxing.sln
Normal file
22
15_Boxing/csharp/Boxing.sln
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30114.105
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boxing", "Boxing.csproj", "{52A7BDE5-3085-4F58-AC57-2BA4E65212D8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{52A7BDE5-3085-4F58-AC57-2BA4E65212D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
115
15_Boxing/csharp/OpponentAttackStrategy.cs
Normal file
115
15_Boxing/csharp/OpponentAttackStrategy.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using static Boxing.GameUtils;
|
||||
using static System.Console;
|
||||
|
||||
namespace Boxing;
|
||||
|
||||
public class OpponentAttackStrategy : AttackStrategy
|
||||
{
|
||||
private readonly Opponent _opponent;
|
||||
|
||||
public OpponentAttackStrategy(Opponent opponent, Boxer player, Action notifyGameEnded, Stack<Action> work) : base(player, work, notifyGameEnded)
|
||||
{
|
||||
_opponent = opponent;
|
||||
}
|
||||
|
||||
protected override AttackPunch GetPunch()
|
||||
{
|
||||
var punch = (Punch)Roll(4);
|
||||
return new AttackPunch(punch, punch == _opponent.BestPunch);
|
||||
}
|
||||
|
||||
protected override void FullSwing() // 720
|
||||
{
|
||||
Write($"{_opponent} TAKES A FULL SWING AND");
|
||||
if (Other.Vulnerability == Punch.FullSwing)
|
||||
{
|
||||
ScoreFullSwing();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(60, x => x < 30))
|
||||
{
|
||||
WriteLine(" IT'S BLOCKED!");
|
||||
}
|
||||
else
|
||||
{
|
||||
ScoreFullSwing();
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreFullSwing()
|
||||
{
|
||||
WriteLine(" POW!!!!! HE HITS HIM RIGHT IN THE FACE!");
|
||||
if (Other.DamageTaken > KnockoutDamageThreshold)
|
||||
{
|
||||
Work.Push(RegisterOtherKnockedOut);
|
||||
}
|
||||
Other.DamageTaken += 15;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Hook() // 810
|
||||
{
|
||||
Write($"{_opponent} GETS {Other} IN THE JAW (OUCH!)");
|
||||
Other.DamageTaken += 7;
|
||||
WriteLine("....AND AGAIN!");
|
||||
Other.DamageTaken += 5;
|
||||
if (Other.DamageTaken > KnockoutDamageThreshold)
|
||||
{
|
||||
Work.Push(RegisterOtherKnockedOut);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Uppercut() // 860
|
||||
{
|
||||
Write($"{Other} IS ATTACKED BY AN UPPERCUT (OH,OH)...");
|
||||
if (Other.Vulnerability == Punch.Uppercut)
|
||||
{
|
||||
ScoreUppercut();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(200, x => x > 75))
|
||||
{
|
||||
WriteLine($" BLOCKS AND HITS {_opponent} WITH A HOOK.");
|
||||
_opponent.DamageTaken += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScoreUppercut();
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreUppercut()
|
||||
{
|
||||
WriteLine($"AND {_opponent} CONNECTS...");
|
||||
Other.DamageTaken += 8;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Jab() // 640
|
||||
{
|
||||
Write($"{_opponent} JABS AND ");
|
||||
if (Other.Vulnerability == Punch.Jab)
|
||||
{
|
||||
ScoreJab();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(7, x => x > 4))
|
||||
{
|
||||
WriteLine("BLOOD SPILLS !!!");
|
||||
ScoreJab();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("IT'S BLOCKED!");
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreJab() => Other.DamageTaken += 5;
|
||||
}
|
||||
|
||||
private void RegisterOtherKnockedOut()
|
||||
=> RegisterKnockout($"{Other} IS KNOCKED COLD AND {_opponent} IS THE WINNER AND CHAMP!");
|
||||
}
|
||||
121
15_Boxing/csharp/PlayerAttackStrategy.cs
Normal file
121
15_Boxing/csharp/PlayerAttackStrategy.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using static Boxing.GameUtils;
|
||||
using static System.Console;
|
||||
namespace Boxing;
|
||||
|
||||
public class PlayerAttackStrategy : AttackStrategy
|
||||
{
|
||||
private readonly Boxer _player;
|
||||
|
||||
public PlayerAttackStrategy(Boxer player, Opponent opponent, Action notifyGameEnded, Stack<Action> work)
|
||||
: base(opponent, work, notifyGameEnded) => _player = player;
|
||||
|
||||
protected override AttackPunch GetPunch()
|
||||
{
|
||||
var punch = GameUtils.GetPunch($"{_player}'S PUNCH");
|
||||
return new AttackPunch(punch, punch == _player.BestPunch);
|
||||
}
|
||||
|
||||
protected override void FullSwing() // 340
|
||||
{
|
||||
Write($"{_player} SWINGS AND ");
|
||||
if (Other.Vulnerability == Punch.FullSwing)
|
||||
{
|
||||
ScoreFullSwing();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(30, x => x < 10))
|
||||
{
|
||||
ScoreFullSwing();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("HE MISSES");
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreFullSwing()
|
||||
{
|
||||
WriteLine("HE CONNECTS!");
|
||||
if (Other.DamageTaken > KnockoutDamageThreshold)
|
||||
{
|
||||
Work.Push(() => RegisterKnockout($"{Other} IS KNOCKED COLD AND {_player} IS THE WINNER AND CHAMP!"));
|
||||
}
|
||||
Other.DamageTaken += 15;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Uppercut() // 520
|
||||
{
|
||||
Write($"{_player} TRIES AN UPPERCUT ");
|
||||
if (Other.Vulnerability == Punch.Uppercut)
|
||||
{
|
||||
ScoreUpperCut();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(100, x => x < 51))
|
||||
{
|
||||
ScoreUpperCut();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("AND IT'S BLOCKED (LUCKY BLOCK!)");
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreUpperCut()
|
||||
{
|
||||
WriteLine("AND HE CONNECTS!");
|
||||
Other.DamageTaken += 4;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Hook() // 450
|
||||
{
|
||||
Write($"{_player} GIVES THE HOOK... ");
|
||||
if (Other.Vulnerability == Punch.Hook)
|
||||
{
|
||||
ScoreHookOnOpponent();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(2, x => x == 1))
|
||||
{
|
||||
WriteLine("BUT IT'S BLOCKED!!!!!!!!!!!!!");
|
||||
}
|
||||
else
|
||||
{
|
||||
ScoreHookOnOpponent();
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreHookOnOpponent()
|
||||
{
|
||||
WriteLine("CONNECTS...");
|
||||
Other.DamageTaken += 7;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Jab()
|
||||
{
|
||||
WriteLine($"{_player} JABS AT {Other}'S HEAD");
|
||||
if (Other.Vulnerability == Punch.Jab)
|
||||
{
|
||||
ScoreJabOnOpponent();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RollSatisfies(8, x => x < 4))
|
||||
{
|
||||
WriteLine("IT'S BLOCKED.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ScoreJabOnOpponent();
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreJabOnOpponent() => Other.DamageTaken += 3;
|
||||
}
|
||||
}
|
||||
29
15_Boxing/csharp/Program.cs
Normal file
29
15_Boxing/csharp/Program.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Boxing;
|
||||
using static Boxing.GameUtils;
|
||||
using static System.Console;
|
||||
|
||||
WriteLine(new string('\t', 33) + "BOXING");
|
||||
WriteLine(new string('\t', 15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||
WriteLine("{0}{0}{0}BOXING OLYMPIC STYLE (3 ROUNDS -- 2 OUT OF 3 WINS){0}", Environment.NewLine);
|
||||
|
||||
var opponent = new Opponent();
|
||||
opponent.SetName("WHAT IS YOUR OPPONENT'S NAME"); // J$
|
||||
var player = new Boxer();
|
||||
player.SetName("INPUT YOUR MAN'S NAME"); // L$
|
||||
|
||||
PrintPunchDescription();
|
||||
player.BestPunch = GetPunch("WHAT IS YOUR MANS BEST"); // B
|
||||
player.Vulnerability = GetPunch("WHAT IS HIS VULNERABILITY"); // D
|
||||
opponent.SetRandomPunches();
|
||||
WriteLine($"{opponent}'S ADVANTAGE IS {opponent.BestPunch.ToFriendlyString()} AND VULNERABILITY IS SECRET.");
|
||||
|
||||
|
||||
for (var i = 1; i <= 3; i ++) // R
|
||||
{
|
||||
var round = new Round(player, opponent, i);
|
||||
round.Start();
|
||||
round.CheckOpponentWin();
|
||||
round.CheckPlayerWin();
|
||||
if (round.GameEnded) break;
|
||||
}
|
||||
WriteLine("{0}{0}AND NOW GOODBYE FROM THE OLYMPIC ARENA.{0}", Environment.NewLine);
|
||||
9
15_Boxing/csharp/Punch.cs
Normal file
9
15_Boxing/csharp/Punch.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Boxing;
|
||||
|
||||
public enum Punch
|
||||
{
|
||||
FullSwing = 1,
|
||||
Hook = 2,
|
||||
Uppercut = 3,
|
||||
Jab = 4
|
||||
}
|
||||
96
15_Boxing/csharp/Round.cs
Normal file
96
15_Boxing/csharp/Round.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
namespace Boxing;
|
||||
|
||||
class Round
|
||||
{
|
||||
|
||||
private readonly Boxer _player;
|
||||
private readonly Boxer _opponent;
|
||||
private readonly int _round;
|
||||
private Stack<Action> _work = new();
|
||||
private readonly PlayerAttackStrategy _playerAttackStrategy;
|
||||
private readonly OpponentAttackStrategy _opponentAttackStrategy;
|
||||
|
||||
public bool GameEnded { get; private set; }
|
||||
|
||||
public Round(Boxer player, Opponent opponent, int round)
|
||||
{
|
||||
_player = player;
|
||||
_opponent = opponent;
|
||||
_round = round;
|
||||
_work.Push(ResetPlayers);
|
||||
_work.Push(CheckOpponentWin);
|
||||
_work.Push(CheckPlayerWin);
|
||||
|
||||
void NotifyGameEnded() => GameEnded = true;
|
||||
_playerAttackStrategy = new PlayerAttackStrategy(player, opponent, NotifyGameEnded, _work);
|
||||
_opponentAttackStrategy = new OpponentAttackStrategy(opponent, player, NotifyGameEnded, _work);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
while (_work.Count > 0)
|
||||
{
|
||||
var action = _work.Pop();
|
||||
// This delay does not exist in the VB code but it makes a bit easier to follow the game.
|
||||
// I assume the computers at the time were slow enough
|
||||
// so that they did not need this delay...
|
||||
Thread.Sleep(300);
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckOpponentWin()
|
||||
{
|
||||
if (_opponent.IsWinner)
|
||||
{
|
||||
Console.WriteLine($"{_opponent} WINS (NICE GOING, {_opponent}).");
|
||||
GameEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckPlayerWin()
|
||||
{
|
||||
if (_player.IsWinner)
|
||||
{
|
||||
Console.WriteLine($"{_player} AMAZINGLY WINS!!");
|
||||
GameEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetPlayers()
|
||||
{
|
||||
_player.ResetForNewRound();
|
||||
_opponent.ResetForNewRound();
|
||||
_work.Push(RoundBegins);
|
||||
}
|
||||
|
||||
private void RoundBegins()
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"ROUND {_round} BEGINS...");
|
||||
_work.Push(CheckRoundWinner);
|
||||
for (var i = 0; i < 7; i++)
|
||||
{
|
||||
_work.Push(DecideWhoAttacks);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckRoundWinner()
|
||||
{
|
||||
if (_opponent.DamageTaken > _player.DamageTaken)
|
||||
{
|
||||
Console.WriteLine($"{_player} WINS ROUND {_round}");
|
||||
_player.RecordWin();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{_opponent} WINS ROUND {_round}");
|
||||
_opponent.RecordWin();
|
||||
}
|
||||
}
|
||||
|
||||
private void DecideWhoAttacks()
|
||||
{
|
||||
_work.Push( GameUtils.RollSatisfies(10, x => x > 5) ? _opponentAttackStrategy.Attack : _playerAttackStrategy.Attack );
|
||||
}
|
||||
}
|
||||
35
15_Boxing/csharp/Utils.cs
Normal file
35
15_Boxing/csharp/Utils.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace Boxing;
|
||||
public static class GameUtils
|
||||
{
|
||||
private static readonly Random Rnd = new((int) DateTime.UtcNow.Ticks);
|
||||
public static void PrintPunchDescription() =>
|
||||
Console.WriteLine($"DIFFERENT PUNCHES ARE: {PunchDesc(Punch.FullSwing)}; {PunchDesc(Punch.Hook)}; {PunchDesc(Punch.Uppercut)}; {PunchDesc(Punch.Jab)}.");
|
||||
|
||||
private static string PunchDesc(Punch punch) => $"({(int)punch}) {punch.ToFriendlyString()}";
|
||||
|
||||
public static Punch GetPunch(string prompt)
|
||||
{
|
||||
Console.WriteLine(prompt);
|
||||
Punch result;
|
||||
while (!Enum.TryParse(Console.ReadLine(), out result) || !Enum.IsDefined(typeof(Punch), result))
|
||||
{
|
||||
PrintPunchDescription();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Func<int, int> Roll { get; } = upperLimit => (int) (upperLimit * Rnd.NextSingle()) + 1;
|
||||
|
||||
public static bool RollSatisfies(int upperLimit, Predicate<int> predicate) => predicate(Roll(upperLimit));
|
||||
|
||||
public static string ToFriendlyString(this Punch punch)
|
||||
=> punch switch
|
||||
{
|
||||
Punch.FullSwing => "FULL SWING",
|
||||
Punch.Hook => "HOOK",
|
||||
Punch.Uppercut => "UPPERCUT",
|
||||
Punch.Jab => "JAB",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(punch), punch, null)
|
||||
};
|
||||
|
||||
}
|
||||
197
36_Flip_Flop/csharp/FlipFlop.cs
Normal file
197
36_Flip_Flop/csharp/FlipFlop.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
// Flip Flop Game
|
||||
|
||||
PrintGameInfo();
|
||||
|
||||
bool startNewGame = true;
|
||||
|
||||
string[] board = new string[] { "X", "X", "X", "X", "X", "X", "X", "X", "X", "X" };
|
||||
|
||||
do
|
||||
{
|
||||
int stepsCount = 0;
|
||||
int lastMove = -1;
|
||||
int moveIndex;
|
||||
int gameSum;
|
||||
double gameEntropyRate = Rnd();
|
||||
bool toPlay = false;
|
||||
bool setNewBoard = true;
|
||||
|
||||
Print();
|
||||
Print("HERE IS THE STARTING LINE OF X'S.");
|
||||
Print();
|
||||
|
||||
do
|
||||
{
|
||||
bool illegalEntry;
|
||||
bool equalToLastMove;
|
||||
|
||||
if (setNewBoard)
|
||||
{
|
||||
PrintNewBoard();
|
||||
board = new string[] { "X", "X", "X", "X", "X", "X", "X", "X", "X", "X" };
|
||||
setNewBoard = false;
|
||||
toPlay = true;
|
||||
}
|
||||
|
||||
stepsCount++;
|
||||
gameSum = 0;
|
||||
|
||||
// Read User's move
|
||||
do
|
||||
{
|
||||
Write("INPUT THE NUMBER? ");
|
||||
var input = Console.ReadLine();
|
||||
illegalEntry = !int.TryParse(input, out moveIndex);
|
||||
|
||||
if (illegalEntry || moveIndex > 11)
|
||||
{
|
||||
illegalEntry = true;
|
||||
Print("ILLEGAL ENTRY--TRY AGAIN.");
|
||||
}
|
||||
}
|
||||
while (illegalEntry);
|
||||
|
||||
if (moveIndex == 11)
|
||||
{
|
||||
// Run new game, To start a new game at any point
|
||||
toPlay = false;
|
||||
stepsCount = 12;
|
||||
startNewGame = true;
|
||||
}
|
||||
|
||||
|
||||
if (moveIndex == 0)
|
||||
{
|
||||
// To reset the line to all X, same game
|
||||
setNewBoard = true;
|
||||
toPlay = false;
|
||||
}
|
||||
|
||||
if (toPlay)
|
||||
{
|
||||
board[moveIndex - 1] = board[moveIndex - 1] == "O" ? "X" : "O";
|
||||
|
||||
if (lastMove == moveIndex)
|
||||
{
|
||||
equalToLastMove = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
equalToLastMove = false;
|
||||
lastMove = moveIndex;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
moveIndex = equalToLastMove
|
||||
? GetMoveIndexWhenEqualeLastMove(moveIndex, gameEntropyRate)
|
||||
: GetMoveIndex(moveIndex, gameEntropyRate);
|
||||
|
||||
board[moveIndex] = board[moveIndex] == "O" ? "X" : "O";
|
||||
}
|
||||
while (lastMove == moveIndex && board[moveIndex] == "X");
|
||||
|
||||
PrintGameBoard(board);
|
||||
|
||||
foreach (var item in board)
|
||||
{
|
||||
if (item == "O")
|
||||
{
|
||||
gameSum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (stepsCount < 12 && gameSum < 10);
|
||||
|
||||
if (toPlay)
|
||||
{
|
||||
PrintGameResult(gameSum, stepsCount);
|
||||
|
||||
Write("DO YOU WANT TO TRY ANOTHER PUZZLE ");
|
||||
|
||||
var toContinue = Console.ReadLine();
|
||||
|
||||
if (!string.IsNullOrEmpty(toContinue) && toContinue?.ToUpper()[0] == 'N')
|
||||
{
|
||||
startNewGame = false;
|
||||
}
|
||||
|
||||
Print();
|
||||
}
|
||||
}
|
||||
while (startNewGame);
|
||||
|
||||
void Print(string str = "") => Console.WriteLine(str);
|
||||
|
||||
void Write(string value) => Console.Write(value);
|
||||
|
||||
string Tab(int pos) => new(' ', pos);
|
||||
|
||||
double Rnd() => new Random().NextDouble();
|
||||
|
||||
int GetMoveIndex(int moveIndex, double gameEntropyRate)
|
||||
{
|
||||
double rate = Math.Tan(gameEntropyRate + moveIndex / gameEntropyRate - moveIndex) - Math.Sin(gameEntropyRate / moveIndex) + 336 * Math.Sin(8 * moveIndex);
|
||||
return Convert.ToInt32(Math.Floor(10 * (rate - Math.Floor(rate))));
|
||||
}
|
||||
|
||||
int GetMoveIndexWhenEqualeLastMove(int moveIndex, double gameEntropyRate)
|
||||
{
|
||||
double rate = 0.592 * (1 / Math.Tan(gameEntropyRate / moveIndex + gameEntropyRate)) / Math.Sin(moveIndex * 2 + gameEntropyRate) - Math.Cos(moveIndex);
|
||||
return Convert.ToInt32(Math.Floor(10 * (rate - Math.Floor(rate))));
|
||||
}
|
||||
|
||||
void PrintNewBoard()
|
||||
{
|
||||
Print("1 2 3 4 5 6 7 8 9 10");
|
||||
Print("X X X X X X X X X X");
|
||||
Print();
|
||||
}
|
||||
|
||||
void PrintGameBoard(string[] board)
|
||||
{
|
||||
Print("1 2 3 4 5 6 7 8 9 10");
|
||||
|
||||
foreach (var item in board)
|
||||
{
|
||||
Write($"{item} ");
|
||||
}
|
||||
|
||||
Print();
|
||||
Print();
|
||||
}
|
||||
|
||||
void PrintGameResult(int gameSum, int stepsCount)
|
||||
{
|
||||
if (gameSum == 10)
|
||||
{
|
||||
Print($"VERY GOOD. YOU GUESSED IT IN ONLY {stepsCount} GUESSES.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Print($"TRY HARDER NEXT TIME. IT TOOK YOU {stepsCount} GUESSES.");
|
||||
}
|
||||
}
|
||||
|
||||
void PrintGameInfo()
|
||||
{
|
||||
Print(Tab(32) + "FLIPFLOP");
|
||||
Print(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||
Print();
|
||||
Print("THE OBJECT OF THIS PUZZLE IS TO CHANGE THIS:");
|
||||
Print();
|
||||
|
||||
Print("X X X X X X X X X X");
|
||||
Print();
|
||||
Print("TO THIS:");
|
||||
Print();
|
||||
Print("O O O O O O O O O O");
|
||||
Print();
|
||||
|
||||
Print("BY TYPING THE NUMBER CORRESPONDING TO THE POSITION OF THE");
|
||||
Print("LETTER ON SOME NUMBERS, ONE POSITION WILL CHANGE, ON");
|
||||
Print("OTHERS, TWO WILL CHANGE. TO RESET LINE TO ALL X'S, TYPE 0");
|
||||
Print("(ZERO) AND TO START OVER IN THE MIDDLE OF A GAME, TYPE ");
|
||||
Print("11 (ELEVEN).");
|
||||
}
|
||||
10
36_Flip_Flop/csharp/FlipFlop.csproj
Normal file
10
36_Flip_Flop/csharp/FlipFlop.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
25
36_Flip_Flop/csharp/FlipFlop.sln
Normal file
25
36_Flip_Flop/csharp/FlipFlop.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.32014.148
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlipFlop", "FlipFlop.csproj", "{192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{192EDAD4-5EF5-4B11-9EB3-B17FFAD0861F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {108E5099-D7AA-4260-B587-1B1FE1AF6B54}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
111
73_Reverse/ruby/reverse.rb
Normal file
111
73_Reverse/ruby/reverse.rb
Normal file
@@ -0,0 +1,111 @@
|
||||
ARRAYSIZE = 9
|
||||
$digitArray = Array.new(ARRAYSIZE)
|
||||
$winningArray = Array.new(ARRAYSIZE)
|
||||
|
||||
# Method to print the rules
|
||||
def displayTheRules
|
||||
puts "This is the game of 'Reverse'. to win, all you have"
|
||||
puts "to do is arrange a list of numbers (1 through " + ARRAYSIZE.to_s + ")"
|
||||
puts "in numerical order from left to right. to move, you"
|
||||
puts "tell me how many numbers (counting from the left) to"
|
||||
puts "reverse. For example, if the current list is:"
|
||||
puts "2 3 4 5 1 6 7 8 9"
|
||||
puts "and you reverse 4, the result will be:"
|
||||
puts "5 4 3 2 1 6 7 8 9"
|
||||
puts "Now if you reverse 5, you win!"
|
||||
puts "1 2 3 4 5 6 7 8 9"
|
||||
puts "No doubt you will like this game, but"
|
||||
puts "if you want to quit, reverse 0 (zero)."
|
||||
end
|
||||
|
||||
# Method to print the list
|
||||
def printList
|
||||
puts "\n" + $digitArray.join(" ") + "\n\n"
|
||||
end
|
||||
|
||||
# Zero-based arrays contain digits 1-9
|
||||
# Make a random array and an ordered winning answer array A[0] to A[N]
|
||||
def makeRandomList
|
||||
for kIndex in 0..ARRAYSIZE-1 do
|
||||
$digitArray[kIndex] = kIndex+1
|
||||
$winningArray[kIndex] = kIndex+1
|
||||
end
|
||||
# now randomize the digit array order
|
||||
$digitArray.shuffle!
|
||||
end
|
||||
|
||||
def checkForWin? (triesSoFar)
|
||||
# Check for a win (all array elements in order)
|
||||
if $digitArray == $winningArray then
|
||||
puts "You won it in " + triesSoFar.to_s + " moves!!!\n\n"
|
||||
puts "try again (yes or no)?"
|
||||
tryAgain = gets.strip.upcase
|
||||
if tryAgain == "YES" then
|
||||
return true
|
||||
end
|
||||
puts "\nO.K. Hope you had fun!!"
|
||||
exit
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def reverseIt (howManyToReverse, triesSoFar)
|
||||
# REVERSE R NUMBERS AND PRINT NEW LIST
|
||||
|
||||
# extract and reverse the first howManyToReverse elements of the array
|
||||
subArray = $digitArray.take(howManyToReverse)
|
||||
subArray.reverse!
|
||||
|
||||
# get the remaining elements of the original array
|
||||
endArray = $digitArray.slice(howManyToReverse, ARRAYSIZE)
|
||||
# append those elements to the reversed elements
|
||||
$digitArray = subArray.concat(endArray)
|
||||
|
||||
# if we got all in order, randomize again
|
||||
isWinner = checkForWin?(triesSoFar)
|
||||
if isWinner == true then
|
||||
makeRandomList
|
||||
end
|
||||
printList # always print the newly ordered list
|
||||
return isWinner
|
||||
end
|
||||
|
||||
def askHowManyToReverse
|
||||
puts "How many shall I reverse?";
|
||||
rNumber = gets.to_i
|
||||
if rNumber > 0 then
|
||||
if rNumber > ARRAYSIZE then
|
||||
puts "Oops! Too many! I can reverse at most " + ARRAYSIZE.to_s
|
||||
end
|
||||
else
|
||||
rNumber = 0 # zero or negative values end the game
|
||||
end
|
||||
return rNumber
|
||||
end
|
||||
|
||||
puts "REVERSE"
|
||||
puts "Creative Computing Morristown, New Jersey\n\n\n"
|
||||
puts "REVERSE -- A game of skill\n\n"
|
||||
|
||||
puts "Do you want the rules?"
|
||||
wantRules = gets.strip.upcase
|
||||
if wantRules == "YES" then
|
||||
displayTheRules
|
||||
end
|
||||
|
||||
makeRandomList
|
||||
howManyTries = 0
|
||||
puts "\nHere we go ... the list is:"
|
||||
printList # display the initial list
|
||||
# start the game loop
|
||||
r = askHowManyToReverse
|
||||
while r != 0 do # zero will end the game
|
||||
if r <= ARRAYSIZE then
|
||||
howManyTries = howManyTries+1
|
||||
if reverseIt(r, howManyTries) then
|
||||
howManyTries = 0
|
||||
end
|
||||
end
|
||||
r = askHowManyToReverse
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user