SEC-S20W6 Practice cycles and Guess the number gamesteemCreated with Sketch.

in Ukraine on Steem2 months ago (edited)

For these five lessons, we have only scratched the surface of the world of programming. But it's enough to build any program's logic. I am talking about the conditional operator and loops.

In this sixth and final lesson of this mini-course, we will conduct a small practice on using loops, consolidating the knowledge we've gained during these sessions. And if I get the chance to continue the course, we will delve deeper into data types, arrays, and more.


image.png

Break & Continue

First, I will introduce you to two commands that allow you to control loops. Of course, you can do without them, just as you can manage with only one type of loop. But everything is created for convenience. That's why the break and continue operators were invented.

Philosophically speaking, these two operators break the cycle, the loop iteration. However, break completely interrupts the loop, ending the current iteration and the entire loop, while continue only interrupts the current iteration and continues executing the loop.

Remember the problem from the last lesson: Print numbers from 11 to 111: 11, 21, 31...101, 111 - but skip the number 51
You would have solved it like this, for example, without the then-unknown continue:

for(int i=11; i<=51; i++)
{
    if(i==51) i++;
    cout<<i<<", ";
}

or like this

for(int i=11; i<=51; i++)
{
    if(i!=51)
    {
        cout<<i<<", ";
    }
}

Now with з continue

for(int i=11; i<=51; i++)
{
    if(i==51)
    {
        continue;
    }
    cout<<i<<", ";
/*x*/
}

I marked with the comment /*x*/ the place where the execution of the continue operator jumps, or you can consider that the jump will go to the third section of the for loop operator, to i++.

for(int i=11; i<=51; i++)
{
    if(i==51)
    {
        break;
    }
    cout<<i<<", ";
}
/*x*/

If you replace break with continue, the jump will be outside the loop—where I placed /*x*/.

Colors

Programming often starts in console mode. A long time ago, computers worked in two modes: text and graphical. Now I want to show you how to decorate the output in this text-based, console, terminal mode. There is a thing called ESC-sequences.

These are special commands/characters whose "output" does not appear directly on the screen but affects the output: it sets the color of characters, changes their appearance to inverse, underlined, bold, etc. You can explore this on your own, but I will tell you about colors. Printing an ESC-sequence starts with a special character "\e" or "\0x1b" "\033" which is the same thing. After this code, control commands follow. For example, \033[0m cancels previously set attributes, returning to the default.

For example: print("\033[31mHello, World!\033[0m") // Prints "Hello, World!" in red.

#include <iostream>
using namespace std;
#define RESET   "\e[0m"    // Reset all attributes
#define BLACK   "\e[30m"   // Black
#define RED     "\e[31m"   // Red
#define GREEN   "\e[32m"   // Green
#define YELLOW  "\e[33m"   // Yellow
#define BLUE    "\e[34m"   // Blue
#define MAGENTA "\e[35m"   // Magenta
#define CYAN    "\e[36m"   // Cyan
#define WHITE   "\e[37m"   // White

int main()
{
    cout << RED << "This text is red!" << RESET << endl;
    cout << GREEN << "This text is green!" << RESET << endl;
    cout << BLUE << "This text is blue!" << RESET << endl;
    cout << YELLOW << "This text is yellow!" << RESET << endl;
    cout << MAGENTA << "This text is magenta!" << RESET << endl;
    cout << CYAN << "This text is cyan!" << RESET << endl;
    cout << WHITE << "This text is white!" << RESET << endl;
    return 0;
}


image.png

You can consider #define as a variable, but in fact, it’s a substitution, meaning the directive #define from to will replace the from text with the to text in the program code. However, the search is done by the whole word, not part of it, so in cout << "some string with from word";, there will be no substitution in such text. That is, the line of code before execution: cout << RED << "This text is red!" << RESET << endl; will be transformed into: cout << "\e[30mThis text is red!\e[0m" << endl; - which is clearer.

Random numbers - rand()

Another thing we need is random numbers. I’ll provide a brief description here, with more details outside of this lesson: In the stdlib.h library, there is a random number generator function rand(). To use it, include the library #include<stdlib.h> or its modern C++ version #include<cstdlib>. This function generates random numbers in a rather large range, but if we need to reduce the range, as in the next task, we should take the remainder of division. By combining arithmetic operations, you can get a random number from any range.

Guess the Number Game

Let me say right away, despite its simplicity, this game will have further continuation and more than once. The essence of the game is as follows: The computer thinks of a number within a certain range, for example, from 0 to 99. The player guesses it by suggesting their variants, to which the computer responds with “higher” or “lower” until the number is guessed correctly.

The first thing we need to take care of is two variables: one for storing the computer’s guessed number, komp, and another for the player's guesses, plr. komp = rand() % 100; - the computer picks a number between 00 and 99. The player needs to make at least one guess, so the loop will be do.. while();, meaning as long as the guess is incorrect, the guessing continues, where a correct guess is defined as komp == plr.

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    int komp = rand() % 100;
    int plr;                 

    std::cout << "The computer has chosen a number from 00 to 99.\nTry to guess it!\n";
    
    do
    {
        cout << "Enter your number: ";
        cin >> plr; 
        
        if (plr < komp)
        {
            cout << "Higher!\n"; 
        }
        else if (plr > komp)
        {
            cout << "Lower!\n"; 
        }
        else
        {
            cout << "Congratulations! You guessed the number\n"; 
        }
    } while (plr != komp); 

    return 0;
}

