one implementation of the exam

This commit is contained in:
hugogogo
2022-12-01 15:47:19 +01:00
parent 16dcd06da6
commit c91d23a5d4
43 changed files with 925 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
#include "Warlock.hpp"

35
cpp_module_00/Warlock.hpp Normal file
View File

@@ -0,0 +1,35 @@
#ifndef WARLOCK_HPP
# define WARLOCK_HPP
# include <iostream>
# include <string>
class Warlock {
private:
Warlock();
Warlock(Warlock const & other);
Warlock & operator=(Warlock const & other);
std::string name;
std::string title;
public:
Warlock(std::string const & name, std::string const & title) {
this->name = name;
this->title = title;
std::cout << this->name << ": This looks like another boring day.\n";
};
~Warlock() {
std::cout << this->name << ": My job here is done!\n";
};
std::string const & getName() const {return (this->name);};
std::string const & getTitle() const {return (this->title);};
void setTitle(std::string const & title) {this->title = title;};
void introduce() const {
std::cout << this->name << ": I am " << this->name << ", " << this->title << "!\n";
};
};
#endif

BIN
cpp_module_00/a.out Executable file

Binary file not shown.

17
cpp_module_00/main.cpp Normal file
View File

@@ -0,0 +1,17 @@
# include "Warlock.hpp"
int main()
{
Warlock const richard("Richard", "Mistress of Magma");
richard.introduce();
std::cout << richard.getName() << " - " << richard.getTitle() << std::endl;
Warlock* jack = new Warlock("Jack", "the Long");
jack->introduce();
jack->setTitle("the Mighty");
jack->introduce();
delete jack;
return (0);
}

View File

@@ -0,0 +1,81 @@
Assignment name : cpp_module_00
Expected files : Warlock.cpp Warlock.hpp
--------------------------------------------------------------------------------
Make a Warlock class. It has to be in Coplien's form.
It has the following private attributes :
* name (string)
* title (string)
Since they're private, you will write the following getters :
* getName, returns a reference to constant string
* getTitle, returns a reference to constant string
Both these functions will have to be callable on a constant Warlock.
Create the following setter:
* setTitle, returns void and takes a reference to constant string
Your Warlock will also have, in addition to whatever's required by Coplien's
form, a constructor that takes, in this order, its name and title. Your Warlock
will not be able to be copied, instantiated by copy, or instantiated without a
name and a title.
For example :
Warlock bob; //Does not compile
Warlock bob("Bob", "the magnificent"); //Compiles
Warlock jim("Jim", "the nauseating"); //Compiles
bob = jim; //Does not compile
Warlock jack(jim); //Does not compile
Upon creation, the Warlock says :
<NAME>: This looks like another boring day.
Of course, whenever we use placeholders like <NAME>, <TITLE>, etc...
in outputs, you will replace them by the appropriate value. Without the < and >.
When he dies, he says:
<NAME>: My job here is done!
Our Warlock must also be able to introduce himself, while boasting with all its
might.
So you will write the following function:
* void introduce() const;
It must display:
<NAME>: I am <NAME>, <TITLE>!
Here's an example of a test main function and its associated output:
int main()
{
Warlock const richard("Richard", "Mistress of Magma");
richard.introduce();
std::cout << richard.getName() << " - " << richard.getTitle() << std::endl;
Warlock* jack = new Warlock("Jack", "the Long");
jack->introduce();
jack->setTitle("the Mighty");
jack->introduce();
delete jack;
return (0);
}
~$ ./a.out | cat -e
Richard: This looks like another boring day.$
Richard: I am Richard, Mistress of Magma!$
Richard - Mistress of Magma$
Jack: This looks like another boring day.$
Jack: I am Jack, the Long!$
Jack: I am Jack, the Mighty!$
Jack: My job here is done!$
Richard: My job here is done!$
~$

BIN
cpp_module_00/test Executable file

Binary file not shown.

5
cpp_module_01/ASpell.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include "ASpell.hpp"
void ASpell::launch(ATarget const & atarget) const {
atarget.getHitBySpell(*this);
};

45
cpp_module_01/ASpell.hpp Normal file
View File

