A LITTLE CLARITY

Your C++ handbook.

Every C++ word in the game, and a few that come next. Big ideas, in small words.

move(direction, steps)

Moves Noodle. The direction is UP, DOWN, LEFT or RIGHT, and the steps are optional (1 if you leave them out). If something's in the way, Noodle bumps into it and stays put.

move(RIGHT);
move(DOWN, 3);
Noodle's garden

look(direction)

Gives back what's next to Noodle, as a string: "wall", "grass", "snack", "home", "water", "ice", "door", "open door", "bridge", "gap", "stone" or "sign".

if (look(RIGHT) == "wall") {
    move(DOWN);
}
Noodle's garden

at_home() and snacks_left()

at_home() gives back true when Noodle is home. snacks_left() gives back how many snacks haven't been eaten yet, as an int.

while (!at_home()) {
    move(RIGHT);
}
cout << snacks_left() << endl;
Noodle's garden

where() and where_home()

Give back a Spot: a struct with an x and a y. x counts to the right and y counts down, from the top-left corner.

Spot me = where();
int distance = where_home().x - me.x;
Noodle's garden

read_sign()

Reads the sign Noodle is standing on, and gives back its text as a string. Walk onto the sign first! If the sign holds a number, convert it with stoi().

move(DOWN);
string way = read_sign();
Noodle's garden

The garden's rules

garden.h gives you variables that shape the garden: door_open (a bool) opens doors, pond (a string, "water" or "ice") freezes ponds, bridge_length (an int) builds bridge planks, and stones (a vector<string>) decides which stepping stones exist. They're checked every time Noodle does something.

door_open = true;
pond = "ice";
bridge_length = 5;
stones = {"stone", "stone"};
Noodle's garden

Direction: UP, DOWN, LEFT, RIGHT

