• Forum
  • Lounge
  • “Wheel Of Fortune” game CHALLENGE!!!

 
“Wheel Of Fortune” game CHALLENGE!!!1!

Pages: 123
With all the hangman games lately, I thought I’d have some fun.

Your challenge, should you choose to accept it, is to produce a nice little word/phrase guessing game.

[edit] One of the goals here is — Make it Pretty!
Standard run-of-the-mill console apps are to be discouraged!

Requirements:

  • Console / Terminal ONLY!

  • Make it work on Windows AND Linux / Mac.

  • Minimize the number of files please. A single game.cpp is ideal.

  • If it is bigger than three or four posts, host it somewhere reasonable (like
    https://github.com)

  • Third-party dependencies are okay IFF they are a simple download and include.
    No one wants to configure and compile <insert random library here>.
    This includes Boost Libraries (https://www.boost.org)!

Strongly preferred:

  • No hanging people, please. Hangman has roots in the lynching of Black people by
    racist a**holes in the American past. (The idea of the stool thing in Europe is
    made-up apologetics.) Plus, I just don’t like the violence.

    My version uses an apple tree.

  • A culled list of the first twenty seasons of Wheel of Fortune puzzles can be
    obtained from https://github.com/Duthomhas/WOF1-20

    It’s a largish file. It’s okay to tell people they need to download it from my git.

  • C++17 (see comments below)

I will include a little primer in the next post of how to initialize your console for virtual terminal sequences on both Windows and Linux. It's a messy ride, but is easy enough to make things pretty.

Today is 21 August 2022.
I’ll post my game in a week or so.
Last edited on
All right, I will assume y’all want the following powers:

  • Windows Console
  • Windows Terminal
  • Linux Console without requiring X

  • UTF-8 I/O
  • 24-bit color
  • query terminal size
  • clear_screen, gotoxy, title, is_key_pressed, etc

  • NO DEPENDENCIES

I am leaving out quite a lot:

  • abnormal program termination cleanup
  • guaranteed attachment to a terminal (Linux)
  • error checking and handling of various corner cases
  • Linux event subsystem input
  • mouse input
  • terminal window resize events
  • query cursor position
  • event dispatch design
  • any reasonable C++ encapsulation (such as a class!) for our singleton

For brevity (post size) I will not explain everything in detail. Ask questions below and I’ll answer them. A lot of what follows is pretty ugly.

Ready?

    console.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#ifndef SIMPLE_CONSOLE_HPP
#define SIMPLE_CONSOLE_HPP

#include <sstream>
#include <string>

// First, a couple of useful helpers

template <typename T = std::string, typename...Args>
T build_string( Args...args )
{
  std::ostringstream oss;
  (oss << ... << args);
  return T( oss.str() );
}

template <typename E = std::runtime_error, typename...Args>
E error( Args...args ) { return build_string <E> ( args... ); }

// Here’s our 24-bit color

struct rgb
{
  typedef unsigned char byte;

  byte red, green, blue;

  rgb( byte r = 0, byte g = 0, byte b = 0 )
  : red{r}, green{g}, blue{b} { }
};

// basic queries (which do NOT auto-magically invoke our “raw” console mode)

struct width_height { int width, height; };
width_height get_terminal_size();

bool is_key_pressed( int timeout_ms ); // (-1) for INFINITY, 0 for no wait
void flush_input();

// and all basic output (which DO auto-magically start our fancy-pants console mode)

template <typename...Args>
void output( Args...args )
{
  void _output( const std::string & );
  _output( build_string( args... ) );
}

void title( const std::string & );
void clear_screen();
void gotoxy( int x, int y ); // home == 0,0
void cursor( bool );
void colors( const rgb & fg, const rgb & bg );
void fcolor( const rgb & c );
void bcolor( const rgb & c );

#endif 

    console.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <ciso646>
#include <cstdio>
#include "console.hpp"

bool _is_initialized = false;
#define Q(b) if (_is_initialized == b) return;  _is_initialized = b

// All Windows-specifc code begins with the following incantation:

#ifdef _WIN32

  #include <windows.h>

  #define hstdin  GetStdHandle( STD_INPUT_HANDLE )
  #define hstdout GetStdHandle( STD_OUTPUT_HANDLE )

  static DWORD input_mode,     output_mode;
  static UINT  input_codepage, output_codepage;

  #define CSBI \
    CONSOLE_SCREEN_BUFFER_INFO csbi; \
    GetConsoleScreenBufferInfo( hstdout, &csbi );

  width_height get_terminal_size()
  {
    CSBI return {
      csbi.srWindow.Right  - csbi.srWindow.Left + 1,
      csbi.srWindow.Bottom - csbi.srWindow.Top  + 1 };
  }

  bool is_key_pressed( int timeout_ms )
  {
    return WaitForSingleObject( hstdin, (DWORD)timeout_ms ) == WAIT_OBJECT_0;
  }

  void flush_input() { FlushConsoleInputBuffer( hstdin ); }

  // On Windows, the only One True Way™ to print Unicode output is using WriteConsoleW().
  // This works for ANY code page on both Windows Console and Windows Terminal.

  void _write( const std::string & s )
  {
    DWORD n;
    std::wstring w( s.size(), 0 );  // Convert to UTF-16
    w.resize( MultiByteToWideChar( CP_UTF8, 0, (char *)s.c_str(), (int)s.size(), (wchar_t *)w.c_str(), (int)w.size() ) );
    WriteConsoleW( hstdout, (wchar_t *)w.c_str(), (DWORD)w.size(), &n, NULL );
  }

  void _finalize()
  {
    Q(false);
    _write( "\033[?1049l" "\033[?25h" );
    SetConsoleCP( input_codepage );
    SetConsoleOutputCP( output_codepage );
    SetConsoleMode( hstdin,  input_mode );
    SetConsoleMode( hstdout, output_mode );
  }

  void _initialize()
  {
    Q(true);
    GetConsoleMode( hstdin,  &input_mode );
    GetConsoleMode( hstdout, &output_mode );
    SetConsoleMode( hstdin,  ENABLE_VIRTUAL_TERMINAL_INPUT | ENABLE_EXTENDED_FLAGS );
    SetConsoleMode( hstdout, ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT );
    input_codepage  = GetConsoleCP();
    output_codepage = GetConsoleOutputCP();
    SetConsoleCP( 65001 );
    SetConsoleOutputCP( 65001 );
    setlocale( LC_ALL, ".UTF-8" );
    _write( "\033[?1049h" "\033[?25l" );
    atexit( &_finalize );
  }

// If it ain’t Windows, it must be Linux / OS X / etc

#else 

  #include <sys/types.h>
  #include <sys/ioctl.h>
  #include <poll.h>
  #include <termios.h>
  #include <unistd.h>

  static int _esc_delay = 100;
  static struct termios _initial_settings;

  width_height get_terminal_size()
  {
    struct winsize ws;
    ioctl( 0, TIOCGWINSZ, &ws );
    return { ws.ws_col, ws.ws_row };
  }

  bool is_key_pressed( int timeout_ms )
  {
    struct pollfd pls[ 1 ];
    pls[ 0 ].fd     = STDIN_FILENO;
    pls[ 0 ].events = POLLIN | POLLPRI;
    return poll( pls, 1, timeout_ms ) > 0;
  }

  void flush_input() { while (is_key_pressed( 0 )) getchar(); }

  // The Linux console has been UTF-8 capable for ages now.
  // Alas, we must still convert individual code point values to UTF-8 before output.

  void _write( const std::string & s ) { printf( "%s", s.c_str() ); fflush( stdout ); }

  void _finalize()
  {
    Q(false);
    _write( "\033[?1049l" "\033[?25h" );
    tcsetattr( STDIN_FILENO, TCSANOW, &_initial_settings );
  }

  void _initialize()
  {
    Q(true);
    const char * eds = getenv( "ESCDELAY" );
    if (eds) _esc_delay = atoi( eds );
    _esc_delay = (_esc_delay < 50) ? 50 : _esc_delay;

    auto e = error( "Could not initialize terminal" );

    if (tcgetattr( STDIN_FILENO, &_initial_settings ) < 0) throw e;
    auto settings = _initial_settings;
    settings.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | ICRNL | ISTRIP | INLCR | IXON );
    settings.c_oflag &= ~(OPOST);
    settings.c_cflag |=  (CS8);
    settings.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN | TOSTOP);
    settings.c_cc[VMIN] = 0;
    settings.c_cc[VTIME] = 0;

    if (tcsetattr( STDIN_FILENO, TCSANOW, &settings ) < 0) throw e;

    setlocale( LC_ALL, ".UTF-8" );
    _write( "\033[?1049h" "\033[?25l" );
    atexit( &_finalize );
  }