@@ -0,0 +1,45 @@
#ifndef ASPELL_HPP
# define ASPELL_HPP
# include <iostream>
# include <string>
class ATarget;
class ASpell {
private:
std::string name;
std::string effects;
public:
ASpell() {
};
ASpell(ASpell const & other) {
*this = other;
};
ASpell & operator=(ASpell const & other) {
this->name = other.name;
this->effects = other.effects;
return (*this);
};
ASpell(std::string const & name, std::string const & effects) {
this->name = name;
this->effects = effects;
};
virtual ~ASpell() {
};
std::string const & getName() const {
return (this->name);
};
std::string const & getEffects() const {
return (this->effects);
};
void launch(ATarget const & atarget) const;
virtual ASpell * clone() const = 0;
};
#include "ATarget.hpp"
#endif

View File

@@ -0,0 +1,5 @@
#include "ATarget.hpp"
void ATarget::getHitBySpell(ASpell const & aspell) const {
std::cout << this->type << " has been " << aspell.getEffects() << "!\n";
};

38
cpp_module_01/ATarget.hpp Normal file
View File

@@ -0,0 +1,38 @@
#ifndef ATARGET_HPP
# define ATARGET_HPP
# include <iostream>
# include <string>
class ASpell;
class ATarget {
private:
std::string type;
public:
ATarget() {
};
ATarget(ATarget const & other) {
*this = other;
};
ATarget & operator=(ATarget const & other) {
this->type = other.type;
return (*this);
};
ATarget(std::string const & type) {
this->type = type;
};
~ATarget() {};
std::string const & getType() const {return (this->type);};
void getHitBySpell(ASpell const & aspell) const;
virtual ATarget * clone() const = 0;
};
#include "ASpell.hpp"
#endif

2
cpp_module_01/Dummy.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "Dummy.hpp"

16
cpp_module_01/Dummy.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef DUMMY_HPP
# define DUMMY_HPP
# include "ATarget.hpp"
class Dummy: public ATarget {
public:
Dummy(): ATarget("Target Practice Dummy") {};
~Dummy() {};
virtual ATarget * clone() const {
return (new Dummy());
};
};
#endif

2
cpp_module_01/Fwoosh.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "Fwoosh.hpp"

16
cpp_module_01/Fwoosh.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef FWOOSH_HPP
#define FWOOSH_HPP
# include "ASpell.hpp"
class Fwoosh: public ASpell {
public:
Fwoosh(): ASpell("Fwoosh", "fwooshed") {};
~Fwoosh() {};
virtual ASpell * clone() const {
return (new Fwoosh());
};
};
#endif

View File

@@ -0,0 +1,2 @@
#include "Warlock.hpp"

67
cpp_module_01/Warlock.hpp Normal file
View File

@@ -0,0 +1,67 @@
#ifndef WARLOCK_HPP
# define WARLOCK_HPP
# include <iostream>
# include <string>
# include "ASpell.hpp"
# include "ATarget.hpp"
# include <map>
class Warlock {
private:
Warlock();
Warlock(Warlock const & other);
Warlock & operator=(Warlock const & other);
std::string name;
std::string title;
std::map<std::string, ASpell *> arr;
public:
Warlock(std::string const & name, std::string const & title) {
this->name = name;
this->title = title;
std::cout << this->name << ": This looks like another boring day.\n";
};
~Warlock() {
std::cout << this->name << ": My job here is done!\n";
std::map<std::string, ASpell *>::iterator it_begin = this->arr.begin();
std::map<std::string, ASpell *>::iterator it_end = this->arr.end();
while (it_begin != it_end) {
delete it_begin->second;
++it_begin;
}
this->arr.clear();
};
std::string const & getName() const {return (this->name);};
std::string const & getTitle() const {return (this->title);};
void setTitle(std::string const & title) {this->title = title;};
void introduce() const {
std::cout << this->name << ": I am " << this->name << ", " << this->title << "!\n";
};
void learnSpell(ASpell * aspell) {
if (aspell)
arr.insert(std::pair<std::string, ASpell *>(
aspell->getName(),
aspell->clone()
));
};
void forgetSpell(std::string name) {
std::map<std::string, ASpell *>::iterator it = arr.find(name);
if (it == arr.end())
return;
delete it->second;
arr.erase(name);
};
void launchSpell(std::string name, ATarget const & target) {
ASpell * spell = arr[name];
if (spell)
spell->launch(target);
};
};
#endif

