it is all in the docs the question is under the specification
Life - Part 2: Assignment Specification CAB201 Semester 2, 2020 Last Updated: 04/10/2020 Assigment Details Progress Due Date: 18/10/2020 - 11:59pm Final Due Date: 25/10/2020 - 11:59pm Weighting: 35% Type: Individual Project Version: 1.2 - 02/10/2020 Change Log There is no intention to have this assignment specification change over time. However, if anything does change or additional detail is added to the specification, the table below will be updated to reflect the changes. Version Date Description 1.0 21/09/2020 Initial specification 1.1 25/09/2020 Rectified validation requirements for neighbourhood command line option 1.2 02/10/2020 Fixed test-case videos and seed files Overview In Part 1 of your major project for this semester you implemented the classic, Conway’s Game of Life. Part 2 is focussed on extending your implementation to be more generalised, scalable and versatile. As such, your solution to Part 1 is crucial to completing Part 2. This specification details the additional features that your game must implement. This assignment is designed to test your ability to: � Modify existing code to implement new features � Enforce good object oriented programming practices � Handle unexpected code behaviour elegantly 1 Neighbourhoods Previously, the neighbourhood was defined as the cells positioned horizontally, vertically and diagonally adjacent of any given cell. This is type of neighbourhood is also commonly referred to as a Moore neigh- bourhood. There is another type of neighbourhood that will be introduced for this assignment: the von Neumann. Both of these neighbourhoods will be of variable size and described below. Your program must have the ability to observe these neighbourhoods of a specified order. In addition, your program must have the ability to count the centre of the neighbourhood part of the neighbourhood when requested. Moore Neighbourhood An nth order Moore neighbourhood is defined as the cells that have a Chebyshev distance of n or less from any given cell. The Chebyshev distance is defined as the largest distance in a single dimension among all dimensions between two points. A Moore neighbourhood may be easier to understand visually. See figure 1 for a visual depiction of a Moore neighbourhoods of different sizes. 0 1 2 3 4 5 6 0 1 2 3 4 5 6 1st Order 0 1 2 3 4 5 6 0 1 2 3 4 5 6 2nd Order 0 1 2 3 4 5 6 0 1 2 3 4 5 6 3rd Order Figure 1: Visual representation of a Moore neighbourhoods of various orders in Life. The neighbours of the cell highlighted in blue are highlighted in light blue. Von Neumann Neighbourhood An nth order von Neumann neighbourhood is defined as the cells that have a Manhattan distance of n or less from any given cell. The Manhattan distance is defined as the sum of distances in each dimension between two points. As with the Moore neighbourhood, the von Neumann neighbourhood may be easier to understand visually. See figure 2 for a visual depiction of a Moore neighbourhoods of different sizes. 0 1 2 3 4 5 6 0 1 2 3 4 5 6 1st Order 0 1 2 3 4 5 6 0 1 2 3 4 5 6 2nd Order 0 1 2 3 4 5 6 0 1 2 3 4 5 6 3rd Order Figure 2: Visual representation of a von Neumann neighbourhoods of various orders in Life. The neighbours of the cell highlighted in blue are highlighted in light blue. 2 Custom Rules With variable neighbourhood sizes and shapes comes the necessity of more versatile rules. Previously, the number of alive neighbours required for a cell to survive or be born was fixed. Your program must have the ability to evolve by allowing cells to survive or be born based on a variable number of alive neighbours required for either. As before, the game will progress (or evolve) through a series of generations, with each generation de- pending on the one that proceeded it. But this time, the rules that determine the next generation are generalised to the following: � Any live cell with exactly any number of live neighbours contained in the set of numbers S survive (stay alive) in the next generation. � Any dead cell with exactly any number of live neighbours contained in the set of numbers B are born (become alive) in the next generation. � All other cells are dead in the next generation. The original rules of Life can still be respected using these generalised rules with the following set definitions: S = {2, 3} B = {3} Steady-State Detection During your development and testing of Part 1, you likely noticed that the game can exhibit forever repreat- ing patterns or settle to some unchanging state. Both of these scenarios are considered as steady-states. Your program must be able to detect steady-states by comparing each generation against its predecessors. By default your program must use the 16 most recent generations to determine whether a steady state has been reached, but this can be as high as 512 and as low as 4. When a steady state is reached, the game must be marked as complete and the user must be notified with a message after the grid display is closed. The notification should detail whether a steady-state was reached. If a steady-state is reached, the pro- gram should report the periodicity of the steady-state. The periodicity refers to the number of generations required for the steady-state to repeat itself. If the steady-state is non-periodic (for example, in the case where all cells die) then the periodicity should be displayed as none or N/A. File I/O If you ever tried creating your own seed file based on the previous specification, you may have noticed that it is simple, but rather tedious. For Part 2, your program must be able to read a new version (#version=2.0) of seed files. Instead of having each line of the file detailing the row and column of alive cells, the new version of the seed file will allow each line to detail a structure of cells and whether it should be initially treated as dead or alive. This way, initial configurations can be more easily designed. The new version of seed files have a number of structures (described below) and will be formatted according to the following rules: � The first line of the file will always be #version=2.0. � Each line of the file represents a structure that is initialy alive or dead with the following syntax: • The line will start with an x or an o character in parenthesis. o if initially alive, x is initially dead. 3 • A keyword representing the structure type will follow, followed by a colon. • The parameters for the structures will follow, each separated by commas. • Whitespaces are to be ignored completely when reading each line. Below is an example of a seed file that would result in the glider pattern shown in the last specification: #version=2.0 (o) cell: 3, 2 (o) cell: 2, 0 (o) cell: 2, 2 (o) cell: 1, 1 (o) cell: 1, 2 It is important to note that your program must be able to support both versions of seed files when reading. Your program should use the version number to determine how it is going to read the file. Your program must also be able to write the final generation of the game to a seed file if an output file path is specified via the command line arguments. The seed file must be written using the #version=2.0 specification, using only the cell structure. cell Structure The cell structure can be used to specify a cell, given it’s location. The parameters that can be provided to cell are the following (in order): � The row index � The column index rectangle Structure The rectangle structure can be used to specify a rectangle, given the location of two of it’s opposing corners. The parameters that can be provided to rectangle are the following (in order): � The bottom-left row index � The bottom-left column index � The top-right row index � The top-right row index ellipse Structure The ellipse structure can be used to specify an elipse, given the location of two of it’s opposing bounding corners (you are to assume that the ellipse is bounded by a rectangle). The parameters that can be provided to ellipse are identical to rectangle (see above). The cells that make up an ellipse are those whose centre- points are within the elipse (or on it’s border). Figure 3 contains a visual depiction of this, which may help with your understanding. You may find the following equation useful when determining which cells are part of an ellipse structure. In the equation x0 and y0 represent the coordinates of the centre of the ellipse, dx and dy represent the width and height of the ellipse, and x and y represent the coordinates of some arbitrary point. If the equation is true, then the point (x, y) is inside the ellipse. 4(x− x0)2 d2x + 4(y − y0)2 d2y ≤ 1 4 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 (o) rectangle : 1, 1, 4, 8 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 (o) ellipse : 1, 1, 4, 8 Figure 3: Example of the cells represented by rectangle and ellipse structures, each bounded by (1,1) and (4,8). Note that only cells that have their centre point within the ellipse are represented Ghost Mode As a "bonus feature", your program should be able to render the game of life using what will be referred to as ghost mode. Instead of just rendering the latest generation, ghost mode should make the program render the four most recent generations of life concurrently. The oldest generation should be rendered using the lightest shading, and the shading should increase for the more recent generations. Ghost mode is best understood visually so be sure to watch the related test cases to gain a better understanding. If you have read into the code provided in the Display library, you may note that the CellState enum contains more states than the two that you would have used in Part 1 (Blank and Full). You should be using the the remaining states (Dark, Medium and Light) in tandem to implement ghost mode. Command Line Arguments Many of the new features introduced above will require their own command line arguments in the form of new options and parameters. Each of the new options will be described below. Neighbourhood The type and size of the neighbourhood to be used may be specified using the –neighbour option. The flag must be followed by three parameters, the first specifying the neighbourhood type, the second specifying or- der (size) of the neighbourhood, and the third specifying whether the centre of the neighbourhood is counted as a neighbour or not. Defaults: The game will use a 1st order Moore neighbourhood that doesn’t count the centre. Validation: The neighbourhood type must must be one of two strings, either "moore" or "vonNeumann",