[SOLVED] CENG242-Assignment 4

24.99 $

Programming resource
Digital learning resource
Category:
Practical programming resource
Suitable for guided study and reference
Tutor guidance available when needed

Description

Rate this product

In this homework you will get familiar with Inheritance, Polymorphism and Abstract class concepts in Object Oriented programming.

Keywords: OOP, Inheritance, Abstract class, Polymorphism

1           Problem Definition

In this homework, you are going to simulate a treasure hunt game. In this game, there are players (abstract class) with different classes (implementations) divided in two teams. The hunt commences on a square grid of size N which is the Board class. The top left square of the grid has the coordinate (0,0) while the bottom right square has coordinates(N-1,N-1). X axis is the horizontal axis and Y axis is the vertical axis. One of the squares contains the treasure, some of them contains the characters and other squares are empty. The classes you are going to define are Player (and its implementations), Board, Game and Input Parser. They are explained below.

2           Class Definitions

2.1         Player

Player is an abstract class. There are 5 types of players, namely, Fighter, Archer, Tank, Priest and Scout. Each player can be in the barbarian team or the knight team. Each type of player has different HP, attack damage, heal power and goal priority (will be explained later in the game class). The class and method definitions of Player is written below. After that there are subsections that explains the sub-classes of Player.

class Player{ protected :

const uint id;

Coordinate coordinate; int HP;

Team team;

//DO NOT MODIFY THE UPPER PART

//ADD YOU OWN PROVATE METHODS/PROPERTIES BELOW

public :

/∗∗

∗ Main constructor

∗ @param id      id    of       the player .

∗ @param x x−coordinate         of       the player

∗ @param y y−coordinate         of       the player

∗ @param team team of               the player , BARBARIAN or KNIGHT

∗/

Player(uint id, int x, int y, Team team) ; virtual ˜Player() = default ;

uint getID() const ; const Coordinate& getCoord() const ; int getHP() const ;

Team getTeam()       const ;

/∗∗

∗ @return the board ID of the player , If the ID is single digit add a prefix ∗ 0 , otherwise just turn it into a string .

∗ Example :

∗ 3 −> ”03” ∗ 12 −> ”12”

∗/ std : : string getBoardID() ; virtual int getAttackDamage() const = 0; virtual int getHealPower() const = 0; virtual int getMaxHP() const = 0;

/∗∗

∗ For each    subclass of            Player   there      are         different              priority l i s t s      defined ∗ that      controls the next action   to take   for          that Player .         It        is            given     in the ∗ header of              the         subclasses .

∗ @return the goal            priority       l i s t     for       the Player

∗/ virtual std : : vector<Goal> getGoalPriorityList() ;

/∗∗

∗ @return the class abbreviation of player , i f the player is on the barbarian ∗ team , the abbreviation will consist of uppercase characters , otherwise it ∗ will consist of lowercase characters .

∗/

virtual                    const std : : string getClassAbbreviation()                   const ;

/∗∗

∗ Attack the given           player .

∗ Enemy HP should   decrease as much as the attack damage of attacker .             Print ∗ the boardID of    the         attacker and the attack and the amount of damage as below←

.

∗ ”Player 01 attacked Player 05 (75)”

∗ @param enemy player         that     is      attacked .

∗ @return true              i f            the opponent is     dead          false i f      alive .
∗/

bool attack(Player ∗enemy) ;

/∗∗

 
∗ Heal the given                         player by the adding amount of        heal power of        this         character
∗ to the HP of ally . Print ∗ below . the boardID of          the healer and healed players       as
∗ ”Player 01 healed Player 05”        
∗ Healed player                       should not

∗/ void heal(Player ∗ally) ; /∗∗

have more HP than its max HP.    
∗ @Important The coordinates may not be on the board .

∗ @return the   coordinates         that the unit        is            able to attack      given ∗ of             the unit . Empty vector    i f            the unit cannot attack .

∗/

virtual std : : vector<Coordinate> getAttackableCoordinates() ;

the position

/∗∗ ∗ @Important The coordinates may not be on the board .

∗ @return the coordinates the unit is able to move given the position of the ∗ unit . Empty vector i f the unit cannot move.

∗/ virtual std : : vector<Coordinate> getMoveableCoordinates() ; /∗∗ ∗

∗ @return the coordinates the unit is able to heal a l l i e s given the position ←of the ∗ unit . Empty vector i f none available .

∗/ virtual std : : vector<Coordinate> getHealableCoordinates() ;

/∗∗

∗ Move player to coordinate . Print the boardID of the player and the old and ←new

∗ coordinates         as below :

∗ ”Player 01 moved from (0/1) to (0/2)”

∗ @Important before           calling              this method you must verify             that      this                     coordinate

∗ is       valid      to move

∗/ void movePlayerToCoordinate(Coordinate c) ;

/∗∗ ∗ Decide whether the player             is            dead .

∗ @return true        i f          the player ‘ s HP <= 0 ,           false       otherwise .

∗/ bool isDead()     const ;

};

