diff --git a/01_Acey_Ducey/README.md b/01_Acey_Ducey/README.md index 77ff8621..f8e16312 100644 --- a/01_Acey_Ducey/README.md +++ b/01_Acey_Ducey/README.md @@ -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 diff --git a/15_Boxing/csharp/AttackStrategy.cs b/15_Boxing/csharp/AttackStrategy.cs new file mode 100644 index 00000000..5ffdb2cc --- /dev/null +++ b/15_Boxing/csharp/AttackStrategy.cs @@ -0,0 +1,48 @@ +namespace Boxing; + +public abstract class AttackStrategy +{ + protected const int KnockoutDamageThreshold = 35; + protected readonly Boxer Other; + protected readonly Stack Work; + private readonly Action _notifyGameEnded; + + public AttackStrategy(Boxer other, Stack 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); +} \ No newline at end of file diff --git a/15_Boxing/csharp/Boxer.cs b/15_Boxing/csharp/Boxer.cs new file mode 100644 index 00000000..3f5fdd26 --- /dev/null +++ b/15_Boxing/csharp/Boxer.cs @@ -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); + } +} \ No newline at end of file diff --git a/15_Boxing/csharp/Boxing.csproj b/15_Boxing/csharp/Boxing.csproj new file mode 100644 index 00000000..74abf5c9 --- /dev/null +++ b/15_Boxing/csharp/Boxing.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/15_Boxing/csharp/Boxing.sln b/15_Boxing/csharp/Boxing.sln new file mode 100644 index 00000000..6202b593 --- /dev/null +++ b/15_Boxing/csharp/Boxing.sln @@ -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 diff --git a/15_Boxing/csharp/OpponentAttackStrategy.cs b/15_Boxing/csharp/OpponentAttackStrategy.cs new file mode 100644 index 00000000..c5bf3e38 --- /dev/null +++ b/15_Boxing/csharp/OpponentAttackStrategy.cs @@ -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 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!"); +} \ No newline at end of file diff --git a/15_Boxing/csharp/PlayerAttackStrategy.cs b/15_Boxing/csharp/PlayerAttackStrategy.cs new file mode 100644 index 00000000..fd43c0ed --- /dev/null +++ b/15_Boxing/csharp/PlayerAttackStrategy.cs @@ -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 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; + } +} \ No newline at end of file diff --git a/15_Boxing/csharp/Program.cs b/15_Boxing/csharp/Program.cs new file mode 100644 index 00000000..57923de0 --- /dev/null +++ b/15_Boxing/csharp/Program.cs @@ -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); \ No newline at end of file diff --git a/15_Boxing/csharp/Punch.cs b/15_Boxing/csharp/Punch.cs new file mode 100644 index 00000000..add2003a --- /dev/null +++ b/15_Boxing/csharp/Punch.cs @@ -0,0 +1,9 @@ +namespace Boxing; + +public enum Punch +{ + FullSwing = 1, + Hook = 2, + Uppercut = 3, + Jab = 4 +} \ No newline at end of file diff --git a/15_Boxing/csharp/Round.cs b/15_Boxing/csharp/Round.cs new file mode 100644 index 00000000..dfa1e26b --- /dev/null +++ b/15_Boxing/csharp/Round.cs @@ -0,0 +1,96 @@ +namespace Boxing; + +class Round +{ + + private readonly Boxer _player; + private readonly Boxer _opponent; + private readonly int _round; + private Stack _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 ); + } +} \ No newline at end of file diff --git a/15_Boxing/csharp/Utils.cs b/15_Boxing/csharp/Utils.cs new file mode 100644 index 00000000..1ada516c --- /dev/null +++ b/15_Boxing/csharp/Utils.cs @@ -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 Roll { get; } = upperLimit => (int) (upperLimit * Rnd.NextSingle()) + 1; + + public static bool RollSatisfies(int upperLimit, Predicate 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) + }; + +} \ No newline at end of file diff --git a/36_Flip_Flop/csharp/FlipFlop.cs b/36_Flip_Flop/csharp/FlipFlop.cs new file mode 100644 index 00000000..53c613e8 --- /dev/null +++ b/36_Flip_Flop/csharp/FlipFlop.cs @@ -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)."); +} \ No newline at end of file diff --git a/36_Flip_Flop/csharp/FlipFlop.csproj b/36_Flip_Flop/csharp/FlipFlop.csproj new file mode 100644 index 00000000..74abf5c9 --- /dev/null +++ b/36_Flip_Flop/csharp/FlipFlop.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/36_Flip_Flop/csharp/FlipFlop.sln b/36_Flip_Flop/csharp/FlipFlop.sln new file mode 100644 index 00000000..a26f312e --- /dev/null +++ b/36_Flip_Flop/csharp/FlipFlop.sln @@ -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 diff --git a/73_Reverse/ruby/reverse.rb b/73_Reverse/ruby/reverse.rb new file mode 100644 index 00000000..0e2f7934 --- /dev/null +++ b/73_Reverse/ruby/reverse.rb @@ -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 +