Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Need help with C++ Simplegame Inheritance! Instructions are posted at the bottom of main.cpp. I am having issues completing BlinkEntity.cpp/.h and WanderingEntity.ccp/.h. main.cpp // lab4:

Need help with C++ Simplegame Inheritance! Instructions are posted at the bottom of main.cpp. I am having issues completing BlinkEntity.cpp/.h and WanderingEntity.ccp/.h.

main.cpp

// lab4: simplegame_Inheritance

//

// read main.cpp, and follow the instructions at the bottom of main.cpp

#include // printf(char*, ...), putchar(int)

#include // _getch()

#include "game.h"

void main()

{

Game game;

do

{

game.draw();

game.setInput(_getch());

game.update();

}

while(game.getState() == Game::RUNNING);

printf("Press ESCAPE to quit ");

while(_getch() != 27);

}

// INSTRUCTIONS

// ------------

// Compile this code. You should see a rectangular play field of periods, with

// 3 Entity objects visible on it. The happy-face Entity moves with the "wasd"

// keys, and the club Entity moves with the "ijkl" keys. If the happy-face

// reaches the diamond Entity, the player wins. If the happy-face reaches the

// club, the player loses.

//

// Read through this code! Try to understand it before starting the assignment.

// Comment confusing lines with what you think code is doing, and experiment

// with existing code to test your understanding.

// Once you feel comfortable with this code, accomplish each of the following,

// and make sure your code compiles and runs after each step is completed.

//

// 1) Getting comfortable with the game code

// a) Implement initialization lists in Vector2, Entity, and Game (setting

// object values after a ':', between the constructor signature and body).

// Have initialization lists set initial values for each member variable.

// b) Add another Entity to the game that isn't the same location as an

// existing Entity. Use a heart icon (ASCII code 3). It should display in

// the game.

// c) Add logic that makes the club (PLAYER2) win the game if that player

// reaches the heart Entity. You may want to make new constants, like

// GOAL2, and WIN2, to follow the existing code convention.

// d) Make a new private function called "void Game::handleUserInput()", move

// the user input handling logic from Game::update() into this new

// function, and call Game::handleUserInput from Game::update.

// e) Add whitespace to the handleUserInput logic, and comment each line with

// what you understand it is doing. If you don't understand what the code

// is doing, experiment with it until you do! Do things like printing

// variables you are unsure about, and guess what output will look like.

// f) Implement the prototyped overloaded operators for Vector2. Once they

// are finished you should be able to use the alternate code for setting

// up PLAYER2 in Game::Game() in "game.cpp".

// 2) A "BlinkEntity" class

// a) Create 2 new files in your project: "blinkentity.h", and

// "blinkentity.cpp"

// b) Make a BlinkEntity class that extends Entity. Declare the class in

// "blinkentity.h" and define it's methods in "blinkentity.cpp". Your

// "blinkentity.h" file should look something like:

// #pragma once

//

// #include "entity.h"

//

// class BlinkEntity : public Entity {

// };

// c) Instead of using an Entity for the Entity marked GOAL1 in the Game

// constructor, use a BlinkEntity. You will need to create a public

// BlinkEntity constructor.

// d) Give BlinkEntity another member variable called "alternateIcon". When

// BlinkEntity calls it's update function, swap the values of "icon" and

// "alternateIcon". You won't notice a change during runtime until you add

// the virtual modifier to Entity::update().

// 3) A "WanderingEntity" class

// a) Create 2 new files in your project: "wanderingentity.h", and

// "wanderingentity.cpp"

// b) Make a WanderingEntity class that extends Entity. Declare the class in

// "wanderingentity.h" and define it's methods in "wanderingentity.cpp".

// Your "wanderingentity.h" file should look something like:

// #pragma once

//

// #include "entity.h"

//

// class WanderingEntity : public Entity {

// };

// c) Instead of using an Entity for the Entity marked PLAYER2 in the Game

// constructor, use a WanderingEntity. You will need to create a public

