Language C++ // FILE GameOfLife2.h #pragma once #include // Provides ostream #in
ID: 3845960 • Letter: L
Question
Language C++
// FILE GameOfLife2.h
#pragma once
#include // Provides ostream
#include // String operations
#include // Randomizer
namespace csci2312
{
using std::string;
using std::ostream;
using std::istream;
// PA2: standard exception if memory allcation failed
using std::bad_alloc;
// Class Cell stays the same for PA1 and PA2
class Cell
{
public:
static const char alive ='o'; // alive image
static const char dead = '-'; // dead image
Cell();
Cell(bool cellState);
~Cell();
// Accessors have no intention to modify the object, so it is a good practice to make them 'const' functions
bool getState() const;
char getFace() const;
// Mutators
void setState(bool newState);
private:
bool state=false;
char face;
};
// PA2: File IO Error custom exception class
class FileIOException
{
// Nothing inside, just a class type to handle exception
};
// PA2: Class GameOfLife will have some new and some changed features
class GameOfLife
{
public:
// PA1: maximum display board size
// PA2: default display board size
static const unsigned int MAX_BOARD = 30;
// PA2: New type (pointer to Cell type) handy with dynamic arrays
typedef Cell* CellPtr;
// PA1: Default constructor construct a board with all dark cells of MAX_BOARD size
// GameOfLife();
// PA1: Constructs the board of the requested size
// GameOfLife(size_t boardSize);
// PA2: Constructs the board of the requested size, can throw exception.
// If parameter is omitted, it becomes the default constructor, and the board will have MAX_BOARD size
GameOfLife(size_t boardSize = MAX_BOARD) throw (bad_alloc);
// PA2: Copy-constructor creates a new instance as a deep copy of the referenced object
GameOfLife(const GameOfLife& game);
// PA2: destructor must release memory taken by dynamic arrays
~GameOfLife();
// Returns board size
size_t getBoardSize() const;
// PA1: seeds the board from a file
// int seedBoard(string fileName);
// PA2: seeds the board from a file and throws an exception if there was trouble with file
void seedBoard(string fileName) throw (FileIOException);
// PA1 and PA2: seeds the board with a given number of seeds at randomized locations
void seedBoard(size_t seeds);
// Executes Conway set of rules. Returns next state
// Needed for TASK #4 to develop a test harness (the files test harness will be provided separately)
bool executeRules(unsigned int countAlive, bool currentState);
// PA1 and PA2:
void run();
void run(unsigned int numberOfIterations);
// Just an example of an possible accessor which reaches to a private array. Not needed to satisfy PAs
// A const(!) accessor method that returns a handle to the private currentLife array.
// The return type must also be 'const' because we return a pointer to a static array, and these are fixed
// It is just an example. It is not needed if we have a friend operator.
// PA1: const Cell(*getCurrentLife() const )[MAX_BOARD+2] { return currentLife; };
// PA2: const CellPtr* getCurrentLIfe() const { return currentLife; };
// PA1 and PA2: overloaded output operator to displsy the board
// friend operator can access private members of GameOfLife
friend ostream& operator << (ostream& out, const GameOfLife& board);
// PA2: overloaded input operator to input the board (from file of keyboard)
friend istream& operator >> (istream& in, GameOfLife& board);
private:
// PA2: Encapsulate next generation calculation in a method.
void calculateNextGen(CellPtr* current, CellPtr* next);
// PA1: static arrays of Cells. With "Halo" approach we need a bigger board
// Cell currentLife[MAX_BOARD + 2][MAX_BOARD + 2];
// Cell nextLife[MAX_BOARD + 2][MAX_BOARD + 2];
// PA2: dynamic arrays of Cells. New type CellPtr defined (typedef Cell* CellPtr)
// currentLife and and nextLife are handles to the dynamic arrays
CellPtr *currentLife;
CellPtr *nextLife;
// Just an example how to declare variable cl as a handle to our array of Cells. Not needed to satisfy PAs
// The accessor method getCurrentLife() above uses the same syntax for the return type
// PA1 with static arrays: const Cell(*cl)[MAX_BOARD + 2] = currentLife;
// PA2 with dynamic arrays: const CellPtr* cl = currentLife;
// PA1 and PA2, keeps track of the actual board size, set in the constructor
size_t boardSize;
// PA2: A handle to the array that needs to be displyed next.
CellPtr *displayBoard;
};
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------
// GameOfLife2_TestApp.cpp
#include
#include "ErrorContext.h"
#include "GameOfLife2_Tests.h"
using std::cout;
using std::endl;
using namespace Testing;
using namespace csci2312;
int main() {
ErrorContext ec(cout);
cout << endl << "Testing PA2!!" << endl << endl;
// Cell tests
test_cell_smoketest(ec);
test_cell_setget(ec);
// GameOfLife tests
test_game_smoketest(ec);
test_game_rules(ec);
system("pause");
return 0;
}
-------------------------------------------------------------------------------------------------------------------------------------
//ErrorContext.h
#pragma once
/**
* Acknowledgement: Donnie Pinkston, CALTECH
*/
#include
#include
#include
namespace Testing {
using std::set;
using std::ostream;
using std::string;
class ErrorContext // displays test results
{
public:
ErrorContext(ostream &os); // write header to stream
void desc(const char *msg, int line); // write line/description
void desc(string msg, int line);
void result(bool good); // write test result
~ErrorContext(); // write summary info
bool ok() const; // true iff all tests passed
private:
ostream &os; // output stream to use
int passed; // # of tests which passed
int total; // total # of tests
int lastline; // line # of most recent test
set badlines; // line #'s of failed tests
bool skip; // skip a line before title?
};
}
---------------------------------------------------------------------------------------------------------------------------
//GameOfLife2_Tests.cpp
#include
#include
#include
#include
#include "ErrorContext.h"
#include "GameOfLife2_Tests.h"
using std::cout;
using std::endl;
using std::setprecision;
using Testing::ErrorContext;
using csci2312::GameOfLife;
#define DESC(x) desc(x, __LINE__) // ugly hack, but saves some time
///////// STUDENT TASK: Fill in implementatin for Cell tests
// Test Cell constructor and destructor
void test_cell_smoketest(ErrorContext &ec) {
// to do
}
// Test Cell setters and getters
void test_cell_setget(ErrorContext &ec) {
// to do
}
///////// END TASK
// Test GameOfLife constructor and destructor
void test_game_smoketest(ErrorContext &ec) {
bool pass;
GameOfLife* myGame;
ec.DESC("--- Test - GameOfLife - Smoketest ---");
ec.DESC("Default Constructor");
pass = true;
// Construct a Default GameOfLife - boardSize should be set to MAX_BOARD
myGame = new GameOfLife;
pass = (myGame->getBoardSize() == myGame->MAX_BOARD);
ec.result(pass);
ec.DESC("Destruct Defualt Test Game");
// Cleans up after previous test, destruct the object
delete myGame;
ec.DESC("Custom Constructor requesting a specific boad size");
pass = true;
// Construct a Custom GameOfLife - boardSize should be set to what was requested
myGame = new GameOfLife(50);
pass = (myGame->getBoardSize() == 50);
ec.result(pass);
ec.DESC("Destruct Custom Test Game");
// Cleans up after previous test, destruct the object
delete myGame;
}
// Game rules test
void test_game_rules(ErrorContext &ec) {
bool pass;
GameOfLife *myGame;
// Run at least once!!
// assert(numRuns > 0);
ec.DESC("--- Test - Game Rule 110 ---");
pass = true;
// Construct a Default GameOfLife - boardSize should be set to MAX_BOARD
myGame = new GameOfLife;
ec.DESC("--------- Alive cell with 2 alive neighbors ---");
pass = (myGame->executeRules(2, true) == true);
ec.result(pass);
ec.DESC("--------- Dead cell with 2 alive neighbors ---");
pass = (myGame->executeRules(2, false) == false);
ec.result(pass);
///////// STUDENT TASK: add test for the remaining rule outcomes
///////// END TASK
// Destruct the object at the end of test
ec.DESC("Destruct Test Game");
// Cleans up after previous test, destruct the object
delete myGame;
}
Explanation / Answer
package org.bitstorm.gameoflife;
import java.applet.Applet;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
/**
* The Game Of Life Applet.
* This is the heart of the program. It initializes everything en put it together.
* @author Edwin Martin
*/
public class GameOfLife extends Applet implements Runnable, GameOfLifeControlsListener {
protected CellGridCanvas gameOfLifeCanvas;
protected GameOfLifeGrid gameOfLifeGrid;
protected int cellSize;
protected int cellCols;
protected int cellRows;
protected int genTime;
protected GameOfLifeControls controls;
protected static Thread gameThread = null;
/**
* Initialize UI.
* @see java.applet.Applet#init()
*/
public void init() {
getParams();
// set background colour
setBackground(new Color(0x999999));
// create gameOfLifeGrid
gameOfLifeGrid = new GameOfLifeGrid(cellCols, cellRows);
gameOfLifeGrid.clear();
// create GameOfLifeCanvas
gameOfLifeCanvas = new CellGridCanvas(gameOfLifeGrid, cellSize);
// create GameOfLifeControls
controls = new GameOfLifeControls();
controls.addGameOfLifeControlsListener( this );
// put it all together
GridBagLayout gridbag = new GridBagLayout();
setLayout(gridbag);
GridBagConstraints canvasContraints = new GridBagConstraints();
canvasContraints.fill = GridBagConstraints.BOTH;
canvasContraints.gridx = GridBagConstraints.REMAINDER;
canvasContraints.gridy = 0;
canvasContraints.weightx = 1;
canvasContraints.weighty = 1;
canvasContraints.anchor = GridBagConstraints.CENTER;
gridbag.setConstraints(gameOfLifeCanvas, canvasContraints);
add(gameOfLifeCanvas);
GridBagConstraints controlsContraints = new GridBagConstraints();
canvasContraints.gridy = 1;
canvasContraints.gridx = 0;
controlsContraints.gridx = GridBagConstraints.REMAINDER;
gridbag.setConstraints(controls, controlsContraints);
add(controls);
try {
// Start with a shape (My girlfriend clicked "Start" on a blank screen and wondered why nothing happened).
setShape( ShapeCollection.getShapeByName( "Glider" ) );
} catch (ShapeException e) {
// Ignore. Not going to happen.
}
setVisible(true);
validate();
}
/**
* Get params (cellSize, cellCols, cellRows, genTime) from applet-tag
*/
protected void getParams() {
cellSize = getParamInteger( "cellsize", 11 );
cellCols = getParamInteger( "cellcols", 50 );
cellRows = getParamInteger( "cellrows", 30 );
genTime = getParamInteger( "gentime", 1000 );
}
/**
* Read applet parameter (int) or, when unavailable, get default value.
* @param name name of parameter
* @param defaultParam default when parameter is unavailable
* @return value of parameter
*/
protected int getParamInteger( String name, int defaultParam ) {
String param;
int paramInt;
param = getParameter( name );
if ( param == null )
paramInt = defaultParam;
else
paramInt = Integer.valueOf(param).intValue();
return paramInt;
}
/**
* Starts creating new generations.
* No start() to prevent starting immediately.
*/
public synchronized void start2() {
controls.start();
if (gameThread == null) {
gameThread = new Thread(this);
gameThread.start();
}
}
/**
* @see java.applet.Applet#stop()
*/
public void stop() {
controls.stop();
gameThread = null;
}
/**
* @see java.lang.Runnable#run()
*/
public synchronized void run() {
while (gameThread != null) {
nextGeneration();
try {
Thread.sleep(genTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Is the applet running?
* @return true: applet is running
*/
public boolean isRunning() {
return gameThread != null;
}
/**
* Go to the next generation.
*/
public void nextGeneration() {
gameOfLifeGrid.next();
gameOfLifeCanvas.repaint();
showGenerations();
}
/**
* Set the new shape
* @param shape name of shape
*/
public void setShape( Shape shape ) {
if ( shape == null )
return;
try {
gameOfLifeCanvas.setShape( shape );
reset();
} catch (ShapeException e) {
alert( e.getMessage() );
}
}
/**
* Resets applet (after loading new shape)
*/
public void reset() {
stop(); // might otherwise confuse user
gameOfLifeCanvas.repaint();
showGenerations();
showStatus( "" );
}
/**
* @see java.applet.Applet#getAppletInfo()
*/
public String getAppletInfo() {
return "Game Of Life v. 1.5 Copyright 1996-2004 Edwin Martin";
}
/**
* Show number of generations.
*/
private void showGenerations() {
controls.setGeneration( gameOfLifeGrid.getGenerations() );
}
/**
* Set speed of new generations.
* @param fps generations per second
*/
public void setSpeed( int fps ) {
genTime = fps;
}
/**
* Sets cell size.
* @param p size of cell in pixels
*/
public void setCellSize( int p ) {
cellSize = p;
gameOfLifeCanvas.setCellSize( cellSize );
}
/**
* Gets cell size.
* @return size of cell
*/
public int getCellSize() {
return cellSize;
}
/**
* Shows an alert
* @param s text to show
*/
public void alert( String s ) {
showStatus( s );
}
/** Callback from GameOfLifeControlsListener
* @see org.bitstorm.gameoflife.GameOfLifeControlsListener#startStopButtonClicked(org.bitstorm.gameoflife.GameOfLifeControlsEvent)
*/
public void startStopButtonClicked( GameOfLifeControlsEvent e ) {
if ( isRunning() ) {
stop();
} else {
start2();
}
}
/** Callback from GameOfLifeControlsListener
* @see org.bitstorm.gameoflife.GameOfLifeControlsListener#nextButtonClicked(org.bitstorm.gameoflife.GameOfLifeControlsEvent)
*/
public void nextButtonClicked(GameOfLifeControlsEvent e) {
nextGeneration();
}
/** Callback from GameOfLifeControlsListener
* @see org.bitstorm.gameoflife.GameOfLifeControlsListener#speedChanged(org.bitstorm.gameoflife.GameOfLifeControlsEvent)
*/
public void speedChanged(GameOfLifeControlsEvent e) {
setSpeed( e.getSpeed() );
}
/** Callback from GameOfLifeControlsListener
* @see org.bitstorm.gameoflife.GameOfLifeControlsListener#speedChanged(org.bitstorm.gameoflife.GameOfLifeControlsEvent)
*/
public void zoomChanged(GameOfLifeControlsEvent e) {
setCellSize( e.getZoom() );
}
/** Callback from GameOfLifeControlsListener
* @see org.bitstorm.gameoflife.GameOfLifeControlsListener#shapeSelected(org.bitstorm.gameoflife.GameOfLifeControlsEvent)
*/
public void shapeSelected(GameOfLifeControlsEvent e) {
String shapeName = (String) e.getShapeName();
Shape shape;
try {
shape = ShapeCollection.getShapeByName( shapeName );
setShape( shape );
} catch (ShapeException e1) {
// Ignore. Not going to happen.
}
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.