Saturday, 24 February 2018

Where does the time go?

So my last post on this blog was the 1st of June 2017. It's disheartening to see I only posted twice last year however I found my first year of uni a little overwhelming. Since the last post I've completed my first year and I'm now four months away from completing my second and receiving a foundation degree. I'll definitely be doing the honours top-up to receive a full bachelors degree next year however the course I'm doing is heavily focused on video-game design with some programming involved. Over the past year and half I've realised that I much prefer programming over making games. 

With the industry moving towards making games in pre-made engines such as Unreal, Unity, CryEngine or their own in-house engines like RAGE and Snowdrop it would appear the art of programming a game from absolute scratch is a thing of the past. Sure you can but it's something that indie devs would do and if you're an indie dev (like I wanted to be) it's hard to complete a full game without the use of an engine like game maker whilst paying the bills. 

I've become a big fan of C and procedural programming as it follows how my brain works. I like to make lists and follow those lists; ticking one task off at a time. Object-Orientated programming is more than a little confusing to me as it jumps around all over the place. I recently just finished implementing a font class for my DirectX 11 engine and the amount of times I had to go back and change function declarations; create new functions or just redesign the entire thing entirely did my head in. Perhaps it just goes to show how weak my C++ skills are right now, I'm certainly more comfortable writing class interfaces now than I was a year ago. A year ago, trying to implement code from MSDN seemed impossible so perhaps I'm just being impatient with myself.

I've decided to do a masters degree in Computer Science once I've finished my bachelors as it's more geared towards data science, memory management and general programming which I'm much more interested in now. The past year of my degree has been filled with writing game design documents, researching mobile input methods and 3D modelling; the latter I detest with a passion. I'm also not a big fan of Unreal and I find it dissatisfying to have to use it constantly throughout my degree. I am however enjoying building my own engine using C++ and DirectX, there is just something about writing code and clicking the build button and it compiles with no issues.

I took this blog off google for while as I wondered if I should continue it, however I am determined to finish this book and his next one which is for more advanced C++ programmers. I will begin re-posting however at a slower pace as I have many deadlines looming. I would like to finish this book by the end of summer though. Thank you to everyone who drops by and I hope someone finds these posts helpful.

Thursday, 1 June 2017

Chapter 6 // Exercise 10 - Principles & Practice Using C++

Chapter 6 // Exercise 10


"Design a program that asks users for two numbers, and asks them whether they want to calculate permutations or combinations, and prints out the result. This will have several parts. Do an analysis of the above requirements. Write exactly what the program will have to do. Then, go into the design phase. Write pseudo code for the program and break it into sub-components. This program should have error-checking. Make sure that all erroneous inputs will generate good error messages."

OK, at first this sounds pretty daunting and there are some rather large(ish) equations given in the book however when you actually break down what he's asking, it becomes a pretty simple task.

We have already been given the formulas so it's just a matter of getting some numbers from the user and throwing them at some functions which solve the formulas, the pseudo code could look like this:

Ask user for two numbers
>numbers
Does user want combination or permutation?
>answer

If answer == Combination
       pass numbers to function and place into equation
       print combinations

If answer == Permutation
       pass numbers to function and place into equation
       print permutations

Pause & Quit

For some more information on combinations and permutations, check out this site. After reading this, it would appear that there are two ways to solve each problem but Bjarne only gives the formula to solve combinations without repetition. According to the site above, solving combinations with repetition requires a slightly different formula. So which one do we use?

For this exercise, I'm just going to stick to the formulas given.



#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <cctype>

#undef max //undefine max so it can be used in getInt

using namespace std;

double a;
double b;

//this function was taken from http://www.cplusplus.com/forum/beginner/21595/
//it makes sure that only numbers can be used
double getInt()
{
  double x = 0;

  while (!(cin >> x)) 
  {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "You need to input a number: ";
 }

 return x;
}