// WanderingEntity constructor.

// d) Create a new update method for WanderingEntity. Declare it in

// "wanderingentity.h", and define it in "wanderingentity.cpp". In the

// WanderingEntity::update() method, set the "howToMoveNext" variable

// to a random number from 0 to 3. You can use "rand() % 4" to do this in

// "wanderingentity.cpp" if you #include or . After

// setting the "howToMoveNext" variable in update, call the parent class's

// updated with "Entity::update()".

// e) Add at least 2 more WanderingEntity objects in the Game. Add game logic

// will cause the player to lose if the player shares a location with any

// WanderingEntity object.

game.cpp

#include "game.h"

#include "BlinkEntity.h"

#include "wanderingentity.h"

#include "consoleutil.h"

#include

// moves for players. each list in order defined by Entity::Move_XXXX variables

char * moveCommands[] = { "wasd", "ijkl" };

const int NUMBER_OF_PLAYERS = sizeof(moveCommands) / sizeof(moveCommands[0]);

Game::Game()

{

state = RUNNING;

size.init(20, 15);

// allocate each entity

list[PLAYER1] = new Entity(4, 3, 1);

list[GOAL1] = new BlinkEntity(10, 7, 4);

list[GOAL2] = new Entity(1, 1, 3);

Vector2 g1 = list[GOAL1]->getPosition();

Vector2 p1 = list[PLAYER1]->getPosition();

list[PLAYER2] = new WanderingEntity(

(g1.x + p1.x) / 2,

(g1.y + p1.y) / 2, 5);

// add 2 more wandering entities

list[WANDERER2] = new WanderingEntity(

(g1.x + p1.x + 4) / 2,

(g1.y + p1.y + 4) / 3, 232);

list[WANDERER3] = new WanderingEntity(

(g1.x + p1.x + 6) / 2,

(g1.y + p1.y) / 2, 178);

// TODO overload operators below to replace logic above

//Vector2 p2 = (g1 + p1) / 2;

//list[PLAYER2] = new Entity(p2.x, p2.y, 5);

}

void Game::draw()

{

// draw the game world

moveCursor(0, 0);

for (int row = 0; row < size.y; row++) {

for (int col = 0; col < size.x; col++) {

putchar('.');

}

putchar(' ');

}

// draw players in the game

for (int i = 0; i < LIST_SIZE; ++i) {

list[i]->draw();

}

// inform player how to play

for (int i = 0; i < NUMBER_OF_PLAYERS; i++) {

moveCursor(0, size.y + i);

printf("use \"%s\" to move %c ",

moveCommands[i], list[i]->getIcon());

}

}

void Game::update()

{

// if the user pressed the escape key

if (userInput == 27) {

state = USER_QUIT;

return; // quit

}

// move the players, based on what key was pressed

int whatMove = Entity::MOVE_NONE, whosTurnItIs;

for (int player = 0; player < NUMBER_OF_PLAYERS; ++player) {

for (int i = 0; moveCommands[player][i] != '\0'; ++i) {

if (moveCommands[player][i] == userInput) {

whosTurnItIs = player;

whatMove = i;

break;

}

}

if (whatMove != Entity::MOVE_NONE) {

break;

}

}

if (whatMove != Entity::MOVE_NONE) {

list[whosTurnItIs]->move(whatMove);

}

// game logic

for (int i = 0; i < LIST_SIZE; ++i) {

list[i]->update();

}

Entity * player1 = list[PLAYER1];

Entity * player2 = list[PLAYER2];

Entity * goal = list[GOAL1];

Entity * wanderer2 = list[WANDERER2];

Entity * wanderer3 = list[WANDERER3];

if (goal->getPosition().is(player1->getPosition())) {

state = WIN;

}

if (!player1->getPosition().isWithin(0, 0, size.x, size.y)) {

state = LOST;

}

if (player2->getPosition().is(player1->getPosition())) {

state = DEFEAT;

}

// add game logic the will cause the player to lose if the player shares a location with any

// wanderingEntity object

if (player1->getPosition().is(player2->getPosition()) || player1->getPosition().is(wanderer2->getPosition())

|| player1->getPosition().is(wanderer3->getPosition())) {

state = LOST;

}

//show the end-of-game state message when the game ends

if (state != Game::RUNNING) {

moveCursor(0, size.y + NUMBER_OF_PLAYERS + 1);

char * message;

switch (state)

{

case WIN: message = "Goal ACHIEVED!"; break;

case LOST: message = "Player lost..."; break;

case DEFEAT:message = "Player was CLUBBED"; break;

default: message = "unknown state occured"; break;

}

printf("%s ", message);

}

}