3.1.1 Archer class Archer : public Player{

/∗∗

∗ Attack damage 50

∗ Heal power 0

∗ Max HP 200

∗ Goal Priorities −> {ATTACK} ∗ Class abbreviation −> ”ar” or ”AR” ∗ Not able to move at all .

∗ Can attack to a range of 2 squares directly up , down, l e f t or right , from ∗ its coordinate .

∗ ∗/

};

3.1.2 Fighter class Fighter : public Player{

/∗∗

∗ Attack damage 100

∗ Heal power 0

∗ Max HP 400

∗ Goal               Priorities −> {ATTACK,TOENEMY,CHEST} in                decreasing       order

∗ Class                abbreviation −> ” f i ” or ”FI”

∗ Can move to adjacent up , down, l e f t or right square ∗ Can attack to adjacent up , down, l e f t or right square

∗ ∗/

};

3.1.3 Priest class Priest : public Player{

/∗∗

∗ Attack damage 0

∗ Heal power 50

∗ Max HP 150

∗ Goal                Priorities −> {HEAL,TO ALLY,CHEST} in                decreasing       order

∗ Class               abbreviation −> ”pr” or ”PR”

∗ Can move to            all           adjacent squares ,        including             diagonals . ∗ Can heal       all        adjacent squares ,             including             diagonals .

∗ ∗/

};

3.1.4 Scout class Scout : public Player{

/∗∗

∗ Attack damage 25

∗ Heal power 0

∗ Max HP 125

∗ Goal                Priorities −> {CHEST,TO ALLY,ATTACK} in                decreasing       order

∗ Class                abbreviation −> ”sc” or ”SC”

∗ Can move to            all           adjacent squares ,        including             diagonals . ∗ Can attack   all        adjacent squares ,             including             diagonals .

∗ ∗/

};

3.1.5 Tank class Tank : public Player{

/∗∗

∗ Attack damage 25

∗ Heal power 0

∗ Max HP 1000

∗ Goal               Priorities −> {TOENEMY,ATTACK,CHEST} in                decreasing       order

∗ Class                abbreviation −> ”ta” or ”TA”

∗ Can move to adjacent up , down, l e f t or right square ∗ Can attack to adjacent up , down, l e f t or right square

∗ ∗/

};

2.2         Board

Board holds size of the board, players and position of the chest. Its methods are concerned with printing the contents of the field and returning the properties of coordinates. The class header is given below.

