From c9f9f9bcdd36e1faaa59807cfbf01dd51bc394b5 Mon Sep 17 00:00:00 2001 From: zoot661 Date: Fri, 7 Jan 2022 21:40:42 +0000 Subject: [PATCH 01/11] Create Program.cs Add initial implementation Working version but requires commenting and maybe some better error handling --- 92_Trap/csharp/Program.cs | 119 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 92_Trap/csharp/Program.cs diff --git a/92_Trap/csharp/Program.cs b/92_Trap/csharp/Program.cs new file mode 100644 index 00000000..6cd74d10 --- /dev/null +++ b/92_Trap/csharp/Program.cs @@ -0,0 +1,119 @@ +using System; + +namespace trap_cs +{ + class Program + { + const int maxGuesses = 6; + const int maxNumber = 100; + static void Main(string[] args) + { + int lowGuess = 0; + int highGuess = 0; + + Random randomNumberGenerator = new (); + + Print("TRAP"); + Print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + Print(); + Print(); + Print(); + + PrintInstructions(); + + int numberToGuess = randomNumberGenerator.Next(1, maxNumber); + + for (int nGuess = 1; nGuess <= maxGuesses + 1; nGuess++) + { + if (nGuess > maxGuesses) + { + Print(string.Format("SORRY, THAT'S {0} GUESSES. THE NUMBER WAS {1}", maxGuesses, numberToGuess)); + Print(); + break; + } + + GetGuesses(nGuess, ref lowGuess, ref highGuess); + + if(lowGuess == highGuess && lowGuess == numberToGuess) + { + Print("YOU GOT IT!!!"); + Print(); + Print("TRY AGAIN."); + Print(); + break; + } + if (highGuess < numberToGuess) + { + Print("MY NUMBER IS LARGER THAN YOUR TRAP NUMBERS."); + } + else if (lowGuess > numberToGuess) + { + Print("MY NUMBER IS SMALLER THAN YOUR TRAP NUMBERS."); + } + else + { + Print("YOU HAVE TRAPPED MY NUMBER."); + } + } + } + +// TRAP +// REM - STEVE ULLMAN, 8 - 1 - 72 + static void PrintInstructions() + { + Print("INSTRUCTIONS ?"); + + char response = Console.ReadKey().KeyChar; + if (response == 'Y') + { + Print(string.Format("I AM THINKING OF A NUMBER BETWEEN 1 AND {0}", maxNumber)); + Print("TRY TO GUESS MY NUMBER. ON EACH GUESS,"); + Print("YOU ARE TO ENTER 2 NUMBERS, TRYING TO TRAP"); + Print("MY NUMBER BETWEEN THE TWO NUMBERS. I WILL"); + Print("TELL YOU IF YOU HAVE TRAPPED MY NUMBER, IF MY"); + Print("NUMBER IS LARGER THAN YOUR TWO NUMBERS, OR IF"); + Print("MY NUMBER IS SMALLER THAN YOUR TWO NUMBERS."); + Print("IF YOU WANT TO GUESS ONE SINGLE NUMBER, TYPE"); + Print("YOUR GUESS FOR BOTH YOUR TRAP NUMBERS."); + Print(string.Format("YOU GET {0} GUESSES TO GET MY NUMBER.", maxGuesses)); + } + } + static void Print(string stringToPrint) + { + Console.WriteLine(stringToPrint); + } + static void Print() + { + Console.WriteLine(); + } + static void GetGuesses(int nGuess, ref int lowGuess, ref int highGuess) + { + Print(); + Print(string.Format("GUESS #{0}", nGuess)); + + lowGuess = GetIntFromConsole("Type low guess"); + highGuess = GetIntFromConsole("Type high guess"); + + if(lowGuess > highGuess) + { + int tempGuess = lowGuess; + + lowGuess = highGuess; + highGuess = tempGuess; + } + } + static int GetIntFromConsole(string prompt) + { + + Console.Write( prompt + " > "); + string intAsString = Console.ReadLine(); + + if(int.TryParse(intAsString, out int intValue) ==false) + { + intValue = 1; + } + + return intValue; + } + } +} From ab5301151e064a395410efc0f198f1406f94ca37 Mon Sep 17 00:00:00 2001 From: Robert Flach Date: Fri, 7 Jan 2022 16:38:29 -0600 Subject: [PATCH 02/11] Fixed 2 bugs. 1 yes and no both restarted the game 2. zero is supposed to skip the third card but was treated as an invalid bet. 1. In trying as keep as close to the spirit of the original game as possible, there is no handling for an invalidly low number. A zero input prints "chicken" and skips the third card and starts over with 2 new initial cards. 2. After the wad is blown, anything but a yes answer to the "Try again" question ends the game --- 01_Acey_Ducey/javascript/aceyducey.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/01_Acey_Ducey/javascript/aceyducey.js b/01_Acey_Ducey/javascript/aceyducey.js index 8bf5e9e1..9969ebbf 100644 --- a/01_Acey_Ducey/javascript/aceyducey.js +++ b/01_Acey_Ducey/javascript/aceyducey.js @@ -90,19 +90,23 @@ async function main() { print('\nWHAT IS YOUR BET? '); bet = parseInt(await input(), 10); let minimumRequiredBet = 0; - if (bet > minimumRequiredBet) { + if (bet >= minimumRequiredBet) { if (bet > availableDollars) { print('SORRY, MY FRIEND, BUT YOU BET TOO MUCH.'); print(`YOU HAVE ONLY ${availableDollars} DOLLARS TO BET.`); } else { validBet = true; } - } else { - // Does not meet minimum required bet - print('CHICKEN!!'); - print(''); } } + if (bet == 0) + { + // User chose not to bet. + print('CHICKEN!!'); + print(''); + // Don't draw a third card, draw a new set of 2 cards. + continue; + } print('\n\nHERE IS THE CARD WE DREW: '); print(getCardValue(cardThree)); @@ -127,7 +131,7 @@ async function main() { print(''); print(''); - if (isValidYesNoString(tryAgainInput)) { + if (isValidYesString(tryAgainInput)) { availableDollars = 100; } else { print('O.K., HOPE YOU HAD FUN!'); From a14a7bea3cfe411f1ce704cd12f911aa93b240d7 Mon Sep 17 00:00:00 2001 From: simonskrede Date: Sat, 8 Jan 2022 00:42:53 +0100 Subject: [PATCH 03/11] Initial port of Poker to plain Java --- 71_Poker/java/Poker.java | 851 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 851 insertions(+) create mode 100644 71_Poker/java/Poker.java diff --git a/71_Poker/java/Poker.java b/71_Poker/java/Poker.java new file mode 100644 index 00000000..426a71fd --- /dev/null +++ b/71_Poker/java/Poker.java @@ -0,0 +1,851 @@ +import java.util.Random; +import java.util.Scanner; + +import static java.lang.System.out; + +/** + * Port of CREATIVE COMPUTING Poker written in Commodore 64 Basic to plain Java + * + * Original source scanned from magazine: https://www.atariarchives.org/basicgames/showpage.php?page=129 + * + * I based my port on the OCR'ed source code here: https://github.com/coding-horror/basic-computer-games/blob/main/71_Poker/poker.bas + * + * Why? Because I remember typing this into my C64 when I was a tiny little developer and having great fun playing it! + * + * Goal: Keep the algorithms and UX more or less as-is; Improve the control flow a bit (no goto in Java!) and rename some stuff to be easier to follow. + * + * Result: There are probably bugs, please let me know. + */ +public class Poker { + + public static void main(String[] args) { + new Poker().run(); + } + + float[] cards = new float[50]; // Index 1-5 = Human hand, index 6-10 = Computer hand + float[] B = new float[15]; + + float playerValuables = 1; + float computerMoney = 200; + float humanMoney = 200; + float pot = 0; + + String J$ = ""; + float computerHandValue = 0; + + int K = 0; + float G = 0; + float T = 0; + int M = 0; + int D = 0; + + int U = 0; + float N = 1; + + float I = 0; + + float X = 0; + + int Z = 0; + + String handDescription = ""; + + float V; + + void run() { + printWelcome(); + playRound(); + startAgain(); + } + + void printWelcome() { + tab(33); + out.println("POKER"); + tab(15); + out.print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + out.println(); + out.println(); + out.println(); + out.println("WELCOME TO THE CASINO. WE EACH HAVE $200."); + out.println("I WILL OPEN THE BETTING BEFORE THE DRAW; YOU OPEN AFTER."); + out.println("TO FOLD BET 0; TO CHECK BET .5."); + out.println("ENOUGH TALK -- LET'S GET DOWN TO BUSINESS."); + out.println(); + } + + void tab(int number) { + System.out.print("\t".repeat(number)); + } + + int random0to10() { + return new Random().nextInt(10); + } + + int removeHundreds(long x) { + return _int(x - (100F * _int(x / 100F))); + } + + void startAgain() { + pot = 0; + playRound(); + } + + void playRound() { + if (computerMoney <= 5) { + computerBroke(); + } + + out.println("THE ANTE IS $5. I WILL DEAL:"); + out.println(); + + if (humanMoney <= 5) { + playerBroke(); + } + + pot = pot + 10; + humanMoney = humanMoney - 5; + computerMoney = computerMoney - 5; + for (int Z = 1; Z < 10; Z++) { + generateCards(Z); + } + out.println("YOUR HAND:"); + N = 1; + showHand(); + N = 6; + I = 2; + + describeHand(); + + out.println(); + + if (I != 6) { + if (U >= 13) { + if (U <= 16) { + Z = 35; + } else { + Z = 2; + if (random0to10() < 1) { + Z = 35; + } + } + computerOpens(); + playerMoves(); + } else if (random0to10() >= 2) { + computerChecks(); + } else { + I = 7; + Z = 23; + computerOpens(); + playerMoves(); + } + } else if (random0to10() <= 7) { + if (random0to10() <= 7) { + if (random0to10() >= 1) { + Z = 1; + K = 0; + out.print("I CHECK. "); + playerMoves(); + } else { + X = 11111; + I = 7; + Z = 23; + computerOpens(); + playerMoves(); + } + } else { + X = 11110; + I = 7; + Z = 23; + computerOpens(); + playerMoves(); + } + } else { + X = 11100; + I = 7; + Z = 23; + computerOpens(); + playerMoves(); + } + } + + void playerMoves() { + playersTurn(); + checkWinnerAfterFirstBet(); + promptPlayerDrawCards(); + } + + void computerOpens() { + V = Z + random0to10(); + computerMoves(); + out.print("I'LL OPEN WITH $" + V); + K = _int(V); + } + + @SuppressWarnings("StatementWithEmptyBody") + void computerMoves() { + if (computerMoney - G - V >= 0) { + } else if (G != 0) { + if (computerMoney - G >= 0) { + computerSees(); + } else { + computerBroke(); + } + } else { + V = computerMoney; + } + } + + void promptPlayerDrawCards() { + out.println(); + out.println("NOW WE DRAW -- HOW MANY CARDS DO YOU WANT"); + inputPlayerDrawCards(); + } + + void inputPlayerDrawCards() { + T = Integer.parseInt(readString()); + if (T == 0) { + computerDrawing(); + } else { + Z = 10; + if (T < 4) { + playerDrawsCards(); + } else { + out.println("YOU CAN'T DRAW MORE THAN THREE CARDS."); + inputPlayerDrawCards(); + } + } + } + + // line # 980 + void computerDrawing() { + Z = _int(10 + T); + for (U = 6; U <= 10; U++) { + if (_int((float) (X / Math.pow(10F, (U - 6F)))) == (10 * (_int((float) (X / Math.pow(10, (U - 5))))))) { + drawNextCard(); + } + } + out.print("I AM TAKING " + _int(Z - 10 - T) + " CARD"); + if (Z == 11 + T) { + out.println(); + } else { + out.println("S"); + } + + N = 6; + V = I; + I = 1; + describeHand(); + startPlayerBettingAndReaction(); + } + + void drawNextCard() { + Z = Z + 1; + drawCard(); + } + + @SuppressWarnings("StatementWithEmptyBody") + void drawCard() { + cards[Z] = 100 * new Random().nextInt(4) + new Random().nextInt(100); + if (_int(cards[Z] / 100) > 3) { + drawCard(); + } else if (cards[Z] - 100 * _int(cards[Z] / 100) > 12) { + drawCard(); + } else if (Z == 1) { + } else { + for (K = 1; K <= Z - 1; K++) { + if (cards[Z] == cards[K]) { + drawCard(); + } + } + if (Z <= 10) { + } else { + N = cards[U]; + cards[U] = cards[Z]; + cards[Z] = N; + } + } + } + + void playerDrawsCards() { + out.println("WHAT ARE THEIR NUMBERS:"); + for (int Q = 1; Q <= T; Q++) { + U = Integer.parseInt(readString()); + drawNextCard(); + } + + out.println("YOUR NEW HAND:"); + N = 1; + showHand(); + computerDrawing(); + } + + void startPlayerBettingAndReaction() { + computerHandValue = U; + M = D; + + if (V != 7) { + if (I != 6) { + if (U >= 13) { + if (U >= 16) { + Z = 2; + playerBetsAndComputerReacts(); + } else { + Z = 19; + if (random0to10() == 8) { + Z = 11; + } + playerBetsAndComputerReacts(); + } + } else { + Z = 2; + if (random0to10() == 6) { + Z = 19; + } + playerBetsAndComputerReacts(); + } + } else { + Z = 1; + playerBetsAndComputerReacts(); + } + } else { + Z = 28; + playerBetsAndComputerReacts(); + } + } + + void playerBetsAndComputerReacts() { + K = 0; + playersTurn(); + if (T != .5) { + checkWinnerAfterFirstBetAndCompareHands(); + } else if (V == 7 || I != 6) { + computerOpens(); + promptAndInputPlayerBet(); + checkWinnerAfterFirstBetAndCompareHands(); + } else { + out.println("I'LL CHECK"); + compareHands(); + } + } + + void checkWinnerAfterFirstBetAndCompareHands() { + checkWinnerAfterFirstBet(); + compareHands(); + } + + void compareHands() { + out.println("NOW WE COMPARE HANDS:"); + J$ = handDescription; + out.println("MY HAND:"); + N = 6; + showHand(); + N = 1; + describeHand(); + out.print("YOU HAVE "); + K = D; + printHandDescriptionResult(); + handDescription = J$; + K = M; + out.print(" AND I HAVE "); + printHandDescriptionResult(); + out.print(". "); + if (computerHandValue > U) { + computerWins(); + } else if (U > computerHandValue) { + humanWins(); + } else if (handDescription.contains("A FLUS")) { + someoneWinsWithFlush(); + } else if (removeHundreds(M) < removeHundreds(D)) { + humanWins(); + } else if (removeHundreds(M) > removeHundreds(D)) { + computerWins(); + } else { + handIsDrawn(); + } + } + + void printHandDescriptionResult() { + out.print(handDescription); + if (!handDescription.contains("A FLUS")) { + K = removeHundreds(K); + printCardValue(); + if (handDescription.contains("SCHMAL")) { + out.print(" HIGH"); + } else if (!handDescription.contains("STRAIG")) { + out.print("'S"); + } else { + out.print(" HIGH"); + } + } else { + K = K / 100; + printCardColor(); + out.println(); + } + } + + void handIsDrawn() { + out.print("THE HAND IS DRAWN."); + out.print("ALL $" + pot + " REMAINS IN THE POT."); + playRound(); + } + + void someoneWinsWithFlush() { + if (removeHundreds(M) > removeHundreds(D)) { + computerWins(); + } else if (removeHundreds(D) > removeHundreds(M)) { + humanWins(); + } else { + handIsDrawn(); + } + } + + @SuppressWarnings("StatementWithEmptyBody") + void checkWinnerAfterFirstBet() { + if (I != 3) { + if (I != 4) { + } else { + humanWins(); + } + } else { + out.println(); + computerWins(); + } + } + + void computerWins() { + out.print(". I WIN. "); + computerMoney = computerMoney + pot; + potStatusAndNextRoundPrompt(); + } + + void potStatusAndNextRoundPrompt() { + out.println("NOW I HAVE $" + computerMoney + " AND YOU HAVE $" + humanMoney); + out.print("DO YOU WISH TO CONTINUE"); + + if (yesFromPrompt()) { + startAgain(); + } else { + System.exit(0); + } + } + + private boolean yesFromPrompt() { + String h = readString(); + if (h != null) { + if (h.toLowerCase().matches("y|yes|yep|affirmative|yay")) { + return true; + } else if (h.toLowerCase().matches("n|no|nope|fuck off|nay")) { + return false; + } + } + out.println("ANSWER YES OR NO, PLEASE."); + return yesFromPrompt(); + } + + void computerChecks() { + Z = 0; + K = 0; + out.print("I CHECK. "); + playerMoves(); + } + + void humanWins() { + out.println("YOU WIN."); + humanMoney = humanMoney + pot; + potStatusAndNextRoundPrompt(); + } + + // line # 1740 + void generateCards(int Z) { + cards[Z] = (100 * new Random().nextInt(4)) + new Random().nextInt(100); + if (_int(cards[Z] / 100) > 3) { + generateCards(Z); + return; + } + if (cards[Z] - 100 * (_int(cards[Z] / 100)) > 12) { + generateCards(Z); + return; + } + if (Z == 1) {return;} + for (int K = 1; K <= Z - 1; K++) {// TO Z-1 + if (cards[Z] == cards[K]) { + generateCards(Z); + return; + } + } + if (Z <= 10) {return;} + float N = cards[U]; + cards[U] = cards[Z]; + cards[Z] = N; + } + + // line # 1850 + void showHand() { + for (int cardNumber = _int(N); cardNumber <= N + 4; cardNumber++) { + out.print(cardNumber + "-- "); + printCardValueAtIndex(cardNumber); + out.print(" OF"); + printCardColorAtIndex(cardNumber); + if (cardNumber / 2 == (cardNumber / 2)) { + out.println(); + } + } + } + + // line # 1950 + void printCardValueAtIndex(int Z) { + K = removeHundreds(_int(cards[Z])); + printCardValue(); + } + + void printCardValue() { + if (K == 9) { + out.print("JACK"); + } else if (K == 10) { + out.print("QUEEN"); + } else if (K == 11) { + out.print("KING"); + } else if (K == 12) { + out.print("ACE"); + } else if (K < 9) { + out.print(K + 2); + } + } + + // line # 2070 + void printCardColorAtIndex(int Z) { + K = _int(cards[Z] / 100); + printCardColor(); + } + + void printCardColor() { + if (K == 0) { + out.print(" CLUBS"); + } else if (K == 1) { + out.print(" DIAMONDS"); + } else if (K == 2) { + out.print(" HEARTS"); + } else if (K == 3) { + out.print(" SPADES"); + } + } + + // line # 2170 + void describeHand() { + U = 0; + for (Z = _int(N); Z <= N + 4; Z++) { + B[Z] = removeHundreds(_int(cards[Z])); + if (Z == N + 4) {continue;} + if (_int(cards[Z] / 100) != _int(cards[Z + 1] / 100)) {continue;} + U = U + 1; + } + if (U != 4) { + for (Z = _int(N); Z <= N + 3; Z++) { + for (K = Z + 1; K <= N + 4; K++) { + if (B[Z] <= B[K]) {continue;} + X = cards[Z]; + cards[Z] = cards[K]; + B[Z] = B[K]; + cards[K] = X; + B[K] = cards[K] - 100 * _int(cards[K] / 100); + } + } + X = 0; + for (Z = _int(N); Z <= N + 3; Z++) { + if (B[Z] != B[Z + 1]) {continue;} + X = (float) (X + 11 * Math.pow(10, (Z - N))); + D = _int(cards[Z]); + + if (U >= 11) { + if (U != 11) { + if (U > 12) { + if (B[Z] != B[Z - 1]) { + fullHouse(); + } else { + U = 17; + handDescription = "FOUR "; + } + } else { + fullHouse(); + } + } else if (B[Z] != B[Z - 1]) { + handDescription = "TWO PAIR, "; + U = 12; + } else { + handDescription = "THREE "; + U = 13; + } + } else { + U = 11; + handDescription = "A PAIR OF "; + } + } + + if (X != 0) { + schmaltzHand(); + } else { + if (B[_int(N)] + 3 == B[_int(N + 3)]) { + X = 1111; + U = 10; + } + if (B[_int(N + 1)] + 3 != B[_int(N + 4)]) { + schmaltzHand(); + } else if (U != 10) { + U = 10; + X = 11110; + schmaltzHand(); + } else { + U = 14; + handDescription = "STRAIGHT"; + X = 11111; + D = _int(cards[_int(N + 4)]); + } + } + } else { + X = 11111; + D = _int(cards[_int(N)]); + handDescription = "A FLUSH IN"; + U = 15; + } + } + + void schmaltzHand() { + if (U >= 10) { + if (U != 10) { + if (U > 12) {return;} + if (removeHundreds(D) <= 6) { + I = 6; + } + } else { + if (I == 1) { + I = 6; + } + } + } else { + D = _int(cards[_int(N + 4)]); + handDescription = "SCHMALTZ, "; + U = 9; + X = 11000; + I = 6; + } + } + + void fullHouse() { + U = 16; + handDescription = "FULL HOUSE, "; + } + + void playersTurn() { + G = 0; + promptAndInputPlayerBet(); + } + + String readString() { + Scanner sc = new Scanner(System.in); + return sc.nextLine(); + } + + @SuppressWarnings("StatementWithEmptyBody") + void promptAndInputPlayerBet() { + out.println("WHAT IS YOUR BET"); + T = readFloat(); + if (T - _int(T) == 0) { + processPlayerBet(); + } else if (K != 0) { + playerBetInvalidAmount(); + } else if (G != 0) { + playerBetInvalidAmount(); + } else if (T == .5) { + } else { + playerBetInvalidAmount(); + } + } + + private float readFloat() { + try { + return Float.parseFloat(readString()); + } catch (Exception ex) { + System.out.println("INVALID INPUT, PLEASE TYPE A FLOAT. "); + return readFloat(); + } + } + + void playerBetInvalidAmount() { + out.println("NO SMALL CHANGE, PLEASE."); + promptAndInputPlayerBet(); + } + + void processPlayerBet() { + if (humanMoney - G - T >= 0) { + humanCanAffordBet(); + } else { + playerBroke(); + promptAndInputPlayerBet(); + } + } + + void humanCanAffordBet() { + if (T != 0) { + if (G + T >= K) { + processComputerMove(); + } else { + out.println("IF YOU CAN'T SEE MY BET, THEN FOLD."); + promptAndInputPlayerBet(); + } + } else { + I = 3; + moveMoneyToPot(); + } + } + + void processComputerMove() { + G = G + T; + if (G == K) { + moveMoneyToPot(); + } else if (Z != 1) { + if (G > 3 * Z) { + computerRaisesOrSees(); + } else { + computerRaises(); + } + } else if (G > 5) { + if (T <= 25) { + computerRaisesOrSees(); + } else { + computerFolds(); + } + } else { + V = 5; + if (G > 3 * Z) { + computerRaisesOrSees(); + } else { + computerRaises(); + } + } + } + + void computerRaises() { + V = G - K + random0to10(); + computerMoves(); + out.println("I'LL SEE YOU, AND RAISE YOU" + V); + K = _int(G + V); + promptAndInputPlayerBet(); + } + + void computerFolds() { + I = 4; + out.println("I FOLD."); + } + + void computerRaisesOrSees() { + if (Z == 2) { + computerRaises(); + } else { + computerSees(); + } + } + + void computerSees() { + out.println("I'LL SEE YOU."); + K = _int(G); + moveMoneyToPot(); + } + + void moveMoneyToPot() { + humanMoney = humanMoney - G; + computerMoney = computerMoney - K; + pot = pot + G + K; + } + + void computerBusted() { + out.println("I'M BUSTED. CONGRATULATIONS!"); + System.exit(0); + } + + @SuppressWarnings("StatementWithEmptyBody") + private void computerBroke() { + if ((playerValuables / 2) == _int(playerValuables / 2) && playerBuyBackWatch()) { + } else if (playerValuables / 3 == _int(playerValuables / 3) && playerBuyBackTieRack()) { + } else { + computerBusted(); + } + } + + private int _int(float v) { + return (int) Math.floor(v); + } + + private boolean playerBuyBackWatch() { + out.println("WOULD YOU LIKE TO BUY BACK YOUR WATCH FOR $50"); + if (yesFromPrompt()) { + computerMoney = computerMoney + 50; + playerValuables = playerValuables / 2; + return true; + } else { + return false; + } + } + + private boolean playerBuyBackTieRack() { + out.println("WOULD YOU LIKE TO BUY BACK YOUR TIE TACK FOR $50"); + if (yesFromPrompt()) { + computerMoney = computerMoney + 50; + playerValuables = playerValuables / 3; + return true; + } else { + return false; + } + } + + // line # 3830 + @SuppressWarnings("StatementWithEmptyBody") + void playerBroke() { + out.println("YOU CAN'T BET WITH WHAT YOU HAVEN'T GOT."); + if (playerValuables / 2 != _int(playerValuables / 2) && playerSellWatch()) { + } else if (playerValuables / 3 != _int(playerValuables / 3) && playerSellTieTack()) { + } else { + playerBusted(); + } + } + + private void playerBusted() { + out.println("YOUR WAD IS SHOT. SO LONG, SUCKER!"); + System.exit(0); + } + + private boolean playerSellWatch() { + out.println("WOULD YOU LIKE TO SELL YOUR WATCH"); + if (yesFromPrompt()) { + if (random0to10() < 7) { + out.println("I'LL GIVE YOU $75 FOR IT."); + humanMoney = humanMoney + 75; + } else { + out.println("THAT'S A PRETTY CRUMMY WATCH - I'LL GIVE YOU $25."); + humanMoney = humanMoney + 25; + } + playerValuables = playerValuables * 2; + return true; + } else { + return false; + } + } + + private boolean playerSellTieTack() { + out.println("WILL YOU PART WITH THAT DIAMOND TIE TACK"); + + if (yesFromPrompt()) { + if (random0to10() < 6) { + out.println("YOU ARE NOW $100 RICHER."); + humanMoney = humanMoney + 100; + } else { + out.println("IT'S PASTE. $25."); + humanMoney = humanMoney + 25; + } + playerValuables = playerValuables * 3; + return true; + } else { + return false; + } + } + +} From 8db8272d0b088749867350f1674ec8369d0ae259 Mon Sep 17 00:00:00 2001 From: Flavio Poletti Date: Sat, 8 Jan 2022 02:14:33 +0100 Subject: [PATCH 04/11] Add 72_Queen in Perl --- 72_Queen/perl/queen.pl | 209 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 72_Queen/perl/queen.pl diff --git a/72_Queen/perl/queen.pl b/72_Queen/perl/queen.pl new file mode 100644 index 00000000..62682210 --- /dev/null +++ b/72_Queen/perl/queen.pl @@ -0,0 +1,209 @@ +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; +no warnings 'experimental::signatures'; + +use constant TARGET => 158; + +main(@ARGV); + +sub main (@args) { + welcome(); + help() if ask_yes_no('DO YOU WANT INSTRUCTIONS'); + do { one_match() } while ask_yes_no('ANYONE ELSE CARE TO TRY'); + __exit(); +} + +sub one_match { + print_board(); + + # the player can choose the starting position in the top row or the + # right column + my $move = ask_first_move() or return forfeit(); + + # we alternate moves between computer or player from now on + while ('playing') { + $move = computer_move($move); + say "COMPUTER MOVES TO SQUARE $move"; + return print_computer_victory() if $move == TARGET; + + $move = ask_player_move($move) or return forfeit(); + return print_player_victory() if $move == TARGET; + } +} + +sub is_valid_move ($move, $current, $skip_prevalidation = 0) { + + # pre-validation is needed for moves coming from the user + if (! $skip_prevalidation) { + state $valid_position = { map { $_ => 1 } board_identifiers() }; + return 0 unless $move =~ m{\A [1-9]\d+ \z}mxs; + return 1 if $move == 0; + return 0 unless $valid_position->{$move}; + return 0 if $move <= $current; + } + + # the move might be valid in general, let's check from $current + my $delta = $move - $current; + + # a valid move differs from the current position by a multiple of 10, + # or 11, or 21. If dividing by all of them yields a remainder, then + # the move is not valid + return 0 if $delta % 10 && $delta % 11 && $delta % 21; + + # otherwise it is + return 1; +} + +sub ask_player_move ($current) { + while ('necessary') { + my $move = ask_input('WHAT IS YOUR MOVE'); + return $move if is_valid_move($move, $current); + say "\nY O U C H E A T . . . TRY AGAIN"; + } +} + +sub computer_move ($current) { + + # this game has some optimal/safe positions from where it's possible + # to win with the right strategy. We will aim for them, if possible + state $optimals = [ 158, 127, 126, 75, 73 ]; + for my $optimal ($optimals->@*) { + + # moves can only increase, if we did not find any optimal move so far + # then there's no point going on + last if $optimal <= $current; + + # computer moves are "syntactically" valid, skip pre-validation + return $optimal if is_valid_move($optimal, $current, 'skip'); + + } + + # cannot reach an optimal position... resort to randomness + my $z = rand(); + return $current + 11 if $z > 0.6; # move down + return $current + 21 if $z > 0.3; # move diagonally + return $current + 10; ; # move horizontally +} + +sub board_identifiers { + return ( + 81, 71, 61, 51, 41, 31, 21, 11, + 92, 82, 72, 62, 52, 42, 32, 22, + 103, 93, 83, 73, 63, 53, 43, 33, + 114, 104, 94, 84, 74, 64, 54, 44, + 125, 115, 105, 95, 85, 75, 65, 55, + 136, 126, 116, 106, 96, 86, 76, 66, + 147, 137, 127, 117, 107, 97, 87, 77, + 158, 148, 138, 128, 118, 108, 98, 88, + ); +} + +sub print_player_victory { + print <<'END'; + +C O N G R A T U L A T I O N S . . . + +YOU HAVE WON--VERY WELL PLAYED. +IT LOOKS LIKE I HAVE MET MY MATCH. +THANKS FOR PLAYING---I CAN'T WIN ALL THE TIME. + +END +} + +sub print_computer_victory { + print <<'END'; + +NICE TRY, BUT IT LOOKS LIKE I HAVE WON. +THANKS FOR PLAYING. + +END +} + +sub forfeit { say "\nIT LOOKS LIKE I HAVE WON BY FORFEIT.\n" } + +sub ask_input ($prompt) { + print "$prompt? "; + defined(my $input = ) or __exit(); + + # remove spaces from the input (including newlines), they are not used + $input =~ s{\s+}{}gmxs; + + return $input; +} + +sub ask_yes_no ($prompt) { + while ('necessary') { + my $input = ask_input($prompt); + return 1 if $input =~ m{\A (?: yes | y) \z}imxs; + return 0 if $input =~ m{\A (?: no | n) \z}imxs; + say q{PLEASE ANSWER 'YES' OR 'NO'.}; + } +} + +sub ask_first_move { + while ('necessary') { + my $input = ask_input('WHERE WOULD YOU LIKE TO START'); + if ($input =~ m{\A (?: 0 | [1-9]\d+) \z}mxs) { + return 0 unless $input; + my $diagonal = int($input / 10); + my $row = $input % 10; + return $input if $row == 1 || $row == $diagonal; + } + say <<'END' +PLEASE READ THE DIRECTIONS AGAIN. +YOU HAVE BEGUN ILLEGALLY. + +END + } +} + +sub __exit { + say "\nOK --- THANKS AGAIN."; + exit 0; +} + +sub welcome { + print <<'END' + QUEEN + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + +END +} + +sub help { + print <<'END'; +WE ARE GOING TO PLAY A GAME BASED ON ONE OF THE CHESS +MOVES. OUR QUEEN WILL BE ABLE TO MOVE ONLY TO THE LEFT, +DOWN, OR DIAGONALLY DOWN AND TO THE LEFT. + +THE OBJECT OF THE GAME IS TO PLACE THE QUEEN IN THE LOWER +LEFT HAND SQUARE BY ALTERNATING MOVES BETWEEN YOU AND THE +COMPUTER. THE FIRST ONE TO PLACE THE QUEEN THERE WINS. + +YOU GO FIRST AND PLACE THE QUEEN IN ANY ONE OF THE SQUARES +ON THE TOP ROW OR RIGHT HAND COLUMN. +THAT WILL BE YOUR FIRST MOVE. +WE ALTERNATE MOVES. +YOU MAY FORFEIT BY TYPING '0' AS YOUR MOVE. +BE SURE TO PRESS THE RETURN KEY AFTER EACH RESPONSE. + + +END +} + +sub print_board { + say ''; + my @ids = board_identifiers(); + my $row_template = join ' ', ($ENV{ORIGINAL} ? '%d' : '%3d') x 8; + for my $A (0 .. 7) { + my $start = $A * 8; + my @range = $start .. $start + 7; + say ' ', sprintf $row_template, @ids[@range]; + say "\n"; + } + say ''; +} From 9f636574a41084dd4284f0c4b4066611f96d3a65 Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Fri, 7 Jan 2022 22:49:51 -0300 Subject: [PATCH 05/11] Added ruby version of russian roulette --- 76_Russian_Roulette/ruby/russianroulette.rb | 73 +++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 76_Russian_Roulette/ruby/russianroulette.rb diff --git a/76_Russian_Roulette/ruby/russianroulette.rb b/76_Russian_Roulette/ruby/russianroulette.rb new file mode 100644 index 00000000..abb3ad35 --- /dev/null +++ b/76_Russian_Roulette/ruby/russianroulette.rb @@ -0,0 +1,73 @@ +puts <<~INSTRUCTIONS + RUSSIAN ROULETTE + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + +THIS IS A GAME OF >>>>>>>>>>RUSSIAN ROULETTE. + +HERE IS A REVOLVER. + +INSTRUCTIONS + +NUMBER_OF_ROUNDS = 9 + +def parse_input + correct_input = false + + while not correct_input + puts " ?" + inp = gets.chomp + if inp == "1" or inp == "2" + correct_input = true + end + end + + inp +end + +while true + + dead = false + n = 0 + + puts "TYPE \'1\' TO SPIN CHAMBER AND PULL TRIGGER" + puts "TYPE \'2\' TO GIVE UP" + puts "GO" + + while not dead + + inp = parse_input + + if inp == "2" + break + end + + if rand > 0.8333333333333334 + dead = true + else + puts "- CLICK -" + n += 1 + end + + if n > NUMBER_OF_ROUNDS + break + end + + end + + if dead + puts "BANG!!!!! You're Dead!" + puts "Condolences will be sent to your relatives.\n\n\n" + puts "...Next victim..." + else + if n > NUMBER_OF_ROUNDS + puts "You win!!!!!" + puts "Let someone else blow his brain out.\n" + else + puts " Chicken!!!!!\n\n\n" + puts "...Next victim...." + end + end + +end From 32eee996546c66d3b21004b535da4abd01837c4a Mon Sep 17 00:00:00 2001 From: Pat Ludwig Date: Fri, 7 Jan 2022 21:26:46 -0600 Subject: [PATCH 06/11] Fix exception if choice 2 for damage is selected Initialize the variables. --- 12_Bombs_Away/javascript/bombsaway.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/12_Bombs_Away/javascript/bombsaway.js b/12_Bombs_Away/javascript/bombsaway.js index 835a2608..84831856 100644 --- a/12_Bombs_Away/javascript/bombsaway.js +++ b/12_Bombs_Away/javascript/bombsaway.js @@ -45,6 +45,8 @@ function tab(space) // Main program async function main() { + s = 0; + t = 0; while (1) { print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.\n"); while (1) { From ab2b9d0c3425e5d14fd6cbed4f8be1e71741ada7 Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Fri, 7 Jan 2022 21:51:00 -0600 Subject: [PATCH 07/11] Initial commit --- 51_Hurkle/perl/hurkle.pl | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100755 51_Hurkle/perl/hurkle.pl diff --git a/51_Hurkle/perl/hurkle.pl b/51_Hurkle/perl/hurkle.pl new file mode 100755 index 00000000..abb42d5a --- /dev/null +++ b/51_Hurkle/perl/hurkle.pl @@ -0,0 +1,84 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +# global variables + +my($GRID) = 10; +my($TRIES) = 5; + + +# main program starts here + +# print instructions +print <); + # Use a regex to attempt to parse out + # two integers separated by a comma. + if ($in =~ m{(\d+)\s*,\s*(\d+)}) { + $G1 = $1; $G2 = $2; + last CHECK; + } + # Input not accepted, please try again + print "Please enter two numbers separated by a comma ? "; + } + + if (abs($H1 - $G1) + abs($H2 - $G2) != 0) { + + # print directional info + printf("Go %s%s\n\n", + ($G2 == $H2 ? '' : $G2 < $H2 ? 'north' : 'south'), + ($G1 == $H1 ? '' : $G1 < $H1 ? 'east' : 'west' ), + ); + } else { + # win! + printf("\nYou found him in %d tries!\n", $i); + # move to the continue block + next PLAY; + } + } # tries loop + + # No more guesses + printf("Sorry, that's %d gueses.\n", $TRIES); + printf("The Hurkle is at %d, %d\n", $H1, $H2); +} + +# Execution comes here either from the "next PLAY" +# statement, or by the PLAY block naturally ending +# after the player has lost. +continue { + print "\nLet's play again. Hurkle is hiding.\n\n"; +} \ No newline at end of file From 4d66d18e714e08384395a03775d6f1756ef43bc8 Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Fri, 7 Jan 2022 21:51:56 -0600 Subject: [PATCH 08/11] typo --- 51_Hurkle/perl/hurkle.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/51_Hurkle/perl/hurkle.pl b/51_Hurkle/perl/hurkle.pl index abb42d5a..52d7e853 100755 --- a/51_Hurkle/perl/hurkle.pl +++ b/51_Hurkle/perl/hurkle.pl @@ -72,7 +72,7 @@ PLAY: while (1) { } # tries loop # No more guesses - printf("Sorry, that's %d gueses.\n", $TRIES); + printf("Sorry, that's %d guesses.\n", $TRIES); printf("The Hurkle is at %d, %d\n", $H1, $H2); } From 83a9d95fc43f65233719434f2af5f4039aec50ab Mon Sep 17 00:00:00 2001 From: James Allenspach Date: Fri, 7 Jan 2022 21:52:30 -0600 Subject: [PATCH 09/11] add line break at eof --- 51_Hurkle/perl/hurkle.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/51_Hurkle/perl/hurkle.pl b/51_Hurkle/perl/hurkle.pl index 52d7e853..1497e50c 100755 --- a/51_Hurkle/perl/hurkle.pl +++ b/51_Hurkle/perl/hurkle.pl @@ -81,4 +81,4 @@ PLAY: while (1) { # after the player has lost. continue { print "\nLet's play again. Hurkle is hiding.\n\n"; -} \ No newline at end of file +} From 42ed63d175cd387e5505485d7c80b9bd78e32766 Mon Sep 17 00:00:00 2001 From: Pat Ludwig Date: Fri, 7 Jan 2022 22:03:14 -0600 Subject: [PATCH 10/11] Add *.class to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4707e8fb..d2115efc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.class */.vs *.suo From bc6580f2098dce0f215e0821ed87c68dd2ec951d Mon Sep 17 00:00:00 2001 From: Tim Buchalka <70119791+journich@users.noreply.github.com> Date: Sat, 8 Jan 2022 17:28:18 +1030 Subject: [PATCH 11/11] Fix for gunner rate being incorrectly asked for when missiles selected - see issue #457. Add test for player entering an amount for the percentage hit rate of gunners less than the minimum. It now shoots down the player as per the original game. --- 12_Bombs_Away/java/src/BombsAway.java | 51 +++++++++++++++++---------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/12_Bombs_Away/java/src/BombsAway.java b/12_Bombs_Away/java/src/BombsAway.java index e156ea73..b084ddcb 100644 --- a/12_Bombs_Away/java/src/BombsAway.java +++ b/12_Bombs_Away/java/src/BombsAway.java @@ -4,10 +4,16 @@ import java.util.Scanner; * Game of Bombs Away * * Based on the Basic game of Bombs Away here - * https://github.com/coding-horror/basic-computer-games/blob/main/12%20Bombs%20Away/bombsaway.bas + * https://github.com/coding-horror/basic-computer-games/blob/main/12_Bombs_Away/bombsaway.bas + * + * Note: The idea was to create a version of the 1970's Basic game in Java, without adding new features. + * Obvious bugs where found have been fixed, but the playability and overlook and feel + * of the game have been faithfully reproduced. + * + * Modern Java coding conventions have been employed and JDK 11 used for maximum compatibility. + * + * Java port by https://github.com/journich * - * Note: The idea was to create a version of the 1970's Basic game in Java, without introducing - * new features - no additional text, error checking, etc has been added. */ public class BombsAway { @@ -116,8 +122,9 @@ public class BombsAway { private int missions; - private int chanceToHit; + private int chanceToBeHit; private int percentageHitRateOfGunners; + private boolean liar; public BombsAway() { @@ -139,8 +146,9 @@ public class BombsAway { // Show an introduction the first time the game is played. case START: intro(); - chanceToHit = 0; + chanceToBeHit = 0; percentageHitRateOfGunners = 0; + liar = false; gameState = GAME_STATE.CHOOSE_SIDE; break; @@ -267,7 +275,7 @@ public class BombsAway { break; case CHOOSE_ENEMY_DEFENCES: - boolean bothWeapons = true; + percentageHitRateOfGunners = 0; ENEMY_DEFENCES enemyDefences = getEnemyDefences("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3) ? "); if(enemyDefences == null) { @@ -275,31 +283,38 @@ public class BombsAway { } else { switch(enemyDefences) { case MISSILES: - case GUNS: - bothWeapons = false; + chanceToBeHit = 35; + break; - // fall through on purpose to BOTH since its pretty much identical code other than the chance to hit - // increasing if both weapons are part of the defence. + case GUNS: + + // fall through (no break) on purpose to case BOTH + // since it's identical code for GUNS or BOTH weapons case BOTH: + chanceToBeHit = 0; percentageHitRateOfGunners = getNumberFromKeyboard("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? "); if(percentageHitRateOfGunners < 10) { System.out.println("YOU LIE, BUT YOU'LL PAY..."); - } - if(bothWeapons) { - chanceToHit = 35; - + liar = true; } break; } } - gameState = GAME_STATE.PROCESS_FLAK; + // If player didn't lie when entering percentage hit rate of gunners continue with game + // Otherwise shoot down the player. + if(!liar) { + gameState = GAME_STATE.PROCESS_FLAK; + } else { + gameState = GAME_STATE.SHOT_DOWN; + } + break; - // Determine if the players airplan makes it through the Flak. + // Determine if the player's airplane makes it through the Flak. case PROCESS_FLAK: double calc = (CHANCE_OF_BEING_SHOT_DOWN_BASE * randomNumber(1)); - if ((chanceToHit + percentageHitRateOfGunners) > calc) { + if ((chanceToBeHit + percentageHitRateOfGunners) > calc) { gameState = GAME_STATE.SHOT_DOWN; } else { gameState = GAME_STATE.MADE_IT_THROUGH_FLAK; @@ -462,7 +477,7 @@ public class BombsAway { /** * Check whether a string equals one of a variable number of values * Useful to check for Y or YES for example - * Comparison is case insensitive. + * Comparison is case-insensitive. * * @param text source string * @param values a range of values to compare against the source string