1 CSC 221: Computer Programming I Spring 2010 interaction & design modular design: roulette game ...

15
1 CSC 221: Computer Programming I Spring 2010 interaction & design modular design: roulette game constants, static fields % operator, string equals variable scope logical operators

Transcript of 1 CSC 221: Computer Programming I Spring 2010 interaction & design modular design: roulette game ...

Page 1: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

1

CSC 221: Computer Programming I

Spring 2010

interaction & design modular design: roulette game constants, static fields % operator, string equals variable scope logical operators

Page 2: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

2

Roulette games

consider the task of simulating a roulette game need to be able to spin a wheel make bets, either by number or even/odd keep track of winnings/losses (most likely losses!)

behaviors? create a game initialize the player's bankroll for each spin of the wheel

get the player's bet determine if winner and update bankroll accordingly make sure the player has credits in order to play?

we could try modeling a game by implementing a class directly must model the wheel behavior, also manage the bankroll and bets

lots of details to keep track of; not easy to generalize

Page 3: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

3

A modular design

instead, we can encapsulate all of the behavior of a roulette wheel in a class

RouletteWheel class: create a RouletteWheel spin the wheel, return number keep track of the number of spins so far

once the RouletteWheel class is defined, a RouletteGame will be much simpler

RouletteGame class: create a RouletteGame (with its own RouletteWheel) add credits to bankroll check the bankroll balance take a number bet & determine if a winner take an even/odd bet & determine if a winner

Page 4: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

4

RouletteWheel class

public class RouletteWheel { private Die roller; private int numSpins; public RouletteWheel() { this.roller = new Die(38); this.numSpins = 0; }

public int spin() { int number = this.roller.roll(); this.numSpins++;

if (number > 36) { return 0; } else { return number; } } public int getNumberOfSpins() { return this.numSpins; }}

more naturally:

fields store a Die (for generating random numbers) and a counter for the number of spins

constructor creates the Die object and initializes the count

methods access and update these fields to maintain the wheel's state

CREATE AND PLAY

Page 5: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

5

Magic numbers

the RouletteWheel class works, but what if we wanted to change to a European-style wheel? only 1-36 and 0 (no 00)

would have to change die = new Die(38);to die = new Die(37);

having "magic numbers" like 38 in code is bad practiceunclear what 38 refers to when

reading the coderequires searching for the number

when a change is desired

public class RouletteWheel { private Die roller; private int numSpins; public RouletteWheel() { this.roller = new Die(38); this.numSpins = 0; }

public int spin() { int number = this.roller.roll(); this.numSpins++;

if (number > 36) { return 0; } else { return number; } } public int getNumberOfSpins() { return this.numSpins; }}

Page 6: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

6

Constants

better solution: define a constant a constant is a variable whose value

cannot change use a constant any time a "magic

number" appears in code

a constant declaration looks like any other field except the keyword final specifies that

the variable, once assigned a value, is unchangeable

the keyword static specifies that the variable is shared by all objects of that class

since a final value cannot be changed, it is wasteful to have every object store a copy of it

instead, can have one static variable that is shared by all

by convention, constants are written in all upper-case with underscores

public class RouletteWheel { private final static int MAX_NUM = 36; private final static int NUM_ZEROS = 2;

private Die roller; private int numSpins; public RouletteWheel() { this.roller = new Die(RouletteWheel.MAX_NUM + RouletteWheel.NUM_ZEROS); this.numSpins = 0; }

public int spin() { int number = this.roller.roll(); this.numSpins++;

if (number > RouletteWheel.MAX_NUM) { return 0; } else { return number; } } public int getNumberOfSpins() { return this.numSpins; }}

Page 7: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

7

Static fields

in fact, it is sometimes useful to have static fields that aren't constants if all roulette wheels have the same

range, there is no reason for every wheel to have its own Die

we could declare the Die field to be static, so that the one Die is shared by all wheels

the first RouletteWheel object creates/inits the field, subsequent objects simply access it

note: methods can be declared static as well e.g., Math.random()

MORE LATER

public class RouletteWheel { private final static int MAX_NUM = 36; private final static int NUM_ZEROS = 2; private static Die roller = new Die(RouletteWheel.MAX_NUM + RouletteWheel.NUM_ZEROS); private int numSpins; public RouletteWheel() { this.numSpins = 0; }

public int spin() { int number = RouletteWheel.roller.roll(); this.numSpins++;

if (number > RouletteWheel.MAX_NUM) { return 0; } else { return number; } } public int getNumberOfSpins() { return this.numSpins; }}

Page 8: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

using the RouletteWheel class, a RouletteGame class is straightforward

fields store roulette wheel and bankroll

constructor creates the RouletteWheel and inits the bankroll

methods utilize the RouletteWheel methods to produce the game behaviors

8

RouletteGame classpublic class RouletteGame { private RouletteWheel wheel; private int credits;

public RouletteGame() { this.wheel = new RouletteWheel(); this.credits = 0; }

public void addCredits(int numCredits) { this.credits += numCredits; } public int checkCredits() { return this.credits; } public String makeBet(int betAmount, int number) { int result = this.wheel.spin(); if (result == number) { this.credits += 35*betAmount; return result + " - winner"; } else { this.credits -= betAmount; return result + " - loser"; } } public String makeBet(int betAmount, String betType) { int result = this.wheel.spin(); String resultType = "odd"; if (result % 2 == 0) { resultType = "even"; } if (betType.equals(resultType)) { this.credits += betAmount; return result + " - winner"; } else { this.credits -= betAmount; return result + " - loser"; } }}

