Skuullkid
Skuullkid

Reputation: 1

for loop with counter not working after adding input

I have this counter programm based on object oriented programming in C# and the counter has an Increment Method which counts up so like it goes from 0..1...2.. to 30.

The for loop was working perfectly fine but then I decided to add a class with two Methods that either count up in odd or even steps which also works fine. The only problem is that after changing the main class now it doesn't work in a loop anymore until its on 30, so I have to enter every step individually.

This is my main code (I'm pretty sure the problem is due to the Console.ReadLine and input in general but I don't know what exactly is the issue)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Counter
{
    class Program
    {
        static void Main(string[] args)
        {
            char confirm;
            int input;

            do
            {
                //int inNum;
                Console.Clear();
                ModusCounter b = new ModusCounter(0, 30);

                for (; ; )
                {
                    b.Display(19, 7);
                    Console.Write("do you want (1)odd // (2) even // (0)standard ? ");
                    
                    input = Convert.ToInt32(Console.ReadLine());
                    if (input == 1)
                    {
                        b.OddCount();
                    }
                    else if (input == 2)
                    {
                        b.EvenCount();
                    }
                    else
                        b.Increment();

                    System.Threading.Thread.Sleep(300);
                    if (Console.KeyAvailable) break;
                }

               //b.Increment();
                b.Display(19, 7);

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("do you want to restart? (J // N) ");
                confirm = Convert.ToChar(Console.ReadLine());
            }
            while (confirm == 'J');

            Console.ReadLine();
        }
    }
}

ModusCounter:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Counter
{
    public class ModusCounter:CCounter
    {
        private int wholenum;

        public int Wholenum
        {
            get => wholenum;
            set
            {
                wholenum = value;
            }
        }

        public ModusCounter(int start, int limit) : base(start, limit)
        { }

        public void EvenCount() //2
        {
            Wholenum = 2;
            Level += Wholenum;
            if (Level % 2 == 0)
            {
                Level += Wholenum - 2; 
            }
            else
            {
                Level += Wholenum -1;
            }
            if (Level > Limit)
                Level = Start;
        }

        public void OddCount() //1
        {
            Wholenum = 1;
            Level += Wholenum;
            if (Level % 2 == 0)
            {
                Level += Wholenum;
            }
            else
            {
                Level += Wholenum + 1;
            }
            if (Level > Limit)
            Level = Start;
        }
    }
}

base class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Counter
{
    public class CCounter
    {

        private int start;
        private int limit;
        private int level;

        public int Start
        {
            get => start;
            protected set
            {
                start = value;
            }
        }

        public int Limit
        {
            get => limit;
            protected set
            {
                limit = value;
            }
        }

        public int Level
        {
            get => level;
            protected set
            {
                if (value < Start)
                    level = Start;
                else if (value > Limit)
                    Level = Limit;
                else
                    level = value;
            }
        }

        public CCounter(int start_, int limit_)
        {
            Start = start_;
            Limit = limit_;
            Level = Start;
        }

        public void Increment()
        {
            int level = Level + 1;
            if (level > Limit9
                Level = Start;
            else
                Level = level;
        }

        public void Display(int x_, int y_)
        {
            Console.SetCursorPosition(x_, y_);
            Console.Write(Level.ToString("00"));
        }
    }
}

Upvotes: 0

Views: 329

Answers (1)

DRapp
DRapp

Reputation: 48139

First, welcome to S/O. Hope you get good info out here during your obvious learning curve into development. A couple things could get simplified, but that will come with learning, so I wont pounce, but you will see as your skills improve over time.

First, your for(;;) loop. That is in-itself causing an infinite loop. The console read line to get input is always waiting for the next option from your prompt asking for odd, even or standard, so it keeps cycling through.

I dont think your Console.KeyAvailable is ever really getting triggered to break out of the for loop to get you to the next prompt of allowing the user to retry J/N option. You have the console.ReadLine which reads the entire buffer until you hit the enter key. By that time, you are incrementing your cycle, displaying the results and giving a 300 millisecond delay from your Thread.Sleep(300) call, of which you are probably not clicking a key in that short span to break the loop. Now, if you changed the Thread.Sleep(2000) you would be giving the user 2 seconds (1 second = 1000 milliseconds) AFTER the display to press any key to break the loop.

Next item/question I have for you. Your incrementing you appear to be ok with that functionality, but what / why do you want to break. When it gets to the limit? If so, then test for that after the increment process has completed such as (before the Thread.Sleep call)

            if (b.Level >= b.Limit)
                break;

Getting to your CCounter class and looking at its Increment method. You have a check that if the local "level" variable is greater than the limit to set the level = START value. Was that intended, or not. Also, by using a new int value by the same name as a property on your class (int level vs property level) is not a good practice and can add confusion.

public void Increment()
{
    int level = Level + 1;
    if (level > Limit)
        Level = Start;
    else
        Level = level;
}

It appears you are trying to use a local temporary variable but is not necessary. It could just as easily be done with slight alteration as I have below.

public void Increment()
{
    if (Level +1 > Limit)
        Level = Start;
    else
        Level = Level +1;
}

Because I am not ASSIGNING a value to the "Level" public property, it in essence is doing the +1 before its COMPARISON to the LIMIT property. Only in the ELSE condition do I assign.

Also, a shortcut on adding to a variable or subtracting could be seen as

Level++

or

Level--

Hopefully this helps add SOME clarity to what you are looking to get resolution to and can get you further in your development.

Upvotes: 1

Related Questions