Greed Game Contest
<< GreedGameSim | OtherProjectsTrailIndex | War Game >>
The Greed Game is something I was told was invented by Rex Bogs. It is a fun party game that is based on "pressing your luck" on five rounds of throwing a die. The points accumulate until the number 2 is cast. Before the die is cast, players have an option of banking the total. If they think the next roll is not a 2, they keep standing. But if it is a 2, they get zero points for that round. To get a idea, you can try the game here
To compete, you need to write a sub-class of Player:
Player.java
/** * You can make a subclass of Player to employ your own * strategy. Your subclass can have its own counters * and randomness to know when to "press your luck" * or when to "quit while you're ahead" * * @author Chris Thiel, OFMCap * @version 8 Jan 2013 * */ public class Player { private String name; /** * scores[] holds the scores for the 5 rounds */ private int[] scores; /** * rollCount keeps track of how many rolls in the current round */ private int rollCount; /** * times zapped keeps track of how rounds they scored zero */ private int timesZapped; /** * when go is true, player pressing luck on current round */ private boolean go; public Player(String name) { this.name = name; initNewGame(); } public void initNewRound() { go=true; } public void initNewGame() { timesZapped = 0; scores = new int[5]; for (int round=0; round<5; round++) { scores[round]=0; } initNewRound(); } /** * the decide method is where to program your strategy * by either making setActive(true)--or do nothing-- to press your luck * or setting setActive(false) to quit, to bank the pointsSoFar. * * @param roundNumber * @param pointsSoFar */ public void decide(int roundNumber, int pointsSoFar) { if (Math.random()<.16) this.setActive(false); if (pointsSoFar>25) this.setActive(false); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getTotalScore() { int total=0; for (int s:scores) total+=s; return total; } public int getTimesZapped() { return this.timesZapped; } public void setScore( int round, int value) { scores[round-1]=value; if(value==0) this.timesZapped++; } public boolean isActive() { return go; } public void setActive(boolean value) { this.go=value; } }
Some examples of subclasses of Player:
TimidPlayer.java
public class TimidPlayer extends Player { public TimidPlayer(String name) { super(name); } public void decide(int roundNumber, int pointsSoFar) { this.setActive(false); } }
GreedyPlayer.java
public class GreedyPlayer extends Player { public GreedyPlayer(String name) { super(name); } public void decide(int roundNumber, int pointsSoFar) { if(pointsSoFar>32) this.setActive(false); } }
After5Player.java
The strategy here needs to keep track of how many rolls have occurred, so this subclass has a new field rollCount
, and to make it work right it has to initialize it in the constructor, and override the initNewRound()
method to reset it each round:
public class After5Player extends Player { private int rollCount; public After5Player(String name) { super(name); rollCount=0; } public void decide(int roundNumber, int pointsSoFar) { rollCount++; if (rollCount>5) this.setActive(false); } public void initNewRound() { this.setActive(true); rollCount=0; } }
To Run the contest, you'll need these classes:
Die.java
import java.awt.*; /** * A six sided Die. * * @author Chris Thiel, OFMCap * @version 21 Aug 2010 */ public class Die { // instance variables - private int size; private int x; //top left corner private int y; private int pips; private Color color; /** * Constructor for objects of class Die */ public Die(int x, int y, int size) { this.size=size; this.x=x; this.y=y; this.pips=(int)(Math.random()*6.0)+1; this.color=Color.WHITE; } public int getValue(){ return pips; } public void setColor(Color c) { this.color=c; } public void draw(Graphics g) { g.setColor(color); g.fillRect(x,y,size,size); g.setColor(Color.BLACK); g.drawRect(x,y,size,size); g.setColor(Color.BLACK); int dotSize=size/7; if (pips%2==1){ g.fillOval(x+3*dotSize, y+3*dotSize, dotSize,dotSize); } if (pips>1){ g.fillOval(x+dotSize, y+dotSize, dotSize,dotSize); g.fillOval(x+5*dotSize, y+5*dotSize, dotSize,dotSize); } if (pips>3){ g.fillOval(x+dotSize, y+5*dotSize, dotSize,dotSize); g.fillOval(x+5*dotSize, y+dotSize, dotSize,dotSize); } if (pips==6){ g.fillOval(x+dotSize, y+3*dotSize, dotSize,dotSize); g.fillOval(x+5*dotSize, y+3*dotSize, dotSize,dotSize); } } }
MiniButton.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Rectangle; public class MiniButton { private Rectangle box; private boolean active; private String name; private Color bgColor, txtColor; public MiniButton(String name, int x, int y, int width, int height){ box = new Rectangle(x,y,width,height); this.setName(name); setActive(true); this.setBgColor(Color.BLUE); this.setTxtColor(Color.YELLOW); } public boolean contains(int x, int y){ return active && box.contains(x,y); } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } public void draw(Graphics g){ if (!active) return; g.setColor(getBgColor()); g.fillRect(box.x, box.y, box.width, box.height); g.setColor(txtColor); g.setFont(new Font("Helvetica", Font.BOLD, box.height/2)); g.drawString(name, box.x+5, box.y+box.height-12); g.setColor(Color.BLACK); g.drawRect(box.x, box.y, box.width, box.height); } public Color getTxtColor() { return txtColor; } public void setTxtColor(Color txtColor) { this.txtColor = txtColor; } public Color getBgColor() { return bgColor; } public void setBgColor(Color bgColor) { this.bgColor = bgColor; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
PlayerScoreCard.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.text.DecimalFormat; /** * The purpose of the PlayerScoreCard is to contain, * keep track, and display info of eachPlayer * * @author Chris Thiel, OFMCap * @version 8 Jan 2013 * */ public class PlayerScoreCard { private Player player; private int[] currentScore; // the scores of the current game private int total; //sum of all the scores of all the games private int zaps; //total number of times they went too far private int wins; //total number of wins so far private int gameCount; private Color scoreColor, winsColor, avgColor, zapsColor; private DecimalFormat df; public static final int LEFT=50, WIDTH=425, HEIGHT=45, GAP=5; public PlayerScoreCard(Player p){ this.player=p; currentScore=new int[5]; for(int i=0; i<5; i++) currentScore[i]=0; total=0; zaps=0; wins=0; gameCount=0; resetColors(); df=new DecimalFormat("#0.00"); } public void initNewGame() { player.initNewGame(); gameCount++; for(int i=0; i<5; i++) currentScore[i]=0; } public boolean isActive() { return player.isActive(); } public void decide(int round, int roundTotal) { player.decide(round, roundTotal); } public void setScore(int round, int roundTotal) { player.setScore(round, roundTotal); currentScore[round-1] = roundTotal; } public int getCurrentGameTotal() { int tot=0; for (int s:currentScore) tot+=s; return tot; } public void setActive(boolean value) { player.setActive(value); } public void increaseZapCount() { this.zaps++; } public void recordGame() { this.total+=getCurrentGameTotal(); } public void recordWin(){ wins++; scoreColor=Color.yellow; } public void initNewRound() { player.initNewRound(); } public void draw(Graphics g, int y) { g.setFont(new Font("Helvetica", Font.BOLD, 18)); g.setColor(Color.BLACK); g.fillRect(LEFT, y, 425, HEIGHT); g.fillRect(LEFT+430, y, HEIGHT, HEIGHT); g.fillRect(LEFT+430+50, y, 2*HEIGHT, HEIGHT); g.fillRect(LEFT+430+100+HEIGHT, y, 2*HEIGHT, HEIGHT); g.fillRect(LEFT+430+150+2*HEIGHT, y, 70, HEIGHT); g.setColor(scoreColor); g.fillRect(LEFT+GAP, y+GAP, WIDTH-2*GAP, HEIGHT-2*GAP); g.setColor(scoreColor); g.fillRect(LEFT+430+GAP, y+GAP, HEIGHT-2*GAP, HEIGHT-2*GAP);//score g.setColor(avgColor); g.fillRect(LEFT+430+50+GAP, y+GAP, 2*HEIGHT-2*GAP, HEIGHT-2*GAP);//avg g.setColor(zapsColor); g.fillRect(LEFT+430+100+GAP+HEIGHT, y+GAP, 2*HEIGHT-2*GAP, HEIGHT-2*GAP);//zaps g.setColor(winsColor); g.fillRect(LEFT+430+150+GAP+2*HEIGHT, y+GAP, 70-2*GAP, HEIGHT-2*GAP);//wins g.setColor(Color.BLACK); g.drawString(player.getName(), LEFT+4*GAP, y+2*HEIGHT/3); for(int i=0;i<5; i++) g.drawString(""+this.currentScore[i], LEFT+200+(i)*9*GAP, y+2*HEIGHT/3); g.drawString(""+this.getCurrentGameTotal(), LEFT+430+2*GAP, y+2*HEIGHT/3); if (gameCount>0){ g.drawString(df.format((double)(total)/gameCount), LEFT+440+50+2*GAP, y+2*HEIGHT/3); g.drawString(df.format((double)(zaps)/gameCount), LEFT+445+100+2*GAP+HEIGHT, y+2*HEIGHT/3); } g.drawString(""+this.wins, LEFT+430+150+2*GAP+2*HEIGHT, y+2*HEIGHT/3); } public int getGameCount() { return gameCount; } public void resetColors() { scoreColor=winsColor=avgColor=zapsColor=Color.CYAN; } public int getZaps() { return zaps; } public int getTotal() { return this.total; } public int getWins() { return this.wins; } public void setZapsColor(Color c) { zapsColor=c; } public void setWinsColor(Color c) { winsColor=c; } public void setAvgColor(Color c) { avgColor=c; } public String getName() { return player.getName(); } }
GreedContest.java
You will need to modify the init()
method to include the competitors.
import java.applet.Applet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; public class GreedContest extends Applet implements MouseListener, MouseMotionListener { private Image virtualMem; private Graphics g0; private Font font;//The font for our messages private String message; private MiniButton play1GameBtn, play1000GameBtn; private ArrayList<PlayerScoreCard> players; private boolean gameOver; private int round, roundTotal; private Die d1; public void init() { players = new ArrayList<PlayerScoreCard>(); //add your competitors here players.add(new PlayerScoreCard(new Player("Random"))); players.add(new PlayerScoreCard(new TimidPlayer("Timid"))); players.add(new PlayerScoreCard(new GreedyPlayer("Greedy"))); players.add(new PlayerScoreCard(new After5Player("After 5"))); gameOver=true; this.play1GameBtn = new MiniButton (" Play 1 Game",150, 50, 150,40); this.play1000GameBtn = new MiniButton (" Play 1000 Games",350, 50, 200,40); this.addMouseListener(this); this.addMouseMotionListener(this); font = new Font("Helvetica", Font.BOLD, 18); roundTotal=0; round=0; message="Greed Contest"; } public void paint(Graphics g){ //make a new buffer in case the applet size changed virtualMem = createImage(getWidth(),getHeight()); g0 = virtualMem.getGraphics(); g0.setColor(Color.WHITE); g0.fillRect(0, 0, this.getWidth(), this.getHeight()); g0.setColor(Color.BLACK); g0.setFont(font); g0.drawString(message, 20, 20); g0.drawString("Games played so far: "+players.get(0).getGameCount(), 320, 40); g0.drawString("Round:" , 150, 140); for(int i=1;i<=5; i++) g0.drawString(""+i, 250+(i-1)*45, 140); g0.drawString("Score", 480, 140); g0.drawString(" Avg Score", 480+50, 140); g0.drawString(" Avg Zaps", 630, 140); g0.drawString("Wins", 720, 140); if (gameOver){ this.play1GameBtn.draw(g0); this.play1000GameBtn.draw(g0); } for(int i=0; i<players.size(); i++) players.get(i).draw(g0, 150+i*50); g.drawImage(virtualMem,0,0,this);//set new display to Screen } public void update(Graphics g) { paint(g); //get rid of flicker with this method } @Override public void mouseClicked(MouseEvent e) {} @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) { int x=e.getX(); int y=e.getY(); if (gameOver){ if (play1GameBtn.contains(x, y)){ newGame(); } else if (play1000GameBtn.contains(x, y)){ for (int i=0; i<1000; i++){ newGame(); } } }else{//game in progress } repaint(); } @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} @Override public void mouseDragged(MouseEvent e) {} @Override public void mouseMoved(MouseEvent e) {} public int indexOfBest(int[] a){ int best=0; for(int i=0; i<a.length; i++){ if (a[i]>a[best]) best=i; } return best; } public void newGame(){ gameOver=false; for (PlayerScoreCard p:players){ p.initNewGame(); p.resetColors(); } for (round=1; round <=5; round++) { newRound(); //ask players to decide first time int activePlayers=0; for(PlayerScoreCard p:players) { if (p.isActive()) { p.decide(round, roundTotal); if (p.isActive()) activePlayers++; else { p.setScore(round, roundTotal); } } } //keep rolling until a 2 or all players are inactive while (activePlayers>0) { activePlayers=0; d1 = new Die(220,50, 50); if (d1.getValue()==2) { for (PlayerScoreCard p:players) if (p.isActive()) { p.setScore(round, 0); p.setActive(false); p.increaseZapCount(); } } else //new die is not a two { roundTotal+=d1.getValue(); for(PlayerScoreCard p:players) { if (p.isActive()) { p.decide(round, roundTotal); if (p.isActive()) activePlayers++; else { p.setScore(round, roundTotal); } } } } }//end of while loop repaint(); }//end of round loop //update game totals for (PlayerScoreCard p: players) p.recordGame(); int maxScore=0,maxZap=0, maxAv=0, maxWin=0; for (int i = 0; i< players.size(); i++){ if (players.get(i).getCurrentGameTotal()>players.get(maxScore).getCurrentGameTotal()) maxScore=i; if (players.get(i).getZaps() > players.get(maxZap).getZaps()) maxZap=i; if (players.get(i).getTotal() > players.get(maxAv).getTotal()) maxAv=i; if (players.get(i).getWins() > players.get(maxWin).getWins()) maxWin=i; } players.get(maxScore).recordWin(); players.get(maxZap).setZapsColor(Color.RED); players.get(maxAv).setAvgColor(Color.YELLOW); players.get(maxWin).setWinsColor(Color.YELLOW); message = players.get(maxWin).getName()+" won "; message += 100*players.get(maxWin).getWins()/players.get(0).getGameCount()+"% of the time"; repaint(); gameOver=true; }//end of game method public void newRound(){ d1=new Die(220,50, 50); while (d1.getValue()==2) d1=new Die(220,50, 50);//ignore if first roll is a 2 roundTotal=d1.getValue(); for(PlayerScoreCard p:players){ p.initNewRound(); } } }