#endif

void _output( const std::string & s ) { _initialize(); _write( s ); }

template <typename...Args> void OSC( Args...args ) { output( "\033]", args..., "\033\\" ); }
template <typename...Args> void CSI( Args...args ) { output( "\033[", args... ); }

void title( const std::string & s ) { OSC( "0;", s ); }
void clear_screen()                 { CSI( "2J" ); }
void gotoxy( int x, int y )         { CSI( y+1, ";", x+1, "H" ); }  // Home --> 0,0
void cursor( bool visible )         { CSI( visible ? "\?25h" : "\?25l" ); }
void colors( const rgb & fg, const rgb & bg )
#define C(F,c,L) F "8;2;", (int)c.red, ";", (int)c.green, ";", (int)c.blue, L
{
  CSI(C( "3", fg, ";" ), C( "4", bg, "m" ));
}
void fcolor( const rgb & c ) { CSI(C( "3", c, "m" )); }
void bcolor( const rgb & c ) { CSI(C( "4", c, "m" )); }

    example1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "console.hpp"

int main()
{
  title( "Console Example" );
  colors( rgb( 255, 255, 128 ), rgb( 0, 64, 32 ) );
  clear_screen();

  auto [width, height] = get_terminal_size();
  int x = width / 2 - 15;
  int y = height * 4 / 10;

  gotoxy( x, y );
  output( "Los niños dicen ¿qúe sapo, yo?" );

  gotoxy( x, y+1 );
  fcolor( rgb( 128, 128, 128 ) );

  output( "Now press the ‘ANY’ key..." );
  flush_input();
  is_key_pressed( -1 );
  flush_input();
}