Game::~Game()

{

// de-allocate each entity

for (int i = 0; i < LIST_SIZE; ++i)

delete list[i];

}

entity.cpp

#include "entity.h"

#include

#include "consoleutil.h"

/** draws the entity at it's known location, dependent on moveCursor(,) and putchar() */

void Entity::draw()

{

moveCursor(pos.x, pos.y);

putchar(icon);

}

/** re-initialize */

void Entity::init(int a_x, int a_y, char a_icon)

{

pos.init(a_x, a_y);

icon = a_icon;

}

/**

* @param MOVE_UP, MOVE_LEFT, MOVE_DOWN, or MOVE_RIGHT

* @return true if the parameter was a valid move

*/

bool Entity::move(int direction)

{

bool validMove = false;

switch(direction)

{

case MOVE_UP:

case MOVE_LEFT:

case MOVE_DOWN:

case MOVE_RIGHT:

this->howToMoveNext = direction;

validMove = true;

}

return validMove;

}

/** implement actual changes to the Entity's state, including movement */

void Entity::update()

{

switch(howToMoveNext)

{

case MOVE_UP: pos += Vector2(0,-1); break;

case MOVE_LEFT: pos += Vector2(-1,0); break;

case MOVE_DOWN: pos += Vector2(0,+1); break;

case MOVE_RIGHT:pos += Vector2(+1,0); break;

}

howToMoveNext = MOVE_NONE;

}

entity.h

#pragma once

#include "vector2.h"

/**

* basic game entity

*/

class Entity

{

protected:

/** where the entity is */

Vector2 pos;

/** what the entity looks like */

char icon;

/** */

int howToMoveNext;

public:

/** used to determine which move to make (based on what key was pressed) */

static const int MOVE_NONE = -1, MOVE_UP = 0, MOVE_LEFT = 1, MOVE_DOWN = 2, MOVE_RIGHT = 3;

/**

* @param x where

* @param y where

* @param icon what it looks like

*/

Entity(int x, int y, char icon)

{

pos.x = x;

pos.y = y;

this->icon = icon;

howToMoveNext = MOVE_NONE;

}

Entity(){}

/** draws the entity at it's known location, dependend on moveCursor(,) and putchar() */

void draw();

short getX() { return pos.x; }

short getY() { return pos.y; }

void setX(int value){ pos.x = value; }

void setY(int value){ pos.y = value; }

void addX(int value){ pos.x += value; }

void addY(int value){ pos.y += value; }

/** returns a the Entity's position */

Vector2 getPosition(){return pos;}

/** re-initialize */

void init(int x, int y, char icon);

/**

* @param MOVE_UP, MOVE_LEFT, MOVE_DOWN, or MOVE_RIGHT

* @return true if the parameter was a valid move

*/

bool move(int direction);

/** implement actual changes to the Entity's state, including movement */

void update();

/** access what the Entity looks like */

char getIcon(){return icon;}

};

vector2.h

#pragma once

/**

* Object Oriented implementation of a 2 dimensional (math) vector, using short precision

*/

struct Vector2

