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();
		}
	}
}