Executive Summary
Your job is to create a simple matching game with a GUI, a
screenshot of which is shown on the right. The
simple game, and several more sophisticated variants were
suggestd by 3/C Ingliss. Don't blame her, though ... I had
something far tougher in mind!
The basic idea is this: the game starts with a 6x6 grid
containing 36 tiles. The user clicks on pairs of matching
tiles (in the simplest version the tiles only have a background color)
The goal is to clear the
screen as quickly as possible. There's a running clock as you
play, and when you've cleared the board the time ellapsed is
displayed. There's actually a fair bit going on in this game,
from a programming perspective, and the steps below help guide
you along one path towards implementing it. I hope that some of
you will try to take the game beyond this simple version and
make it more interesting and fun in creative ways - extra credit
awaits those that do!
Note: the submit system won't give you feedback on this,
since it's a GUI. You'll have to test it for yourself!
Honor
The
course policy
and the instructions it references,
most pertinently
COMPSCIDEPTINST 1531.1C,
spell out
what kinds of assistance are permissable for programming
projects. The instructor can give explicit permission for
things that would otherwise not be allowed.
For this project, you have explicit permission
- to get help from both Spring 2016 IC211 instructors
(any assistance must be documented though),
and
- to use general purpose Java resources online (though such
use must be documented).
Resources that might specifically address this project,
like the code of programs that are grid-based or
tile-based games, are not allowed.
Put together the instructions referenced in the course policy and the
explicit permissions above, and what you get is summarized as:
-
The only help you may receive on
a project is from your instructor or the other IC211
instructors, and that help must be clearly cited. In turn, you
cannot provide help to any IC211 students on this
project.
-
In no circumstance - project, homework or lab - may you copy
code and submit it as your own work. That is the definition
of plagarism.
-
For projects, you may not look at other
people's project code nor may you show your own code to
others.
-
You can look at online resources for general purpose Java
programming, but not for help writing games with ncurses
or anything else that is specific to the functionality
required of your project.
Part 1 (25 Points): A Single Tile
Just as a journey of 1000 miles begins with a single step, our
journey starts with a single "tile". In object-oriented design,
we are encouraged to encapsulate data and functions into
"objects", with a well-defined interface consisting of the
object's public methods.
Similarly, in GUI programs it's wise to make the individual
componts of our GUI into objects with well-defined interfaces.
The most basic component of our game is the "tile" ... after all,
we'll have 36 of them in our GUI!
A Part 1 solution will be a program run as
java P1
that produces a GUI consisting of
labels NORTH, SOUTH, EAST and WEST, with a single "tile" in
the middle of it, as shown on the right.
Note: You may want to use the JLabel constructor
that takes a second argument defining the hoizontal alignment
of the label text within the label component
(e.g. SwingConstants.CENTER
).
Requirements are:
-
you must have a class named "Tile", extending JPanel,
that is the actual tile in the GUI
-
the Tile must have size 100x100
(try
setPreferredSize(new Dimension(100,100));
)
and must have a simple black border around it
(see How
to use borders)
-
the tile should be white initially
(see the "setBackground" method)
-
when you click on the tile, the message "Tile activated"
should be printed to the terminal; when you click again
"Tile deactivated" should be printed to the screen. This
behavior should toggle back and forth with each subsequent
click.
Note:
You use the
MouseListener
interface
to do this.
-
As a bit of an add on, you might want to try printing
"Tile pressed" and "Tile released" as the mouse button is
pressed and released. In Java's Swing library, clicking
on an object results in three MouseListener callbacks:
"mousePressed" when the mouse button is pressed down,
"mouseReleased" when the mouse button is released, and
then immediately after "mouseClicked" is called.
Part 2 (25 Points): All 36 Tiles
A Part 2 solution will be a program run as
java P2 <number>
that produces a GUI window with a 6x6 grid of tiles.
Note: my gifts to you for this part are
class Pos, for representing
positions in the 6x6 grid, and
class DrBrownUtil,
which includes method
public static Color[][] getRandomColorAssignments(int seed)
which produces a 6x6 2D array of colors suitable for
initializing a game board for this game - i.e. every position
i,j has a matching position m,n of the same color.
Requirements are:
-
the colors in the 6x6 grid you write to the screen should
match the colors produced DrBrownUti.getRandomColorAssignments
with the seed value given by the command-line argument
(the image to the right comes from seed value 2018).
If no command-line argument is given, generate a random seed.
-
when you click on tile i,j in the GUI, the message printed
to the terminal should now be
Tile i,j activated
where, of course, "i,j" is replaced with the actual indices
of the tile you clicked on. For example, if you click on
the upper-left tile you should get "Tile 0,0 activated".
Important Advice:
- I strongly recommend that you define a new class "Board"
that extends JPanel, and which uses the GridLayout (see
How
to Use GridLayout)
- expect to do a lot of rewriting (refactoring is
the technical term) of your Tile class. It's a natural part
of the process that you'll find things to add and to change
from what you had for Part 1. Embrace it!
Part 3 (25 Points): Responding to Matches
A Part 3 solution extends/modifies the Part 2 solution
in that the response to mouse clicks is different.
Specifically,
-
if you click on tile i,j and no other tile is currently
activated, tile i,j is activated/deactivated exactly as in
Part 2
-
if you click on tile i,j and exactly one other tile is currently
activated, then
-
if the colors of the two tiles are different, both
are deactivated (with the corresponding messages written
to the terminal)
-
otherwise (i.e. if the two tiles have the same color)
three things happen:
- both tiles are deactivated (with the corresponding messages written
to the terminal)
- both tiles have their colors set to white (
Color.WHITE
)
- both tiles ignore any mouse actions taken on them
So, for example, starting with the same board pictured above, if
I clicked on the two darker green squares, I'd get the terminal
output
Tile 3,1 activated
Tile 3,2 activated
Tile 3,1 deactivated
Tile 3,2 deactivated
... and the two tiles on the board would be colored
white. Moreover, from now on they are unresponsive to clicks!
Important Advice:
As you contemplate how to make this next step, you'll find
that you really want the Board to be notified when Tiles are
activated/deactivied in response to clicks. The nicest way to
handle this is to think like the Java Swing language
designers:
I want the board to listen for the activate event and
deactivate event on Tiles. Doesn't that sound like the same
situation as buttons, or text fields, or what not?
So my suggestion is that you make an interface like:
public interface TileListener
{
public void activated(Tile t);
public void deactivated(Tile t);
}
... and make the Board implement it, and add the Board as a
TileListener for each of the tiles.
Part 4 (10 Points): Adding Visual Feedback For Activated Tiles
The game is a lot nicer to play if there's some sort of visual
mark that shows the user what the currently active tile is. You
don't need to remember what you just clicked on. I chose to do
that by drawing a thick black line around the edge of the tile.
I actually drew that line from the time the mouse button is
pressed, not just from the completion of the click. That
way, the second tile you click is outlined in the same way as
you click it.
A Part 4 solution marks the active tile as described above,
i.e. when a tile is "active" it should have a thick black
rectangle drawn around it, which goes away when the tile is no
longer active.
Doing this requires overriding the method
protected void paintComponent(Graphics g)
for the tile. The tricky bit about this is not the drawing
itself, but that you have to call
repaint()
on
the Tile after changes to its state that will mean adding or
removing the thick black border. The call to repaint() will,
eventually, force the Tile's paintComponent method to be called.
Part 5 (10 Points): Starting and Stopping Play
A Part 5 solution embeds the board from Part 4 into a larger
frame that includes a button which, initially, has the text
"start" on it.
- Before the button is clicked, none of the tiles
in the game respond to mouse clicks in any way.
-
When the button
is clicked the first time, its label changes to "pause",
and the the tiles respond to mouse clicks.
-
After the first click, the button toggles back and forth
between the "pause" label (and tiles respond to mouse clicks),
and the "resume" label (and tiles don't respond to mouse
clicks)
until all tiles have been matched.
-
When all tiles on the board have been matched, the button
label changes to "exit", and clicking on the button when it
has the exit label results in ... exiting the program, what
else?
The screenshot at the beginning of the project description shows
all the required elements for this part (plus the timer from
Part 6). The arrangment of the button and any labels you might
have is up to you.
Part 6 (5 Points): Adding a Timer
A Part 6 solution behaves exactly like a Part 5 solution except
a timer is added to the game window. The timer counts in
minutes and seconds starting at 00:00. It starts when
"play" is clicked, pauses when "pause" is clicked, resumes when
"resume" is clicked, and stops for good, displaying the time
ellapsed, when all tiles on the board have been matched.
The screenshot at the beginning of the project description shows
all the required elements for this part. Once again, the
details of how the timer, button and labels are arranged is up
to you.
My only advice to you for this part is that you've already
more or less solved this problem in Lab 11.
Part 7 (up to 15 Points EXTRA CREDIT): Make it Better!
Up to 15 points are available for improvements to this game came
from you. Improvements will be awarded points for technical
difficulty, creativity and degree of improvement in the game
experience. You are welcome to discuss with classmates what
improvements you made to the game from the user's perspective,
but not how you used Java constructs to make it happen.
Miss Ingliss has some ideas if you can't think of anything!
When to submit
-
Part 1 of the project must be ready to demo (i.e. function correctly!)
by the time you class starts on Monday, 25 April.
There will be a 5 point penalty assessed if you miss this
deadline.
-
The full project is due by close of business on Tuesday, 3 May.
What to submit
As usual, there will be a paper and electronic submission.
-
Paper Submission:
The paper submission should be a codeprint printout of all your
source code for your furthest correctly functioning
non-extra credit solution (i.e. I don't need any
extra credit specific .java files printed out),
with this coversheet
filled out and signed.
Note that you are required to have someone outside of the
CS/IT major play the game you produce (to the furthest part
you've completed) and sign-off that they've played the game.
-
Electronic Submission (Non-Extra Credit Part):
Via the usual submit system, you will submit to project proj03:
- A README file that includes your name and alpha,
which Part you are submitting (i.e. the furthest working
part), and the name of the class defining "main"
(i.e. what should I run?)
- Your source code (you don't need to submit any extra
credit specific .java files here)
-
A jar-file version of your game that is named
myyxxxx.jar
Note: read these
instructions for creating jar files
to see how this is done.
-
Electronic Submission (Extra Credit Part):
Via the usual submit system, you will submit to project proj03EC:
- A EXREADME file that includes your name and alpha,
the name of the class defining "main" for your extra
credit program
(i.e. what should I run?), and describes what additional
features you've added for extra credit.
- Your source code and any additional (e.g. image)
files needed to compile and run your program.
-
A jar-file version of your game that is named
myyxxxxEC.jar
Note: read these
instructions for creating jar files
to see how this is done.
How to submit
To submit the regular (non extra credit) part of your project electronically:
~/bin/submit -c=IC211 -p=proj03 README *.java myyxxxx.jar
To submit the Extra Credit part of your project electronically:
~/bin/submit -c=IC211 -p=proj03EC README *.java myyxxxxEC.jar
Note: if your extra credit has other files (e.g. image
files) they should be included in the submit line as well.
How projects are graded / how to maximize your points
Things to keep in mind to receive full marks:
-
Submit all required items (as described above) on time.
-
Do not submit any .java files that do not compile!
Whichever Step you submit, your project should compile and
run correctly at that step. If it doesn't, you should be
submitting the previous step.
-
Use good object-oriented design! The means adhering to the
principles of ecapsulation, data/information
hiding, inheritance and polymorphism.
-
Practice good Java Style.
This means proper indentation, use of whitespace within
lines of code, logical organization of chunks of code,
proper naming of classes, methods, fields and constants in
accordance with Java conventions.
This means good commenting: your name & alpha in every file,
and descriptive comments for each public method at a minimum!
Most important: Look at the
the grading sheet!