class Board{

private : uint size;

std : : vector<Player∗>∗ players; Coordinate chest;

//DO NOT MODIFY THE UPPER PART

//ADD YOU OWN PROVATE METHODS/PROPERTIES BELOW

public :

Board(uint _size, std : : vector<Player∗>∗ _players, Coordinate chest) ;

˜Board() ; /∗∗ ∗ @return true i f the coordinate is in the board limits , false otherwise .

∗/ bool isCoordinateInBoard( const Coordinate& c) ; /∗∗ ∗ @return true i f there is a player on the given coordinate , false otherwise .

∗/ bool isPlayerOnCoordinate( const Coordinate& c) ;

/∗∗

∗ @return pointer to the player at the given coordinate . Return NULL i f no ∗ player is there .

∗/

Player ∗operator               [ ] ( const Coordinate& c) ;

/∗∗

∗ @return the chest           coordinate

∗/ Coordinate getChestCoordinates() ; /∗∗

∗ Print the board with character ID ‘ s .

∗ For each empty square                print two underscore            characters .

∗ For the squares with a player on it ,                   print         the board id       of         the player .

∗ For the square with the chest ,                print     the        string ”Ch”.

∗ If a character is on the square with the chest , only print the ID of the ∗ character .

∗ For each row print a new line ,                for            each column print a space character .

∗ void printBoardwithID() ; /∗∗

∗ For each empty square                print two underscore            characters .

∗ For the squares with a player on it , print the class abbreviation of the ∗ player .

∗ For the square with the chest ,                print     the        string ”Ch”.

∗ If a character           is on the square with the chest ,    only       print      the        abbreviation ∗ of               the         character .

∗ To separate each row print a new line , to separate each column print a ∗ space character . ∗ Example :

∗                  PR

∗ Ch

∗/ void printBoardwithClass() ;

};

2.3         Game

Game class is responsible for running the game and managing the memory. The most important method here is the playTurnForPlayer method which computes the moves for the players given their different goal priorities.

class Game{

private :

Board board; uint turnNumber; uint maxTurnNumber; std : : vector<Player∗> players;

//DO NOT MODIFY THE UPPER PART

//ADD YOU OWN PROVATE METHODS/PROPERTIES BELOW

public : /∗∗

∗ Costructor            for Game class .

∗ Game manages the memory allocated             for          future    contents the vector              (added ←players ) .

∗ Pass a pointer                   to the       players              vector to board constructor                so

will

∗ not miss the                  addition      of      players         to the game.

∗ @param maxTurnNumber turn number to end the game

∗ @param boardSize     size        of            the board ∗ @param chest  coordinate          of            the chest

∗/

Game(uint maxTurnNumber, uint boardSize, Coordinate chest) ;

that the board ←
˜Game() ;

/∗∗

 
∗ Add a new player to the game. Add a pointer to players vector . the new player to the this−>
∗ Do not            forget    that Game will manage the memory ∗ @param id ID of             the new player .

∗ @param x x coordinate                   of        the new player .

∗ @param y y coordinate            of            the new player . ∗ @param team team of   the new player .

∗/

void addPlayer( int id,                       int x,                       int y, Team team ) ;

/∗∗

∗ The game ends when either                     of       these happens :

∗ − All              barbarians      die     ( knight       victory )

∗ − All              knights     die      ( barbarian       victory )

allocated              for the players .
∗ − A barbarian                gets        to the square          containing        the chest ( barbarian victory )
∗ − maxTurnNumber of                    turns played ( knight           victory )

∗ If       the game ends announce it py printing      the reason , victor ∗ as in the       following             examples :

turn number and the ←
∗ Game ended at turn 13.                      All        barbarians dead .            Knight victory .

∗ Game ended at turn 121.                      All        knights dead .         Barbarian       victory .

∗ Game ended at turn 52. Chest captured . Barbarian victory . ∗ Game ended at turn 215. Maximum turn number reached . Knight victory .

∗ @return true              i f     any of       the above      is        satisfied ,         false       otherwise

∗/ bool isGameEnded() ;

/∗∗

∗ Play a turn         for       each player .

∗ Actions are taken in the order of ID numbers of players ( player with ∗ smaller ID acts f i r s t ) .

∗ At the         start       of            the turn it            announces that the turn has started by printing ∗ to stdout . Turn numbers starts         with 1.

∗ Ex: ”Turn 13 has started .” ∗ Call playTurnForPlayer for every player .

∗/ void playTurn() ; /∗∗

∗ Play a turn         for              the player with the given ID.

∗ If the player is dead announce its death by printing the boardID of the ←player

∗ as in ”Player 07 died .”. Remove that player from the board and release its ←resources . ∗

∗ Each player has a goal            l i s t        sorted by its           priority       for     that  player .

∗ When a player plays a turn it iterates over its goal l i s t and tries to take ∗ an action . Valid actions are attack , move and heal . A player can take only

∗ one action in a turn , and     i f            there      is no action         it            can take it              stops and ←does nothing .

∗ Before moving a player you must check          i f            the         coordinate          to move is     valid . ∗ Meaning that ,     the         coordinate          is            in the bounds of the board and there         are no ∗ players  there .

∗ IMPORTANT NOTE: every usage of the word nearest is referencing smallest the ←Manhattan

∗ distance ,       which    is                 formulated as (abs(x 1−x 2 ) + abs(y 1−y 2 ) ) .            operator−

∗ overloaded                  in Coordinate .h computes exactly that ,                  so you can use that method←

to

∗ calculate        the             distance between two coordinates .

∗ Below are the           explanations       for     goals :

∗ ∗ ATTACK:

∗      − If         there      are any enemies in the attack range of        the player            attack to        it . ∗        If            there      are more than 1 enemy in the range attack to the one with ∗        lowest ID.            If            there      is no one to attack            try the next goal .

∗ ∗ CHEST:

∗ − Move to the direction of the chest , i f both vertical and horizontal ←moves

∗       are        available ,            pick the horizontal one .  If            the         horizontal move is ←blocked

∗      but the  vertical move is  not , move vertically .       If            all           directions        towards ∗            the chest              is            blocked try the next goal .

∗ TOENEMY:

∗       − Move towards the         nearest enemy.   If            there      are more than one enemies with ←the same distance

∗       move towards the one with the    smallest ID.         If            both       vertical and ←horizontal moves

∗              are       available ,         pick the          horizontal one .            If an enemy is              in the squares
∗                                         that the player can move or every move that brings            the player        closer        to
∗              the         selected enemy is          blocked ,              try the next

∗ TO ALLY:

goal .
∗ − Move towards the nearest ally . If there are the same distance more than one            a l l i e s      with ←
∗       move towards the one with the           smallest ID. horizontal moves If        both         vertical and ←
∗              are       available ,         pick the          horizontal one .            If an ally         is         in the squares
∗                                         that the player can move or every move that brings            the player        closer        to
∗              the      selected       ally     is      blocked ,                try the next

∗ HEAL:

goal .
∗             − If         there      are any  a l l i e s in the     healing  range heal           all           of them .               i f               there ∗   is no one to heal try the next goal .

∗ @return the goal that the action was taken upon . NO GOAL i f no action was ←taken .

∗/

Goal playTurnForPlayer(Player∗ player) ;

};