Earlier, I explained loops this way:
First, the task was to print a single star * on the screen.
This is easy to do:

int main()
{
    cout<<"*";
}

Next, it was necessary to print it a certain number of times,
for example, 11 stars. Initially, many write it like this:

int main()
{
    cout<<"***********";
}

But when I say, “Now print 23, 36, 71…,” it becomes clear that something’s not quite right.

int main()
{
    int count=23;
    for(int i=1; i<=count; i++)
        cout<<"*";
    cout<<"\n";
}

That is, we wrapped the previous task of printing stars in a loop.

Long ago, and this rule still applies today, if there is only one instruction in a loop or conditional operator, {} can be omitted.

Now, how to "draw" a square or rectangle using stars, for example, 4x11, i.e., four rows of 11 stars?

*********
*********
*********

Here, some people guess that by analogy, as we wrapped a star in a loop to get a row, now if we wrap the row in another loop, we get a rectangle.

int main()
{
    int k=11, rows=4;
    for(int r=1; r<=rows; r++)
        for(int c=1; c<=k; c++)
            cout<<"*";
    cout<<"\n";
}

At first, they suggest this to me)) - but this results in 44 stars, not a rectangle of 4x11

int main()
{
    int k=11, rows=4;
    for(int r=1; r<=rows; r++)
    {
        for(int c=1; c<=k; c++)
        {
            cout<<"*";
        }
        cout<<"\n";     
    }
    cout<<"\n";
}

You need to move to a new line after each row using cout << "\n";

Now, let's make a triangle:

*
**
***
****
*****

Here, the line break isn't as obvious, but you only need to change one symbol in the code to turn a rectangle into a triangle.

But triangles can come in four other types:

  2           3              4            5
*****       *****              *          *
****         ****             **         ***
***           ***            ***        *****
**             **           ****       ******* 
*               *          *****      *********

Homework

  1. (1 point) Experiment with colors—are there more than the ones we’ve used? How can you check?
  2. (2 points) Write your own version of the game "Guess the Number"—this time, creativity is more important than efficiency.
  3. (1 point) You don’t need to write any code for this question—just estimate how long it would take to guess a number if the range is from 0 to 1000 or from 0 to 10,000.
  4. (3 points) Write a two-player game. There are 30 balls on the table, and players take turns picking between 1 and 5 balls. The winner is the one who takes the last ball. There's no need to develop a winning strategy. Just write code to enforce the rules, make the players take turns, and announce the winner.
  5. (3 points) Follow the same path from a single star to a square, then transform the square into a triangle. Pick any triangle. Experienced students should choose one with a higher number, as it's more challenging. Triangle number 1 is for those who scored lower in previous lessons.

Participation Rules

You can publish your work in any language, in any community, or simply on your own blog—just provide a link to your work as a comment here.

To help me find, review, and grade your submissions quickly, leave the link in a comment under this text. In your post, use the hashtag #sec20w6sergeyk.

Encourage two or three of your friends to participate as well!

You can submit your work anytime between Monday, October 14, 2024, and Sunday, October 20, 2024.

All submissions will be evaluated by me, and I’ll select the five best works.


Ua

За ці п'ять уроків ми познайомилися лиш з краплиною зі світу програмування. Але цього достатньо щоб побудувати будь яку логіку програми. Я говорю про умовний оператор та про цикли.

На на шостому, останньому уроці, цього міні курсу ми з проведемо невеличку практику використання циклів, закріпимо наші отримані знання за ці проведені разом заняття. А якщо мені пощастить продовжити курс далі ми заглибимося в типи даних, познайомимося з масивами тощо.


image.png

Break & Continue