Direction is a type with exactly four values: UP, DOWN, LEFT and RIGHT (it's an enum). You can keep them in variables and vectors too.

Direction d = RIGHT;
move(d, 2);
vector<Direction> route = {RIGHT, DOWN};
Noodle's garden

The shape of a program

#include brings in tools (<iostream> for printing, "garden.h" for Noodle). using namespace std; lets you write cout instead of std::cout. The program starts in int main() { ... }.

#include <iostream>
#include "garden.h"
using namespace std;

int main() {
    move(RIGHT);
}
First steps

cout and endl

cout << value prints a value, and you can chain as many as you like with <<. endl ends the line. In the garden, whatever you print, Noodle says.

cout << "Hello, garden!" << endl;
cout << "I see " << snacks_left() << " snacks" << endl;
First steps

Semicolons ;

Every statement ends with a semicolon. Lines that open a block, like if (...) { or int main() {, don't need one.

move(RIGHT, 2);
move(DOWN);
First steps

Comments

// starts a comment that runs to the end of the line. /* ... */ can span several lines. The compiler skips them.

// turn this line off:
// move(LEFT);
move(RIGHT); // walk on
First steps

The compiler

C++ is compiled: before anything runs, the compiler reads the whole program and turns it into machine code. If it finds a mistake, nothing runs, and it tells you the line. Fix the first error first: later ones are often caused by it.

int steps = "4";   // error: an int can't hold text
int steps = 4;     // fine
First steps

Calling a function

Write the function's name, then its arguments in round brackets, separated by commas. Some arguments have defaults and can be left out.

move(RIGHT, 3);
move(RIGHT);      // steps defaults to 1
string s = look(DOWN);
First steps

Variables

A variable is a named box with a type. Declare it once with its type, then use or change it by name. = stores a new value.

int steps = 3;     // declaration
steps = 5;         // assignment
move(RIGHT, steps);
Variables and types

int and double

int holds whole numbers (3, -12). double holds numbers with a point (2.5). Dividing two ints drops the remainder: 7 / 2 is 3, but 7.0 / 2 is 3.5.

int planks = 5;
double speed = 1.5;
int half = 7 / 2;   // 3
Variables and types

bool, true and false

A bool is either true or false (lowercase). Comparisons like x > 3 give back a bool.

bool ready = true;
door_open = false;
bool far = steps > 5;
Variables and types

string

A string holds text in double quotes. Join strings with +. It lives in the standard library (std::string).

string name = "Noodle";
string hi = "Hi, " + name;
Variables and types

Types must match

A variable's type never changes, and the compiler checks every value you give it. "4" is text and 4 is a number: different types.

int a = 4;        // ok
int b = "4";      // error
int c = stoi("4"); // ok: converted
Variables and types

+, -, *, /, %

Maths works as you'd expect. % gives the remainder: 7 % 2 is 1. With two ints, / rounds down.

int total = 3 + 4 * 2;   // 11
int left = 10 % 3;       // 1
Variables and types

++, += and friends

x++ adds one to x. x += 3 is short for x = x + 3. There's also --, -=, *= and /=.

int steps = 0;
steps++;       // 1
steps += 3;    // 4
Variables and types

const

const makes a variable that can't change after it's made. The compiler stops anyone who tries.

const int SIZE = 4;
move(RIGHT, SIZE);
Variables and types

auto

auto lets the compiler work out the type from the value. The variable still has one fixed type.

auto steps = 3;          // int
auto way = read_sign();  // string
Variables and types

if and else

if runs its block only when the condition (in round brackets) is true. else runs when it isn't.

if (look(RIGHT) == "grass") {
    move(RIGHT);
} else {
    move(DOWN);
}
Conditionals

else if

Chain more choices with else if. Only the first block whose condition is true runs.

if (way == "left") {
    move(LEFT);
} else if (way == "right") {
    move(RIGHT);
} else {
    move(DOWN);
}
Conditionals

==, !=, <, >, <=, >=

Comparisons give back a bool. == compares (a single = stores!), != means not equal.

if (snacks_left() > 0) { ... }
if (look(RIGHT) != "wall") { ... }
Conditionals

&&, || and !

a && b is true when both are, a || b when at least one is, and !a flips true and false.

if (!at_home() && look(RIGHT) != "wall") {
    move(RIGHT);
}
Conditionals

Blocks { }

Curly brackets group statements into a block. A variable declared inside a block only exists until its }.

if (ready) {
    int steps = 2;   // only exists in here
    move(RIGHT, steps);
}
Conditionals

for loops

for (start; keep going while; after each round). The classic: count i from 0 while it's less than n.

for (int i = 0; i < 3; i++) {
    move(RIGHT);
    move(DOWN);
}
Loops

while loops

Repeats its block as long as the condition is true. It checks before every round.

while (!at_home()) {
    move(RIGHT);
}
Loops

Range-for: for (x : v)

Visits every item of a vector (or every char of a string), in order.

for (Direction d : route) {
    move(d);
}
for (char c : path) { ... }
Loops

break and continue

break leaves the loop right away. continue skips to the next round.

while (true) {
    if (at_home()) {
        break;
    }
    move(RIGHT);
}
Loops

Counters

Start a variable at 0 before the loop, and add to it inside.

int steps = 0;
while (!at_home()) {
    move(RIGHT);
    steps++;
}
Loops

Writing a function

A function has a return type, a name, parameters in brackets, and a body in curly brackets. void means it gives nothing back. Write it above main so the compiler knows it in time.

void stairs(int n) {
    for (int i = 0; i < n; i++) {
        move(RIGHT);
        move(DOWN);
    }
}
Functions

Parameters

Parameters are variables that get their values from the call. Each one needs a type.

void walk(Direction d, int steps) {
    move(d, steps);
}

walk(RIGHT, 3);
Functions

return

return ends the function and gives a value back to whoever called it. The value must match the function's return type.

int distance_home() {
    return where_home().x - where().x;
}
Functions

Functions that answer yes or no

A function that returns bool answers a question. A comparison is already a bool, so you can return it directly.

bool can_go(Direction d) {
    return look(d) != "wall";
}
Functions

Copies (pass by value)

Normally a parameter is a copy of what was passed. Changing it inside the function doesn't change the original.

void grow(int n) {
    n += 5;   // only changes the copy
}
References and pointers

References &

int& x is a reference: another name for an existing variable. A reference parameter changes the caller's variable itself.

void grow(int& n) {
    n += 5;
}

grow(bridge_length);   // the bridge grows
References and pointers

Pointers * and &

&x is the address of x. A pointer (int*) holds an address. *p follows the pointer to the variable it points at.

int* p = &bridge_length;
*p = 4;      // bridge_length is now 4
References and pointers

vector

A vector<T> keeps many values of type T in order. Fill it with {...}.

vector<string> stones = {"stone", "stone"};
vector<int> numbers = {3, 1, 2};
Vectors

Indexing: v[i]

v[0] is the first item, v[1] the second. The last one is v[v.size() - 1]. Going past the end crashes the program.

stones[0] = "stone";
cout << stones[1] << endl;
Vectors

.push_back() and .size()

v.push_back(x) adds x to the end. v.size() tells you how many items there are.

stones.push_back("stone");
cout << stones.size() << endl;
Vectors

{ } lists

Curly brackets with commas build a list of values, to fill a vector or a struct.

vector<Direction> route = {RIGHT, RIGHT, DOWN};
Step s = {RIGHT, 2};
Vectors

Comparing strings

Strings compare with == and !=, letter by letter. Capitals matter: "Left" isn't "left".

if (way == "left") {
    move(LEFT);
}
Strings and chars

char

A char is one character, in single quotes: 'R'. A string is a sequence of chars, and a range-for visits them one by one.

for (char c : "RRD") {
    if (c == 'R') {
        move(RIGHT);
    }
}
Strings and chars

stoi() and to_string()

stoi("3") turns text into an int. to_string(3) turns a number into text.

int steps = stoi(read_sign());
string text = "Steps: " + to_string(steps);
Strings and chars

.length() and .substr()

s.length() is how many characters a string has. s.substr(start, count) cuts out a piece.

string word = "garden";
cout << word.length() << endl;     // 6
cout << word.substr(0, 3) << endl; // gar
Strings and chars

struct

A struct makes a new type out of members. Build one with {...}, and reach members with a dot.

struct Step {
    Direction dir;
    int count;
};

Step s = {RIGHT, 2};
move(s.dir, s.count);
Structs and classes

class and objects

A class bundles data with the functions that use it. Each variable of the class is an object with its own data.

class Bridge {
public:
    int planks = 0;
};

Bridge b;
b.planks = 5;
Structs and classes

Methods

Functions inside a class are methods. Call them on an object with a dot. They can use the object's own members directly.

class Bridge {
public:
    int planks = 0;
    void add(int n) {
        planks += n;
    }
};

b.add(3);
Structs and classes

Constructors

A constructor has the class's name and no return type. It runs when an object is made, and sets it up.

class Walker {
public:
    Direction dir;
    Walker(Direction d) {
        dir = d;
    }
};

Walker w(RIGHT);
Structs and classes

public and private

public: members can be used by anyone. private: members only by the class's own methods. In a class everything is private until you say otherwise.

class Counter {
public:
    void add() { count++; }
private:
    int count = 0;
};
Structs and classes