import java.applet.Applet; import java.awt.*; import java.util.Vector; /** * This class is an applet designed to provide a roulette game for users. * This is a lite version of the roulette game. You are allowed all bets you would * be allowed in a regular roulette game except for the corners and sides of numbers. * This means you cannot bet on the corner of four numbers or the side of two numbers. * However there is a simply work around for this. Instead of betting on a corner for four * numbers, you could bet on the actual four numbers themselves. For example, instead of betting * 20 dollars on the corner of four numbers, you should bet 5 on each of those four numbers. This * would equal the exact payoff. * * @author Chris Juffre, cjuffre@cs.uml.edu * @since 1.0 * @version 1.0 */ public class Roulette extends Applet { /** * The border from the top in pixels where the board will start being drawn from. * @since 1.0 */ public static final int iTopBorder = 100; /** * The border from the left side in pixels where the board will start from. * @since 1.0 */ public static final int iSideBorders = 100; /** * The width (and height) in pixels each of the regular numbers spots on the roulette board will be. * @since 1.0 */ public static final int iNumberWidth = 50; /** * The font everything will be drawn in on the board. * @since 1.0 */ public static final Font fBoardFont = new Font("SansSerif", Font.PLAIN, 22); /** * The button used to reset the current board state. All bets will be removed. * @since 1.0 */ public Button bResetBoard = new Button("Reset Current Bets on Table"); /** * The button used to remove the last bet placed on the board. This will remove the total wager on that board position. * @since 1.0 */ public Button bRemoveLast = new Button("Remove Last Bet in List"); /** * The button used to "spin the roulette wheel". Generates a random number to use as the number drawn. * @since 1.0 */ public Button bSpinWheel = new Button("Spin Wheel"); /** * The button used to restart the game. All bets will be cleared and funds will be restored back to 1000 dollars. * @since 1.0 */ public Button bRestartGame = new Button("Restart Entire Game"); /** * The button used to display the help dialog box (an alternative to pressing F1) * @since 1.0 */ public Button bHelp = new Button("Help"); /** * The label used to display the text box used to show current bets and winnings reports. * @since 1.0 */ public Label lblCurrentBets = new Label("Current Bets:"); /** * The TextArea that will hold current betting information and win/lose reports. * @since 1.0 */ public TextArea txtCurrentBets = new TextArea("", 30, 50, TextArea.SCROLLBARS_VERTICAL_ONLY); /** * The label used to display the text field used to show you your current available funds. * @since 1.0 */ public Label lblCurrentFunds = new Label("Available Betting Dollars"); /** * The TextField that holds your available betting funds. * @since 1.0 */ public TextField txtCurrentFunds = new TextField(""); /** * Holds the integer format of the available funds. * @since 1.0 */ public int iCurrentFunds = 1000; /** * The label used to display the choice box used to select the betting denomination. * @since 1.0 */ public Label lblCurrentBetDonom = new Label("Current Betting Increment"); /** * The Choice component which holds the different betting denominations. * @since 1.0 */ public Choice cDonom = new Choice(); /** * Holds the integer format of the current denomination. * @since 1.0 */ public int iDonom = 5; /** * The external event listener class used to catch and process all events. * @since 1.0 */ public RouletteListener L; /** * The vector that holds all of the current bets. * @since 1.0 */ public Vector vecBets = new Vector(); /** * The vector that holds all the bets from the previous string. * @since 1.0 */ public Vector vecPreviousRoundBets = new Vector(); /** * The button used to replay last game. * @since 1.0 */ public Button bReplay = new Button("Replay Previous Round's Bets"); /** * The label showing the last number selected by the wheel. * @since 1.0 */ public Label lblNumber = new Label("Last Number Selected"); /** * The label that shows the drawn number. * @since 1.0 */ public Label lblSelectedNumber = new Label(); /** * Called by the system to initialize the applet's components. * @since 1.0 */ public void init() { /* Sets up details by setting the table cloth color to green (the background), setting the layout to null so we can position components exactly where we want them, and creates the external listener and passes it this applet context along with its graphics context. */ setBackground(Color.green); setLayout( null ); L = new RouletteListener(this, getGraphics()); /* The following segments of code set up all the components. It positions all the components, sets their states, adds options and text, and adds the appropriate listeners using the external listener we created above as the module that process their actions. */ lblCurrentBets.setBounds(5, 405, 100, 20); add(lblCurrentBets); txtCurrentBets.setEditable(false); txtCurrentBets.setBounds(5, 405 + lblCurrentBets.getHeight(), 250, 120); txtCurrentBets.addFocusListener(L); add(txtCurrentBets); bResetBoard.setBounds(260, txtCurrentBets.getY(), 175, 25); bResetBoard.setEnabled(false); bResetBoard.addActionListener(L); add(bResetBoard); bRemoveLast.setBounds(260, txtCurrentBets.getY() + 30, 175, 25); bRemoveLast.setEnabled(false); bRemoveLast.addActionListener(L); add(bRemoveLast); bSpinWheel.setBounds(260, txtCurrentBets.getY() + 60, 175, 25); bSpinWheel.setEnabled(false); bSpinWheel.addActionListener(L); add(bSpinWheel); bRestartGame.setBounds(260, txtCurrentBets.getY() + 90, 175, 25); bRestartGame.setEnabled(false); bRestartGame.addActionListener(L); add(bRestartGame); lblCurrentFunds.setBounds(460 + 10, txtCurrentBets.getY(), 175, 20); add(lblCurrentFunds); txtCurrentFunds.setBounds(460 + 50, lblCurrentFunds.getY() + 20, 75, 20); txtCurrentFunds.setEditable(false); txtCurrentFunds.setText(" $" + Integer.toString(iCurrentFunds)); txtCurrentFunds.addFocusListener(L); add(txtCurrentFunds); lblCurrentBetDonom.setBounds(460, txtCurrentFunds.getY() + 30, 175, 20); add(lblCurrentBetDonom); cDonom.setBounds(460 + 15, lblCurrentBetDonom.getY() + 20, 150, 20); cDonom.add("One Dollar"); cDonom.add("Five Dollar"); cDonom.add("Twenty-Five Dollar"); cDonom.add("Hundred Dollar"); cDonom.add("Five-Hundred Dollar"); cDonom.select(1); cDonom.addItemListener(L); add(cDonom); lblNumber.setFont(new Font("SansSerif", Font.PLAIN, 18)); lblNumber.setBounds(650, lblCurrentFunds.getY(), calculateWidth(lblNumber.getText(), getGraphics(), new Font("SansSerif", Font.PLAIN, 18)) + 5, 20); add(lblNumber); lblSelectedNumber.setBounds(650 + getBlockPositionX(lblSelectedNumber.getText(), getGraphics(), lblNumber.getWidth()), txtCurrentFunds.getY(), 75, 20); lblSelectedNumber.setFont(new Font("SansSerif", Font.PLAIN, 18)); add(lblSelectedNumber); bReplay.setBounds(650 + getBlockPositionX(bReplay.getLabel(), getGraphics(), lblNumber.getWidth()) - 5, lblCurrentBetDonom.getY(), 170, 25); bReplay.setEnabled(false); bReplay.addActionListener(L); add(bReplay); bHelp.setBounds(650 + getBlockPositionX(bHelp.getLabel(), getGraphics(), lblNumber.getWidth()) - 40, bReplay.getY() + 30, 100, 25); bHelp.addActionListener(L); add(bHelp); /* Adds the following listeners to the applet (not specific components). */ addMouseListener(L); addMouseMotionListener(L); addKeyListener(L); } /** * The system calls this function whenever the applet needs to be repainted. * * @param g The graphics context of this applet * @since 1.0 */ public void paint(Graphics g) { /* Sets the starting font and color to be used when drawing text on the board. */ g.setFont(fBoardFont); g.setColor(Color.black); paintTable(g); // Paints the actual roulette table /* Paints a chip on the board using each individual bet. The chip will have the wager printed in the center of the chip. */ for(int i = 0; i < this.vecBets.size(); i++) ( (Bet) this.vecBets.elementAt(i) ).paintChipOnBoard(g, this); } /** * This function is responsible for drawing the roulette table on the background of * the applet. * * @param g The graphics context of the applet * @since 1.0 */ public void paintTable(Graphics g) { /* Draws the heading on the table */ g.drawString("Roulette", getBlockPositionX("Roulette", g, 900), 10 + getBlockPositionY("Roulette", g, 10)); g.drawString("Press F1 at any time for help", getBlockPositionX("Press F1 at any time for help", g, 900), 35 + getBlockPositionY("Press F1 at any time for help", g, 10)); /* Draws the 0 and 00 squares on table. */ g.setColor(Color.white); g.drawRect(iSideBorders, iTopBorder + 25, iNumberWidth, iNumberWidth); g.drawString("00", iSideBorders + getBlockPositionX("00", g, iNumberWidth), iTopBorder + 25 + getBlockPositionY("00", g, iNumberWidth)); g.drawRect(iSideBorders, iTopBorder + 75, iNumberWidth, iNumberWidth); g.drawString("0", iSideBorders + getBlockPositionX("0", g, iNumberWidth), iTopBorder + 75 + getBlockPositionY("0", g, iNumberWidth)); int i = 0; // Used in all the loops as a loop counter int iColorMask = 0; // Used at bit level to determine the color int iCurrentNumber = 3; // Current number to draw /* This loop draws the top row of numbers on the roulette board. */ for(i = iSideBorders + iNumberWidth; i < (iSideBorders + iNumberWidth * 13); i += iNumberWidth) { /* calculate current color - this allows the iColorMask number to go from 0 to 1 to 0 to 1 and so on */ iColorMask = iColorMask ^ 1; /* draws a white box next to the previous white box to represent a number square. */ g.setColor(Color.white); g.drawRect(i, iTopBorder, iNumberWidth, iNumberWidth); /* If an odd number, the numbers color is red. If it is even, then draw it in black. */ if(iColorMask == 1) g.setColor(Color.red); else g.setColor(Color.black); /* Draw an inner rectangle for the number's color. */ g.fillRect(i + 5, iTopBorder + 5, iNumberWidth - 10, iNumberWidth - 10); /* Set color back to white and draw the number in the square. Then increment the current number by three for the next number in the row. */ g.setColor(Color.white); String strCurrent = Integer.toString(iCurrentNumber); g.drawString(strCurrent, i + getBlockPositionX(strCurrent, g, iNumberWidth), iTopBorder + getBlockPositionY(strCurrent, g, iNumberWidth)); iCurrentNumber += 3; } /* Draw the top row's 2:1 box */ g.setColor(Color.white); g.drawRect(i, iTopBorder, 75, iNumberWidth); g.drawString("2:1", i + getBlockPositionX("2:1", g, 75), iTopBorder + getBlockPositionY("2:1", g, iNumberWidth)); /* Set the next current number to be the beginning of the second row along with the color mask for appropriate color. */ iColorMask = 0; iCurrentNumber = 2; /* This loop draws the second row EXACTLY the same as drawn in the loop above. I will leave the comments out for this loop and the following loop since they are exactly the same as above. */ for(i = iSideBorders + iNumberWidth; i < (iSideBorders + iNumberWidth * 13); i += iNumberWidth) { iColorMask = iColorMask ^ 1; g.setColor(Color.white); g.drawRect(i, iTopBorder + iNumberWidth, iNumberWidth, iNumberWidth); if(iColorMask == 1) g.setColor(Color.black); else g.setColor(Color.red); g.fillRect(i + 5, iTopBorder + iNumberWidth + 5, iNumberWidth - 10, iNumberWidth - 10); g.setColor(Color.white); String strCurrent = Integer.toString(iCurrentNumber); g.drawString(strCurrent, i + getBlockPositionX(strCurrent, g, iNumberWidth), iTopBorder + 50 + getBlockPositionY(strCurrent, g, iNumberWidth)); iCurrentNumber += 3; } /* Draws the second 2:1 row. */ g.setColor(Color.white); g.drawRect(i, iTopBorder + iNumberWidth, 75, iNumberWidth); g.drawString("2:1", i + getBlockPositionX("2:1", g, 75), iTopBorder + iNumberWidth + getBlockPositionY("2:1", g, iNumberWidth)); /* Sets color mask and current number appropriate for beginning of last number row. Comments left out for this loop since it is the same as first. */ iColorMask = 0; iCurrentNumber = 1; for(i = iSideBorders + iNumberWidth; i < (iSideBorders + iNumberWidth * 13); i += iNumberWidth) { iColorMask = iColorMask ^ 1; g.setColor(Color.white); g.drawRect(i, iTopBorder + (iNumberWidth * 2), iNumberWidth, iNumberWidth); if(iColorMask == 1) g.setColor(Color.red); else g.setColor(Color.black); g.fillRect(i + 5, iTopBorder + (iNumberWidth * 2) + 5, iNumberWidth - 10, iNumberWidth - 10); g.setColor(Color.white); String strCurrent = Integer.toString(iCurrentNumber); g.drawString(strCurrent, i + getBlockPositionX(strCurrent, g, iNumberWidth), iTopBorder + 100 + getBlockPositionY(strCurrent, g, iNumberWidth)); iCurrentNumber += 3; } /* Draws last 2:1 row. */ g.setColor(Color.white); g.drawRect(i, iTopBorder + (iNumberWidth * 2), 75, iNumberWidth); g.drawString("2:1", i + getBlockPositionX("2:1", g, 75), iTopBorder + (iNumberWidth * 2) + getBlockPositionY("2:1", g, iNumberWidth)); /* Uses current number as a column index for the three segments of 12. */ iCurrentNumber = 1; /* Draws the third rows. */ for(i = iSideBorders + iNumberWidth; i < (iSideBorders + iNumberWidth * 13); i += 200) { /* Draw the spot on board for number segment bets and the inner box to draw string in. */ g.drawRect(i, 250, 200, 100); g.drawRect(i + 25, 265, 150, 70); /* Draw the correct designation for that box based on the loop index. */ switch(iCurrentNumber) { case 1: g.drawString("1st 12", i + getBlockPositionX("1st 12", g, 200), iTopBorder + 150 + getBlockPositionY("1st 12", g, 100)); break; case 2: g.drawString("2nd 12", i + getBlockPositionX("2nd 12", g, 200), iTopBorder + 150 + getBlockPositionY("2nd 12", g, 100)); break; case 3: g.drawString("3rd 12", i + getBlockPositionX("3rd 12", g, 200), iTopBorder + 150 + getBlockPositionY("3rd 12", g, 100)); break; } iCurrentNumber++; // Increment the column index } /* Draw last row using iCurrentNumber as the column index again. This will draw the odd and even, colors, and range betting squares. */ iCurrentNumber = 1; for(i = iSideBorders + iNumberWidth; i < (iSideBorders + iNumberWidth * 13); i += 100) { g.setColor(Color.white); // Set color to white /* Draw correct betting square depending on the column index since they all go in a particular order. Each case draws a betting square, an inner square, and a string defining the betting square except for the colors. For the colors, the inner rectangle is colored in with the color and no string defines the square. */ switch(iCurrentNumber) { case 1: g.drawRect(i, 350, 100, 50); g.drawRect(i + 10, 350 + 5, 80, 40); g.drawString("1 to 18", i + getBlockPositionX("1 to 18", g, 100), iTopBorder + 250 + getBlockPositionY("1 to 18", g, 50)); break; case 2: g.drawRect(i, 350, 100, 50); g.drawRect(i + 10, 350 + 5, 80, 40); g.drawString("EVEN", i + getBlockPositionX("EVEN", g, 100), iTopBorder + 250 + getBlockPositionY("EVEN", g, 50)); break; case 3: g.drawRect(i, 350, 100, 50); g.setColor(Color.red); g.fillRect(i + 10, 350 + 5, 80, 40); break; case 4: g.drawRect(i, 350, 100, 50); g.setColor(Color.black); g.fillRect(i + 10, 350 + 5, 80, 40); break; case 5: g.drawRect(i, 350, 100, 50); g.drawRect(i + 10, 350 + 5, 80, 40); g.drawString("ODD", i + getBlockPositionX("ODD", g, 100), iTopBorder + 250 + getBlockPositionY("ODD", g, 50)); break; case 6: g.drawRect(i, 350, 100, 50); g.drawRect(i + 10, 350 + 5, 80, 40); g.drawString("19 to 36", i + getBlockPositionX("19 to 36", g, 100), iTopBorder + 250 + getBlockPositionY("19 to 36", g, 50)); break; } iCurrentNumber++; // Increments the column index } } /** * This function calculates the pixel position of the X-coordinate inside a rectangle of a given width * where to start writing a given string so it will be centered. * * @param s The string to be drawn inside the rectangle * @param g The graphics context of the applet * @param iBlockWidth The width in pixels of the rectangle to draw the string in * @return X-coordinate pixel position to start drawing the string * @since 1.0 */ public int getBlockPositionX(String s, Graphics g, int iBlockWidth) { /* Gets the font metrics for the graphics. */ FontMetrics fm = g.getFontMetrics(); /* Gets the width in pixels of the string and returns the X-coordinate position it should be drawn at so it is centered in the block. This is calculated be taking the center position of the block and subtracting half the width of the string from it. */ int i = (int) fm.getStringBounds(s, g).getWidth(); return (iBlockWidth / 2) - (i / 2); } /** * This function calculates the pixel position of the Y-coordinate inside a rectangle of a given width * where to start writing a given string so it will be centered. * * @param s The string to be drawn inside the rectangle * @param g The graphics context of the applet * @param iBlockHeight The height in pixels of the rectangle to draw the string in * @return Y-coordinate pixel position to start drawing the string * @since 1.0 */ public int getBlockPositionY(String s, Graphics g, int iBlockHeight) { /* Gets the font metrics for the graphics. */ FontMetrics fm = g.getFontMetrics(); /* Gets the height in pixels of the string and returns the Y-coordinate position it should be drawn at so it is centered in the block. This is calculated be taking the center position of the block and subtracting half the height of the string from it and subtracting an addition 5 pixels. */ int i = (int) fm.getStringBounds(s, g).getHeight(); return (iBlockHeight / 2) + (i / 2) - 5; } /** * Calculate the width for a string. * * @param s String to calculate width of * @param g Graphics context for this applet * @param f The font used in the label * @return width of the string in pixels * @since 1.0 */ public int calculateWidth(String s, Graphics g, Font f) { /* Get the font metrics of the graphics and return the width of the string. */ FontMetrics fm = g.getFontMetrics(f); return (int) fm.getStringBounds(s, g).getWidth(); } }