CS计算机代考程序代写 Java cache META-INF/MANIFEST.MF

META-INF/MANIFEST.MF

ca/uottawa/eecs/puzzler/Board.class

ca/uottawa/eecs/puzzler/Board.java

ca/uottawa/eecs/puzzler/Cell.class

ca/uottawa/eecs/puzzler/Cell.java

ca/uottawa/eecs/puzzler/Puzzler.class

ca/uottawa/eecs/puzzler/Puzzler.java

data/ball-0.png

data/ball-1.png

data/ball-2.png

data/ball-3.png

data/ball-4.png

data/ball-5.png

data/ball-6.png

manifest.mf

Manifest-Version: 1.0
Created-By: 1.6.0_29 (Apple Inc.)
Main-Class: ca.uottawa.eecs.puzzler.Puzzler

Board

package ca.uottawa.eecs.puzzler;
public synchronized class Board extends javax.swing.JPanel implements java.awt.event.ActionListener {
private static final long serialVersionUID = 1;
public static final int NUMBER_OF_ROWS = 7;
public static final int NUMBER_OF_COLUMNS = 7;
private Cell[][] board;
private boolean allowsClicks;
public void Board();
public void reset();
public boolean allowsClicks();
public void setAllowsClicks(boolean);
public void deselectAllCells();
public boolean hasIdenticalNeighbours(int, int);
public void selectCellAndContiguousCells(int, int);
public void removeCellAndContiguousCells(int, int);
public void fallDown();
public void fallRight();
public boolean solved();
public void actionPerformed(java.awt.event.ActionEvent);
}

ca/uottawa/eecs/puzzler/Board.java
ca/uottawa/eecs/puzzler/Board.javapackage ca.uottawa.eecs.puzzler;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JPanel;

/**
 * In this application, Board is a specialized type of JPanel that
 * holds cells (balls). The board also holds the higher level logic of the game
 * for selecting and removing cells.
 * 
 * @author Marcel Turcotte, University of Ottawa
 * 
 */

public class Board extends JPanel implements ActionListener {

    private static final long serialVersionUID = 1L;

    /**
     * Defines the total number of rows.
     */

    public static final int NUMBER_OF_ROWS = 7;

    /**
     * Defines the total number of columns.
     */

    public static final int NUMBER_OF_COLUMNS = 7;

    /**
     * A two dimensional array to keep references to all the cells of the board.
     */

    private Cell[][] board;

    /**
     * Used by the logic to avoid processing multiple clicks.
     */

    private boolean allowsClicks = false;

    /**
     * Displays all the cells on a two dimensional grid.
     */

    public Board() {
    setBackground(Color.WHITE);
    setLayout(new GridLayout(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS));
    setBorder(BorderFactory.createEmptyBorder(20, 20, 0, 20));
    board = new Cell[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];

    for (int row = 0; row < NUMBER_OF_ROWS; row++) {         for (int column = 0; column < NUMBER_OF_COLUMNS; column++) {         board[row][column] = new Cell(this, row, column);         add(board[row][column]);         }     }     }     /**      * Re-initializes all the cells of the grid.      */     public void reset() {     for (int row = 0; row < NUMBER_OF_ROWS; row++) {         for (int column = 0; column < NUMBER_OF_COLUMNS; column++) {         board[row][column].reset();         }     }     }     /**      * Returns true if clicks are allowed, and false otherwise.
     * 
     * @return true if clicks are allowed
     */

    public boolean allowsClicks() {
    return allowsClicks;
    }

    /**
     * A setter for the attribute allowsClick.
     * 
     * @param allowClicks
     *            the allowClicks to set
     */

    public void setAllowsClicks(boolean allowClicks) {
    this.allowsClicks = allowClicks;
    }

    /**
     * Sets the attribute selected to false for all the cells of
     * the grid.
     */

    public void deselectAllCells() {
    for (int row = 0; row < NUMBER_OF_ROWS; row++) {         for (int column = 0; column < NUMBER_OF_COLUMNS; column++) {         board[row][column].setSelected(false);         }     }     }     /**      * Returns true if the cell found at rowcolumn has at
     * least one neighbor of the same type, and false otherwise.
     * 
     * @param row
     *            the specified row
     * @param column
     *            the specified column
     * @return true if the specified cell has at least one neighbor of the same
     *         type
     */

