Thursday, February 14, 2019

Enums Vs Enum Classes Pt 1

Enums and enum classes are essentially the same thing, however, using enum classes can avoid a compiler error as well as some other issues that maybe discussed in later posts.

enum AEnum
{
    OK,
    FAILED,
}

enum BEnum
{
    READY,
    FAILED,
}

The above enums will cause a compiler error and this is because within both enums the value FAILED has been declared twice as both values are within a global scope. By using enum classes instead avoids this problem as each value declared is now within its own enum class scope. A enum class is also known as a strongly typed enum. The below code shows the correct usage of enum classes. NB: Enum Classes are available in C++ 11+.

enum class AEnum
{
    OK,
    FAILED,
}

enum class BEnum
{
    READY,
    FAILED,
}

Monday, February 11, 2019

The Const Keyword: Const Functions

Const is generally used to state that something will not be changed or modified. However, this is dependant on where const is placed. For example if you place the const keyword after a member/class function declaration, you will not be allowed to modify any member variables within that function.

int GetMaxTries() const;

int GetMaxTries() const 
{
    return maxTries; 
}

The above function and function declaration will not produce any compiler errors as it doesn't modify any of the class's member variables. However, the below example would, because even with the const someone has tried to modify the maxTries variable. The const keyword in this situation acts as a guard so that you or anyone else working on the codebase doesn't accidentally modify any member variables within a specific function.

int GetMaxTries() const;

int GetMaxTries() const 
{
    maxTries += 12;
    return maxTries; 
}

Structs Vs Classes

Simply put structs and classes are the same except for one factor, which is, that all member variables and functions are public by default. This can be extremely useful. Below is an example of what a struct might look like and what a class might look like.

Struct Example

struct SomeStruct
{
    int someIntVariable;
    std::string someStringVariable;

    void SomeFunction();
}

Class Example

class SomeClass
{
public:
    SomeClass();
    ~SomeClass();

    void SomeFunction();
    int GetSomeIntVariable() { return someIntVariable; };

private:
    int someIntVariable;
}

Friday, February 1, 2019

Matrices Pt 3

Augmented Matrices
An augmented matrix is a matrix made of several linear equations that make up a system of equations. Each row of the matrix represents a equations within the system, whereas each column of the matrix represents a variable wtihin that equation.

We can see this with the above example, where we have two equations within a system and a matrix representation of that system. It also shows how the columns represents each variable or constant within the equation. For the x variables we have both 2 & 3, for y variables we have 5 & 4 and for the constant we have 10 & 24. This means we can write equations without having to write the x or y letters, or any other letters that might be used.

When converting a system of equations to a matrix, we need to make sure that each variable and constant is in line with each other but also if a variable or constant doesn't exist in one equation of the system then it defaults to 0 within the matrix at the location where the value would have gone.


Matrix Row Operators
There are three types of matrix row operators:

  1. Switch any two rows
  2. Multiply a row by a nonzero constant
  3. Add one row to another
You will know to switch two rows of a matrix when given a question like R1 ↔ R2, which means swap row 1 with row 2. It is important to note that you can also subtract if needed.


You will know to multiply a row of a matrix by a nonzero constant when given a question like 3R1 → R1, which means multiply row 1 by 3. It is also important to note that you can essentially divide by a nonzero constant as well by using fractions like 1/2.


You will know to multiply a row of a matrix by a nonzero constant when given a question like R2 + R3 → R2, which means add row 2 to row 3 and enter the answer in row 2.


Each row operator could also be represented in this format:



On the left side we have the original matrix, in the center is the row operator and the direction being to the final matrix, which we can see on the right side.

It's also worth noting that they can be combined.


Notice how the 2R3 part only applies to the addition in row 1 and is not used to modify row 3.

As mentioned before augmented matrices represent a system of equations. By using row operators we can get equivelent systems of equations. For example by using the mutliplaction by a nonzero constant we can eliminate a variable from an equation.


