Question: CS 1083 Project 3: Concentration The Concentration Class Objectives This is one of three major programming projects this semester. You may NOT collaborate on this

CS 1083 Project 3: Concentration

The Concentration Class

Objectives

This is one of three major programming projects this semester. You may NOT collaborate on this project. While you may ask for assistance in debugging, this project should be ENTIRELY your own work.

Other objectives include:

Call and write methods with parameters and return values.

Use the DrawingPanel, Graphics, and Color classes.

Use while loops and if statements to validate input and control code.

Use arrays to store and process information.

Introduction

The goal of this project is to implement a program that allows the user to play a version of Concentration. In this version, the goal of the user is to match a color on the top row with a color on the bottom row. The initial 700x300 window should have two rows and six columns:

In each turn, the user selects a square from the top row, then a square from the bottom row. The colors of the squares will be revealed. For example, the user might select the second square on the top row and the fourth square on the bottom row. The window now looks like:

In this case, the colors do not match, so after a second or so, the green square and the red square will be hidden with the original gray color. If the colors had matched, they would have remained revealed.

Two arrays of length six are needed to store the colors of the two rows. Two more arrays of length six are needed to remember whether each square is hidden or revealed. DrawingPanel2.java

DrawingPanel2.java has additional methods for closing the window and getting information about the state of the mouse. Here are the methods available to you.

Method Name

Description

getGraphics( )

returns a Graphics object that the program can draw on

setBackground(color)

sets the background color

sleep(milliseconds)

pause for a given number of milliseconds (1000 milliseconds equals one second)

close( )

closes the window

getMouseX( )

returns the X position of the mouse

getMouseY( )

returns the Y position of the mouse

getClickX( )

returns the X position of the last mouse click

getClickY( )

returns the Y position of the last mouse click

mousePressed( )

returns true if any mouse button is pressed

If you run the initial version of Concentration.java, you will see information about the mouse in the status bar of the window. If you look more closely at the code in Concentration.java, you will find out that the code uses these methods to repeatedly ask about the status of the mouse. This is a bad way to program window behavior because a lot of time is wasted in loops waiting for something to happen (called busy waiting or spinning). Instead, the program should be event-driven, but we don't have enough time to discuss Chapter 14 of your textbook.

Concentration.java

The initial version of Concentration.java implements the following pseudocode:

Initialize the window so that the colors of the squares are hidden.

Initialize the two arrays that store the hidden Colors of the top row and bottom row.

Loop forever:

Wait until the user clicks on the top row.

Reveal the color of the square that the user clicked on.

Wait until the user clicks on the bottom row.

Reveal the color of the square that the user clicked on.

If the colors do not match, hide the colors of the squares.

You should study the code in Concentration.java to gain an understanding of how the code implements the above behavior. Describe what is stored in each variable. For the getClickRow and getClickColumn methods, determine the correspondence between the return values and locations of the mouse clicks. Figure out how the program knows the color of a particular square.

Randomizing the Colors

The game is not very interesting if the order of the Colors are the same every time. It would be better if the order of the Colors are different every time. That is, the Colors should be put in a random order.

A simple way to implement the randomizeColors method is to follow the following pseudocode:

Repeat several times:

Generate two random numbers r1 and r2 between 0 and length - 1 of the Color array.

Use the swap method to swap the values at indexes r1 and r2.

The swap method is already implemented for you in Concentration.java.

This pseudocode is not correct if you want an equal chance of generating each possible order. A more sophisticated algorithm is:

Loop for i from 0 up to length - 1 of the Color array.

Generate a random number r between i and length - 1 of the Color array.

Use the swap method to swap the values at indexes i and r.

Detecting the End of the Game

Instead of an infinite loop, the game should end when the user has matched all the colors. One approach is to count how many times the user has found a matching pair of colors. After matching six pairs, the game should be over. Run the following code after the game is over. You will probably need to adjust some of the numbers so the text appears correctly.

g.setFont(new Font("SansSerif", Font.BOLD, 100));

g.setColor(Color.BLACK);

g.drawString("The game is over!", 0, 300);

The program should be modified to ensure that a revealed square cannot be selected. To do this, the program needs to remember which squares have been revealed. One way of implementing this idea is to have two additional boolean arrays. For example, in the above board where there are three matches, one array should represent what has been revealed in the top row.

index

0

1

2

3

4

5

value

false

true

false

true

true

false

The other array should represent what has been revealed in the bottom row.

index

0

1

2

3

4

5

value

true

true

false

false

true

false

Hints: Look at p. 427 in your textbook for an example of how to construct a boolean array. These arrays need to be updated after squares are revealed by the program and when the squares are hidden by the program. Additional code that checks these arrays is needed to ensure that col0 and col1 in the program correspond to hidden squares.

Rubric