//this gets two numbers and asks if the users wants permutations or combinations
//erroneous input is checked by getInt() and only allows P or C to be chosen
char permOrComb()
{
  cout << "Please enter the maximum amount of numbers: " << endl;
  a = getInt();
  cout << "Please enter how many numbers are needed: " << endl;
  b = getInt();

  cout << "\n\nWould you like to perform Permutation (p) or Combination (c)?: " << endl;
  char answer;
  cin >> answer;
  answer = toupper(answer); //converts letter to upper case

  while (answer != 'P' && answer != 'C')
  {
    cout << "You need to enter (p) or (c): ";
    cin >> answer;
    answer = toupper(answer);
  }

  return answer;
}

//this works out a factorial and returns the result
double getFactorial(double n)
{
  if (n == 0)
     n = 1;

  double factorial = n;

  for (double i = n - 1; i > 1; --i)
  {
    factorial = factorial*i;
  }

  return factorial;
}

//this solves permutations
double getPermutation()
{
  double p;
  double temp = a - b;

  //if a - b is a minus, flip it to positive
  if (temp < 0)
    temp *= -1;

  p = (getFactorial(a) / getFactorial(temp));

  return p;
}

//this solves combinations (where there is no repitition)
double getCombination()
{
  double c;
  double tempP = getPermutation();

  c = (tempP) / (getFactorial(b));
 
  return c; 
}

bool getQuit()
{
  char temp;
  bool qTemp = true;

  cout << "\n\nWould you like to quit (q) or continue (c): ";
  cin >> temp;
  temp = toupper(temp);

  while (temp != 'Q' && temp != 'C')
  {
    cout << "You need to enter (q) or (c): ";
    cin >> temp;
    temp = toupper(temp);
  }

  if (temp == 'Q')
    qTemp = false;
  if (temp == 'P')
    qTemp = true;

  return qTemp;
}


int main()
{
  bool quit = true;

  while (quit)
  {
    char answer = permOrComb();

    if (answer == 'P')
    {
      double temp = getPermutation();
      cout << "\nThere are " << temp << " permutations with these numbers.\n";
      quit = getQuit();
    }

   if (answer == 'C')
   {
     double temp = getCombination();
     cout << "\nThere are " << temp << " combinations with these numbers.\n";
     quit = getQuit();
   }

  }

  return 0;
}


I used the factorial function I created in Chapter 6 - Exercise 3 to solve for ! and then it was simply a case of checking for erroneous input. 

As I said above, this only solves combinations where there is no repetition, but it would be simple to create another function which solves for that using the formula given from the link above. Then just ask the user if repetition is allowed or not.

Monday, 26 December 2016

Chapter 6 // Exercise 9 - Principles & Practice Using C++

Chapter 6 // Exercise 9

Write a program that reads digits and composes them into integers. For example 123 is read as the characters 1, 2 and 3. The program should output "123 is 1 hundred and 2 tens and 3 ones". The number should be output as an int value. Handle numbers with one, two, three or four digits.

Hint: To get the integer value 5 from the character '5' subtract '0', that is '5'-'0'==5.


#include "stdafx.h"
#include <vector>
#include <string>
void pause();
void getNumbers();
void printNumbers();
using namespace std;
vector <int> digits;
char er = 'n'; //for error checking

int main()
{
 //get the numbers and convert them to an int from string
 getNumbers();

 //print the numbers out
 printNumbers();


 //ask for letter to quit the program
 pause();

 return 0;
}


void getNumbers()
{
 er = 'n';
 cout << "Please enter a number with up to 4 digits: ";
 string x;
 cin >> x; 

 //error checking
 for (int i = 0; i < x.size(); ++i)
 {
  for (char n = 'a'; n < 'z'; ++n)
  {
   while (x[i] == n)
   {
    er = 'y';
    cout << "That is not a number. Sorry.\n";
    return;
   }  
  }

  int num = x[i] - '0'; //converts letter to int
  digits.push_back(num); //pushes back into int vector
 }
}