This is our original system of equations and the augmented matrix. If we carried out -2R1 → R1, we get:


This then allows us to use the row addition operator; R1 + R2 → R2, which gives us:


In other words, we get the final equation -1y = -4, which we can use to solve for y. So y = 4, which can then be subsituted in any of the equations to solve for x.

Reduced Row Echelon Form
You can solve a system of equations by converting the augmented matrix into the reduced row echelon form. This form is were the diagonal components of a matrix are valued at 1 and every other component is valued at 0, except for any constants. Think of it being a combination of the identity matrix and an augmented matrix. Below is an example, where a, b & c are the constants.


To get to the reduced row echelon form, can use the row operators from earlier.


Once a augmented matrix has been converted we can solve the system of equations. So using the above example we can see that x = 5, y = -1 & z = -1 and if we subsitute them back into the original equations we can see that everything is correct.

1x + 1y + 1z = 3

1(5) + 1(-1) + 1(-1) = 3

5 - 1 -1 = 3

Thursday, January 24, 2019

Design Patterns: Command Pattern Pt 1

The Gang of Four describe the command pattern as "Encapsulate a request as an object, thereby letting users parameterise clients with different request, queue or log requests, and supports undoable operations."Another way to describe it as a thingified method call, which means to wrap a method call in a function.

The command pattern is very similar to callbacks, first-class functions, function pointers and partially applied functions. The Gang of Four also describle commands as an object oriented replacement for callbacks.

An example use for the command pattern is configurable/remappable input, what this means the user can change what actions a button/bumper/trigger can do. Usually specific actions are mapped to specific input like so:

void InputHandling()
{
    if (Input.GetButtonDown(BUTTON_X))
    {
        Reload();
    }
    else if(Input.GetButtonDown(BUTTON_Y))
    {
        SwapWeapons();
    }
    else if(Input.GetButtonDown(BUTTON_B))
    {
        Melee();
    }
    else if(Input.GetButtonDown(BUTTON_A))
    {
        Jump();
    }
}

We could set up preset functions that contain different variations of the type of input and corresponding actions. However, that might not be flexible enough and so allowing the players to swap out actions is a better alternative, which is where commands come in. We can use pointers for each button and when the player wants to change that buttons input we simply point to a new command object.

Example Code

Command Class
class Command
{
public:
virtual ~Command() { };
virtual void Execute() = 0;

};

Example Command Classes
class JumpCommand : public Command
{
public:
virtual void Execute() { Jump(); }
};

class MeleeCommand : public Command
{
public:
virtual void Execute() { Melee(); }
};

class SwapWeaponsCommand : public Command
{
public:
virtual void Execute() { SwapWeapons(); }
};

Input Handler
class InputHandler
{
public:
void HandleInput();

// Methods to bind commands

private:
Command* buttonA;
Command* buttonB;
Command* buttonX;
Command* buttonY;

};

void HandleInput()
{
    if (Input.GetButtonDown(BUTTON_X))
    {
        buttonX->Execute();
    }
    else if(Input.GetButtonDown(BUTTON_Y))
    {
        buttonY->Execute();
    }
    else if(Input.GetButtonDown(BUTTON_B))
    {
        buttonB->Execute();
    }
    else if(Input.GetButtonDown(BUTTON_A))
    {
        buttonA->Execute();
    }
}

However, this assumes that whatever functions that are wrapped in the execute functions as part of the command class, can find the player to do whatever action is required. This isn't always the case and so we can modify the code so that we pass in a reference to an object and then call a specific function of that object. This means we now make these changes to the code:

class Command
{
public:
virtual ~Command() { }
virtual void Execute(Actor& actor) = 0;
};

class SwapWeaponsCommand : public Command
{
public:
virtual void Execute(Actor& actor) 
{ 
actor.SwapWeapons(); 
}
};