    public boolean hasIdenticalNeighbours(int row, int column) {
    Cell cell = board[row][column];
    boolean result = false;

    if ((row – 1 >= 0 && cell.sameType(board[row – 1][column]))
        || (row + 1 < NUMBER_OF_ROWS && cell             .sameType(board[row + 1][column]))             || (column - 1 >= 0 && cell.sameType(board[row][column – 1]))
            || (column + 1 < NUMBER_OF_COLUMNS && cell                 .sameType(board[row][column + 1]))) {         result = true;     }     return result;     }     /**      * This method is called after a call to hasIdenticalNeighbours in
     * order to select (set the attribute selected to true) all the adjacent
     * cells of the same type.
     * 
     * @param row
     *            the specified row
     * @param column
     *            the specified column
     */

    public void selectCellAndContiguousCells(int row, int column) {
    Cell cell = board[row][column];
    cell.setSelected(true);
    if (column – 1 >= 0 && cell.sameType(board[row][column – 1])
        && (!board[row][column – 1].selected())) {
        selectCellAndContiguousCells(row, column – 1);
    }
    if (column + 1 < NUMBER_OF_ROWS         && cell.sameType(board[row][column + 1])         && (!board[row][column + 1].selected())) {         selectCellAndContiguousCells(row, column + 1);     }     if (row - 1 >= 0 && cell.sameType(board[row – 1][column])
        && (!board[row – 1][column].selected())) {
        selectCellAndContiguousCells(row – 1, column);
    }
    if (row + 1 < NUMBER_OF_COLUMNS         && cell.sameType(board[row + 1][column])         && (!board[row + 1][column].selected())) {         selectCellAndContiguousCells(row + 1, column);     }     }     /**      * The selected cells are removed. Actually, this simply means setting the      * type of the selected cells to Empty. As the method proceeds it
     * unselects cells. This is important to avoid looping infinitely.
     * 
     * @param row
     *            the specified row
     * @param column
     *            the specified column
     */

    public void removeCellAndContiguousCells(int row, int column) {
    Cell cell = board[row][column];
    cell.setSelected(false);
    if (column – 1 >= 0 && board[row][column – 1].selected()) {
        removeCellAndContiguousCells(row, column – 1);
    }
    if (column + 1 < NUMBER_OF_ROWS && board[row][column + 1].selected()) {         removeCellAndContiguousCells(row, column + 1);     }     if (row - 1 >= 0 && board[row – 1][column].selected()) {
        removeCellAndContiguousCells(row – 1, column);
    }
    if (row + 1 < NUMBER_OF_COLUMNS && board[row + 1][column].selected()) {         removeCellAndContiguousCells(row + 1, column);     }     cell.setType(Cell.EMPTY);     }     /**      * Detects vertical gaps and collapse those cells.      */     public void fallDown() {     for (int column = NUMBER_OF_COLUMNS - 1; column >= 0; column–) {

        boolean foundGap = false;
        int fallTo = -1;

        for (int row = NUMBER_OF_ROWS – 1; row >= 0; row–) {

        if (board[row][column].isEmpty()) {
            if (!foundGap) {
            foundGap = true;
            fallTo = row;
            }
        } else {
            if (foundGap) {
            board[fallTo][column].setType(board[row][column]
                .getType());
            board[row][column].setType(Cell.EMPTY);
            fallTo–;
            }
        }

        }

    }
    }

    /**
     * Detects horizontal gaps and collapse those cells.
     */

    public void fallRight() {

    for (int row = NUMBER_OF_ROWS – 1; row >= 0; row–) {

        boolean foundGap = false;
        int fallTo = -1;

        for (int column = NUMBER_OF_COLUMNS – 1; column >= 0; column–) {

        if (board[row][column].isEmpty()) {
            if (!foundGap) {
            foundGap = true;
            fallTo = column;
            }
        } else {
            if (foundGap) {
            board[row][fallTo]
                .setType(board[row][column].getType());
            board[row][column].setType(Cell.EMPTY);
            fallTo–;
            }
        }

        }

    }
    }

    /**
     * Returns true if and only if all the cells are Empty.
     * 
     * @return true if and only if all the cells are Empty
     */

    public boolean solved() {
    boolean flag = false;
    for (int row = 0; row < NUMBER_OF_ROWS && !flag; row++) {         for (int column = 0; column < NUMBER_OF_COLUMNS && !flag; column++) {         if (!board[row][column].isEmpty()) {             flag = true;         }         }     }     return !flag;     }     /**      * This method must be implemented as part of the contract specified by      * ActionListener. This method will be called each time the user clicks a      * button. Upon a first click, if there are adjacent cells of the same type,      * the cell and the adjacent cells of the same type are selected. Upon a      * second click, the cell and the adjacent cells of the same type are      * removed from the Board. This causes other cells to fall down, and
     * right.
     * 
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */

