STOP PRESS! The full book is now available DIRECTLY from Amazon with lower shipping costs!
This is a variation of the previous snowstorm program.
It displays several rolling snowstorms. Each snowstorm plots a certain number of character symbols, choosing their colour and font-weight (bold or normal) at random.
The main work is performed by the snow function. When called, this is passed a string value that contains the set of possible characters that are available to choose from.
Another function, wipeout, is called to clear the screen. This is simply a call to the snow function, telling it to display spaces at random positions on the screen.
The calls to activate the snow and wipeout functions can be found within an infinite while loop in the main function.
Compile as usual, either from the command line or from within Geany. Full details in the book.
The deluxe version that I use at work has an additional function that can be called display the contents of various text/ASCII art files, producing a retro teletype effect, one character at a time. Watch this space.
Meanwhile, let it snow...
// To compile on Raspberry Pi or in Ubuntu...
// g++ -o rolling rolling.cpp
// This compiles the rolling.cpp source file ans SHOULD make an executable called rolling
// Run with...
// ./rolling
// Phil Gardner - "Learn to Program Using C++ on the Raspberry Pi"
#include <cstdlib> // Using random numbers - random function
#include <iostream> // To use the screen output - cout "channel out"
#include <unistd.h> // To slow things down by parts of a second - usleep function
#include <sstream> // To convert numbers to character strings when telling the screen where to put the cursor
using namespace std; // Want to use short abbreviations... cout rather than std::cout
// -------------------------------
// These constants are special "escape characters" that tell your terminal to change colour or switch bold on/off
const string BOLD = "\e[1m";
const string NORM = "\e[0m";
const string RED = "\e[31m";
const string GREEN = "\e[32m";
const string BLUE = "\e[34m";
const string YELLOW = "\e[38;5;226m";
// -------------------------------
void positionCursor( int screenRow, int screenColumn )
{
// This function sends the cursor to a particular row and column in your terminal window
// ready to display something at that position.
string columnString, rowString;
// Convert the column number to a character string - uses a new stringstream each time, don't need to reset it after use...
stringstream columnConverter;
columnConverter << screenColumn;
columnConverter >> columnString;
// Convert the row number to a character string
stringstream rowConverter;
rowConverter << screenRow;
rowConverter >> rowString;
// Put the strings together to make an "escape sequence" that tells screen where to position the cursor
cout << "\e[" + rowString + ";" + columnString + "H";
}
// -------------------------------
// This function can be called again and again by the main program
// It displays a certain number of symbols in different colours,
// waiting for a split second after displaying each symbol.
void snow( int numToDisplay, string symbols, string ink1, string ink2, int pauseLength )
{ // Keep count of symbols displayed so far, used to determine whether to display 1 or 0
int numSoFar = 0;
// Infinite loop - do this code again and again forever...
int column, row; // Loop will repeatedly use these variables
while ( numSoFar < numToDisplay )
{ // Pick a random column number on the screen - standard terminal size is 80 columns
column = random() % 80;
// Pick a random row number - standard terminal size is 25 rows
row = random() % 25;
positionCursor( row, column );
// Decide what colour and weight to use when displaying the symbol
switch ( numSoFar % 4 )
{
case 0: cout << NORM << ink1; break;
case 1: cout << NORM << ink2; break;
case 2: cout << BOLD << ink1; break;
case 3: cout << BOLD << ink2; break;
} // End of switch decision
// Display symbol at the current screen position
cout << symbols.at( numSoFar % symbols.length() );
// Tell the screen to update immediately - don't wait until have a finished line of text
cout << flush;
// Delay for part of a second
usleep( pauseLength );
// Update counter that records how many symbols have been displayed
numSoFar++;
} // End of infinite while loop section
}
// --------------------------------------------------------
// This function gradually clears the screen by displaying spaces at random locations.
// It activtes (calls) the "snow" function above, telling it to display spaces instead of visible symbols
void wipeout( int pauseLength )
{
snow( 15000, " ", NORM, NORM, pauseLength );
}
// --------------------------------------------------------
// Program begins execution here...
int main()
{
// Infinite loop, displays same snowstorms forever
while ( true )
{
// Clear screen with randomly positioned spaces
wipeout(3);
// Fill screen with red and yellow + symbols
snow( 5000, "++", YELLOW, RED, 20 );
wipeout(3);
// Fill screen with binary using yellow and red
snow( 10000, "01", YELLOW, RED, 20 );
wipeout(3);
// Say hello, then clear screen
positionCursor( 13, 36 );
cout << YELLOW << "H E L L O !" << NORM << endl;
sleep(3);
// Fill screen with hexadecimal digits
snow( 5000, "0123456789ABCDEF", BLUE, GREEN, 20 );
} // End of while loop
return 0;
} // End of main function
Find out more - buy the book on Amazon...
Further details in Chapter 4: Keyboard input and screen output