Спочатку я познайомлю вас з двома командами що дозволять керувати циклами. Звісно можна обійтися і без них, як і обходитися одним видом циклів. Але все створюється для зручності в користуванні. Тому й вигадали оператори break та continue.
Я скажу так, по філософськи - ці два оператори переривають цикл, ітерацію циклу. Але break перериває цикл повністю, і поточну ітерацію і завершує весь цикл в цілому а continue перериває лиш поточну ітерацію, і продовжує виконання циклу.
Згадайте задачу з минулого уроку: **Виведіть числа від 11 до 111: 11, 21,31....101, 111 - але число 51 не виводьте **
Вам слід було виконати це наприклад так, поки що без невідомого на той момент continue:

for(int i=11; i<=51; i++)
{
    if(i==51) i++;
    cout<<i<<", ";
}

або так

for(int i=11; i<=51; i++)
{
    if(i!=51)
    {
        cout<<i<<", ";
    }
}

А тепер з continue

for(int i=11; i<=51; i++)
{
    if(i==51)
    {
        continue;
    }
    cout<<i<<", ";
/*x*/
}

Я відмітив коментарем /*x*/ місце куди здійснить стрибок виконання оператора continue, або можна вважати що стрибок буде на третій розділ оператора циклу for на i++

for(int i=11; i<=51; i++)
{
    if(i==51)
    {
        break;
    }
    cout<<i<<", ";
}
/*x*/

Якщо ж замінити break на continue то стрибок буде за межі циклу - там де я розмістив /*x*/

Кольори

Програмування починають вивчати в консольному режимі, колись давно комп'ютери працювали в двох режимах текстовому та графічному.
Я ж хочу зараз показати як в цьому текстовому, консольному, термінальному режимі прикрасити вивід.
є така річ як ESC-послідовності

Це спеціальні команди/символи "вивід" яких не відображається на екрані безпосередньо, але впливає на вивід: встановлює колір символів, змінює їх вид на інверсний, підкреслений, напівжирний, та ще деякі інші. можете це дослідити самостійно. я ж хочу розповісти про кольори.
Друк ESC-послідовності починається зі спеціального символа "\e" або "\0x1b" "\033" що одне і теж.
Вслід за даним кодом йдуть команди керування.
наприклад \033[0m це відміна попередньо встановлених атрибутів, друк по замовчуванню.

наприклад
print("\033[31mHello, World!\033[0m") // Виведе червоний текст "Hello, World!"

#include <iostream>
using namespace std;
#define RESET   "\e[0m"    // Reset all attributes
#define BLACK   "\e[30m"   // Black
#define RED     "\e[31m"   // Red
#define GREEN   "\e[32m"   // Green
#define YELLOW  "\e[33m"   // Yellow
#define BLUE    "\e[34m"   // Blue
#define MAGENTA "\e[35m"   // Magenta
#define CYAN    "\e[36m"   // Cyan
#define WHITE   "\e[37m"   // White

int main()
{
    cout << RED << "This text is red!" << RESET << endl;
    cout << GREEN << "This text is green!" << RESET << endl;
    cout << BLUE << "This text is blue!" << RESET << endl;
    cout << YELLOW << "This text is yellow!" << RESET << endl;
    cout << MAGENTA << "This text is magenta!" << RESET << endl;
    cout << CYAN << "This text is cyan!" << RESET << endl;
    cout << WHITE << "This text is white!" << RESET << endl;
    return 0;
}


image.png

Можете вважати що #define це змінна, але насправді це заміна тобто від директиви #define from to в коді програми відбудеться заміна тексту from на текст to. Але пошук ведеться все слово цілком, а не його частини, і cout<<"some string with from word"; в такому тексті заміни не буде.
Тобто рядок коду перед виконанням
cout << RED << "This text is red!" << RESET << endl;
перетвориться на
cout << "\e[30mThis text is red!\e[0m" << endl; - що сприймається краще

Випадкові числа - rand()

Ще одну річ яка нам необхідна - це випадкові числа, детальніший опис винесу за межі цього заняття, наведу тут лиш коротко;
В бібліотеці stdlib.h є функція-генератор випадкових чисел rand() щоб її використати слід підключити бібліотеку #include<stdlib.h> або її осучаснений с++ варіант #include<cstdlib>
Ця функція генерує випадкове число в досить великому діапазоні, якщо ж нам треба зменшити цей діапазон, як наприклад буде у наступній задачі, слід взяти залишок від ділення. Комбінуючи арифметичні операції можна одержати випадкове число з будь якого діапазону.

Гра відгадай число

Відразу скажу ця гра, незважаючи на її простоту, матиме надалі продовження і не раз.
Суть її така: Комп'ютер загадує число в певному діапазоні, наприклад від 0 до 99 включно. Гравець же його відгадує. Називає свої варіанти, на що отримує від комп'ютера, відповіді - більше або менше. Так триває доти, доки число не буде відгадане

Перше про що нам слід подбати - це дві змінні, одна komp для збереження задуманого числа, інша - plr для ходів гравця що вгадує число.
komp=rand()%100; - комп'ютер загадує число від 00 до 99
гравець має хоч раз назвати число - тому цикл буде do.. while(); тобто поки не відгадає, а відгадуванням є співпадіння komp==plr

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    int komp = rand() % 100;
    int plr;                 

    std::cout << "The computer has chosen a number from 00 to 99.\nTry to guess it!\n";
    
    do
    {
        cout << "Enter your number: ";
        cin >> plr; 
        
        if (plr < komp)
        {
            cout << "Higher!\n"; 
        }
        else if (plr > komp)
        {
            cout << "Lower!\n"; 
        }
        else
        {
            cout << "Congratulations! You guessed the number\n"; 
        }
    } while (plr != komp); 

    return 0;
}