{

/** the x, y coordinates */

short x, y;

/** initializes the Vector2 */

Vector2(short x, short y)

{

this->x = x;

this->y = y;

}

/** default constructor - sets x,y to 0,0 */

Vector2()

{

x = 0;

y = 0;

}

/** @return true if the given x, y coordinate mathes this Vector2's data */

bool is(short x, short y);

/** @return true if the given x, y coordinate mathes this Vector2's data */

bool is(Vector2 xy);

/** @return true if the Vector2 is within the given rectangular boundary */

bool isWithin(short minx, short miny, short maxx, short maxy);

/** re-initialize */

void init(short x, short y);

/** @return a random Vector2 within the specified boundary */

static Vector2 random(Vector2 min, Vector2 max);

Vector2& operator+=(Vector2& v);

Vector2 operator+(Vector2& v);

Vector2& operator*=(short value);

Vector2 operator*(short value);

// TODO implement these...

Vector2& operator-=(Vector2& v);

Vector2 operator-(Vector2& v);

Vector2& operator/=(short value);

Vector2 operator/(short value);

};

game.h

#pragma once

#include "entity.h"

#include "vector2.h"

class Game

{

private:

static const int LIST_SIZE = 6;

Entity* list[LIST_SIZE];

/** labels for which Entity in 'list' is what*/

static const int

PLAYER1 = 0,

PLAYER2 = 1,

GOAL1 = 2,

GOAL2 = 3;

WANDERER = 4;

WANDERER = 5;

/** width/height of the map */

Vector2 size;

int userInput;

int state;

public:

void setInput(int input){ userInput = input; }

int getState() { return state; }

/** game state constants */

static const int

RUNNING = 1,

WIN = 2,

LOST = 3,

DEFEAT = 4,

USER_QUIT = -1;

Game();

void draw();

void update();

~Game();

};

vector2.cpp

#include "vector2.h"

/** @return true if the given x, y coordinate matches this Vector2's data */

bool Vector2::is(short x, short y)

{

return this->x == x && this->y == y;

}

/** @return true if the given x, y coordinate matches this Vector2's data */

bool Vector2::is(Vector2 xy)

{

return xy.x == x && xy.y == y;

}

/** @return true if the Vector2 is within the given rectangular boundary */

bool Vector2::isWithin(short minx, short miny, short maxx, short maxy)

{

return x >= minx && y >= miny && x < maxx && y < maxy;

}

/** re-initialize */

void Vector2::init(short a_x, short a_y)

{

x = a_x;

y = a_y;

}

Vector2& Vector2::operator+=(Vector2& v)

{

x += v.x;

y += v.y;

return *this;

}

Vector2 Vector2::operator+(Vector2& v)

{

return Vector2(x+v.x, y+v.y);

}

Vector2& Vector2::operator*=(short value)

{

x *= value;

y *= value;

return *this;

}

Vector2 Vector2::operator*(short value)

{

return Vector2(x*value, y*value);

}

#include "stdlib.h"

/** @return a random Vector2 within the specified boundary */

Vector2 Vector2::random(Vector2 min, Vector2 max)

{

return Vector2(

(rand() % (max.x-min.x)) + min.x,

(rand() % (max.y-min.y)) + min.y);

}

blinkentity.cpp

#include "blinkentity.h"

BlinkEntity::BlinkEntity() { }

BlinkEntity::~BlinkEntity() { }

blinkentity.h

#pragma once

#include "entity.h"

class BlinkEntity : public Entity

{

public:

short x, y;

char alternateIcon;

BlinkEntity(short x, short y, char alternateIcon):x(x),y(y),alternateIcon(alternateIcon){}

BlinkEntity() :x(0), y(0){}

};

wanderingentity.cpp

#include "wanderingentity.h"

WanderingEntity::WanderingEntity() {

}

WanderingEntity::~WanderingEntity() { }

wanderingentity.h

#pragma once

#include "entity.h"

class WanderingEntity : public Entity{

public:

WanderingEntity::update() {

}

};

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

More Books

Students also viewed these Databases questions

Question

What is the formula to calculate the mth Fibonacci number?

Answered: 1 week ago