void printNumbers()
{
 //continue to get input while er is equal to y
 while (er == 'y')
  getNumbers();

 for (int i = 0; i < digits.size(); ++i)
  cout << digits[i];

 cout << " is ";

 if (digits.size() == 4)
 {
  if (digits[0] == 1)
   cout << digits[0] << " thousand and ";
  else
   cout << digits[0] << " thousands and ";

  if (digits[1] == 1)
   cout << digits[1] << " hundred and ";
  else
   cout << digits[1] << " hundreds and ";

  if (digits[2] == 1)
   cout << digits[2] << " ten and ";
  else
   cout << digits[2] << " tens and ";

  cout << digits[3] << " ones.\n";
 }


 if (digits.size() == 3)
 {
  if (digits[0] == 1)
   cout << digits[0] << " hundred and ";
  else
   cout << digits[0] << " hundreds and ";

  if (digits[1] == 1)
   cout << digits[1] << " ten and ";
  else
   cout << digits[1] << " tens and ";

  cout << digits[2] << " ones.\n";
 }


 if (digits.size() == 2)
 {
  if (digits[0] == 1)
   cout << digits[0] << " ten and ";
  else
   cout << digits[0] << " tens and ";
  cout << digits[1] << " ones.\n";
 }

 if (digits.size() == 1)
 {
  cout << digits[0] << " ones.\n";
 }

}

void pause()
{
 cout << "\n\nPlease enter a letter: ";
 char key;
 cin >> key;
}


I'm sure there must be a much easier way to print the digits grammatically however I decided to just do this by brute force because this small program doesn't really take up any memory by doing it this way, nor does it slow it down. 

At first when I read this question I was like "what on earth does he want me to do now?" I didn't know if he wanted us to write into a char but then a char can't hold more than single character, so I thought about a vector of chars and pushing them back but that would require at least 5 different chars to push back. So I went with a string and I actually learnt something very useful today.

So string has similar functions as vector, I knew that I could get the size of it by using .size after the variable to return how many characters had been inputted. However on a whim I decided to see what would happen if I took away '0' from the character within the string, as suggested by Bjarne in the book. And it worked, it returned a number which I applied to a interger called num and then pushed that into a vector so printNumbers() had them all in one place.

Also, as a little extra this includes error checking. This doesn't allow any letters and will only allow numbers. I did this by comparing whatever the current character of x was to the alphabet using a for loop. For example, if the string x was equal to k then k would be compared to each letter of the alphabet and if it was equal to one then it returns to main and executes the next function. However the char 'er' has been set to 'y' so it will keep calling getNumbers() until er is equal to 'n'. It took me a while to get this error check working, so I'm pretty proud it does.

Sunday, 27 November 2016

Little Hiatus & Blog Update

This blog is currently on a small hiatus as I focus on university work. I am currently half way through chapter 7 but my assignments are top priority.

I just handed in my first which was Maths & Physics for game play which focused on parabolic trajectories and IK Chains and have a programming one and another maths due by Christmas. Whilst doing my assignments it has made me think about the future of this blog and would love eventually to put up tutorials on maths for games programming and c++ tutorials. 

As someone who has been programming for just under a year, I'd like to keep the topics on this blog simple, especially for beginner programmers. I've found that newbies asking questions in places like stackoverflow or cplusplus are met with patronizing answers from 'experts' whose answers are way too technical for their level of understanding. 

For example, someone had posted a question on an exercise from chapter 5 of P&P on stackoverflow (I was searching for an answer myself and I was stumped) and one user replied with "just use maps". Another user then had to point out that maps aren't introduced till a much later chapter (I'm currently still trying to wrap my head around classes). I guess what I'm trying to say is, I want this site to be a place where newcomers to C++ can learn the basics without the fear of experienced programmers thinking they're stupid. 
     We all learn at different paces and in different ways. I still use system("pause") every now and then despite what every single user on stackoverflow says. I only ever use windows and it works for what I want. Would I use it in a professional program? Of course not, but that doesn't mean I'm idiot for using it. You have to learn to walk before you can run. That's why Bjarne provides you with a header file with functions such as keep_window_open(). That function works in exactly the same way as system("pause") but for the first few chapters I had no idea how it worked, I only knew that it kept the console window open (as visual studio has a habit of closing the console window when the program has finished executing). Now I understand how it works and how to create a function which does the same thing. 

