/*---
    CS 111 - Week 13 Lecture 2 - 2025-11-20

    compile using:
        g++ 111lect13-2.cpp -o 111lect13-2
    run using:
        ./111lect13-2

    by: Sharon Tuttle
    last modified: 2025-11-20
---*/

#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>
using namespace std;

/*=== COPIED from 111lect13-1.cpp (where its tests were run) ===*/

/*===
    signature: cheer: int -> int
    purpose: expects the number of HIPs in a cheer
        desired, has the SIDE-EFFECT of printing
        to the screen that many HIPs, each on their
        own line, followed by HOORAY!, and returns
        the number of HIPs actually printed
    tests:
        cheer(3) == 3
        but also has the side-effect of printing to the screen:
HIP
HIP
HIP
HOORAY!

        cheer(5) == 5
        but also has the side-effect of printing to the screen:
HIP
HIP
HIP
HIP
HIP
HOORAY!

        cheer(0) == 0
        but also has the side-effect of printing to the screen:
HOORAY!

        cheer(-13) == 0
        but also has the side-effect of printing to the screen:
HOORAY!

===*/

int cheer(int num_hips)
{
    int count = 0;

    // print HIP to the screen num_hips times

    while (count < num_hips)
    {
        cout << "HIP" << endl;
        count = count + 1;
    }

    // ...THEN print HOORAY!

    cout << "HOORAY!" << endl;
    return count;
}

/*=== end of part COPIED from 111lect13-1.cpp ===*/

/*===
    signature: sum_ints: int -> int
    purpose: expects a natural number, and returns
       the sum of the natural numbers from 1 to that
       natural number, inclusive.
    tests:
        sum_ints(3) == 1+2+3
        sum_ints(7) == 1+2+3+4+5+6+7
===*/

int sum_ints(int up_to_val)
{
    int sum_so_far = 0;
    int next_num = 1;

    // compute the sum from 1 to up_to_val
    
    while (next_num <= up_to_val)
    {
        sum_so_far = sum_so_far + next_num;
        next_num = next_num + 1;
    }

    return sum_so_far;
}

/*===
    signature: vertical: string -> int
    purpose: expects any string,
        has the SIDE EFFECT of printing its characters
        "vertically" to the screen, 1 per line,
        and returns the number of characters printed
    tests:
        vertical("moo") == 3
        and prints to the screen:
m
o
o
        vertical("oink") == 4
        and prints to the screen:
o
i
n
k
===*/

int vertical(string desired_msg)
{
    int pos = 0;
    int msg_len = desired_msg.length();

    // print each character in desired_msg on its own line
    
    while (pos < msg_len)
    {
        cout << desired_msg.at(pos) << endl;
        pos = pos + 1;
    }

    return msg_len;
}

/*---
    demonstrate a loop with a non-numeric loop control
        variable, (in this case, a question-controlled loop),
    and then test the functions above
---*/

int main()
{
    cout << boolalpha;

    // to demo that a loop control variable is not
    //    always a number...!:
    
    // I want to allow the user to get as many cheers
    //    as they would like, using their answers
    //    to control a while statement:

    int hip_quant;
    char user_answer;

    cout << "Do you want a cheer?" << endl
         << "   Enter y for yes, any other character for no:"
         << endl;
    cin >> user_answer;

    // while the user still wants cheers, ask them how many
    //     hips and give them those cheers
    
    while (user_answer == 'y')
    {
        cout << "Enter desired number of hips: ";
        cin >> hip_quant;

        cheer(hip_quant);

        // BEFORE end loop, better make sure
        //    there is SOME way for its bool expression
        //    to become false!

        cout << "Do you want another cheer? " << endl
             << "  Enter y for yes, any other character for no:"
             << endl;
        cin >> user_answer;
    }

    cout << "*** Testing: sum_ints ***" << endl;

    cout << (sum_ints(3) == 1+2+3) << endl;
    cout << (sum_ints(7) == 1+2+3+4+5+6+7) << endl;

    cout << "*** Testing: vertical ***" << endl;

    cout << "Should see moo printed vertically, then true: "
         << endl;
    cout << (vertical("moo") == 3) << endl;

    cout << "Should see oink printed vertically, then true: "
         << endl;
    cout << (vertical("oink") == 4) << endl;

    return EXIT_SUCCESS;
}