Number Guessing Game
Sections
- The Code
- Variable and Data Type
- Primitive and non-primitive
- Int Families
- Float Familes
- Syntax
- Integer
- Boolean
- Negating
- Character
- Literals
- Comparison
- Equality and Inequality
- Greater or Lesser
- Arithmetic
- Common arithmetic
- Modulus
- If Statement
- If. Else If, Else
- While Loop
- Second read
- std::srand(std::time(0));
- \n
- auto result = std::scan<int>(std::stdin, "{}");
- auto
- std::scan<int>
- result->value();
- std::println("Congratulations! You guessed it in {} attempts!", attempts);
The Code§
#include <print> // For std::print and std::println
#include <scan> // For std::scan
#include <cstdlib> // For std::rand and std::srand
#include <ctime> // For std::time
int main()
{
// Seed the randomizer using the current time
std::srand(std::time(0));
// Pick a secret number between 1 and 100
int secretNumber = std::rand() % 100 + 1;
int userGuess = 0;
int attempts = 0;
std::println("Welcome to the Number Guessing Game!");
std::println("I have chosen a number between 1 and 100.\n");
while (userGuess != secretNumber)
{
std::print("Enter your guess: ");
auto result = std::scan<int>(std::stdin, "{}");
userGuess = result->value();
attempts = attempts + 1;
if (userGuess > secretNumber)
{
std::println("Too high! Try again.\n");
}
else if (userGuess < secretNumber)
{
std::println("Too low! Try again.\n");
}
else
{
std::println("Congratulations! You guessed it in {} attempts!", attempts);
}
}
return 0;
}
Here is the refactored code. I added layout variables (padTop, padBottom, lineH) at the top. The script now calculates the exact pixel height required to fit your lines array, applies it to the canvas's CSS style, and then scales the internal buffer for high-DPI.
If you add 10 more lines to the array, the canvas will automatically grow to fit them perfectly.
Variable and Data Type§
literally the name, a variable is a value that is variable, you can change it, and store it somewhere. This is the most important concept in programming, having something to manipulate.
Primitive and non-primitive§
Non-primitive types are by definition built out of primitive types. If you type out a sentence, the sentence is a non-primitive that is built out of individual words. Individual words are still non-primitive because it is built out of individuals characters. But characters are the primitive types because the can't be split into smaller types further. The only primitive types are
intfamilies,floatfamilies.char,unsgined charboolThe rest are non-primitive ( there are infinite amout of them because the language allows you to create one yourselfs ) And expanding out both families,
Int Families§
int indicate integers We have
shortunsigned shortintunsigned intlongunsinged longlong longunsigned long long
We have different types of integer here merely to save memories, because for example short only have 2 bytes of memory while long will have 8 bytes of memory, pick which to use depends on your data ranges, because smaller memory can only store smaller values.
And unsigned means the value cannot be negative, we will see later how this impact saving memories while being more declarative about the data.
Float Familes§
Float means the opposite of integers - having decimal points. Unlike int familes, float cannot be unsigned due to technical issues which we will learn later, but the list is
-
float -
doublefloathaving 4 bytes, anddoublehaving8. This times rather than picking which to use by range, pick according to percision of what you need.floathaving less byte are less percise on the decimal arithmetic thandouble.
Other Languages
If you learn python or javascript, there is no such mess about data types, numerics are numerics. But again, this is the culture of this language, to be as low level as possible for us to percisly manipulate memory.
Syntax§
type name; // decalration
type name = value // initiallization
name = value; // assignement
we have seen similar syntax when we are introducing functions, where type is the data type, and names, are all arbitrary names that you can freely changes. This will becomes clearer later on
Note that this is a programming language, not mathematics. The = sign here doesn't indicate equallity, but rather it indicate assingements of values, or setting values.
Integer§
a primitive type in cpp used to store a numerical integer. The syntax for declaration, initialization or assignment is
int a; // this is declaration
int b = 199; // this is initialization to 199
int c = -200; // this is initialization to -200
a = 5000; // this is assingemnt of a to 5000
and here we have numerical literals like 199, -200, 5000, we will explain what literals means later, just know that you can use it literally to means its value.
reminder
a = 199 is setting the value of a to 199, not stating the equality of a is 199.
Boolean§
a primitive type in cpp used to indicate true or false. The syntax for declaration, initialization or assignment is
bool a; // this is declaration
bool b = true; // this is initialization to true
bool c = false; // this is initialization to false
a = false; // this is assingemnt of a to false
and here we have true and false as literals here, you can use it literally to means true or false value.
reminder again
a = false is setting the value of a to false, not stating the equality of a is false.
Negating§
bool a = true;
bool b = false;
bool c = !a; // c is now assigned to false beacuse !a reads as not a, and not a is false
bool d = !b; // same goes here, now d is true, because the opposite of b ( false ) is true,
Character§
a single character, for example A, or *, or q
char a; // this is declaration
char b = 'A'; // this is initialization to A
char c = '*'; // this is initialization to *
a = 'q'; // this is assingemnt of a to 'q'
Literals§
a syntax for directly indicating a value with its type. Thus
- short doesn't have a literals
- integer have no suffix:
13414,-234,0 - long have l suffix:
2341234425l,0l - float have f suffix:
3.1415f,0.f,0.0f - double have no suffix:
132.356,1234.1234 - long long have ll suffix:
134123452443ll - any unsigned will have u suffix:
234uisunsigned int,134134234ulisunsigned long - char are with single quote:
'c','h','a','r'
Comparison§
Equality and Inequality§
a == b or a == true or c == 100 are all examples of equality comparison, technically it should be type == the same type. And this is an expression that will return a boolean value, for exmple
a == b will evaluate to true if a really equals to b, and vice versa. So
int a = 10;
int b = 20;
a == b; // this will be evaluated to false
b = 10;
a == b; // this will be evaluated to true
For inequality, the same goes as long as they are the same type
float a = 100.1232;
float pi = 3.14159;
a != pi; // this will be evaluated to false;
Greater or Lesser§
The same goes to other comparison as long as they are the same type
int a = 10;
int b = 20;
int c = 20;
float d = 10.5;
float e = 1000.123457234;
a == b; // false
a == c; // false
b == c; // true
a < b; // true, this is comparing if a is less than b
a <= c; // true, this is comparing if a is less than OR equals to c
b >= c; // true, this is comparing if b is greater than OR euqls to c
d > e; // false, this is comparing if d is greater than e
So technically, you can do this
int a = 10;
int b = 20;
bool result = a < b; // now result is true
Arithmetic§
Common arithmetic§
int a = 3;
int b = 4;
int c = a + b; // 3 + 4 = 7; this is addition
int d = c - 1; // 5 - 1 = 6; this is subtraction
int e = c * d; // 7 * 6 = 42; this is multiplication
int f = e / b; // 42 / 4 = 10; this is division without decimal point, notice this always round down to closest integer because we are working on integer type
if we have instead
float b = 4.f;
float e = 42.f;
float f = e / b; 42 / 4 = 10.5; this is division with decimal point
Modulus§
Another arithmetic I will state explicitly is the modulus, because it is not a common operation for anyone outside programming or mathematics.
But, by definition a modulus is the remainder from a division. For exmple
- 4 / 2 = 2 with no remainder because 4 divides into 2 cleanly
- 5 / 2 = 2 with remainder 1, because 5 = 2 + 2 + 1 cannot be divided into 2 cleanly
- 100 / 6 = 16 with remainder 4. because 100 = 6 + 6 + ... (16 times) + 4, cannot be divided into 6 cleanly
Thus, syntax wise
4 % 2 // 0
5 % 2 // 1
100 % 6 // 4
To see the most common use of the modulus, le'ts examine x % 4 with arbitrary x.
| x | 0 | 1 | 2 |
| x % 4 | 0 | 1 | 2 |
See? When we mod 4, the results will be
- in the range of 0 to 4 ( exclusive )
- repeats in period of 4
Thus, this expalain the code
int secretNumber = std::rand() % 100 + 1;
// std::rand() is a function that gives us a random integer,
// % 100 force the range of the result to be 0 to 100 ( exclusive )
// + 1 force the range of the result to be 1 to 100 ( inclusive )
-
Control Flow§
control flow is a statement that specifies where the next line of code should be read instead of going top-down.
If Statement§
"If today rains then you should bring your umbrella", and then "Go buy some fruits regardless if it rains", imagine this is what you want to tell your robot. Then to code looks like this
bool isRaining = true;
if (isRaining)
{
bringUmbrella();
}
buyFruits();
Technically, the if practically is defined as such
if (boolean)
{
doSomethingIfBooleanIsTrue();
}
The doSomethingIfBooleanIsTrue() will only execute if the boolean is true, but the code outside the if statement will execute regardless.
If. Else If, Else§
Excatly read as plain english
If It rains, take the umbrella, or else -> if sun bright, take sunglass, or else -> take cap
if (isRaining)
{
takeUmbrella();
}
else if (isBrightSun)
{
takeSunglass();
}
else
{
takeCap();
}
This is just an example, but one note is, takeUmbrella, takeSunglass, takeCap, only one of it will be run depending on the situation.
While Loop§
Tell your robot that while you are not asleep, keep counting sheep until you sleep ( a loop ). And then keep quiet until you wake up ( a loop ) to be ready to do something else. Translate into code
bool sleeping = false;
int sheep = 0;
while (!sleeping)
{
sheep = sheep + 1; // counting sheep
std::println(sheep);
sleeping = checkIfAsleep(); // set sleeping to true if you are actaully sleeping which the code have to check for each loop.
}
// now you are asleep because sheep counting works.
// well technically because the only way for the code to continue and to proceed outside the while loop above is for !sleeping to be false, this means sleeping now is true.
while (sleeping)
{
// do nothing keep quite,
sleeping = checkIfAsleep();
}
// now you are awake
doSomethingElse();
Second read§
Now go read the code above again, and then copy paste, run it in your own cpp setup. Then, you should be able to understand 95% of the code. The 5% will be below and optional since either
- it is already obvious from the interaction and output behaviour of the code
- it is uncommon to use
std::srand(std::time(0));§
This is just a srand function inputing a time function with input a 0. And its whole purpose is to seed the random number generator. And seeding is not a language concept thus will be left for later.
\n§
This is a special character indicating new line.
auto result = std::scan<int>(std::stdin, "{}");§
auto§
This is not a data type, but it means, let the compiler determine its type without us explicitly stating out. The reason depends, but most commonly we will use auto when
- The type is not that important information and information is enough for the compiler to determine the type
- The type name is too long. For exmaple
std::chrono::ambiguous_local_timeis a type but so long.
std::scan<int>§
We have seen std::print and std::println, this is outputing to the concole as you should know by now, scan is the directly opposite, it is taking input from the user, and std::stdin is standard input method, besically means the console.
result->value();§
we are taking calling the value() function that is inside the result variable by using the arrow ->, this will be explained with more detail later. And thus we can know here result is a non-primitive type, because it is made up of functions and other variables.
std::println("Congratulations! You guessed it in {} attempts!", attempts);§
The {} in there is basically a placeholder for the attempts, thus if attemps is 4, the output will read
"Congratulations! You guessed it in 4 attempts!"
The same {} meaning is used in the scan function, bassically means that the entire input is the placeholer ( is the input we want )
Discussion
No comments yet — yours could open the discussion.