BIN
cpp_module_01/a.out Executable file

Binary file not shown.

20
cpp_module_01/main.cpp Normal file
View File

@@ -0,0 +1,20 @@
#include "Warlock.hpp"
#include "Fwoosh.hpp"
#include "Dummy.hpp"
int main()
{
Warlock richard("Richard", "the Titled");
Dummy bob;
Fwoosh* fwoosh = new Fwoosh();
richard.learnSpell(fwoosh);
richard.introduce();
richard.launchSpell("Fwoosh", bob);
richard.forgetSpell("Fwoosh");
richard.launchSpell("Fwoosh", bob);
delete fwoosh;
}

View File

@@ -0,0 +1,94 @@
Assignment name : cpp01_02
Expected files : Warlock.cpp Warlock.hpp
ASpell.hpp ASpell.cpp
ATarget.hpp ATarget.cpp
Fwoosh.hpp Fwoosh.cpp
Dummy.hpp Dummy.cpp
--------------------------------------------------------------------------------
In the Warlock class, the switch statement is FORBIDDEN and its use would
result in a -42.
Create an abstract class called ASpell, in Coplien's form, that has the
following protected attributes:
* name (string)
* effects (string)
Both will have getters (getName and getEffects) that return strings.
Also add a clone pure method that returns a pointer to ASpell.
All these functions can be called on a constant object.
ASpell has a constructor that takes its name and its effects, in that order.
Now you will create an ATarget abstract class, in Coplien's form. It has a type
attribute, which is a string, and its associated getter, getType, that return a
reference to constant string.
In much the same way as ASpell, it has a clone() pure method.
All these functions can be called on a constant object.
It has a constructor that takes its type.
Now, add to your ATarget a getHitBySpell function that takes a reference to
constant ASpell.
It will display :
<TYPE> has been <EFFECTS>!
<TYPE> is the ATarget's type, and <EFFECTS> is the return of the ASpell's
getEffects function.
Finally, add to your ASpell class a launch function that takes a reference to
constant ATarget.
This one will simply call the getHitBySpell of the passed object, passing the
current instance as parameter.
When all this is done, create an implementation of ASpell called Fwoosh. Its
default constructor will set the name to "Fwoosh" and the effects to
"fwooshed". You will, of course, implement the clone() method. In the case of
Fwoosh, it will return a pointer to a new Fwoosh object.
In the same way, create a concrete ATarget called Dummy, the type of which
is "Target Practice Dummy". You must also implement its clone() method.
Add to the Warlock the following member functions:
* learnSpell, takes a pointer to ASpell, that makes the Warlock learn a spell
* forgetSpell, takes a string corresponding a to a spell's name, and makes the
Warlock forget it. If it's not a known spell, does nothing.
* launchSpell, takes a string (a spell name) and a reference to ATarget, that
launches the spell on the selected target. If it's not a known spell, does
nothing.
You will need a new attribute to store the spells your Warlock knows. Several
types fit the bill, it's up to you to choose the best one.
Below is a possible test main and its expected output:
int main()
{
Warlock richard("Richard", "the Titled");
Dummy bob;
Fwoosh* fwoosh = new Fwoosh();
richard.learnSpell(fwoosh);
richard.introduce();
richard.launchSpell("Fwoosh", bob);
richard.forgetSpell("Fwoosh");
richard.launchSpell("Fwoosh", bob);
}
~$ ./a.out | cat -e
Richard: This looks like another boring day.$
Richard: I am Richard, the Titled!$
Target Practice Dummy has been fwooshed!$
Richard: My job here is done!$

BIN
cpp_module_01/testt Executable file

Binary file not shown.

5
cpp_module_02/ASpell.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include "ASpell.hpp"
void ASpell::launch(ATarget const & atarget) const {
atarget.getHitBySpell(*this);
};