Page 9: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

the % operator returns the remainder after dividing one number by another

useful for determining odd/even

(result % 2)

will evaluate to 0 if result is even, 1 if odd

9

RouletteGame details: % and equalspublic class RouletteGame { private RouletteWheel wheel; private int credits;

. . . public String makeBet(int betAmount, String betType) { int result = this.wheel.spin(); String resultType = "odd"; if (result % 2 == 0) { resultType = "even"; } if (betType.equals(resultType)) { this.credits += betAmount; return result + " - winner"; } else { this.credits -= betAmount; return result + " - loser"; } }}

when comparing two String values, == does not always work as expected (explanation later)

instead, use the equals method defined for Strings

str1.equals(str2)

will return true if str1 & str2 are identical, else false

Page 10: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

consider the segment: String resultType = "odd"; if (result % 2 == 0) { resultType = "even"; }

10

RouletteGame details: scope

why not? if (result % 2 == 0) { String resultType = "even"; } else { String resultType = "odd"; }

key idea: on large software projects, need to be able to develop independent modules independently in the real world, a software project might get divided into several parts each part is designed & coded by a different team, then integrated together internal naming conflicts should not be a problem

e.g., when declaring a local variable in a method, the programmer should not have to worry about whether that name is used elsewhere

every variable has a scope (i.e., where in the program it exists and can be accessed) can reuse the same local variable/parameter name in different methods since they

exist in different scopes

Page 11: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

11

RouletteGame details: scope the scope of a field is the entire class (i.e., all methods can access it) the scope of a parameter is its entire method the scope of a local variable is from its declaration to the end of its enclosing block {…}

if (result % 2 == 0) { String resultType = "even"; }

else { String resultType = "odd";}

since the variable is declared inside { },it will not exist after the if-else

String resultType;if (result % 2 == 0) {

resultType = "even"; }

else { resultType = "odd";}

this would work – since declared outside the if-else, the variable exists & can be accessed afterwards

String resultType = "odd";if (result % 2 == 0) {

resultType = "even"; }

if must declare outside the if-else, might as well give it a default value then change only if needed

Page 12: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

does makeBet work correctly in all cases?

what if the spin is 0?

12

RouletteGame fix? public class RouletteGame { private RouletteWheel wheel; private int credits;

. . . public String makeBet(int betAmount, String betType) { int result = this.wheel.spin(); String resultType = "odd"; if (result % 2 == 0) { resultType = "even"; } if (betType.equals(resultType)) { this.credits += betAmount; return result + " - winner"; } else { this.credits -= betAmount; return result + " - loser"; } }}

0 should automatically lose one possible revision

if (result == 0) { this.credits -= betAmount; return result + " – loser";}else if (betType.equals(resultType)) {

this.credits += betAmount; return result + " - winner"; } else { this.credits -= betAmount; return result + " - loser"; }

these two cases have identical code – would like to combine and avoid duplication

Page 13: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

13

RouletteGame fix: logical operators

public String makeBet(int betAmount, String betType) { int result = this.wheel.spin(); String resultType = "odd"; if (result % 2 == 0) { resultType = "even"; } if (result > 0 && betType.equals(resultType)) { this.credits += betAmount; return result + " - winner"; } else { this.credits -= betAmount; return result + " - loser"; } }

Java provides logical operators for simplifying such cases(TEST1 && TEST2) evaluates to true if either TEST1 AND TEST2 is true

(TEST1 || TEST2) evaluates to true if either TEST1 OR TEST2 is true

(!TEST) evaluates to true if TEST is NOT true

warning: the tests that appear on both sides of || and && must be complete Boolean expressions (x == 2 || x == 12) OK (x == 2 || 12) BAD!

Page 14: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

RouletteGame: error checking public void addCredits(int numCredits) { if (numCredits > 0) { this.credits += numCredits; } }

public String makeBet(int betAmount, int number) { if (betAmount > 0 && this.credits >= betAmount && number >= 1 && number <= 36) { // SAME AS BEFORE else { return "ILLEGAL BET"; } }

public String makeBet(int betAmount, String betType) { if (betAmount > 0 && this.credits >= betAmount && (betType.equals("odd") || betType.equals("even"))) { // SAME AS BEFORE } else { return "ILLEGAL BET"; } }

14

Page 15: 1 CSC 221: Computer Programming I Spring 2010 interaction & design  modular design: roulette game  constants, static fields  % operator, string equals.

RouletteWheel: adding color

in addition to odd/even and a specific number, can also bet on a color

red: 1, 3, 5, 7, 9, black: 2, 4, 6, 8, 10, 12, 14, 16, 18 11, 13, 15, 17, 19, 21, 23, 25, 27, 20, 22, 24, 26, 28, 30, 32, 34, 36 29, 31, 33, 35

green: 0, 00

how do we alter the RouletteWheel so that we can determine color?

how do we alter RouletteGame to allow bets on "red" or "black"?

15