Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439

This lab is concerned with manipulating 2d-arrays. First set of exercises is ensure you can use loops to navigate and manipulate a 2D array in many different ways. The second exercise leads to next week's submission on MineSweeper.

2D Array Exercises

In each case you need to write a method that performs some calculations on a parameter array. You can put all these methods into any convenient class, say "ArrayTester" or something like that.

The lab exercises are all based on the simplest case, where the base type of the array is primitive. But you should always consider how to extend this to the situation where the base type is a reference type.

If you think of a 2d-array a as a matrix, then the sub-arrays a[0], a[1], etc are the rows of the matrix. Thus row 0 consists of the elements a[0][0], a[0][1], a[0][2], etc. Then column 0 is the elements a[1][0], a[2][0], a[3][0] and so on.

Column 0 Column 1 Column 2
Row 0 a[0][0] a[0][1] a[0][2]
Row 1 a[1][0] a[1][1] a[1][2]
Row 2 a[2][0] a[2][1] a[2][2]
Row 3 a[3][0] a[3][1] a[3][2]
  1. Write a method
    public int max(int[][] a) 
    that returns the maximum value in the 2d parameter array a.
  2. Write a method
    public int rowSum(int[][] a, int x)
    that returns the sum of the elements in Row x of a.

    Write a method

    public int columnSum(int[][] a, int x)
    that returns the sum of the elements in Column x of a (careful with rows of different lengths!).
  3. Write a method
    public int[] allRowSums(int[][] a)
    that calculates the row sum for every row and returns all of the values in an array.
  4. Write a method
     public boolean isRowMagic(int[][] a)
    that checks if the array is row-magic (this means that every row has the same row sum).
  5. Write a method
    public boolean isColumnMagic(int[][] a)
    that checks if the array is column-magic (this means that every column has the same column sum).
  6. Write a method
    public boolean isSquare(int[][] a)
    that checks if the array is square (i.e. every row has the same length as a itself).
  7. Write a method
    public boolean isMagic(int[][] a)
    that checks if the array is a magic square. This means that it must be square, and that all row sums, all column sums, and the two diagonal-sums must all be equal.
  8. Write a method
    public boolean isLatin(int[][] a)
    that checks to see if the array is a Latin square. This means that it must be square (suppose it is n x n), and that each row and each column must contain the values 1, 2, ..., n with no repeats.
  9. Write a method
    public boolean isSudoku(int[][] a)
    that checks to see if the array is a valid Sudoku grid. This means that the array must be a 9 x 9 Latin square with one extra condition - each of the nine 3 x 3 sub-grids must ALSO contain the entries 1, 2, ..., 9 with no repeats.

MineSweeper - Getting prepared for next submission

Here we will put together an entire class that performs a non-trivial task. Thisis a sort of "mini-project" to get you prepared for the mainproject. The task is to produce an implementation of the gameMineSweeper.

Note: The MineSweeper class is expected to take you two weeks to do, and so it is the assessed portion of .

Notice: In order to get marks for this lab, your MineSweeper classmust actually work - in other words, it must correctly countup the number of mines and display it. There is no partial creditfor code that just draws a few squares, and either displays incorrect numbers or no numbers at all. Also important is to get the game logic correct, such as detecting the end of game and so on.

I expect you to use only the SimpleCanvas class for yourgraphical display. If you wish to do something more complex, using theJava API, then you may do so, but please run it past me first, eitherin person, or by emailing admin1200.But be mindful, the purpose of this lab is to get familiar with 2D arrays, not on Graphical User Interface (GUI). A proper GUI should be done using javax.Swing.*, which supports menus, buttons, selection lists and etc.

MineSweeper: Design Specification

In this section of the lab, we will create a simple version of the popular game "MineSweeper".

Note: I only require very simple graphics; you donot need to try to add the counters, the smiley face, the menus orthe buttons of the familiar "professional" version. I amprimarily concerned that the underlying logic of the gameis correctly implemented.

In this game, the user is presented with a grid of squares as follows:

