Java program code
-
Write a java program that implements a general "Game of Life", a "cellular automaton" world consisting of a rectangular array of cells, each of which is either Alive or Dead. It is important that these guidelines for the question are followed. The world starts in an initial state (i.e. a pattern of Alive and Dead cells), and then moves through a series of successive states. Each state is called a generation. State-transition rules determine the way the pattern of Alive/Dead cells change from one generation to the next. There are 4 transition possibilities for a cell: Dead -> Dead: "stasis" Dead -> Alive: "birth" Alive -> Alive: "survival" Alive -> Dead: "death" The fate of a cell in going from one generation to the next depends on whether it is Alive or Dead in the current generation, and on the number of Alive neighbors it has in the current generation. Different state-transition rules lead to different "Games of Life" with worlds that evolve in different ways. A particularly interesting state transition rule discovered by the mathematician John Horton Conway is this: A "birth" happens only with 3 Alive neighbors, "survival" happens only with 2 or 3 Alive neighbors, and "stasis" or "death" happens otherwise. This Conway Rule leads to many interesting patterns developing in the game. A neighbor of a cell is defined as one of its 8 adjacent cells (upper left, above, upper right, left, right, lower left, below, lower right), so a cell can have at most 8 Alive neighbors. The world is a finite rectangle with a certain number of rows and columns, and there are no Alive cells outside the world. The program shall be run as follows: java Life <FILENAME> The initial state of the world is read from the file whose name is given as the first command line argument (format specified below) A window is created, which contains these components: 1. A central panel, which displays the initial state of the world, and subsequent generations, in a form described below. The user can change the state of the world by clicking the mouse in a displayed cell. Doing so changes the state of that cell (to Alive it was Dead, or to Dead if it was Alive). The result of such a change is displayed. 2. A text field, initialized to "10", in which the user can enter a nonnegative integer which is the number of successive generations to compute and display. This text field should have a label associated with it, that indicates to the user that it represents the number of generations. 3. A button labeled "Start", which when pushed computes and displays as many subsequent generations as are indicated by the number in the text field, at a rate of approximately two per second. 4. An output label that displays a running count of the number of generations displayed, and error messages as appropriate. File format: The initial state of the world will be read from a file. This file is a binary file, with format as follows: The first 4 bytes of the file are an int, indicating the number of rows in the world, R. The next 4 bytes in the file are another int, indicating the number of columns in the world, C. Then there follow R*C bytes. The first C bytes specify the states of the cells in the top row of the world, left to right; and so on. A byte that is equal to 0 indicates a Dead cell; a nonzero byte indicates a Alive cell. If there are more bytes in the file than required by the world size, the extra ones are to be ignored. If there are fewer bytes in the file than required by the world size, the unspecified cells are assumed to be Dead. Display format: When run, the Life program first reads a world state specification file, as described above. It displays this world in a central panel in the application window, and permits the user to change the state of some cells by clicking on them. Each cell in the world should be displayed on the central panel as a filled circle 10 pixels in diameter, and the central panel should be the exact size required to display all cells in the world. The panel background, Alive cells, and Dead cells should be displayed in contrasting colors so they can be distinguished from each other. When the user clicks the start button, new generations are computed and displayed. The application pauses after the required generations have been displayed, permitting the user to continue if they want to, or to exit the application by clicking on the "close window" button provided by the window system. These are the Class interface specifications. The Life class should be defined to extend JFrame. An instance of the Life class will correspond to the top-level application window. Define this protected instance variable in the class: protected boolean[][] world; The elements of the world array represent the states of cells in an instance of the game of Life. Each cell is in one of two states (Alive or Dead), so a boolean array is appropriate. The number of rows and columns of this two-dimensional array must be exactly the same as the number of rows and columns in this instance of Life. (And note that it must have protected visibility, so subclasses can access it as needed.) Define at least these public methods in the Life class: /** Constructor: initialize a new Life object to represent * a world with the given number of rows and columns of cells. * All cells are initially Dead. This constructor also creates * appropriate components and containers and adds them to the * application container, and creates and registers appropriate * listener objects. It does not make any GUI objects visible. */ public Life(int rows, int cols) /** Read a world initial state specification file (format described * in the P7 README) with name given by its argument. * Create and return a Life object whose world is in the state specified * by the file. * @throws java.io.IOException containing an appropriate message if * the file is badly formatted or unreadable, or if an I/O error occurs. */ public static Life fromFile(String filename) throws IOException /** Update the state of the protected boolean[][] world array of * this Life object (i.e., compute the next generation) according * to the Conway state-transition rule. * This method does not do any displaying. */ public void next() /** The entry point for the Life program. * Creates a Life object initialized from the file given as * the first command line argument, and makes it visible. */ public static void main(String args[]) You may define any other private static or instance methods or variables, or inner classes that you wish. Here are some suggestions just to help you out 1. The hard part is supposed to be implementing the next() method. It is quite hard to compute the state of the next generation using only the world array that is representing the current generation; so it is suggested you create another array to hold the new generation while you are computing it, and then make the world array pointer point to it when done. In any case, when next() returns, the protected world variable must point to the new generation. 2. To compute a new generation, apply the rule of the game to each cell. Be sure to take into account that the world "ends" at its edges, as mentioned above. In thinking about how to decompose the problem into manageable pieces, you may find that methods with suggestive names like countLiveNeighbors(int row, int col) and isAlive(int row, int col) might be useful. 4. Each cell takes up a circle 10 pixels in diameter when displayed. Therefore, if your world has R rows and C columns, your central panel must have width 10*C and height 10*R pixels to display the world. The application JFrame needs to be large enough to hold such a central panel, the start button, the text field, the two required labels, plus any default borders and decorations belonging to the JFrame. A trick of JFC/AWT programming to accomplish this is to use a JPanel for the central panel, call the setPreferredSize() method of the JPanel to set its size, and after adding it and all other needed components to the JFrame's content pane, to "pack" the JFrame. Note that setPreferredSize() takes one argument, of type Dimension. Some code in your Life constructor can look something like this: Container c = this.getContentPane(); JPanel p = new JPanel(); p.setPreferredSize(new Dimension(10*C,10*R)); c.add(p); this.pack(); The pack() method computes the right size for the JFrame to be able to contain its Components, so you don't have to. Inner classes will be necessary, and in particular anonymous inner classes will be appropriate. When useful, include these: a. An anonymous inner class that extends JPanel and that overrides the paintComponent(Graphics g) method to display the current world state in the JPanel. This method should first call super.paintComponent(g) to clear the background and produce a better-looking animation. An instance of this class will be the central panel in the application window. b. An anonymous inner class that extends MouseAdapter and that overrides mouseClicked() to handle the mouse click events fired by the central JPanel. An instance of this class will be registered as a MouseEvent listener with the central JPanel. The handler method needs to determine the x,y coordinates of the mouse click, to change the state of the clicked cell appropriately, and to display the new state. To display the new state, you can just call the repaint() method of the JPanel, which takes care of calling its paintComponent() method. c. An anonymous inner class that implements ActionListener and that overrides actionPerformed() to handle the start button being clicked. An instance of this class will be registered as an ActionEvent listener with the start button. The handler method needs to get the text in the text field, convert it to an int, and run the game of life for that many generations (not counting the current generation), causing each generation to be displayed in the central JPanel. If the contents of the text field are not parseable as a positive int, an error should be displayed in the output label. As each generation is displayed, the number of that generation should be displayed in the output label. d. An anonymous inner class that extends WindowAdapter and that overrides windowClosing() to exit the application. An instance of this class will be registered as a WindowEvent listener with the overall JFrame. Alternatively, you could just setDefaultCloseOperation to JFrame.EXIT_ON_CLOSE. 6. To cause a container to display all of its components, you normally call the container's repaint() method. However, for animations such as the Life program, that may not work as you would hope; in an attempt to be efficient, the runtime system can "coalesce" multiple calls to paint() into one call, and you won't see anything but the last frame in the animation. Instead, it is better in animations to call the paintImmediately() method of the container, which does not do this coalescing. Note that paintImmediately() takes 4 int arguments which specify the rectangular area in the container to paint immediately: paintImmediately(int x, int y, int width, int height) You should think about calling paintImmediately for two purposes: a. In the event handler for the start button, after a new generation has been computed, call the paintImmediately() method of the central JPanel. (This leads to its overrided paintComponent() method being called.) If the JPanel is p, painting the entire JPanel immediately can be done with a call like p.paintImmediately(0,0,p.getWidth(),p.getHeight()); b. In the event handler for the start button, after a new generation has been computed, you will update the text in the output label. To make this new text appear immediately, call the paintImmediately() method for that label's container. For convenience, you may want to place that label in a JPanel container, and place that JPanel in a region of the top-level JFrame. 7. You might want to create files to test the class.
-
Answer:
Thank you for your question. Remember please: if you have any questions or need additional features or functionality, use the "Request Clarification" to solicit these *before* rating the question. I am happy to modify the code in response to requests. I have placed these files on http://www.rbnn.com/google/life http://www.rbnn.com/google/life/Life.java http://www.rbnn.com/google/life/LifePanel.java http://www.rbnn.com/google/life/LifeTest.java http://www.rbnn.com/google/life/script.txt http://www.rbnn.com/google/life/file1.dat http://www.rbnn.com/google/life/file2.dat http://www.rbnn.com/google/life/file3.dat http://www.rbnn.com/google/life/file4.dat http://www.rbnn.com/google/life/answer.txt http://www.rbnn.com/google/life/index.html [not for download; for viewing] Here is the description of each file: Life.java is the main JFrame that runs the simulation and is written according to the specification in your question. It's main purpose is to create a bunch of JPanels, JButtons, and other things like that, and to render the main frame. LifePanel.java handles the "Life-specific" logic and rendering. It is responsible for displaying and rendering a particular Life grid, and for computing the next generation from a given generation. LifeTest.java creates 4 files, file1.dat, file2.dat, file3.dat and file4.dat. These files are described in the LifeTest.java documentation, and are designed to test edge cases of the file format. You can read that documentation from the JavaDoc generated HTML here: http://www.rbnn.com/google/life/LifeTest.html , or just go to http://www.rbnn.com/google/life/index.html and click on "LifeTest" . file1.dat is a valid file; file2.dat has missing data; file3.dat has an invalid ncolumns; and file4.dat has extra data . script.txt is a sample script that shows how the files are compiled and run. As it is short, here it is: # This script demonstrates compiling and running the system % ls *.java Life.java # the JFrame LifePanel.java # the JPanel LifeTest.java # creating the test files % javac *.java # compile everything % javadoc -private *.java # lots of output deleted here.... % java LifeTest # create the .dat files % ls *.dat # list the .dat files file1.dat # normal file2.dat # missing rows file3.dat # bad format file4.dat # extra data % java Life file1.dat # this displays a 20x30 life picture % java Life file2.dat # displays same, with all but first two rows dead % java Life file3.dat # gives error Unable to read from file: file3.dat. Got error: java.io.IOException: bad format % java Life file4.dat # same as file1.dat answer.txt is this answer . index.html is the root of the javadoc generated tree that holds HTML documentation of the classes and methods. all.zip is the zipped version of all the files in the directory. TO DOWNLOAD ---------- The simplest way is: 1. download the java files 2. javac *.java # to compile the java files 3. java LifeTest # to generate the dat files 4. java Life file1.dat # to run a Life simulation 5. javadoc -private *.java to generate the .html files from javadoc The script.txt files shows how to generate the .dat and the javadoc .html files. SEARCH STRATEGY/DESIGN DECISIONS ------------------------------- Although I enjoy Life very much, and have even met John Conway in person (in fact I have a paper in a book in which he also has a paper), I had some difficulty with the problem here. One of my friends spent so much time designing Life patterns he delayed his graduation in fact. First, generally I think GUI design should be done by GUI designers. I'm not a GUI designer, and I don't have one available for this project. That means that things like color schemes and button placements, although they work, are not aesthetic. Of course, if you would like to have a different GUI design, just say so and I can implement it. But making a pretty GUI is something that is more for artists than programmers. I tried out many different GUI designs, using BorderLayout first and then finally the BoxLayout. One of the big problems that tended to happen is that a layout would look fine for 50 x 50 grids, but look really bad for 5 x 5 grids. So the current layout solution I have should at least look OK for fairly small to reasonably large grids. Second, some aspects of the specification were a little bit difficult to do. For instance, I might not have put the boolean[][]world instance variable in the main GUI class. I would have just delegated all the Life logic and representation to another class. Having the world be a boolean[][] in the main class forces the main class to have too much information on the details of the representation, perhaps. In general, there were some specific method signatures required that were fairly tricky to do well. I considered three designs for the program: o Everything in one big class o The GUI logic in one class and the Life logic in another o The container logic in one class and the Life logic in another . I coded everything as the first, but the resulting class became huge and hard to read. So I split it up. I also coded a solution using the second, but then I realized that the world[][] requirement made this tricky. So instead I used the third solution. I tried to re-use code and logic from the CreatureWorld class in an earlier question. I also considered using a Swing Timer instead of a Thread.sleep(). This would be a bit cleaner, but did not seem to be required by the spec. A good book on design decisions is Applying UML and Patterns. by Craig Larman. Prentice-Hall 1997. It has a lot of excellent design advice. OTHER LINKS ------------ See: http://www.cse.sc.edu/~bays/Life_4D/objects.html for some simple life objects. These can be input to the program to check that it is correctly generating Life patterns.
wcryder-ga at Google Answers Visit the source
Related Q & A:
- How to Code Encryption Algorithm in Java?Best solution by code2learn.com
- how to close the applet in java code?Best solution by Stack Overflow
- how to Create a Java Package from MATLAB Code?Best solution by Stack Overflow
- What is the Direct TV RC32 remote control program code for TCL LCD TV?Best solution by Yahoo! Answers
- How to create this Java program?Best solution by ChaCha
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.