I am in no way an expert, I'm still learning, and have a lot to learn, but this blog was created because I could not find any help on Principles & Practice. There are a few blog posts and Bjarne himself has answered a few questions but there doesn't seem to be anyone who actually goes through their answers and how they got them. Therefore I hope that someone else finds this blog somewhat useful, if not I'm pretty proud of how far I've progressed so far. But enough rambling, thank you to those who are dropping by and if you have any questions I will try to answer as best I can.

Thursday, 29 September 2016

Chapter 6 // Exercise 8 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 6 // Exercise 8

Redo the "Bulls & Cows" game from exercise 12 in Chapter 5 to use four letters rather than four digits.



#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

void getSeed();
void printRules();
void startGame();
void getLetters();
void compareLetters();
char assignLoop();
vector<char> fourLetters{ 0,0,0,0 };
vector<char> guess{ 0,0,0,0 };

int main()
try
{
char loop = 'y';

while (loop == 'y')
{
//get number for seed  & assign letters to fourLetters
getSeed();

//print rules of game
printRules();

//begin the game and keep going till user decides to quit
startGame();

//ask if you want to play again
loop = assignLoop();
}

keep_window_open();

return 0;
}


catch (exception& e)
{
cerr << "Error: " << e.what() << '\n';
keep_window_open();
return 1;
}

//produces random number which corralates to ASCII lower case alphabet
char getRandLetter()
{
char randNum = (rand()%(122 - 97 + 1)) + 97; // produces random number between 97 and 122
return randNum;
}

//get seed for rand num and assign letters to comp's four letters
void getSeed()
{
cout << "Please enter a number(any number):\n";
int n;
cin >> n;

srand(n);
for (int i = 0; i < fourLetters.size(); ++i)
{
fourLetters[i] = getRandLetter();
}

sort(fourLetters); //to compare if any are the same

for (int i = 1; i < fourLetters.size(); ++i)
{
while (fourLetters[i] == fourLetters[i - 1])
{
fourLetters[i] = getRandLetter();
}
}

}



void printRules()
{
cout << "//RULES//";
cout << "\nLets Play Bulls & Cows.\n";
cout << "Guess the 4 letters.\n";
cout << "If a letter is right in the right position you will get a bull.\n";
cout << "If the letter is right in the wrong position you will get a cow.\n";
cout << "\nGuess a letter a-z. Each letter must be different and lower case. \n\n";
}

void startGame()
{
while (guess != fourLetters)
{
//get user letters
getLetters();
//compare user and random letters for bulls & cows
compareLetters();
}
}

void getLetters()
{

vector<string>n = { "1st Letter: ", "2nd Letter: ", "3rd Letter: ", "4th Letter: " };

for (int i = 0; i < 4; ++i)
{
cout << n[i];
char letter;
cin >> letter;

if (letter < 'a' || letter > 'z')
error("You can only use lower case.\n");

guess[i] = letter;
}

cout << "Your guess: ";

for (int i = 0; i < 4; ++i)
{
cout << guess[i] << " ";
}

cout << '\n';
}

void compareLetters()
{
for (int i = 0; i < 4; ++i)
{
for (int n = 0; n < 4; ++n)
{
if (guess[i] == fourLetters[n])
{
if (i == n)
cout << "1 Bull(" << guess[i] << ")";
else
cout << "1 Cow(" << guess[i] << ")";
}
}
}
}

char assignLoop()
{
cout << "\n\nCongratz! You did it!\n";
cout << "Would you like to play again? y / n:\n";
char l;
cin >> l;
while (l != 'y' && l != 'n')
{
cout << "Invalid answer, try again. y / n:\n";
cin >> l;
}

return l;
}



This one took a while as I figured out how to perfect a few things. The original exercise had you guess a number 1 - 9, this one a letter a -z. Since int and char are interchangeable I simply changed most of the code to char however when it came to randomizing what letters you would get I had to find a new function.


The one I've got accepts a max and a min value, for us we want between 97 and 122 as these are the numbers for the characters a - z. I then just assigned one of the generated numbers to the guess vector. When looking to see if any of them were the same I realised my prior function wasn't exactly perfect and would sometimes allow the same numbers. I've corrected it on this one by sorting them first. This does give the letters some predictability by putting them in order however not all the time as if some are the same they will be changed to another generated number.