mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 07:29:02 -08:00
75_Roulette in java
This commit is contained in:
65
75_Roulette/java/Bet.java
Normal file
65
75_Roulette/java/Bet.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/* A bet has a target (the code entered, which is 1-36, or special values for
|
||||
* the various groups, zero and double-zero), and an amount in dollars
|
||||
*/
|
||||
|
||||
public class Bet {
|
||||
public int target;
|
||||
public int amount;
|
||||
|
||||
/* bet on a target, of an amount */
|
||||
public Bet(int on, int of) {
|
||||
target = on; amount = of;
|
||||
}
|
||||
|
||||
/* check if this is a valid bet - on a real target and of a valid amount */
|
||||
public boolean isValid() {
|
||||
return ((target > 0) && (target <= 50) &&
|
||||
(amount >= 5) && (amount <= 500));
|
||||
}
|
||||
|
||||
/* utility to return either the odds amount in the case of a win, or zero for a loss */
|
||||
private int m(boolean isWon, int odds) {
|
||||
return isWon? odds: 0;
|
||||
}
|
||||
|
||||
/* look at the wheel to see if this bet won.
|
||||
* returns 0 if it didn't, or the odds if it did
|
||||
*/
|
||||
public int winsOn(Wheel w) {
|
||||
if (target < 37) {
|
||||
// A number bet 1-36 wins at odds of 35 if it is the exact number
|
||||
return m(w.isNumber() && (w.number() == target), 35);
|
||||
} else
|
||||
switch (target) {
|
||||
case 37: // 1-12, odds of 2
|
||||
return m(w.isNumber() && (w.number() <= 12), 2);
|
||||
case 38: // 13-24, odds of 2
|
||||
return m(w.isNumber() && (w.number() > 12) && (w.number() <= 24), 2);
|
||||
case 39: // 25-36, odds of 2
|
||||
return m(w.isNumber() && (w.number() > 24), 2);
|
||||
case 40: // Column 1, odds of 2
|
||||
return m(w.isNumber() && ((w.number() % 3) == 1), 2);
|
||||
case 41: // Column 2, odds of 2
|
||||
return m(w.isNumber() && ((w.number() % 3) == 2), 2);
|
||||
case 42: // Column 3, odds of 2
|
||||
return m(w.isNumber() && ((w.number() % 3) == 0), 2);
|
||||
case 43: // 1-18, odds of 1
|
||||
return m(w.isNumber() && (w.number() <= 18), 1);
|
||||
case 44: // 19-36, odds of 1
|
||||
return m(w.isNumber() && (w.number() > 18), 1);
|
||||
case 45: // even, odds of 1
|
||||
return m(w.isNumber() && ((w.number() %2) == 0), 1);
|
||||
case 46: // odd, odds of 1
|
||||
return m(w.isNumber() && ((w.number() %2) == 1), 1);
|
||||
case 47: // red, odds of 1
|
||||
return m(w.isNumber() && (w.color() == Wheel.BLACK), 1);
|
||||
case 48: // black, odds of 1
|
||||
return m(w.isNumber() && (w.color() == Wheel.RED), 1);
|
||||
case 49: // single zero, odds of 35
|
||||
return m(w.value().equals("0"), 35);
|
||||
case 50: // double zero, odds of 35
|
||||
return m(w.value().equals("00"), 35);
|
||||
}
|
||||
throw new RuntimeException("Program Error - invalid bet");
|
||||
}
|
||||
}
|
||||
234
75_Roulette/java/Roulette.java
Normal file
234
75_Roulette/java/Roulette.java
Normal file
@@ -0,0 +1,234 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
|
||||
public class Roulette {
|
||||
public static void main(String args[]) throws Exception {
|
||||
Roulette r = new Roulette();
|
||||
r.play();
|
||||
}
|
||||
|
||||
private BufferedReader reader;
|
||||
private PrintStream writer;
|
||||
|
||||
private int house; // how much money does the house have
|
||||
private int player; // how much money does the player have
|
||||
private Wheel wheel = new Wheel();
|
||||
|
||||
public Roulette() {
|
||||
reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
writer = System.out;
|
||||
house = 100000;
|
||||
player = 1000;
|
||||
}
|
||||
|
||||
// for a test / cheat mode -- set the random number generator to a known value
|
||||
private void setSeed(long l) {
|
||||
wheel.setSeed(l);
|
||||
}
|
||||
|
||||
public void play() {
|
||||
try {
|
||||
intro();
|
||||
writer.println("WELCOME TO THE ROULETTE TABLE\n" +
|
||||
"DO YOU WANT INSTRUCTIONS");
|
||||
String instr = reader.readLine();
|
||||
if (!instr.toUpperCase().startsWith("N"))
|
||||
instructions();
|
||||
|
||||
while (betAndSpin()) { // returns true if the game is to continue
|
||||
}
|
||||
|
||||
if (player <= 0) {
|
||||
// player ran out of money
|
||||
writer.println("THANKS FOR YOUR MONEY.\nI'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL");
|
||||
} else {
|
||||
// player has money -- print them a check
|
||||
writer.println("TO WHOM SHALL I MAKE THE CHECK");
|
||||
|
||||
String payee = reader.readLine();
|
||||
|
||||
writer.println("-".repeat(72));
|
||||
tab(50); writer.println("CHECK NO. " + (new Random().nextInt(100) + 1));
|
||||
writer.println();
|
||||
tab(40); writer.println(LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)));
|
||||
writer.println("\n\nPAY TO THE ORDER OF-----" + payee + "-----$ " + player);
|
||||
writer.print("\n\n");
|
||||
tab(10); writer.println("THE MEMORY BANK OF NEW YORK\n");
|
||||
tab(40); writer.println("THE COMPUTER");
|
||||
tab(40); writer.println("----------X-----\n");
|
||||
writer.println("-".repeat(72));
|
||||
writer.println("COME BACK SOON!\n");
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
// this should not happen
|
||||
System.err.println("System error:\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the starting introduction */
|
||||
private void intro() throws IOException {
|
||||
tab(32); writer.println("ROULETTE");
|
||||
tab(15); writer.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n");
|
||||
}
|
||||
|
||||
/* Display the game instructions */
|
||||
private void instructions() {
|
||||
String[] instLines = new String[] {
|
||||
"THIS IS THE BETTING LAYOUT",
|
||||
" (*=RED)",
|
||||
"" ,
|
||||
" 1* 2 3*",
|
||||
" 4 5* 6 ",
|
||||
" 7* 8 9*",
|
||||
"10 11 12*",
|
||||
"---------------",
|
||||
"13 14* 15 ",
|
||||
"16* 17 18*",
|
||||
"19* 20 21*",
|
||||
"22 23* 24 ",
|
||||
"---------------",
|
||||
"25* 26 27*",
|
||||
"28 29 30*",
|
||||
"31 32* 33 ",
|
||||
"34* 35 36*",
|
||||
"---------------",
|
||||
" 00 0 ",
|
||||
"" ,
|
||||
"TYPES OF BETS",
|
||||
"" ,
|
||||
"THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET",
|
||||
"ON THAT NUMBER.",
|
||||
"THESE PAY OFF 35:1",
|
||||
"" ,
|
||||
"THE 2:1 BETS ARE:",
|
||||
" 37) 1-12 40) FIRST COLUMN",
|
||||
" 38) 13-24 41) SECOND COLUMN",
|
||||
" 39) 25-36 42) THIRD COLUMN",
|
||||
"" ,
|
||||
"THE EVEN MONEY BETS ARE:",
|
||||
" 43) 1-18 46) ODD",
|
||||
" 44) 19-36 47) RED",
|
||||
" 45) EVEN 48) BLACK",
|
||||
"",
|
||||
" 49)0 AND 50)00 PAY OFF 35:1",
|
||||
" NOTE: 0 AND 00 DO NOT COUNT UNDER ANY",
|
||||
" BETS EXCEPT THEIR OWN.",
|
||||
"",
|
||||
"WHEN I ASK FOR EACH BET, TYPE THE NUMBER",
|
||||
"AND THE AMOUNT, SEPARATED BY A COMMA.",
|
||||
"FOR EXAMPLE: TO BET $500 ON BLACK, TYPE 48,500",
|
||||
"WHEN I ASK FOR A BET.",
|
||||
"",
|
||||
"THE MINIMUM BET IS $5, THE MAXIMUM IS $500.",
|
||||
"" };
|
||||
writer.println(String.join("\n", instLines));
|
||||
}
|
||||
|
||||
/* Take a set of bets from the player, then spin the wheel and work out the winnings *
|
||||
* This returns true if the game is to continue afterwards
|
||||
*/
|
||||
private boolean betAndSpin() throws IOException {
|
||||
int betCount = 0;
|
||||
|
||||
while (betCount == 0) { // keep asking how many bets until we get a good answer
|
||||
try {
|
||||
writer.println("HOW MANY BETS");
|
||||
String howMany = reader.readLine();
|
||||
betCount = Integer.parseInt(howMany.strip());
|
||||
|
||||
if ((betCount < 1) || (betCount > 100)) betCount = 0; // bad -- set zero and ask again
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this happens if the input is not a number
|
||||
writer.println("INPUT ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Integer> betsMade = new HashSet<>(); // Bet targets already made, so we can spot repeats
|
||||
ArrayList<Bet> bets = new ArrayList<>(); // All the bets for this round
|
||||
|
||||
while (bets.size() < betCount) {
|
||||
Bet bet = new Bet(0, 0); // an invalid bet to hold the place
|
||||
while (!bet.isValid()) { // keep asking until it is valid
|
||||
try {
|
||||
writer.println("NUMBER " + (bets.size() + 1));
|
||||
String fields[] = reader.readLine().split(",");
|
||||
if (fields.length == 2) {
|
||||
bet = new Bet(Integer.parseInt(fields[0].strip()),
|
||||
Integer.parseInt(fields[1].strip()));
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
writer.println("INPUT ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there is already a bet on the same target
|
||||
if (betsMade.contains(bet.target)) {
|
||||
writer.println("YOU MADE THAT BET ONCE ALREADY,DUM-DUM");
|
||||
} else {
|
||||
betsMade.add(bet.target); // note this target has now been bet on
|
||||
bets.add(bet);
|
||||
}
|
||||
}
|
||||
|
||||
writer.println("SPINNING\n\n");
|
||||
|
||||
wheel.spin(); // this deliberately takes some random amount of time
|
||||
|
||||
writer.println(wheel.value());
|
||||
|
||||
// go through the bets, and evaluate each one
|
||||
int betNumber = 1;
|
||||
for (Bet b : bets) {
|
||||
int multiplier = b.winsOn(wheel);
|
||||
if (multiplier == 0) {
|
||||
// lost the amount of the bet
|
||||
writer.println("YOU LOSE " + b.amount + " DOLLARS ON BET " + betNumber);
|
||||
house += b.amount;
|
||||
player -= b.amount;
|
||||
} else {
|
||||
// won the amount of the bet, multiplied by the odds
|
||||
int winnings = b.amount * multiplier;
|
||||
writer.println("YOU WIN " + winnings + " DOLLARS ON BET " + betNumber);
|
||||
house -= winnings;
|
||||
player += winnings;
|
||||
}
|
||||
++betNumber;
|
||||
}
|
||||
|
||||
writer.println("\nTOTALS:\tME\tYOU\n\t" + house + "\t" + player);
|
||||
|
||||
if (player <= 0) {
|
||||
writer.println("OOPS! YOU JUST SPENT YOUR LAST DOLLAR");
|
||||
return false; // do not repeat since the player has no more money
|
||||
}
|
||||
if (house <= 0) {
|
||||
writer.println("YOU BROKE THE HOUSE!");
|
||||
player = 101000; // can't win more than the house started with
|
||||
return false; // do not repeat since the house has no more money
|
||||
}
|
||||
|
||||
// player still has money, and the house still has money, so ask the player
|
||||
// if they want to continue
|
||||
writer.println("AGAIN");
|
||||
String doContinue = reader.readLine();
|
||||
|
||||
// repeat if the answer was not "n" or "no"
|
||||
return (!doContinue.toUpperCase().startsWith("N"));
|
||||
}
|
||||
|
||||
// utility to print n spaces for formatting
|
||||
private void tab(int n) {
|
||||
writer.print(" ".repeat(n));
|
||||
}
|
||||
}
|
||||
69
75_Roulette/java/Wheel.java
Normal file
69
75_Roulette/java/Wheel.java
Normal file
@@ -0,0 +1,69 @@
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
// The roulette wheel
|
||||
public class Wheel {
|
||||
// List the numbers which are black
|
||||
private HashSet<Integer> black = new HashSet<>(Arrays.asList(new Integer[] { 1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36 }));
|
||||
|
||||
private Random random = new Random();
|
||||
private int pocket = 38;
|
||||
|
||||
public static final int ZERO=0;
|
||||
public static final int BLACK=1;
|
||||
public static final int RED=2;
|
||||
|
||||
// Set up a wheel. You call "spin", and then can check the result.
|
||||
public Wheel() {
|
||||
}
|
||||
|
||||
// Cheat / test mode
|
||||
void setSeed(long l) {
|
||||
random.setSeed(l);
|
||||
}
|
||||
|
||||
// Spin the wheel onto a new random value.
|
||||
public void spin() {
|
||||
// keep spinning for a while
|
||||
do {
|
||||
try {
|
||||
// 1 second delay. Where it stops, nobody knows
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e) {}
|
||||
|
||||
pocket = random.nextInt(38) + 1;
|
||||
} while (random.nextInt(4) > 0); // keep spinning until it stops
|
||||
}
|
||||
|
||||
// The string representation of the number; 1-36, 0, or 00
|
||||
public String value() {
|
||||
if (pocket == 37) return "0";
|
||||
else if (pocket == 38) return "00";
|
||||
else return String.valueOf(pocket);
|
||||
}
|
||||
|
||||
// True if either 0 or 00 is hit
|
||||
public boolean zero() {
|
||||
return (pocket > 36);
|
||||
}
|
||||
|
||||
// True if anything other than 0 or 00 is hit
|
||||
public boolean isNumber() {
|
||||
return (pocket < 37);
|
||||
}
|
||||
|
||||
// The number rolled
|
||||
public int number() {
|
||||
if (zero()) return 0;
|
||||
else return pocket;
|
||||
}
|
||||
|
||||
// Either ZERO, BLACK, or RED
|
||||
public int color() {
|
||||
if (zero()) return ZERO;
|
||||
else if (black.contains(pocket)) return BLACK;
|
||||
else return RED;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user