Alas, there isn’t room in this post for input processing.
I’ll add it tomorrow (or something) and update this post with a link.
Last edited on
Can it use C++20? I'm thinkin' modules and std::format especially.
https://github.com/GeorgePimpleton/WoF

A quick "read the phrases from the WOF data file" and randomly choose one of the phrases.

A bit resource hungry reading the entire file into a vector.
This was my first project in college. It was supposed to span the semester and I did it out to the end by the second week; me and another guy were adding random crap during labs like animation and sound out of boredom. Animation with ascii art was tricky. And yea, with an actual hanged person. Probably cause collective head exploding to do that today.
BTW, "challenge accepted," along with some rudimentary code mashing for starting the game. :)
Hmm, didn't think of C++20.

Is there anyone here who can’t compile that yet?

I don’t think it’s unreasonable... I’ve been sticking to C++17, but I could definitely make the code shorter with some C++20-isms.

[edit] see George P’s good comment below for why I will prefer against C++20 for this challenge (not everyone can use it yet).
Last edited on
This was also one of my first projects. We had 1 week to do it I believe, I finished it the first day and the instructor made me add more and more functionality to it so that I wouldn't leave early.

Not as intricate as to have animation though!

I still have the program, but as an executable, the code is long gone.

Anyway, here's my solution to this. Hard coded the number of lines in the text file.

I used ANSI which is cross-platform as long as the console supports it :O.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//

#include <iostream>
#include <random>
#include <fstream>
#include <string>
#include <limits>

#define underline "\033[4m"
#define noUnderline "\033[0m"
#define clr "\033[2J\033[1;1H"

int main()
{
	std::random_device rd;
	std::mt19937 mersenne(rd());
	std::uniform_int_distribution<> die(0, 12880);

	int num = die(mersenne);

	std::ifstream inFile("wof.txt");

	if (!inFile.is_open())
	{
		std::cout << "Could Not Open File...\n";
		return 1;
	}

	std::string phrase, correct = "", guesses = "";

	for (int i = 0; i <= num; i++)
		getline(inFile, phrase);

	for (auto& i : phrase)
		i = toupper(i);

	bool won;
	num = 6;
	char g;
	do
	{
		std::cout << "\n\n\n" << clr;
		won = true;

		std::cout << "Tries Left: " << num << "\nPrevious Guesses: ";
		for (auto& i : guesses)
			std::cout << i << ' ';

		std::cout << "\n\n";

		for (auto& i : phrase)
		{
			if (i == ' ') std::cout << "  ";
			else if (!isalpha(i)) std::cout << i;
			else if(correct.find(i) != std::string::npos) std::cout << underline << i << noUnderline << ' ';
			else std::cout << underline << ' ' << noUnderline << ' ' && (won = false);
		}

		if (won)
			break;

		std::cout << "\n\nEnter Your Guess: ";
		std::cin >> g;

		//Left out so you can type whole words or letters if you know them
		//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

		if (!isalpha(g))
			continue;

		g = toupper(g);

		if (phrase.find(g) == std::string::npos)
		{
			if (guesses.find(g) == std::string::npos)
			{
				num--;
				guesses += g;
			}
		}
		else correct += g;

	} while (!won && num);

	if (won) std::cout << "\n\nYou've Won!\n";
	else std::cout << "\nYou suck... You've lost.\n";

	for (auto& i : phrase)
	{
		if (i == ' ') std::cout << "  ";
		else if (!isalpha(i)) std::cout << i;
		else std::cout << underline << i << noUnderline << ' ';
	}

	std::cout << '\n';
}
Last edited on
Re: C++20.