45
cpp_module_02/ASpell.hpp Normal file
View File

@@ -0,0 +1,45 @@
#ifndef ASPELL_HPP
# define ASPELL_HPP
# include <iostream>
# include <string>
class ATarget;
class ASpell {
private:
std::string name;
std::string effects;
public:
ASpell() {
};
ASpell(ASpell const & other) {
*this = other;
};
ASpell & operator=(ASpell const & other) {
this->name = other.name;
this->effects = other.effects;
return (*this);
};
ASpell(std::string const & name, std::string const & effects) {
this->name = name;
this->effects = effects;
};
virtual ~ASpell() {
};
std::string const & getName() const {
return (this->name);
};
std::string const & getEffects() const {
return (this->effects);
};
void launch(ATarget const & atarget) const;
virtual ASpell * clone() const = 0;
};
#include "ATarget.hpp"
#endif

View File

@@ -0,0 +1,5 @@
#include "ATarget.hpp"
void ATarget::getHitBySpell(ASpell const & aspell) const {
std::cout << this->type << " has been " << aspell.getEffects() << "!\n";
};

40
cpp_module_02/ATarget.hpp Normal file
View File

@@ -0,0 +1,40 @@
#ifndef ATARGET_HPP
# define ATARGET_HPP
# include <iostream>
# include <string>
class ASpell;
class ATarget {
private:
std::string type;
public:
ATarget() {
};
ATarget(std::string const & type) {
this->type = type;
};
ATarget(ATarget const & other) {
*this = other;
};
ATarget & operator=(ATarget const & other) {
this->type = other.type;
return (*this);
};
virtual ~ATarget() {};
std::string const & getType() const {
return (this->type);
};
void getHitBySpell(ASpell const & aspell) const;
virtual ATarget * clone() const = 0;
};
#include "ASpell.hpp"
#endif

View File

@@ -0,0 +1,2 @@
#include "BrickWall.hpp"

View File

@@ -0,0 +1,16 @@
#ifndef BRICKWALL_HPP
# define BRICKWALL_HPP
# include "ATarget.hpp"
class BrickWall: public ATarget {
public:
BrickWall(): ATarget("Inconspicuous Red-brick Wall") {};
~BrickWall() {};
virtual ATarget * clone() const {
return (new BrickWall());
};
};
#endif

2
cpp_module_02/Dummy.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "Dummy.hpp"

16
cpp_module_02/Dummy.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef DUMMY_HPP
# define DUMMY_HPP
# include "ATarget.hpp"
class Dummy: public ATarget {
public:
Dummy(): ATarget("Target Practice Dummy") {};
~Dummy() {};
virtual ATarget * clone() const {
return (new Dummy());
};
};
#endif

View File

@@ -0,0 +1,2 @@
#include "Fireball.hpp"

View File

@@ -0,0 +1,16 @@
#ifndef FIREBALL_HPP
#define FIREBALL_HPP
# include "ASpell.hpp"
class Fireball: public ASpell {
public:
Fireball(): ASpell("Fireball", "burnt to a crisp") {};
~Fireball() {};
virtual ASpell * clone() const {
return (new Fireball());
};
};
#endif

2
cpp_module_02/Fwoosh.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "Fwoosh.hpp"

16
cpp_module_02/Fwoosh.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef FWOOSH_HPP
#define FWOOSH_HPP
# include "ASpell.hpp"
class Fwoosh: public ASpell {
public:
Fwoosh(): ASpell("Fwoosh", "fwooshed") {};
~Fwoosh() {};
virtual ASpell * clone() const {
return (new Fwoosh());
};
};
#endif

View File

@@ -0,0 +1,2 @@
#include "Polymorph.hpp"

View File

@@ -0,0 +1,16 @@
#ifndef POLYMORPH_HPP
#define POLYMORPH_HPP
# include "ASpell.hpp"
class Polymorph: public ASpell {
public:
Polymorph(): ASpell("Polymorph", "turned into a critter") {};
~Polymorph() {};
virtual ASpell * clone() const {
return (new Polymorph());
};
};
#endif

View File

