Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,40 @@
# example_roulette
Program to refactor that plays a game of roulette
Refactoring by: Michael Daou and Sharrin Manor

Added High/Low bet subclass -- not enough time to implement the other two but would be just as simple and straightforward, as explained in the response to the questions below.

##### What code would be needed to be added to the game in order to allow the user to make another type of bet?

After refactoring, new bet types could be introduced into the game as new classes extending the Bet superclass, and implementing their ```placeBet()``` and ```betIsMade()``` methods. In addition, the new Bet type must be added to the array in Game holding the different types of types.

##### In what ways is the refactored code simpler?

The refactored code is simpler because it's clearer to see what the different types of bets are; instead of having an if-statements that redirect the input to the appropriate code, the input is fed directly into the method defined within a specific Bet subclass.

This also means that there is less code in the Game class making it more readable and modifiable.

##### In what ways is the refactored code more complex?

There are more classes in the refactored code and each subclass of Bet has its own behavior.

##### What trade-offs did we make when refactoring our old code?
We traded customizability for the compactness associated with keeping all code within one class and even one method having several if-statements.

##### Which code do we prefer, and why?
We prefer the refactored code because it's designed more intuitively and allows for more customizability especially with adding more Bet subclasses.

#####What methods would make sense as behaviors of a Bet hierarchy (i.e., make bets open to extension)?

A Bet superclass and a subclass for each Bet type (red/black, high/low, odd/even) where each subclass uses the same methods of the superclass but implements them differently.

#####What methods would help improve the code in the Game's methods (i.e., close it to modification)?

Making things private and having getter and setter methods would close the Game class to modification. We've also removed methods from Game and moved them to the Bet subclasses. If we had more time, we would have found a way to make the Bet array list a separate entity and not require its modification within Game to add new Bet types.

#####What methods can be completely implemented in the Bet super-class (i.e., are common across the hierarchy), and which completely in the Bet sub-classes (i.e., vary across the hierarchy)?

The methods that can be completely implemented in the Bet superclass are the description, the odds and the constructor.

The methods that vary are the ones that determine if the user's bet was a winning bet.

#####How should the Game class create the correct Bet subclass?
We are creating our own subclasses, but the Game class instantiates them at the beginning and puts them in an array. Given more time, we would have created a method within Bet that creates new subclasses, and gotten rid of the array that must be manually changed, and make the new method modify that array to include new bet choices.
21 changes: 19 additions & 2 deletions src/roulette/Bet.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package roulette;

import util.ConsoleReader;

