How to make it "snow" in command prompt.

Hello. I need to make an array of 50 points or coordinates on the command prompt. They need to start in a random position off the screen. I need to make a timer that will move down all the points every tick as if it is snowing. I don't know where to start. Any help will be greatly appreciated. Thank you.
Hi,

please edit your topic and move it to windows programming

you may want to start with using color 0f to make background black and font white (default font is grey i suppose)


Last edited on
Needs a (Windows?) command prompt. Looks pretty silly in CPP shell.
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
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

const int ROWS = 20;          // number of rows
const int COLS = 50;          // number of columns
const int NRANDOM = 3;        // max snowflakes per line
const int NTIMES = 100;       // number of timesteps
const double WAIT = 0.3;      // refresh time in seconds
const char SNOW = '*';        // a snowflake (ahhh!)


void plot( char m[ROWS][COLS], int topRow )
{
   system( "cls" );
   for ( int i = 0; i < ROWS; i++ )
   {
      int row = ( topRow + i ) % ROWS;
      for ( int j = 0; j < COLS; j++ ) cout << m[row][j];
      cout << endl;
   }
   for ( int j = 0; j < COLS; j++ ) cout << "-";
   cout << "\nHAPPY CHRISTMAS EVERYBODY\n";
}


void waitTime( double waitSecs )
{
  clock_t start = clock();
  while ( clock() - start < CLOCKS_PER_SEC * waitSecs );
}


int main()
{
   int topRow = 0;
   char m[ROWS][COLS] = { ' ' };

   srand( time( 0 ) );
   for ( int t = 0; t < NTIMES; t++ )
   {
      plot( m, topRow );
      topRow -= 1;   if ( topRow < 0 ) topRow = ROWS - 1;
      for ( int j = 0; j < COLS   ; j++ ) m[topRow][j] = ' ';
      for ( int r = 0; r < NRANDOM; r++ ) m[topRow][rand() % COLS] = SNOW;
      waitTime( WAIT );
   } 
}
Last edited on
Windows version.
How to make something simple, complicated.
With borrowings from lastchance above and whitenite1
http://www.cplusplus.com/forum/beginner/68989/#msg368472

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
#include <conio.h>
#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <windows.h>

const int ROWS = 40;          // number of rows
const int COLS = 60;          // number of columns
const int NRANDOM = 3;        // max snowflakes per line
const double WAIT = 0.3;      // refresh time in seconds

void gotoXY(int x, int y); 
bool keypress();

void fillRow(std::vector<int> & row)
{
    for (int i=0; i<NRANDOM; ++i)
        row.push_back(rand() %  COLS);   
}

void fill(std::list<std::vector<int>> & data)
{
    for (int y = 0; y<ROWS; ++y)
    {
        std::vector<int> row;
        fillRow(row);
        data.push_front(row);
    }
}

void display(std::list<std::vector<int>> & data)
{
   gotoXY(0,0);
   
   for (const auto & row : data)
   {
       std::string line(COLS, ' ');
       for (int n : row)
           line[n] = '*';
       std::cout << line << '\n';
   } 
}

void fall(std::list<std::vector<int>> & data)
{
    std::vector<int> row;
    fillRow(row);
    data.push_front(row);
    data.pop_back();
            
    for (auto & row : data)
       for (int & n : row)
           n = (COLS + n + rand() % 3 - 1 ) % COLS;
}

int main()
{
    std::list<std::vector<int>> content;
    fill(content);
    
    while (!keypress())
    {
        display(content);
        fall(content);
        Sleep(1000*WAIT);
    }
}

void gotoXY(int x, int y) 
{ 
    // Sets position for next thing to be printed 
    
    static HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    static COORD CursorPosition;

    CursorPosition.X = x; // Locates column
    CursorPosition.Y = y; // Locates Row
    SetConsoleCursorPosition(console,CursorPosition); 
}

bool keypress()
{
   return _kbhit();
}
Just one comment, @lastchance

I'd try to avoid cpu-hungry empty loops like this:
 
    while ( clock() - start < CLOCKS_PER_SEC * waitSecs );