@@ -0,0 +1,2 @@
#include "Warlock.hpp"

View File

@@ -0,0 +1,50 @@
#ifndef SPELLBOOK_HPP
#define SPELLBOOK_HPP
# include <iostream>
# include <string>
# include "ASpell.hpp"
# include <map>
class SpellBook {
private:
SpellBook(SpellBook const & other);
SpellBook & operator=(SpellBook const & other);
std::map<std::string, ASpell *> arr;
public:
SpellBook() {};
~SpellBook() {
std::map<std::string, ASpell *>::iterator it_begin = this->arr.begin();
std::map<std::string, ASpell *>::iterator it_end = this->arr.end();
while (it_begin != it_end) {
delete it_begin->second;
++it_begin;
}
this->arr.clear();
};
void learnSpell(ASpell *aspell) {
if (aspell)
arr.insert(std::pair<std::string, ASpell *>(
aspell->getName(),
aspell->clone()
));
};
void forgetSpell(std::string & name) {
std::map<std::string, ASpell *>::iterator it = arr.find(name);
if (it == arr.end())
return;
delete it->second;
arr.erase(name);
};
ASpell * createSpell(std::string & name) {
std::map<std::string, ASpell *>::iterator it = arr.find(name);
if (it == arr.end())
return NULL;
return arr[name];
};
};
#endif

View File

@@ -0,0 +1,2 @@
#include "TargetGenerator.hpp"

View File

@@ -0,0 +1,50 @@
#ifndef TARGETGENERATOR_HPP
#define TARGETGENERATOR_HPP
# include <iostream>
# include <string>
# include "ATarget.hpp"
# include <map>
class TargetGenerator {
private:
TargetGenerator(TargetGenerator const & other);
TargetGenerator & operator=(TargetGenerator const & other);
std::map<std::string, ATarget *> arr;
public:
TargetGenerator() {
};
~TargetGenerator() {
std::map<std::string, ATarget *>::iterator it_begin = this->arr.begin();
std::map<std::string, ATarget *>::iterator it_end = this->arr.end();
while (it_begin != it_end) {
delete it_begin->second;
++it_begin;
}
this->arr.clear();
};
void learnTargetType(ATarget * atarget) {
if (atarget)
arr.insert(std::pair<std::string, ATarget *>(
atarget->getType(),
atarget->clone()
));
};
void forgetTargetType(std::string const & name) {
std::map<std::string, ATarget *>::iterator it = arr.find(name);
if (it != arr.end())
delete it->second;
arr.erase(name);
};
ATarget * createTarget(std::string const & name) {
std::map<std::string, ATarget *>::iterator it = arr.find(name);
if (it != arr.end())
return arr[name];
return NULL;
};
};
#endif

View File

@@ -0,0 +1,2 @@
#include "SpellBook.hpp"

71
cpp_module_02/Warlock.hpp Normal file
View File

@@ -0,0 +1,71 @@
#ifndef WARLOCK_HPP
# define WARLOCK_HPP
# include <iostream>
# include <string>
# include "ASpell.hpp"
# include "ATarget.hpp"
# include "SpellBook.hpp"
class Warlock {
private:
Warlock();
Warlock(Warlock const & other);
Warlock & operator=(Warlock const & other);
std::string name;
std::string title;
SpellBook book;
public:
Warlock(std::string const & name, std::string const & title)
{
this->name = name;
this->title = title;
std::cout << this->name << ": This looks like another boring day.\n";
};
~Warlock()
{
std::cout << this->name << ": My job here is done!\n";
};
std::string const & getName() const
{
return (this->name);
};
std::string const & getTitle() const
{
return (this->title);
};
void setTitle(std::string const & title)
{
this->title = title;
};
void introduce() const
{
std::cout << this->name << ": I am " << this->name << ", " << this->title << "!\n";
};
void learnSpell(ASpell *aspell)
{
book.learnSpell(aspell);
};
void forgetSpell(std::string name)
{
book.forgetSpell(name);
};
void launchSpell(std::string name, ATarget const & atarget)
{
//ATarget const * test = 0;
//if (test == & atarget)
// return;
ASpell * spell = book.createSpell(name);
if (spell)
spell->launch(atarget);
};
};
#endif