It depends on the compiler, only VS is 100% compliant, others don't do modules or C++ stdlib text formatting. GCC is the closest after VS.

Modules don't add anything to the mix that could be beneficial AFAIK, std::format could be useful for prettifying the output. Possibly.
Hello. I am surprised. It is exactly the latest code which I made. I post here my contribution. You got a shuffled word - you have to find it or an anagram. The dictionary can be downloaded at the link below. Have fun ++

https://github.com/dwyl/english-words/blob/master/words_alpha.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <iostream>
#include <fstream>
#include <vector>
#include <random>
#include <ctime>

class giveMeDate {

private:
    struct tm newtime;
    __time32_t aclock;
    char buffer[32];
    errno_t errNum;

public:
    giveMeDate();
};

giveMeDate::giveMeDate()
{
    _time32(&aclock);
    _localtime32_s(&newtime, &aclock);

    errNum = asctime_s(buffer, 32, &newtime);
    std::cout << "Welcome : " << buffer << std::endl;
}

class guessMyWord : giveMeDate {

public:
    guessMyWord(std::string& myBook, int length = 4);
    bool bAnagram(std::string lhs, std::string rhs);
    void showSecretWords(std::string& guess, bool hiddenWord);
    // all words from the dictionary
    std::vector<std::string> words;
    std::pair<std::string, std::string> secretWord; // !!!

private:
    size_t randomNumber(const int min_, const int max_);
    void selectWord();
    std::string shuffleWord(std::string& word);
};
// constructor
guessMyWord::guessMyWord(std::string& myBook, int length)
{
    std::string word;
    std::ifstream input_file(myBook);

    if (!input_file.is_open())
    {
        std::cout << "Could not open the file " << myBook << std::endl;
        exit(EXIT_FAILURE);
    }

    while (input_file >> word)
        if (word.size() == length)
            words.push_back(word);

    input_file.close();
    // selects one word in the main vector
    selectWord();
}

size_t guessMyWord::randomNumber(const int min_, const int max_)
{
    std::random_device rd;
    std::mt19937 rng{ rd() };
    std::uniform_int_distribution<int> uid(min_, max_);

    return uid(rng);
}

void guessMyWord::selectWord()
{
    int rn = randomNumber(1, words.size() - 1);
    secretWord.first = words[rn];
    secretWord.second = shuffleWord(words[rn]); // debug mode
//  std::cout << "Hidden word : " << secretWord.first << " " << secretWord.second << std::endl;
}

std::string guessMyWord::shuffleWord(std::string& word) {
    
    std::string tmp{ word };

    do {
        std::shuffle(tmp.begin(), tmp.end(), std::default_random_engine(unsigned int(randomNumber(1, tmp.size() - 1))));
    } while (std::find(words.begin(), words.end(), tmp) != words.end());

    return tmp;
}

bool guessMyWord::bAnagram(std::string lhs, std::string rhs) 
{
    std::sort(lhs.begin(), lhs.end());
    std::sort(rhs.begin(), rhs.end());

    return lhs == rhs;
}

void guessMyWord::showSecretWords(std::string& guess, bool showHiddenWord)
{
    std::cout << std::endl;
    std::cout << "Anagrams available for this word (alternative good answers) :" << std::endl;
    int occ = 0;

    if (showHiddenWord)
    {
        std::cout << secretWord.first << std::endl;
        occ++;
    }

    for (size_t i = 0; i < words.size(); i++)
    {
        if (bAnagram(secretWord.first, words[i]) && guess != words[i])
        {
            std::cout << words[i] << std::endl;
            occ++;
        }
    }
    // no occurrence for anagrams
    occ == 0 ? std::cout << "[nothing]" << std::endl << std::endl
             : std::cout << std::endl;
}