Раніше я пояснював цикли так:
Спочатку завдання вивести на екран один символ - зірочку *
це зробити просто:

int main()
{
    cout<<"*";
}

Далі її слід вивести певну кількість раз.
Наприклад 11 штук, спочатку багато хто пише так:

int main()
{
    cout<<"***********";
}

Але коли я скажу, а тепер 23, 36, 71,.... - стає зрозуміло що щось тут не те

int main()
{
    int count=23;
    for(int i=1; i<=count; i++)
        cout<<"*";
    cout<<"\n";
}

тобто ми попередню задачу - малювання зірочок - загорнули в цикл
Колись давно, та і зараз це ще правило діє - якщо в циклі чи умовному операторі лише одна інструкція {} можна не ставити.

А як тепер 'намалювати' отакими зірочками квадрат чи прямокутник, наприклад 4x11 тобто чотири рядки по 11 зірочок.

*********
*********
*********

Тут дехто здогадається що за аналогією як ми обгорнули зірочку в цикл і отримали рядок, то якщо тепер ми обгорнемо рядок у ще один цикл - одержимо прямокутник.

int main()
{
    int k=11, rows=4;
    for(int r=1; r<=rows; r++)
        for(int c=1; c<=k; c++)
            cout<<"*";
    cout<<"\n";
}

Спочатку мені пропонують так)) - але так виходить 44 зірочки на не прямокутник 4х11

int main()
{
    int k=11, rows=4;
    for(int r=1; r<=rows; r++)
    {
        for(int c=1; c<=k; c++)
        {
            cout<<"*";
        }
        cout<<"\n";     
    }
    cout<<"\n";
}

Слід після кожного рядка переходити на новий cout<<"\n";

А тепер трикутник

*
**
***
****
*****

Тут вже перехід не такий очевидний, але слід в коді змінити один символ - і прямокутник стане трикутником.

Але трикутників буває ще чотири види

  2           3              4            5
*****       *****              *          *
****         ****             **         ***
***           ***            ***        *****
**             **           ****       ******* 
*               *          *****      *********

Домашнє завдання

  1. (1 бал) Поекспериментуйте з кольорами, можливо їх більше? Як це перевірити?
  2. (2 бали) Напишіть свій варіант гри "Відгадай число" - на це раз має значення креативність, а не ефективність.
  3. (1 бал) Тут код писати не слід - як думаєте наскільки довго треба буде відгадувати число, якщо воно від 0 до 1000, або якщо від 0 до 10000?
  4. (3 бали ) Напишіть гру для двох гравців. **На столі лежить 30 кульок, гравці по черзі беруть від 1 до 5 кульок. Виграє той хто бере останню. ** Тут не слід продумувати стратегію виграшу. Слід лише покласти правила гри на код. Тобто змусити ходити гравців за правилами, та повідомити виграш.
  5. (3 бали) Повторіть шлях від зірочки до квадрата, та перетворіть квадрат на трикутник. Оберіть будь-який трикутник. Причому досвідченим слід обирати трикутник з більшим номером, він складніший. А трикутник з номером 1 для тих то отримував на минулих уроках менші бали.

Правила проведення

Публікувати можна на будь-якій мові, в будь якій спільноті чи просто у власному блозі, посилання на вашу роботу додайте сюди коментарем

Щоб я швидко знайшов, перевірив та оцінив ваші роботи залиште посилання в коментарі під цим текстом а в роботі поставите тег #sec20w6sergeyk

Порекомендуйте прийняти участь своїм двом-трьом друзям.

Роботи слід опублікувати з Monday 14 Oct 24 to Sunday 20 Oct 24

Всі Ваші роботи будуть мною оцінені та відібрані п'ять кращих робіт

I will submit the English version a little later