BIN
cpp_module_02/a.out Executable file

Binary file not shown.

30
cpp_module_02/main.cpp Normal file
View File

@@ -0,0 +1,30 @@
#include "Warlock.hpp"
#include "Fwoosh.hpp"
#include "Dummy.hpp"
#include "BrickWall.hpp"
#include "Polymorph.hpp"
#include "TargetGenerator.hpp"
#include "Fireball.hpp"
int main()
{
Warlock richard("Richard", "foo");
richard.setTitle("Hello, I'm Richard the Warlock!");
BrickWall model1;
Polymorph* polymorph = new Polymorph();
TargetGenerator tarGen;
tarGen.learnTargetType(&model1);
richard.learnSpell(polymorph);
Fireball* fireball = new Fireball();
richard.learnSpell(fireball);
ATarget* wall = tarGen.createTarget("Inconspicuous Red-brick Wall");
richard.introduce();
richard.launchSpell("Polymorph", *wall);
richard.launchSpell("Fireball", *wall);
}

View File

@@ -0,0 +1,86 @@
Assignment name : cpp_module_02
Expected files : Warlock.cpp Warlock.hpp
ASpell.hpp ASpell.cpp
ATarget.hpp ATarget.cpp
Fwoosh.hpp Fwoosh.cpp
Dummy.hpp Dummy.cpp
Fireball.hpp Fireball.cpp
Polymorph.hpp Polymorph.cpp
BrickWall.hpp BrickWall.cpp
SpellBook.hpp SpellBook.cpp
TargetGenerator.hpp TargetGenerator.cpp
--------------------------------------------------------------------------------
In the Warlock, SpellBook and TargetGenerator classes, the switch statement is
FORBIDDEN and its use would result in a -42.
Create the following two spells, on the same model as Fwoosh:
* Fireball (Name: "Fireball", Effects: "burnt to a crisp")
* Polymorph (Name: "Polymorph", Effects: "turned into a critter")
In addition to this, just so he won't have only dummy to attack, let's make a
new target for him, which will be the BrickWall (Type: "Inconspicuous Red-brick Wall").
Now, make a SpellBook class, in canonical form, that can't be copied or instantiated
by copy. It will have the following functions:
* void learnSpell(ASpell*), that COPIES a spell in the book
* void forgetSpell(string const &), that deletes a spell from the book, except
if it isn't there
* ASpell* createSpell(string const &), that receives a string corresponding to
the name of a spell, creates it, and returns it.
Modify the Warlock, now, make it have a spell book that will be created with
him and destroyed with him. Also make his learnSpell and forgetSpell functions
call those of the spell book.
The launchSpell function will have to use the SpellBook to create the spell
it's attempting to launch.
Make a TargetGenerator class, in canonical form, and as before,
non-copyable.
It will have the following functions:
* void learnTargetType(ATarget*), teaches a target to the generator
* void forgetTargetType(string const &), that makes the generator forget a
target type if it's known
* ATarget* createTarget(string const &), that creates a target of the
specified type
Phew, that's done. Now here's a test main. It's not very thorough, so make sure
to use your own aswell.
int main()
{
Warlock richard("Richard", "foo");
richard.setTitle("Hello, I'm Richard the Warlock!");
BrickWall model1;
Polymorph* polymorph = new Polymorph();
TargetGenerator tarGen;
tarGen.learnTargetType(&model1);
richard.learnSpell(polymorph);
Fireball* fireball = new Fireball();
richard.learnSpell(fireball);
ATarget* wall = tarGen.createTarget("Inconspicuous Red-brick Wall");
richard.introduce();
richard.launchSpell("Polymorph", *wall);
richard.launchSpell("Fireball", *wall);
}
~$ ./a.out | cat -e
Richard: This looks like another boring day.$
Richard: I am Richard, Hello, I'm Richard the Warlock!!$
Inconspicuous Red-brick Wall has been turned into a critter!$
Inconspicuous Red-brick Wall has been burnt to a crisp!$
Richard: My job here is done!$
~$