int main()
{
    std::string dico = ".\\dictionary.txt";
    int letters = 4;

    while (true)
    {
        int tries{};
        std::string myGuess;
        // load dico, select a word, shuffle it...
        guessMyWord *gmw = new guessMyWord(dico, letters);

        std::cout << "~~ Guess My Word ~~" << std::endl;
        std::cout << "Words in the dictionary with " << letters << " letters : " << gmw->words.size() << std::endl;
        std::cout << std::endl;

        do
        {
            std::cout << "What is your suggestion for the letters [" << gmw->secretWord.second << "] ? " << std::endl;
            std::cin >> myGuess;
            // to lower case
            std::transform(myGuess.begin(), myGuess.end(), myGuess.begin(), [](unsigned char c) { return (unsigned char)std::tolower(c); });
            tries++;

            if (myGuess == "*cheat")
            {
                gmw->showSecretWords(gmw->secretWord.first, true);
                system("pause");
                return EXIT_SUCCESS;
            }
            // boring game?
            if (myGuess == "exit")
                return EXIT_SUCCESS;
            // not the right word length
            if (myGuess.length() != gmw->secretWord.first.length())
                std::cout << "Not the same length" << std::endl;
            else if (!gmw->bAnagram(myGuess, gmw->secretWord.first)) // one or more letters are not in the secret word
                std::cout << "Not the right letters" << std::endl; // the letters are good, the length too, but this word is weird
            else if (gmw->bAnagram(myGuess, gmw->secretWord.first) && std::find(gmw->words.begin(), gmw->words.end(), myGuess) == gmw->words.end())
                std::cout << "It seems that this word does not exist" << std::endl;
        } while (!gmw->bAnagram(myGuess, gmw->secretWord.first) || std::find(gmw->words.begin(), gmw->words.end(), myGuess) == gmw->words.end());
        // check if two strings are anagrams and if the guessed word exists in the dictionary - or loop again
        std::cout << "Correct! You got it in " << tries << " guesses!" << std::endl;
        // display alternatives - except the guessed word
        gmw->showSecretWords(myGuess, false);
        // increase difficulty
        letters++;
        // max difficulty
        if (letters > 14)letters = 14;
        // clean up
        delete gmw;
    }

    return EXIT_SUCCESS;
}
Last edited on
... without the code corrections! eg. Don't use random_shuffle() as this is now deleted (since C++17)! See comments at https://cplusplus.com/forum/beginner/284709/


I fixed some. Be sure that this is not disrespectful for what you said. Under VS 17 compiling to 32 bits, I have no warnings and it works as expected. I just need to understand by myself how to improve this code according all your precious explanations. I will erase this part soon. Thank you ++

Done :)
Last edited on
I see someone hasn't been reading/following the suggested guidelines for this challenge, it is currently C++17 only based. As seeplus points out std::random_shuffle is not allowed, per the C++17 standard. Deprecated in C++14, removed in C++17.
https://en.cppreference.com/w/cpp/algorithm/random_shuffle

std::random_shuffle() uses the C library pseudo random number function rand(). C++ has perfectly adequate random number generation facilities in <random>, better than the facilities provided by the C library, used by std::shuffle().

A decent PDF paper on "Random Number Generation in C++" if'n a refresher is needed/wanted: https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3551.pdf

One suggestion in the C++ paper is creating a simple toolkit so using <random> is nearly as easy as using C's srand/rand functions. I bulked up the suggestion to create my own header only/module interface file I can easily add to any project that needs to generate random numbers.

https://github.com/GeorgePimpleton/misc_files/tree/main/Random%20Toolkit
Sorry. I forgot to say that it works using C++ 17 since I modified the shuffle function. I will take a look at your random number generator @GeorgeP. Thanks for the link ++
Alas, I don’t think I’ve been clear enough in my challenge description.
While nice, so far we’ve got standard ho-hum games.

You guys are villians, all right, just not SUPER ones!
https://www.youtube.com/watch?v=sBbN4Cjzyrw?start=0&stop=73&autoplay=1



Assuming I don’t decide to never program again before the week is over, I’ll update the second post with useful info, I guess...

Also, this should be FUN. Do it if you wanna.
I mostly wanted to code it so I could use my shiny new keyboard hehe.

I have some ideas on how to make a pretty one, but on a console app it seems like a waste. When I want something pretty, I usually use C# to create a GUI.
Alas, I don’t think I’ve been clear enough in my challenge description.
While nice, so far we’ve got standard ho-hum games.

I haven't coded up even close to a semi-final version of the challenge yet. Mostly I mashed up how to suss out the random phrase from the provided text file.

A "proof of concept" bit for the guts, the skin and hair are to come.

A prettified cross-platform console UI is definitely gonna take a lot of work.
The cross-platform part is: just use VT sequences. The hardest part is getting input correctly. Give me a day or two more and I’ll fill the second post with useful stuff — initializing and finalizing the console and getting the dang input.
Last edited on
Outputting a bunch of blank lines and setting the cursor to the top again should be enough for flashy animation. Like a flip book.
Doing that output that way, zapshe, would be considered "don't go there, old school" by some people. They want to fancy froo-froo up the I/O.

Sarcasm, or is it?
Pages: 123