    public void actionPerformed(ActionEvent e) {

    if (e.getSource() instanceof Cell) {

        Cell src = (Cell) e.getSource();

        if (src.getType() != Cell.EMPTY && allowsClicks()) {

        setAllowsClicks(false);

        int row = src.getRow(), column = src.getColumn();

        if (!src.selected()) {
            deselectAllCells();
            if (hasIdenticalNeighbours(row, column)) {
            selectCellAndContiguousCells(row, column);
            }
        } else {
            removeCellAndContiguousCells(row, column);
            fallDown();
            fallRight();
            if (solved()) {
            System.out.println(“Solved!”);
            reset();
            }
            src.setSelected(false);
        }

        setAllowsClicks(true);
        }
    }

    }
}

Cell

package ca.uottawa.eecs.puzzler;
public synchronized class Cell extends javax.swing.JButton {
private static final long serialVersionUID = 1;
private static java.util.Random generator;
public static final int NUM_COLOURS = 5;
public static final int EMPTY = 0;
private int type;
private boolean selected;
private int row;
private int column;
private static final javax.swing.ImageIcon[] icons;
public void Cell(Board, int, int);
public void Cell(Board, int, int, int);
private int newRandomCellType();
private javax.swing.ImageIcon getImageIcon();
public void reset();
public int getType();
public boolean sameType(Cell);
public void setType(int);
public boolean isEmpty();
public boolean selected();
public void setSelected(boolean);
public int getRow();
public int getColumn();
static void ();
}

ca/uottawa/eecs/puzzler/Cell.java
ca/uottawa/eecs/puzzler/Cell.javapackage ca.uottawa.eecs.puzzler;

import java.util.Random;

import java.awt.Color;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.BorderFactory;
import javax.swing.border.Border;

/**
 * In the application Puzzler, a Cell is a specialized type of
 * JButton that represents a ball in the game. Upon a first click, if
 * there are adjacent cells of the same type, this cell and the adjacent cells
 * of the same type are selected. Upon a second click, this cell and the
 * adjacent cells of the same type are removed from the Board. This
 * causes other cells to fall down, and right.
 * 
 * @author Marcel Turcotte, University of Ottawa
 */

public class Cell extends JButton {

    private static final long serialVersionUID = 1L;

    /**
     * A random number generator is used to generate the cell type, when a new
     * board is created, or the user clicks reset. The same number generator is
     * shared by all the cells.
     */

    private static Random generator = new Random();

    /**
     * Number of colours
     */

    public static final int NUM_COLOURS = 5;

    /**
     * Symbolic constant that represents an empty cell
     */

    public static final int EMPTY = 0;

    /**
     * The cell type. Valid values are Empty, Blue, Green, etc.
     */

    private int type;

    /**
     * This instance variable is true if the cell is selected.
     */

    private boolean selected = false;

    /**
     * The coordinate of this cell on the Board.
     */

    private int row, column;

    /**
     * A an array is used to cache all the images. Since the images are not
     * modified. All the cells that display the same image reuse the same
     * ImageIcon object. Notice the use of the keyword static.
     */

    private static final ImageIcon[] icons = new ImageIcon[NUM_COLOURS + 2];

    /**
     * Constructor used for initializing a cell of an unspecified type. The
     * actual type is randomly generated. A randomly generated cell is never
     * Empty.
     * 
     * @param board
     *            the grid that holds all the cells
     * @param row
     *            the row of this Cell
     * @param column
     *            the column of this Cell
     */

    public Cell(Board board, int row, int column) {
    this(board, row, column, generator.nextInt(NUM_COLOURS) + 1);
    }

    /**
     * Constructor used for initializing a cell of a specified type.
     * 
     * @param board
     *            the grid that holds all the cells
     * @param row
     *            the row of this Cell
     * @param column
     *            the column of this Cell
     * @param type
     *            specifies the type of this cell
     */

    public Cell(Board board, int row, int column, int type) {
    this.row = row;
    this.column = column;
    this.type = type;
    setBackground(Color.WHITE);
    setIcon(getImageIcon());
    Border emptyBorder = BorderFactory.createEmptyBorder(0, 0, 0, 0);
    setBorder(emptyBorder);
    setBorderPainted(false);
    addActionListener(board);
    }

    /**
     * A helper method that randomly generates a non-empty cell type.
     * 
     * @return randomly generated non-empty cell type
     */

    private int newRandomCellType() {
    return generator.nextInt(NUM_COLOURS) + 1;
    }