/**
* Represents player's attempt to bet on outcome of the roulette wheel's spin.
*
* @author Robert C. Duvall
*/
public class Bet {
abstract class Bet {
private String myDescription;
private int myOdds;
protected String chosenBet = "";


/**
* Constructs a bet with the given name and odds.
Expand All @@ -34,4 +36,19 @@ public int getOdds () {
public String getDescription () {
return myDescription;
}

public void placeBet(){


}

public String getChosenBet(){
return chosenBet;
}

protected boolean betIsMade(Wheel color){

return false;
}

}
29 changes: 29 additions & 0 deletions src/roulette/BetEvenOdd.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package roulette;

import util.ConsoleReader;

public class BetEvenOdd extends Bet{

public BetEvenOdd(String description, int odds) {
super(description, odds);
// TODO Auto-generated constructor stub



}

public void placeBet(){

chosenBet = ConsoleReader.promptOneOf("Please bet", "even", "odd");

}

protected boolean betIsMade(Wheel myWheel){

return (myWheel.getNumber() % 2 == 0 && chosenBet.equals("even")) ||
(myWheel.getNumber() % 2 == 1 && chosenBet.equals("odd"));

}


}
27 changes: 27 additions & 0 deletions src/roulette/BetHighLow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package roulette;

import util.ConsoleReader;

public class BetHighLow extends Bet{

public BetHighLow(String description, int odds) {
super(description, odds);
// TODO Auto-generated constructor stub


}

public void placeBet(){

chosenBet = ConsoleReader.promptOneOf("Please bet","High", "Low");

}

@Override
protected boolean betIsMade(Wheel myWheel){
return (myWheel.getNumber() <=18 && chosenBet.equals("Low")) ||
(myWheel.getNumber() > 19 && chosenBet.equals("High"));


}
}
27 changes: 27 additions & 0 deletions src/roulette/BetRedBlack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package roulette;

import util.ConsoleReader;

public class BetRedBlack extends Bet{

public BetRedBlack(String description, int odds) {
super(description, odds);
// TODO Auto-generated constructor stub


}

public void placeBet(){

chosenBet = ConsoleReader.promptOneOf("Please bet", Wheel.BLACK, Wheel.RED);

}

@Override
protected boolean betIsMade(Wheel myWheel){
return myWheel.getColor().equals(chosenBet);



}
}
27 changes: 27 additions & 0 deletions src/roulette/BetThree.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package roulette;

import util.ConsoleReader;

public class BetThree extends Bet {

public BetThree(String description, int odds) {
super(description, odds);
// TODO Auto-generated constructor stub


}

public void placeBet(){

chosenBet = "" + ConsoleReader.promptRange("Enter first of three consecutive numbers",
1, Wheel.NUM_SPOTS - 3);

}

protected boolean betIsMade(Wheel myWheel){
int start = Integer.parseInt(chosenBet);
return (start <= myWheel.getNumber() && myWheel.getNumber() < start + 3);
}


}
164 changes: 65 additions & 99 deletions src/roulette/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,110 +9,76 @@
* @author Robert C. Duvall
*/
public class Game {
// name of the game
private static final String DEFAULT_NAME = "Roulette";
// bets player can make
private Bet[] myPossibleBets = {
new Bet("Red or Black", 1),
new Bet("Odd or Even", 1),
new Bet("Three in a Row", 11)
};
private Wheel myWheel;
// name of the game
private static final String DEFAULT_NAME = "Roulette";
// bets player can make
private Bet[] myPossibleBets = {
new BetRedBlack("Red or Black", 1),
new BetEvenOdd("Odd or Even", 1),
new BetThree("Three in a Row", 11),
new BetHighLow("High/Low", 1)
};
private Wheel myWheel;
private Bet myBetType;

/**
* Construct the game.
*/
public Game () {
myWheel = new Wheel();
}
/**
* Construct the game.
*/
public Game () {
myWheel = new Wheel();
}

/**
* @return name of the game
*/
public String getName () {
return DEFAULT_NAME;
}
/**
* @return name of the game
*/
public String getName () {
return DEFAULT_NAME;
}

/**
* Play a round of roulette.
*
* Prompt player to make a bet, then spin the roulette wheel, and then verify
* that the bet is won or lost.
*
* @param player one that wants to play a round of the game
*/
public void play (Gambler player) {
int amount = ConsoleReader.promptRange("How much do you want to bet",
0, player.getBankroll());
int whichBet = promptForBet();
String betChoice = placeBet(whichBet);
/**
* Play a round of roulette.
*
* Prompt player to make a bet, then spin the roulette wheel, and then verify
* that the bet is won or lost.
*
* @param player one that wants to play a round of the game
*/
public void play (Gambler player) {
int amount = ConsoleReader.promptRange("How much do you want to bet",
0, player.getBankroll());
int whichBet = promptForBet();

myBetType = myPossibleBets[whichBet];
myBetType.placeBet();
System.out.println();

System.out.print("Spinning ...");
myWheel.spin();
System.out.println(String.format("Dropped into %s %d", myWheel.getColor(), myWheel.getNumber()));

if (myBetType.betIsMade(myWheel)) {
System.out.println("*** Congratulations :) You win ***");
amount *= myBetType.getOdds();
}
else {
System.out.println("*** Sorry :( You lose ***");
amount *= -1;
}
player.updateBankroll(amount);
}

/**
* Prompt the user to make a bet from a menu of choices.
*/
private int promptForBet () {
System.out.println("You can make one of the following types of bets:");
for (int k = 0; k < myPossibleBets.length; k++) {
System.out.println(String.format("%d) %s", (k + 1), myPossibleBets[k].getDescription()));
}
return ConsoleReader.promptRange("Please make a choice", 1, myPossibleBets.length) - 1;
}

System.out.print("Spinning ...");
myWheel.spin();
System.out.println(String.format("Dropped into %s %d", myWheel.getColor(), myWheel.getNumber()));
if (betIsMade(whichBet, betChoice)) {
System.out.println("*** Congratulations :) You win ***");
amount *= myPossibleBets[whichBet].getOdds();
}
else {
System.out.println("*** Sorry :( You lose ***");
amount *= -1;
}
player.updateBankroll(amount);
}

/**
* Prompt the user to make a bet from a menu of choices.
*/
private int promptForBet () {
System.out.println("You can make one of the following types of bets:");
for (int k = 0; k < myPossibleBets.length; k++) {
System.out.println(String.format("%d) %s", (k + 1), myPossibleBets[k].getDescription()));
}
return ConsoleReader.promptRange("Please make a choice", 1, myPossibleBets.length) - 1;
}

/**
* Place the given bet by prompting user for specific information need to complete that bet.
*
* @param whichBet specific bet chosen by the user
*/
private String placeBet (int whichBet) {
String result = "";
if (whichBet == 0) {
result = ConsoleReader.promptOneOf("Please bet", Wheel.BLACK, Wheel.RED);
}
else if (whichBet == 1) {
result = ConsoleReader.promptOneOf("Please bet", "even", "odd");
}
else if (whichBet == 2) {
result = "" + ConsoleReader.promptRange("Enter first of three consecutive numbers",
1, Wheel.NUM_SPOTS - 3);
}
System.out.println();
return result;
}

/**
* Checks if the given bet is won or lost given user's choice and result of spinning the wheel.
*
* @param whichBet specific bet chosen by the user
* @param betChoice specific value user chose to try to win the bet
*/
private boolean betIsMade (int whichBet, String betChoice) {
if (whichBet == 0) {
return myWheel.getColor().equals(betChoice);
}
else if (whichBet == 1) {
return (myWheel.getNumber() % 2 == 0 && betChoice.equals("even")) ||
(myWheel.getNumber() % 2 == 1 && betChoice.equals("odd"));
}
else if (whichBet == 2) {
int start = Integer.parseInt(betChoice);
return (start <= myWheel.getNumber() && myWheel.getNumber() < start + 3);
}
else {
return false;
}
}
}