There are better ways (I used Windows Sleep() and I'm sure there are other options to pause without chewing up cpu cycles). system( "cls" ) is also probably not an optimum approach.
Last edited on
Ah, well. I've managed to post an example of "how not to do it". Best forgotten, even if it was only intended as tongue-in-cheek. @Chervil is right: my time-delay approach will certainly give the processor some exercise!
Actually though @lastchance, your use of arrays is probably better than my pushing and popping of a list. In any case, I know the OP had a serious question and my response probably didn't help very much, whereas yours could have been useful.

Another bit of tongue-in-cheek silliness. Based on the stuff I posted yesterday, which had the flakes jitter randomly from side-to-side, this uses a spiralling motion and attempts some depth too. But its just a console application, so hardly worth the trouble.
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
#include <conio.h>
#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <windows.h>
#include <cmath>

//#define BLIZZARD
const int    ROWS    = 25;       // number of rows
const int    COLS    = 40;       // number of columns
const int    NRANDOM = 4;        // max snowflakes per line, 3 ok
const double WAIT    = 0.1;      // refresh time in seconds


class Snowflake {
    static constexpr double PI =  3.1415926535897932385;
    
    double angle;
    double inc;
    double depth;
    double x;
    double column;
    double xradius;

public:    
    Snowflake(int col) : angle(0.0), inc(20.0), depth(1.0), x(0), column(col), xradius(rand() % 3 + 1)
    { 
        inc += (rand() % 30 - 15);
        if (rand() % 100 < 50)
            inc = - inc;
    }
    
    char getc() const
    {
        int d = std::round(depth);
        if      (d == -1) return '.';
        else if (d == 0)  return '+';
        return '*';
    }

    int getcol() const
    {
        return std::round(column + x);
    }
    
    void update()
    {
        angle += inc;
        depth = std::cos(angle * (PI/180.0));
        x     = std::sin(angle * (PI/180.0)) * xradius;
    }
       
};

void gotoXY(int x, int y); 
bool keypress();

using namespace std;

void fillRow(vector<Snowflake> & row)
{
#ifdef BLIZZARD    
    static unsigned count = 0;
    int NRANDOM = 0;
    ++count;
        
    if (count/ROWS < 80)
        NRANDOM = count / ROWS + 1;
    else
        NRANDOM = 6;
#endif
        
       
    for (int i=0; i<NRANDOM; ++i)
    {
        int x = rand() %  COLS; 
        row.push_back( Snowflake(x));   
    }
}


void fill(list<vector<Snowflake>> & data)
{
    for (int y = 0; y<ROWS; ++y)
    {
        vector<Snowflake> row;
        fillRow(row);
        data.push_front(row);
    }
}

void fall(list<vector<Snowflake>> & data)
{
    vector<Snowflake> row;
    fillRow(row);
    data.push_front(row);
    data.pop_back();
            
    for (auto & row : data)
       for (Snowflake & n : row)
           n.update();
           //n = (COLS + n + rand() % 3 - 1 ) % COLS;
}


void display(list<vector<Snowflake>> & data)
{
   gotoXY(0,0);
   
   for (const auto & row : data)
   {
       string line(COLS, ' ');
       for (const Snowflake& n : row)
       {
           int col = (n.getcol() + COLS) % COLS;
           line[col] = n.getc();
       }
       std::cout << line << '\n';
   } 
}


int main()
{
    list<vector<Snowflake>> content;
    fill(content);
    
    while (!keypress())
    {
        display(content);
        fall(content);
        Sleep(1000*WAIT);
    }
}

void gotoXY(int x, int y) 
{ 
    // Sets position for next thing to be printed 
    
    static HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    static COORD CursorPosition;

    CursorPosition.X = x; // Locates column
    CursorPosition.Y = y; // Locates Row
    SetConsoleCursorPosition(console,CursorPosition); 
}

bool keypress()
{
   return _kbhit();
}

Last edited on
Topic archived. No new replies allowed.