    /**
     * Determine the image to use based on the cell type. Uses
     * getResource to locate the image file, either on the file system or
     * the .jar file. Implements a caching mechanism.
     * 
     * @return the image to be displayed by the button
     */

    private ImageIcon getImageIcon() {
    int id;
    if (selected) {
        id = NUM_COLOURS + 1;
    } else {
        id = type;
    }
    if (icons[id] == null) {
        String strId = Integer.toString(id);
        icons[id] = new ImageIcon(Cell.class.getResource(“/data/ball-”
            + strId + “.png”));
    }
    return icons[id];
    }

    /**
     * This method is called when the used clicks the reset button. A new cell
     * type is generated. Its image is updated. The cell is unselected.
     */

    public void reset() {
    type = newRandomCellType();
    setIcon(getImageIcon());
    selected = false;
    }

    /**
     * Returns the cell type of this cell.
     * 
     * @return the type
     */

    public int getType() {
    return type;
    }

    /**
     * Returns true if this and the other cell have the same type.
     * 
     * @param other
     *            other cell used for the comparison
     * @return true if both cells have the same type
     */

    public boolean sameType(Cell other) {
    return type == other.type;
    }

    /**
     * Changes the cell type of this cell. The image is updated accordingly.
     * 
     * @param type
     *            the type to set
     */

    public void setType(int type) {
    this.type = type;
    setIcon(getImageIcon());
    }

    /**
     * Returns true if this cell is empty, i.e. its type is
     * CellType.Empty.
     * 
     * @return true is this cell is empty
     */

    public boolean isEmpty() {
    return type == EMPTY;
    }

    /**
     * Returns true is this cell is selected. Note: isSelected would have
     * been a better name. However, this would overwrite the parent method
     * isSelected.
     * 
     * @return true is this cell is selected.
     */

    public boolean selected() {
    return selected;
    }

    /**
     * Sets the value of the attribute selected.
     * 
     * @param selected
     *            the new value for the attribute selected
     */

    public void setSelected(boolean selected) {
    this.selected = selected;
    setIcon(getImageIcon());
    }

    /**
     * Getter method for the attribute row.
     * 
     * @return the value of the attribute row
     */

    public int getRow() {
    return row;
    }

    /**
     * Getter method for the attribute column.
     * 
     * @return the value of the attribute column
     */

    public int getColumn() {
    return column;
    }
}

Puzzler

package ca.uottawa.eecs.puzzler;
public synchronized class Puzzler extends javax.swing.JFrame implements java.awt.event.ActionListener {
private static final long serialVersionUID = 1;
private Board board;
public void Puzzler();
public void actionPerformed(java.awt.event.ActionEvent);
public static void main(String[]);
}

ca/uottawa/eecs/puzzler/Puzzler.java
ca/uottawa/eecs/puzzler/Puzzler.javapackage ca.uottawa.eecs.puzzler;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

/**
 * This is the main window of the application. A Board object is placed
 * in the center of the frame. The reset button is placed at the bottom.
 * 
 * Based on Puzzler by Apple.
 * 
 * @author Marcel Turcotte, University of Ottawa
 */

public class Puzzler extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;

    /**
     * Keeps a reference to the object board in order to call the method
     * reset whenever the user clicks the reset button.
     */

    private Board board;

    /**
     * Creates the layout of the application.
     */

    public Puzzler() {
    super(“Puzzler”);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBackground(Color.WHITE);

    board = new Board();
    add(board, BorderLayout.CENTER);

    JButton button = new JButton(“Reset”);
    button.setFocusPainted(false);
    button.addActionListener(this);

    JPanel control = new JPanel();
    control.setBackground(Color.WHITE);
    control.add(button);
    add(control, BorderLayout.SOUTH);

    pack();
    setResizable(false);
    setVisible(true);

    board.setAllowsClicks(true);
    }

    /**
     * This method must be implemented as part of the contract specified by
     * ActionListener. When the user clicks the reset button, it calls the
     * method reset of the object designated by board.
     * 
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */

    public void actionPerformed(ActionEvent e) {
    if (board.allowsClicks()) {
        board.setAllowsClicks(false);
        board.reset();
        board.setAllowsClicks(true);
    }
    }

    /**
     * Java programs start by executing the main method. Here, this main method
     * creates the main window of the application.
     * 
     * @param args
     *            the command line arguments
     */

    public static void main(String[] args) {
    new Puzzler();
    }

}

Main-Class: ca.uottawa.eecs.puzzler.Puzzler