Your program should compile without any errors. A program with more than one or two compile errors will likely get a zero for the whole assignment.

The following criteria will also be used to determine the grade for this assignment:

[2 points] If your submission includes the following:

The main method prints "Project 3 written by [...]".

Your submission was a Zip file named project3.zip containing a folder named project3, which contains the other files.

If your submission contains files named Concentration.java and DrawingPanel2.java.

If your program contains a comment that describes what the program does and contains a comment describing each method.

If your program is indented properly.

[6 Points] The randomizeColors Method was implemented correctly.

[6 Points] The program detects the end of the game and displays a message in the window after the game is over.

[6 Points] The program uses arrays to keep track of what squares have been revealed and prevents the user from selecting a square that has been revealed.

I wil post this questin one more time because i forgot to add the project3 zip file that comes with DrawingPanel2:

/*

Stuart Reges and Marty Stepp

February 24, 2007

Changes by Tom Bylander in 2010 (no anti-alias, repaint on sleep)

Changes by Tom Bylander in 2012 (track mouse clicks and movement)

The DrawingPanel class provides a simple interface for drawing persistent

images using a Graphics object. An internal BufferedImage object is used

to keep track of what has been drawn. A client of the class simply

constructs a DrawingPanel of a particular size and then draws on it with

the Graphics object, setting the background color if they so choose.

To ensure that the image is always displayed, a timer calls repaint at

regular intervals.

*/

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

import javax.swing.*;

import javax.swing.event.*;

public class DrawingPanel2 implements ActionListener {

private static final int DELAY = 100; // delay between repaints in millis

private static final boolean PRETTY = false; // true to anti-alias

private int width, height; // dimensions of window frame

private JFrame frame; // overall window frame

private JPanel panel; // overall drawing surface

private BufferedImage image; // remembers drawing commands

private Graphics2D g2; // graphics context for painting

private JLabel statusBar; // status bar showing mouse position

private volatile MouseEvent click; // stores the last mouse click

private volatile boolean pressed; // true if the mouse is pressed

private volatile MouseEvent move; // stores the position of the mouse

// construct a drawing panel of given width and height enclosed in a window

public DrawingPanel2(int width, int height) {

this.width = width;

this.height = height;

image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

statusBar = new JLabel(" ");

statusBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));

panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));

panel.setBackground(Color.WHITE);

panel.setPreferredSize(new Dimension(width, height));

panel.add(new JLabel(new ImageIcon(image)));

click = null;

move = null;

pressed = false;

// listen to mouse movement

MouseInputAdapter listener = new MouseInputAdapter() {

public void mouseMoved(MouseEvent e) {

pressed = false;

move = e;

statusBar.setText("moved (" + e.getX() + ", " + e.getY() + ")");

}

public void mousePressed(MouseEvent e) {

pressed = true;

move = e;

statusBar.setText("pressed (" + e.getX() + ", " + e.getY() + ")");

}

public void mouseDragged(MouseEvent e) {

pressed = true;

move = e;

statusBar.setText("dragged (" + e.getX() + ", " + e.getY() + ")");

}

public void mouseReleased(MouseEvent e) {

pressed = false;

click = e;

statusBar.setText("released (" + e.getX() + ", " + e.getY() + ")");

}

};

panel.addMouseListener(listener);

panel.addMouseMotionListener(listener);

g2 = (Graphics2D)image.getGraphics();

g2.setColor(Color.BLACK);

if (PRETTY) {

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

g2.setStroke(new BasicStroke(1.1f));

}

frame = new JFrame("Drawing Panel");

frame.setResizable(false);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(panel);

frame.getContentPane().add(statusBar, "South");

frame.pack();

frame.setVisible(true);

toFront();

// repaint timer so that the screen will update

new Timer(DELAY, this).start();

}

// used for an internal timer that keeps repainting

public void actionPerformed(ActionEvent e) {

panel.repaint();

}

// obtain the Graphics object to draw on the panel

public Graphics2D getGraphics() {

return g2;

}

// set the background color of the drawing panel

public void setBackground(Color c) {

panel.setBackground(c);

}

// show or hide the drawing panel on the screen

public void setVisible(boolean visible) {

frame.setVisible(visible);

}

// makes the program pause for the given amount of time,

// allowing for animation

public void sleep(int millis) {

panel.repaint();

try {

Thread.sleep(millis);

} catch (InterruptedException e) {}

}

// close the drawing panel

public void close() {

frame.dispose();

}

// makes drawing panel become the frontmost window on the screen

public void toFront() {

frame.toFront();

}

// return the X position of the mouse or -1

public int getMouseX() {

if (move == null) {

return -1;

} else {

return move.getX();

}

}

// return the Y position of the mouse or -1

public int getMouseY() {

if (move == null) {

return -1;

} else {

return move.getY();

}

}

// return the X position of the last click or -1