Each square is either empty, or contains a mine, but the user does not knowwhich is which. The only information that the user has is the numberof squares, and the total number of mines.

At each stage of the game, the user selects a square and chooses whether to "Dig" or "Mark" at that position. If the user digs, and the square does not contain a mine, then a number is revealed, showing the total number of mines contained in theneighbouring squares (a square's neighbours are the 8 squares adjacent toit either horizontally, vertically or diagonally). In the followingpictures, the number 2 appears, indicating that there are two minesin the neighbouring squares (marked in red in the 2nd picture).

If the user digs, and the square does contain a mine, thenit explodes and the user has lost the game. The board then indicates thelocation of all the hidden mines (the square in red is the one wherethe user foolishly dug!):

As the game progresses, the user may be able to deduce thelocation of some of the mines by using the information containedin the revealed numbers. For example, in the following situation, there must be two mines in the squares indicated:

If the user thinks that they have deduced the location of a mine, then theymay mark the square with a little flag. Notice that the square becomes marked whether or not itactually contains a mine.

The user wins the game if they successfully dig all of thesquares that do not contain mines (whether or not they have markedthem).

In the professional version of this game, the squares are selected by mouse clicks (left for "dig" and right for "mark") and thereare a variety of other visual effects. However, we can implement afully functional version, although less slick, as follows:

  1. Classes

    We will create a class called MineSweeper, with eachobject of this class representing (and managing) a single game.It will use a SimpleCanvas to draw on toindicate the progress of the game.

  2. Constructors

    The first constructor for the class MineSweeper should allow theuser to specify the number of rows, the number of columns, and the number of mines to be hidden. The signature of this should be

    public MineSweeper(int numCols, int numRows, int numMines)

    The first task of the constructor is to construct the minefield - thiswill require a 2d-array. You will use the entries of this array totrack the status of each square. There are many ways to do this, with one simple way being to use a simple code to represent all thepossibilities, such as the following:

    • 0 for untouched squares that do not contain a mine
    • 1 for untouched squares that do contain a mine
    • 2 for squares that have been "dug"
    • 3 for correctly marked squares
    • 4 for incorrectly marked squares

    You can also use Java 5's enumeration - read the magic number section.

    Initially, every square is untouched, and so all that is needed is tofill the array with 0s, and then randomly create the correct numberof mines.

    The second task of the constructor is to create a SimpleCanvasand draw the minefield on it - for the time being, just be content todraw a grid of grey squares, and do not attempt to draw the smiley faceor the timer etc.

    The second constructor is vitally important for the marking processand so it must be correct. Its signature is

    public MineSweeper(boolean[][] mineField)
    This allows the client to specify the initial minefield, via a boolean array - the (i,j) entry of this is trueif the cell contains a mine.

    This constructor will be used by my marking program to set up a known initial minefield, so that I can play a game automaticallyand simply watch the correct numbers come up. If you do not supplythis constructor, then it is almost impossible to mark your program.

  3. Methods

    At each stage, the user has only two options - either to dig a squareor to mark a square, and so we only need two public methods. We donot yet know how to make a SimpleCanvas respond to mouse clicks,so we will make do with using co-ordinates to specify the squares.

    public void dig(int i, int j)

    This method indicates that the user wishes to dig thesquare in position (i,j) (where (0,0) isthe top-left square and the co-ordinates use the standard Java graphicsconvention that the first co-ordinate is left-to-right and the second top-to-bottom.

    The object should respond according to the status of the square(i,j):

    • If the square does not contain a mine, then calculate the number of its neighbours that do contain mines, and draw that numberin the square. You may also want to change the colour of the squareto indicate that it has been "revealed". Don't work too hardtrying to obtain the 3d-effect of the professional version.
    • If the square does contain a mine, then the game isover, and you should draw the locations of all of the mines so thatthe user can perform a post-mortem on their incorrect deduction.
    • If the square has already been dug, then either ignore the request, or notify the user that they have made an impossiblerequest by printing an error message to the terminal window.

    At this stage, you should also check to see whether the user hasactually won the game - if so, then maybe print a congratulatory message on the screen. You may find it convenientto use an instance variable to keep track of the number ofsquares remaining to be dug, and when this number reaches zero, theuser has won the game.

    public void mark(int i, int j)

    This method indicates that the user wishes to mark thesquare in position (i,j).

    • If the square is untouched and unmarked, then draw a littleflag on the square (or just change its colour, or something to indicate a mark - don't try too hard to draw the perfect flag!)
    • If the square is already marked, then treat thisrequest as a request to "unmark" the square, and erasethe flag that is currently drawn there.

Do not bother adding any methods to clear the screen, or start a new game - the client can simply create a new MineSweeperif they want to play a new game.

MineSweeper Test

Here is a small that will ensurethat your basic functionality (only dig is being tested) is working.Please make sure that your program gets identical results.

On constructing an MSTester object, your screen should look something like this:

After calling the method test1(), which will do a large numberof dig commands with a small pause between each one, yourscreen should look roughly as follows:

Then test2() will dig the final un-mined square and thereforeit should reveal the mines and display a congratulatory message.

Additional Requirements - Magic Number Removal

Remove all magic numbers from your code, and replace them withsuitable constants. This means removing any literals thatrefer to parts of the program that may be changed.

For example, if you have decided that each of the squares in thegrid should be 40 x 40 pixels, then you might have code such as

drawFilledRectangle(x,y,40,40,java.awt.Color.gray);

This code uses a magic number - 40 - and a "magic colour" java.awt.Color.gray. You should replace these with symbolic constants as follows: create class variables to representthe square size, and the initial colour

private static int SQUARE_SIZE = 40;private static java.awt.Color SQUARE_COLOUR = java.awt.Color.gray;
and replace all occurrences of the magic numbers with theirsymbolic equivalents.
drawFilledRectangle(x,y,SQUARE_SIZE,SQUARE_SIZE,SQUARE_COLOUR);

Clearly, all the "status" values should be replaced by symbolic class variables:

private static int CLEAR = 0;private static int MINED = 1;... etc

Java 5+ Note

As from Java 5, there is a facility called enumerations that permits the use of special types that can only take on a specific fixed range of values, so that errors like this would be prevented by the compiler.

In Java 5, you might define

public enum Status {CLEAR, MINED, CORRECT_MARK, BAD_MARK, DUG};
to indicate the Status is a type (ie a class) that can only take on the five values given. If you have method signature to report status private Status equire(int x, int y) and the compiler would only allow the values CLEAR, MINED, CORRECT_MARK BAD_MARK and DUG to be returned.

Optional Fancy Stuff

The professional version of this game has some additional nicetouches to make playing it slick and convenient. If you have thetime and interest, then consider implementing these improvements.

  1. Mine Counter

    Add a counter that starts off at numMines and goes downby one every time the user marks a square. This allows the user to quickly check how many mines they have remaining - provided theydon't incorrectly mark a square that does not actually contain amine.

  2. Auto-Reveal

    If a square is dug, and it has no mines in the neighbouringsquares, then according to the above rules, you would write a 0 intothat square. However, if a user sees a "0 square" then theyimmediately know that they can safely dig all 8 of its neighbourswithout risk of a mine exploding. Therefore, rather than force theuser to call dig when it is guaranteed to be safe, theauto-reveal feature will automatically dig those safe squares, andreveal the corresponding numbers. (This process may reveal more0-squares, in which case their neighbours are automaticallydug, and so on.)

  3. Beginner's Luck

    When the game starts, the user has no information about the locationof the mines and must therefore choose a square at random. It wouldbe frustrating for the user if that very first square contained a mine,because then the game would end almost before it has begun. Mostversions do not permit this to happen, so that wherever theuser first clicks is always free of mines. This could bedone by delaying the "mine-laying" until immediately afterthe first click, or just shifting a mine if the user is unlucky enough to hit it on the first go.