--- /dev/null
+#include "ClapTrap.h"
+#include <string>
+#include <iostream>
+
+ClapTrap::ClapTrap(std::string name, int hp, int energy, int attack)
+ : m_name(name)
+ , m_hp(hp)
+ , m_energy(energy)
+ , m_attack(attack)
+{
+ std::cout << "ClapTrap " << m_name << " has spawned.\n";
+}
+
+ClapTrap::ClapTrap(std::string name)
+ : m_name(name)
+ , m_hp(start_hp)
+ , m_energy(start_energy)
+ , m_attack(start_attack)
+{
+ std::cout << "ClapTrap " << m_name << " has spawned.\n";
+}
+
+ClapTrap::~ClapTrap()
+{
+ std::cout << "ClapTrap " << m_name << " has despawned.\n";
+}
+
+void ClapTrap::attack(const std::string &target)
+{
+ if (m_hp == 0)
+ std::cout << "ClapTrap " << m_name
+ << " is dead, hence cannot attack.\n";
+ else if (m_energy == 0)
+ std::cout << "ClapTrap " << m_name
+ << " does not have enough energy to attack.\n";
+ else
+ {
+ std::cout << "ClapTrap " << m_name
+ << " attacks " << target << " and deals " << m_attack << " damage.\n";
+ --m_energy;
+ }
+}
+
+void ClapTrap::takeDamage(unsigned int amount)
+{
+ if (m_hp == 0)
+ std::cout << m_name <<
+ " is already dead and cannot be damaged further.\n";
+ else if (amount >= m_hp)
+ {
+ std::cout << m_name
+ << " takes " << amount << " damage and dies\n";
+ m_hp = 0;
+ }
+ else
+ {
+ std::cout << m_name
+ << " takes " << amount << " damage.\n";
+ m_hp -= amount;
+ }
+}
+
+void ClapTrap::beRepaired(unsigned int amount)
+{
+ if (m_hp == 0)
+ std::cout << m_name
+ << " is dead, hence cannot repair itself.\n";
+ else if (m_energy == 0)
+ std::cout << m_name
+ << " does not have enough energy to repair itself.\n";
+ else
+ {
+ std::cout << m_name
+ << " repairs iself for " << amount << " hit points.\n";
+ m_hp += amount;
+ }
+}
--- /dev/null
+#ifndef CLAPTRAP_H
+# define CLAPTRAP_H
+
+# include <string>
+
+class ClapTrap
+{
+ protected:
+ std::string m_name;
+ unsigned int m_hp;
+ unsigned int m_energy;
+ unsigned int m_attack;
+
+ static const int start_hp = 10;
+ static const int start_energy = 10;
+ static const int start_attack = 0;
+
+ ClapTrap(std::string name, int hp, int energy, int attack);
+
+ private:
+ ClapTrap();
+ ClapTrap(const ClapTrap &other);
+
+ ClapTrap &operator=(const ClapTrap &other);
+
+ public:
+ ClapTrap(std::string name);
+ ~ClapTrap();
+
+ void attack(const std::string &target);
+ void takeDamage(unsigned int amount);
+ void beRepaired(unsigned int amount);
+};
+
+#endif // CLAPTRAP_H
--- /dev/null
+#include "DiamondTrap.h"
+#include <string>
+#include <iostream>
+
+DiamondTrap::DiamondTrap(std::string name)
+ : ClapTrap(name + "_clap_name", FragTrap::start_hp, ScavTrap::start_energy,
+ FragTrap::start_attack)
+ , FragTrap(name)
+ , ScavTrap(name)
+ , m_name(name)
+{
+ std::cout << "DiamondTrap " << m_name << " has spawned.\n";
+}
+
+DiamondTrap::~DiamondTrap()
+{
+ std::cout << "DiamondTrap " << m_name << " has despawned.\n";
+}
+
+void DiamondTrap::whoAmI()
+{
+ std::cout << "My DiamondTrap name is " << m_name
+ << " while my ClapTrap name is " << ClapTrap::m_name << ".\n";
+}
--- /dev/null
+#ifndef DIAMONDTRAP_H
+# define DIAMONDTRAP_H
+
+# include "FragTrap.h"
+# include "ScavTrap.h"
+# include <string>
+
+class DiamondTrap: public FragTrap, public ScavTrap
+{
+ private:
+ std::string m_name;
+
+ DiamondTrap();
+ DiamondTrap(const DiamondTrap &other);
+
+ DiamondTrap &operator=(const DiamondTrap &other);
+
+ public:
+ DiamondTrap(std::string name);
+ ~DiamondTrap();
+
+ using ScavTrap::attack;
+ void whoAmI();
+};
+
+#endif // DIAMONDTRAP_H
--- /dev/null
+#include "FragTrap.h"
+#include "ClapTrap.h"
+#include <string>
+#include <iostream>
+
+FragTrap::FragTrap(std::string name)
+ : ClapTrap(name, start_hp, start_energy, start_attack)
+{
+ std::cout << "FragTrap " << m_name << " has spawned.\n";
+}
+
+FragTrap::~FragTrap()
+{
+ std::cout << "FragTrap " << m_name << " has despawned.\n";
+}
+
+void FragTrap::attack(const std::string &target)
+{
+ if (m_hp == 0)
+ std::cout << "FragTrap " << m_name
+ << " is dead, hence cannot attack.\n";
+ else if (m_energy == 0)
+ std::cout << "FragTrap " << m_name
+ << " does not have enough energy to attack.\n";
+ else
+ {
+ std::cout << "FragTrap " << m_name
+ << " attacks " << target << " and deals " << m_attack << " damage.\n";
+ --m_energy;
+ }
+}
+
+void FragTrap::highFivesGuys()
+{
+ if (m_hp == 0)
+ std::cout << m_name << " is dead and cannot request high fives.\n";
+ else
+ std::cout << m_name << " raises hand and shouts, \"Up top!\"\n";
+}
--- /dev/null
+#ifndef FRAGTRAP_H
+# define FRAGTRAP_H
+
+# include "ClapTrap.h"
+# include <string>
+
+class FragTrap : virtual public ClapTrap
+{
+ private:
+ FragTrap();
+ FragTrap(const FragTrap &other);
+
+ FragTrap &operator=(const FragTrap &other);
+
+ protected:
+ static const int start_hp = 100;
+ static const int start_energy = 100;
+ static const int start_attack = 30;
+
+ public:
+ FragTrap(std::string name);
+ ~FragTrap();
+
+
+ void attack(const std::string &target);
+ void highFivesGuys();
+};
+
+#endif // FRAGTRAP_H
--- /dev/null
+CC := c++
+CFLAGS = -std=c++98 -Wall -Wextra -Werror -Wpedantic
+
+ifneq ("$(wildcard .debug)","")
+ CFLAGS += -g
+endif
+
+RM := rm -f
+
+INCDIR := inc
+INCDIR += $(addsuffix /inc, $(SUBPROJECTS));
+ifneq ($(INCLUDE),)
+ INCLUDE := $(addprefix -I, $(INCDIR))
+endif
+
+SRCDIR := .
+
+SOURCES := main.cpp \
+ ClapTrap.cpp \
+ ScavTrap.cpp \
+ FragTrap.cpp \
+ DiamondTrap.cpp \
+
+SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
+
+OBJECTS := $(SOURCES:.cpp=.o)
+
+NAME := diamondtrap
+
+all : $(NAME)
+
+debug : .debug
+ $(MAKE) all
+
+nodebug :
+ $(RM) .debug
+ $(MAKE) re
+
+.% :
+ $(MAKE) fclean
+ touch $@
+
+$(NAME) : $(OBJECTS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LINKS)
+
+%.o : %.cpp
+ $(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)
+
+clean :
+ $(RM) $(OBJECTS)
+
+fclean : clean
+ $(RM) $(NAME)
+
+re : fclean
+ $(MAKE) all
--- /dev/null
+#include "ScavTrap.h"
+#include "ClapTrap.h"
+#include <string>
+#include <iostream>
+
+ScavTrap::ScavTrap(std::string name)
+ : ClapTrap(name, start_hp, start_energy, start_attack)
+ , m_is_guarding(0)
+{
+ std::cout << "ScavTrap " << m_name << " has spawned.\n";
+}
+
+ScavTrap::~ScavTrap()
+{
+ std::cout << "ScavTrap " << m_name << " has despawned.\n";
+}
+
+void ScavTrap::attack(const std::string &target)
+{
+ if (m_hp == 0)
+ std::cout << "ScavTrap " << m_name
+ << " is dead, hence cannot attack.\n";
+ else if (m_energy == 0)
+ std::cout << "ScavTrap " << m_name
+ << " does not have enough energy to attack.\n";
+ else
+ {
+ std::cout << "ScavTrap " << m_name
+ << " attacks " << target << " and deals " << m_attack << " damage.\n";
+ --m_energy;
+ }
+}
+
+void ScavTrap::guardGate()
+{
+ if (m_hp == 0)
+ std::cout << m_name << " is dead and cannot guard the gate.\n";
+ else if (m_is_guarding == 0)
+ {
+ std::cout << m_name << " is now guarding the gate.\n";
+ m_is_guarding = 1;
+ }
+ else
+ std::cout << m_name << " is already guarding the gate.\n";
+}
--- /dev/null
+#ifndef SCAVTRAP_H
+# define SCAVTRAP_H
+
+# include "ClapTrap.h"
+# include <string>
+
+class ScavTrap : virtual public ClapTrap
+{
+ private:
+ bool m_is_guarding;
+
+ ScavTrap();
+ ScavTrap(const ScavTrap &other);
+
+ ScavTrap &operator=(const ScavTrap &other);
+
+ protected:
+ static const int start_hp = 100;
+ static const int start_energy = 50;
+ static const int start_attack = 20;
+
+ public:
+ ScavTrap(std::string name);
+ ~ScavTrap();
+
+ void attack(const std::string &target);
+ void guardGate();
+};
+
+#endif // SCAVTRAP_H
--- /dev/null
+#include "ClapTrap.h"
+#include "ScavTrap.h"
+#include "FragTrap.h"
+#include "DiamondTrap.h"
+
+int main()
+{
+ ClapTrap a("Alen");
+ ScavTrap b("Boris");
+ FragTrap c("Charles");
+ DiamondTrap d("David");
+
+ for (int i = 0; i < 50; ++i)
+ d.attack("test");
+ d.attack("CantTouchThis");
+ d.takeDamage(99);
+ d.highFivesGuys();
+ d.guardGate();
+ d.highFivesGuys();
+ d.guardGate();
+ d.whoAmI();
+ d.takeDamage(1);
+ d.highFivesGuys();
+ d.guardGate();
+ return (0);
+}