public int getClickX() {

if (click == null) {

return -1;

} else {

return click.getX();

}

}

// return the Y position of the last click or -1

public int getClickY() {

if (click == null) {

return -1;

} else {

return click.getY();

}

}

// return true if a mouse button is pressed

public boolean mousePressed() {

return pressed;

}

}

then the concentration class:

import java.awt.*;

import java.util.*;

/*

* This program implements a version of the Concentration game.

* In this version, the game has two rows. The goal of the user

* is to find squares with matching colors on the two rows.

* In each turn, the user selects a square from the top row,

* then a square on the bottom row. The colors of the squares

* are revealed. However, if the colors do not match, the

* squares return to a gray color.

*/

public class Concentration {

public static void main(String[] args) {

// DrawingPanel2 has additional methods for keeping track of the mouse.

DrawingPanel2 panel = new DrawingPanel2(400,300);

Graphics g = panel.getGraphics();

// Draw 6 rectangles: 2 rows and 3 columns.

for (int r = 0; r < 2; r++) {

for (int c = 0; c < 3; c++) {

g.drawRect(c * 100 + 50, r * 100 + 50, 100, 100);

}

}

// Fill the rectangles with light gray.

g.setColor(Color.LIGHT_GRAY);

for (int r = 0; r < 2; r++) {

for (int c = 0; c < 3; c++) {

g.fillRect(c * 100 + 51, r * 100 + 51, 99, 99);

}

}

// Create color arrays.

Color[] colors0 = {Color.RED, Color.GREEN, Color.BLUE};

Color[] colors1 = {Color.GREEN, Color.BLUE, Color.RED};

// Randomize the order of the colors in the arrays.

// Leave randomizeColors commented out for Lab 9.

// Uncomment these lines and implement randomizeColors

// for your final project.

// randomizeColors(colors0);

// randomizeColors(colors1);

// Leave as an infinite loop for Lab 9.

// In the final project, the loop should end when all the

// squares have been revealed.

while (true) {

// Wait for a click on row 0, and then save the column.

// This needs to be changed to ensure that the color of

// the square on row 0 and column col0 is currently hidden.

int row = getClickRow(panel);

while (row != 0) {

row = getClickRow(panel);

}

int col0 = getClickColumn(panel);

System.out.print(col0);

// Reveal the color on row 0 and column col1.

// Need code to remember that this square has been revealed.

Color color0 = colors0[col0];

g.setColor(color0);

g.fillRect(col0*100+51, 51, 99, 99);

// Wait for a click on row 1, and then save the column.

// This needs to be changed to ensure that the color of

// the square on row 1 and column col1 is currently hidden.

row = getClickRow(panel);

while (row != 1) {

row = getClickRow(panel);

}

int col1 = getClickColumn(panel);

System.out.print(col1);

// Reveal the color on row 1 and column col1.

// Need code to remember that this square has been revealed.

Color color1 = colors1[col1];

g.setColor(color1);

g.fillRect(col1 * 100 + 51, 100 + 51, 99, 99);

// Pause a second before (maybe) changing back to light gray.

panel.sleep(1000);

// Hide the colors if they are not the same.

if (! color0.equals(color1)) {

g.setColor(Color.LIGHT_GRAY);

g.fillRect(col0 * 100 + 51, 51, 99, 99);

g.fillRect(col1 * 100 + 51, 100 + 51, 99, 99);

// Need code to remember that the two squares are hidden.

}

}

}

// This method should randomize the order of the colors.

public static void randomizeColors(Color[] colors) {

// repeat several times

// generate two random ints between 0 and colors.length - 1

// call the swap method with the color array and the two ints

}

// This is like the swap method in Chapter 7 on pp. 456-457,

// but modified for Color arrays.

public static void swap(Color[] colors, int i, int j) {

Color temp = colors[i];

colors[i] = colors[j];

colors[j] = temp;

}

// Return 0 if the user clicks on row 0.

// Return 1 if the user clicks on row 1.

// Otherwise, return -1.

public static int getClickRow(DrawingPanel2 panel) {

int x = panel.getClickX();

int y = panel.getClickY();

if (x > 50 && x < 350 && y > 50 && y < 150) {

return 0;

} else if (x > 50 && x < 350 && y > 150 && y < 250) {

return 1;

} else {

return -1;

}

}

// Return c if the user clicks on column c.

// Otherwise, return -1.

public static int getClickColumn(DrawingPanel2 panel) {

int x = panel.getClickX();

int y = panel.getClickY();

if (x > 50 && x < 150 && y > 50 && y < 250) {

return 0;

} else if (x > 150 && x < 250 && y > 50 && y < 250) {

return 1;

} else if (x > 250 && x < 350 && y > 50 && y < 250) {

return 2;

} else {

return -1;

}

}

}

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!