Ta-da! Here's a present for you...
This program displays a Christmas tree with randomly allocated baubles and flashing lights, which blink once every second.
Rather than the traditional pine needles, this tree uses various ASCII characters, stored in a one-dimensional array of string values.
The tree and trunk are generated using simple for loops. Extra characters are then added over the top of the original # pine needle characters for the baubles and lights.
The second part of program uses a for loop to redraw the rows in the tree. To colour in the different parts, the code then examines each character in the array. It uses a switch statement to decide which colour to use for a particular kind of character (needles, bauble, lights, trunk etc.) and whether to use normal or bold font weights when displaying that character.
To find out more about for loops, random numbers and switch statements, take a look in the book - available directly on Amazon in the USA, UK, France, Germany, Spain, Italy and Canada.
To try out the program, select and copy the C++ source-code at the bottom of this post.
Paste into a text editor, such as Nano or Geany.
Then save the new file, ending in .cpp
I used tree.cpp
Here's the code:
#include <iostream> // Screen
#include <unistd.h> // Time functions
#include <cstdlib> // Random number functions
using namespace std;
// - - - - - - - - - -
const char NEEDLES = '#';
const char BAUBLE = 'O';
const char LIGHT1 = '*';
const char LIGHT2 = '+';
const char TOP = '&';
const char TRUNK = '%';
const string BOLD = "\e[1m";
const string NORMAL = "\e[21m";
const string RED = "\e[31m";
const string GREEN = "\e[32m";
const string AMBER = "\e[33m";
const string WHITE = "\e[37m";
const string BRIGHT_YELLOW = "\e[38;5;226m";
const string TOP_LEFT_COORDS = "\e[1;1H";
// - - - - - - - - - -
int main()
{
// Seed the random number process to ensure new tree each time
srandom( time( 0 ) );
const int HEIGHT = 20;
string tree[HEIGHT];
int row, col, len;
// Set up the branches
for ( row = 0; row < HEIGHT-3; row++ )
{
string padding( 1 + HEIGHT - row, ' ' );
string branch( 1 + row*2, NEEDLES );
tree[row] = padding + branch;
} // End of for loop to set up branches
// - - - - - - - - - -
// Randomly add baubles
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
for ( col = 1 + HEIGHT - row; col < len; col++ )
if ( random() % 6 == 0 )
tree[row].at(col) = BAUBLE;
} // End of for loop to add baubles on each row of tree
// - - - - - - - - - -
// Randomly add on lights
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
for ( col = 1 + HEIGHT - row; col < len; col++ )
if ( random() % 8 == 0 )
tree[row].at(col) = LIGHT1;
} // End of for loop to add lights on each row of tree
// - - - - - - - - - -
// Randomly add other kind of lights
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
for ( col = 1 + HEIGHT - row; col < len; col++ )
if ( random() % 8 == 0 )
tree[row].at(col) = LIGHT2;
} // End of for loop to add lights on each row of tree
// - - - - - - - - - -
// Set up the trunk
for ( row = HEIGHT-3; row < HEIGHT; row++ )
{
string padding( HEIGHT-1, ' ' );
string trunk( 5, TRUNK );
tree[row] = padding + trunk;
} // End of for loop to set up the trunk
// - - - - - - - - - -
// Put someone on the top!
tree[0][HEIGHT+1] = TOP;
// - - - - - - - - - -
// Display the tree
bool flashOn = false; // Controls which set of lights is on
// Examines one character at a time in the tree,
// choosing the appropriate colour and bold/normal weight font
// depending on what kind of character is about to be displayed
char current;
// Infinite loop to make lights flash continuously
while ( true )
{
// Start drawing from top-left corner of terminal window
cout << TOP_LEFT_COORDS;
// Examine and draw one row of tree at a time
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
// Examine and draw each individual character from the row
for ( col = 0; col < len; col++ )
{
current = tree[row].at(col);
// Decide which colour and font weight to use
switch ( current )
{
// Decoration on top of the tree
case TOP:
cout << BRIGHT_YELLOW << NORMAL;
break;
// Branch colour green
case NEEDLES:
cout << GREEN << NORMAL;
break;
// Trunk colour amber
case TRUNK:
cout << AMBER << NORMAL;
break;
// Main twinkly lights
case LIGHT1:
cout << BRIGHT_YELLOW;
if ( flashOn )
cout << BOLD;
else
cout << NORMAL;
break;
// Other type of twinkly lights
case LIGHT2:
cout << AMBER;
if ( not flashOn )
cout << BOLD;
else
cout << NORMAL;
break;
// Baubles
case BAUBLE:
cout << RED << NORMAL;
break;
} // End of switch decision that decides colour for each part of tree
// Display tiny part of the tree
cout << current;
} // End of for loop that works on a single row
cout << endl;
} // End of for loop that controls which row is being displayed
// Wait one second in between flashes
sleep( 1 );
// Change which set of lights will be on or off
flashOn = not flashOn;
} // End of infinite while loop block
} // End of program
Find out more - buy the book on Amazon...
This program displays a Christmas tree with randomly allocated baubles and flashing lights, which blink once every second.
Rather than the traditional pine needles, this tree uses various ASCII characters, stored in a one-dimensional array of string values.
The tree and trunk are generated using simple for loops. Extra characters are then added over the top of the original # pine needle characters for the baubles and lights.
The second part of program uses a for loop to redraw the rows in the tree. To colour in the different parts, the code then examines each character in the array. It uses a switch statement to decide which colour to use for a particular kind of character (needles, bauble, lights, trunk etc.) and whether to use normal or bold font weights when displaying that character.
To find out more about for loops, random numbers and switch statements, take a look in the book - available directly on Amazon in the USA, UK, France, Germany, Spain, Italy and Canada.
To try out the program, select and copy the C++ source-code at the bottom of this post.
Paste into a text editor, such as Nano or Geany.
Then save the new file, ending in .cpp
I used tree.cpp
To compile from the command-line:
g++ -o tree tree.cpp
To run from the command-line:
./tree
Here's the code:
#include <iostream> // Screen
#include <unistd.h> // Time functions
#include <cstdlib> // Random number functions
using namespace std;
// - - - - - - - - - -
const char NEEDLES = '#';
const char BAUBLE = 'O';
const char LIGHT1 = '*';
const char LIGHT2 = '+';
const char TOP = '&';
const char TRUNK = '%';
const string BOLD = "\e[1m";
const string NORMAL = "\e[21m";
const string RED = "\e[31m";
const string GREEN = "\e[32m";
const string AMBER = "\e[33m";
const string WHITE = "\e[37m";
const string BRIGHT_YELLOW = "\e[38;5;226m";
const string TOP_LEFT_COORDS = "\e[1;1H";
// - - - - - - - - - -
int main()
{
// Seed the random number process to ensure new tree each time
srandom( time( 0 ) );
const int HEIGHT = 20;
string tree[HEIGHT];
int row, col, len;
// Set up the branches
for ( row = 0; row < HEIGHT-3; row++ )
{
string padding( 1 + HEIGHT - row, ' ' );
string branch( 1 + row*2, NEEDLES );
tree[row] = padding + branch;
} // End of for loop to set up branches
// - - - - - - - - - -
// Randomly add baubles
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
for ( col = 1 + HEIGHT - row; col < len; col++ )
if ( random() % 6 == 0 )
tree[row].at(col) = BAUBLE;
} // End of for loop to add baubles on each row of tree
// - - - - - - - - - -
// Randomly add on lights
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
for ( col = 1 + HEIGHT - row; col < len; col++ )
if ( random() % 8 == 0 )
tree[row].at(col) = LIGHT1;
} // End of for loop to add lights on each row of tree
// - - - - - - - - - -
// Randomly add other kind of lights
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
for ( col = 1 + HEIGHT - row; col < len; col++ )
if ( random() % 8 == 0 )
tree[row].at(col) = LIGHT2;
} // End of for loop to add lights on each row of tree
// - - - - - - - - - -
// Set up the trunk
for ( row = HEIGHT-3; row < HEIGHT; row++ )
{
string padding( HEIGHT-1, ' ' );
string trunk( 5, TRUNK );
tree[row] = padding + trunk;
} // End of for loop to set up the trunk
// - - - - - - - - - -
// Put someone on the top!
tree[0][HEIGHT+1] = TOP;
// - - - - - - - - - -
// Display the tree
bool flashOn = false; // Controls which set of lights is on
// Examines one character at a time in the tree,
// choosing the appropriate colour and bold/normal weight font
// depending on what kind of character is about to be displayed
char current;
// Infinite loop to make lights flash continuously
while ( true )
{
// Start drawing from top-left corner of terminal window
cout << TOP_LEFT_COORDS;
// Examine and draw one row of tree at a time
for ( row = 0; row < HEIGHT; row++ )
{
len = tree[row].length();
// Examine and draw each individual character from the row
for ( col = 0; col < len; col++ )
{
current = tree[row].at(col);
// Decide which colour and font weight to use
switch ( current )
{
// Decoration on top of the tree
case TOP:
cout << BRIGHT_YELLOW << NORMAL;
break;
// Branch colour green
case NEEDLES:
cout << GREEN << NORMAL;
break;
// Trunk colour amber
case TRUNK:
cout << AMBER << NORMAL;
break;
// Main twinkly lights
case LIGHT1:
cout << BRIGHT_YELLOW;
if ( flashOn )
cout << BOLD;
else
cout << NORMAL;
break;
// Other type of twinkly lights
case LIGHT2:
cout << AMBER;
if ( not flashOn )
cout << BOLD;
else
cout << NORMAL;
break;
// Baubles
case BAUBLE:
cout << RED << NORMAL;
break;
} // End of switch decision that decides colour for each part of tree
// Display tiny part of the tree
cout << current;
} // End of for loop that works on a single row
cout << endl;
} // End of for loop that controls which row is being displayed
// Wait one second in between flashes
sleep( 1 );
// Change which set of lights will be on or off
flashOn = not flashOn;
} // End of infinite while loop block
} // End of program
Find out more - buy the book on Amazon...