Initial port of Poker to plain Java

This commit is contained in:
simonskrede
2022-01-08 00:42:53 +01:00
committed by GitHub
parent bd62aa477e
commit a14a7bea3c

851
71_Poker/java/Poker.java Normal file
View File

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