2.4         InputParser

Reads the standard input and creates a Game object. Details are explained in the header.

class InputParser{ public :

/∗∗

∗ Parse the           i n i t i a l     parameters      of         the game from stdin .  
∗ The input           will      be as       follows .

∗ First          line       contains      the     size     of      the board .

∗ Second        line       contains      the       coordinates       of             the chest .

 
∗ Third         line       contains        the number of          players , P.  
∗ Each of               the next P lines                        contains a description for a player as                     follows .  
∗ ID of the player , class of the player , team of coordinate , . the player , x coordinate , y ←
∗ Call the addPlayer method of the Game class to ∗ Example input :

∗ 6

∗ 3 3

∗ 2

∗ 12 ARCHER BARBARIAN 3 5 ∗ 11 FIGHTER KNIGHT 1 1

add the      players .  
∗ @returns Pointer to the Dynamically                                 allocated Game object

∗/ static Game∗ parseGame() ;

};

3           Extras

The enumerations you need are defined in the Constants.h header. You can use them from there.

The Game class owns every player and vector of players in terms of memory management and is responsible for the destruction of these.

In order to get full grade from each part your code should not have any memory leak. This will be checked with valgrind. While grading your classes will be used with the correct implementations, therefore they are expected to work as commented in the code.

Resource details

Understand the Task Before You Use the Resource

Review the requirements, identify the programming concepts involved, study the implementation and test your understanding with your own examples and modifications.