Introduction recap

D is different from any other programming language we've worked with so far. It requires more tools to make it work, but it also gives us much more flexibility and power!

Remember the program we made? You can run it on anyone's computer. Just copy the .exe file to another computer, and run it, and it should do exactly the same thing.

In the class, we learned a bit about "types", and how in D, you must declare the type of a variable, and it can only hold values of that type. I realize that my explanations of this were kind of bad, so I came up with a couple more ways to think about this, they may help. If you still have issues with the concept of types, you can ask on discord, but for the most part, you will get the hang of it pretty quickly.

Analogy 1: imagine a JavaScript type is like a giant box. It can hold anything. It can hold a tiny marble, or a giant car. But it's not very efficient or useful to use a giant box to hold a marble. With D, the box can be the size of the thing you are going to store. It can be a small box for a marble, or a large sturdy box for a car. We might put a label on the box saying "Marble". The label is like the type, that says what it can hold.

When the compiler knows what type something is, it doesn't have to look at the item to figure out what kind of thing is inside. This allows the computer to be much more efficent when executing machine code. It also prevents you from doing things that you most likely didn't want to do. For example, you wouldn't want to drive around on a marble.

Analogy 2: You wouldn't put a shoe on a coat hanger, right? A coat hanger is for coats (or shirts). You also wouldn't put a coat into a shoebox. This is simlar to D, where you would declare a variable can only hold coats, and not shoes. You can make a separate variable that holds shoes, and it wouldn't hold coats.

Just to go over the types we talked about:

Remember that in D a semicolon marks the end of a statement. In the other languages we have learned, a statement ends at the end of a line. In D, you can actually write more than one statement on a line (even though most code does not do this). The reasoning for the semicolon is complicated, but it's just something you need to learn for D.

We also talked about loops and branching. If you remember, a branch is an "if" statement. It looks like:

if(guess == 0) {
   break;
}

I also went over a while loop. A while loop keeps executing the statements inside the loop body until the condition inside the parentheses is true. Here is an example from the code I wrote in class:

while(i < 10)
{
   writeln("i is ", i);
   i = i+1;
}

Homework assignment - Make a better number game

Here is the code that I wrote for the end of the class:

import std.stdio;
import std.random; // this imports a module that allows using random numbers

void main()
{
    int maxNumber; // this will be the maximum number we get from the user.
    writeln("Give me the maximum number"); // prompt the user for the number
    readf("%s\n", maxNumber); // read the number.
    int secretNumber = uniform(1, maxNumber); // use a random number in the range 1 - maxNumber
    int guess = 0; // the guess starts at 0
    while(true) // until we break...
    {
        writeln("Guess the number (0 to quit)"); // prompt for a guess
        readf("%s\n", guess); // read the guess
        if(guess == 0) // if the user entered 0, they wanted to quit
        {
            break; // break from the loop
        }
        if(guess == secretNumber) // if the user guessed right!
        {
            break; // break from the loop
        }
        writeln("No, that's not the number"); // tell the user their guess was wrong.
    } // if we get here, it will oop again (because the condition for the loop is always true)

    if(guess == secretNumber) // if the user guessed right
    {
        writeln("You got it!"); // print a success message
    }
    else // otherwise
    {
        writeln("My number was ", secretNumber); // they quit with 0. Tell the secret
    }
}

I want the game to tell the person if they are getting warmer or colder. They are getting warm if the guess is close to the number, and cold if the guess is far away.

To do this, let's DELETE the code that asks for the maxNumber, and just use 100000. If the user can tell how close they are, then they can make better guesses. See if you can figure out how to do this on your own.

And then, I want to define some ranges to tell the user how warm or cold they are:

So how do we test how far away a guess is from the real number? You can use the abs() function, which stands for "absolute value". In math, absolute value is the positive equivalent if the number is negative. The absolute value of 3 is 3, and the absolute value of -3 is 3.

For the abs() function, we need to import another module, add this line to the top:

import std.math;

Follow this example, do it inside your loop:

// writeln("No, that's not the number"); // comment this out, we are going to change the messages
if(abs(guess - secretNumber) > 10000)
{
   writeln("frigid");
}
else if(abs(guess - secretNumber) > 1000)
{
   ...

Note we aren't checking that the difference is less than or equal to 10000 in the second if statement. That's because if it was greater than 10000, the first message would be printed! Writing chained if and else if statements like this is very useful for doing different things for different ranges of a value.

Get creative with your messages! The more interactive your application feels, the better the users will like it. Once you are done, you can post your code into the discord snippets channel, and we can all see your result and even try it out!

©2019-2020 Steven Schveighoffer