Wednesday, 23 December 2020

Chapter 19 // Drill 14 - Principles & Practice Using C++

In these exercises I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 19 // Drill 14

Bonus: Define input and output operators (>> and  <<) for vector<T>s. For both input and output use a { val, val, val } format. That will allow read_val() to also handle the S<vector<int>> variable.


This drill. I was like "sure no probs". Had it working perfectly for ints and then I remembered that this function can take in vectors of any type. Throw strings, floats, chars etc., at it and it breaks spectacularly. I then had to reset my brain to get into the mindset of generic programming...You need to think of everything and anything that could happen.



Apart from not being able to handle vectors of custom types (what a nightmare), it also doesn't handle strings with spaces in them. But I'm pretty happy with this. He chose this input/output specifically because it's really annoying. Bjarne is the true sneaky fox. If you needed very specific string output though I don't think you would use generic types.

Chapter 19 // Drill 14 - Principles & Practice Using C++

For this it checks if there are any undesirable characters and if not, it then reads the entire entry into a string. It removes commas from the string then converts it to a stringstream to be read into the templated type. This way, we don't have to bother with string to random type conversions; stringstream will take care of it for us. It also has the advantage of reading the entire variable in. So { 1.77, 5 }  will be read as:
- cin >> string, ignore { and ' ' 
- cin >> string (reads 1.77, )
- removes the comma
- stringstream >> type ( 1.77 is converted to type )
- push value into vector
- cin >> string, ignore space
- cin >> string ( reads 5 )
- no comma to remove
- stringstream >> type ( 5 is converted to type )
- push value into vector
- cin >> string, ignore space
- cin >> string, } read, break out of loop and return

Tuesday, 22 December 2020

Chapter 19 // Drill 1, 2, 3, 4, 5, 6, 7, 8 ,9, 10, 11, 12, 13 - Principles & Practice Using C++

In these exercises I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.


Chapter 19 // Drill 1

Define template<typename T> struct S { T val; };.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%201

.

Chapter 19 // Drill 2

Add a constructor, so that you can initialise with a T.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%202

.

Chapter 19 // Drill 3

Define variables of types S<int>, S<char>, S<double>, S<string>, and S<vector<int>>; initialise them with values of your choice.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%203

.

Chapter 19 // Drill 4

Read those values and print them.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%204

 I assume he meant read them in using cin?

Chapter 19 // Drill 5

Add a function template get() that returns a reference to val.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%205

.

Chapter 19 // Drill 6

Put the definition of get() outside the class.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%206

.

Chapter 19 // Drill 7

Make val private. 

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%207

.

Chapter 19 // Drill 8

Do 4 again using get().

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%207

I guess he didn't mean to use cin earlier...literally just print them? Why use read? See code for drill 7 as this does the same thing.

Chapter 19 // Drill 9

Add a set() function template so that you can change val.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%209

.

Chapter 19 // Drill 10

Replace set() with an S<T>::operator=(const T&). Hint: Much simpler than Section 19.2.5.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2019/Drills/Drill%2010

.

Chapter 19 // Drill 11

Provide const and non-const versions of get().


.

Chapter 19 // Drill 12

Define a function template<typename T> read_val(T& v) that reads from cin into v.


Ok, so he definitely didn't mean to read in values in drill 4. I provided the operator overload version in 4 but I implemented the function here as well.

Chapter 19 // Drill 13

Use read_val() to read into each of the variables from 3 except the S<vector<int>> variable.

Github: .

See drill 12 as I did that there...I also already read into the vector...

Sunday, 20 December 2020

Chapter 18 // Exercise 12 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.

I thought about not typing this novel out but for the sake of clarity I did.

Chapter 18 // Exercise 11

Implement a version of the game "Hunt the Wumpus". "Hunt the Wumpus" (or just "Wump") is a simple (non-graphical) computer game originally invented by Gregory Yob. 

The basic premise is that a rather smelly monster lives in a dark cave consisting of connected rooms. Your job is to slay the wumpus using a bow and arrows. In addition to the wumpus, the cave has two hazards; bottomless pits and giant bats. If you enter a room with a bottomless pit; it's the end of the game for you.  If you enter a room with a bat, the bat picks you up and drops you into another room. If you enter a room with the wumpus or he enters yours, he eats you. 

When you enter a room you will be told if a hazard is nearby:
"I smell the wumpus" : It's in an adjoining room.
"I feel a breeze" : One of the adjoining rooms is a bottomless pit.
"I hear a bat" : A giant bat is in an adjoining room.

For your convenience, rooms are numbered. Every room is connected by tunnels to three other rooms. When entering a room, you are told something like "You are in room 12; there are tunnels to rooms 1, 13, and 4; move or shoot?" Possible answers are m13 ("Move to room 13") and s13-4-3 ("Shoot an arrow through rooms 13, 4, and 3"). The range of an arrow is three rooms. At the start of the game, you have five arrows. The snag about shooting is that it wakes up the wumpus and he moves to a room adjoining the one he was in - that could be your room.

Probably the trickiest part of the exercise is to make the cave by selecting which rooms are connected with which other rooms,. You'll probably want to use a random number generator (e.g., randint() from std_lib_facilities.h) to make different runs of the program use different caves and to move around the bats and the wumpus. Hint: Be sure to have a way to produce a debug output of the state of the cave.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2018/Exercise%2012

So I didn't do this exactly; I changed a few things and added some others. This version of Hunt The Wumpus features a procedurally generated cave that generates rooms with 1-3 tunnels and random bats/pits. It then sticks the wumpus somewhere once generated. I like this setup as it creates varied caves and hazards:
Chapter 18 // Exercise 12 - Principles & Practice Using C++

Chapter 18 // Exercise 12 - Principles & Practice Using C++

As you can see though this generation style is kind of cruel if the only route generated around the map contains pits. So instead of the game ending I added a new feature of "planks". The player will get 3 planks and can choose to put a plank over a pit to cross it. When players successfully slay a bat, it has a 25% chance of dropping an arrow or a plank.

I had a look at the original Wumpus game and the main puzzle is creating the dodecahedron like cave structure as all rooms must lead to 3 more rooms. I could change the code to only draw tunnels, however I like the fact that you may have to double back and really pay attention to where you're going as not everything is connected.

One of the reasons this took me so long was because I approached it all wrong. I literally tried to implement everything in one go and because I had no source control that meant backtracking as I went over my code. I tried installing git for use with VS but I just couldn't get it to work the way I wanted it to. At work we use Perforce and it's free if you have a team of 5 or less so I downloaded P4V and Helix Core. I've never been so happy to lock files, submit and check things out in separate changelists. Programming was fun before, but now it feels extra fun. After that I was able to iterate much faster, as well as revert back to older versions if needed. Source control; it just works.

I then sat down and properly planned out what I had to do, created a checklist and after that my motivation came back and I really started to enjoy the exercise. Especially because I was now seeing progress with every submit. 

Here's how it looks without the debug map:

Chapter 18 // Exercise 12 - Principles & Practice Using C++

And with the map:

Chapter 18 // Exercise 12 - Principles & Practice Using C++

In the video, you can see the Wumpus moves to a random adjoining room if you fire an arrow. You also have a 1/10 chance of receiving an arrow or a plank when entering a room. This run was particularly lucky.

The code is not great. I try to aim to finish a chapter a month so I'm seriously behind. There is a lot of repetition but it's done. I did it. I finally finished a full game...for once.

There are a few things I'd like to add; like a proper game over screen and sounds but it will have to wait until I've finished the book.