Command* HandleInput()
{
    if (Input.GetButtonDown(BUTTON_X))
    {
        return buttonX;
    }
    if(Input.GetButtonDown(BUTTON_Y))
    {
        return buttonY;
    }
    if(Input.GetButtonDown(BUTTON_B))
    {
        return buttonB;
    }
    if(Input.GetButtonDown(BUTTON_A))
    {
        return buttonA;
    }

    return NULL:
}

You will notice that we now return the commands, this is because we don't know the actor to execute functions from and so once we know the command, we can pass in the reference to the actor, to the command. Like so:

Command* command = HandleInput();
if (command)
{
command->execute(actor);

}

This also means we can actually control any actor within the game, as we can just swap out which actor is passed in to the execute function.

Number Systems: Introductions

Number systems allow us to count various things with a lot more ease than before. The most common one is Decimal or Base 10, this is most likely because humans generally have 10 fingers, 5 on both hands.

Base 10
Base 10 uses 10 symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
This combined with places allows us to use large numbers such as 231.
If we split 231 down we get:
  • 2 x 100s
  • 3 x 10s
  • 1 x 1s
It is interesting to note that each place increases a multiple of 10, but also can be explained exponentially so:
  • 1 = x10^0
  • 10 = x10^1
  • 100 = x10^2
  • 1000 = x10^3
Base 2 - Binary
Base 2 uses 2 symbols: 0, 1
These usually represents on and off or true and false.

Instead of each place being represented by x10^n, base 2 places are represented by x2^n.
So the first 8 places of binary are:
  • 1 = x2^0
  • 2 = x2^1
  • 4 = x2^2
  • 8 = x2^3
  • 16 = x2^4
  • 32 = x2^5
  • 64 = x2^6
  • 128 = x2^7
We can now convert 231 base 10 into base 2

128 64 32 16 8 4 2 1
---------------------------
    1   1   1   0 0 1 1 1

So in binary 231 is represented as 11100111 and we can check this by adding each place that has a value of 1: 128 + 64 + 32 + 4 + 2 + 1 = 231


Base 16 - Hexadecimal
Base 16 uses 16 symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A (10), B(11), C(12), D(13), E(14), F (15)

As with base 2, base 16 places are represented by something different to x10^n. The places are represented by x16^n. So the first 4 places of base 16 are:
  • 1 = x16^0
  • 16 = x16^1
  • 256 = x16^2
  • 4096 = x16^3
We can now figure out how to write 231 in base 16

4096 256 16 1
-------------------
                  E 7

So in base 16, 231 can be represented as E7 and we can check this by adding the each places total together.
E or 14 x 16 = 224
7 x 1 = 7. 
224 + 7 = 231

Sample Problem: C++ - Order of Execution of Constructors & Destructors Between a Parent & Child Class

You have a parent class that has a constructor and a non-virtual destructor, as well as a child class that inherits from the parent class. What is the execution order for the constructors and destructors?


  1. Parent constructor is called
  2. Child constructor is called
  3. Child destructor is called
  4. Parent destructor is called
Source Code
Source.cpp
#include "Parent.h"

#include "Child.h"
#include <iostream>

int main()
{
Child* testChild = new Child();
testChild->~Child();

int endInput;
std::cin >> endInput;

return 0;
}

Parent.h
#pragma once
#include <iostream>

class Parent
{
public:
Parent();
~Parent();
};

Parent.cpp
#include "Parent.h"

Parent::Parent()
{
std::cout << "Parent Constructor Called" << std::endl;
}

Parent::~Parent()
{
std::cout << "Parent Destructor Called" << std::endl;
}

Child.h
#pragma once
#include "Parent.h"
#include <iostream>

class Child : Parent
{
public:
Child();
~Child();
};

Child.cpp
#include "Child.h"

Child::Child()
{
std::cout << "Child Constructor Called" << std::endl;
}

Child::~Child()
{
std::cout << "Child Destructor Called" << std::endl;
}

Console Output