Showing posts with label printing shapes in Ncurses. Show all posts
Showing posts with label printing shapes in Ncurses. Show all posts

Thursday, January 3, 2013

Creating moving shapes in ncurses

If you followed the couple of my previous posts on ncurses programs, I think you can manage with creating any shape in it colorfully. Think it's time to move the shapes you create (give them a little life :p)

But make sure you can create the shapes easily before going through this post because I won't be explaining the creation of shapes ncurses here.


Moving a triangle down

















The above images show two screenshots that are taken of the running program. All what you can see is a simple triangle printed but moves from top to bottom during run time. What do you think is happening?  Is there anyway to automate the object to move. But what I have done here is very simple as shown below.


  1. have a function to print a triangle
  2. have a function to erase the printed triangle
  3. call the printing method
  4. refresh the screen
  5. call the erasing method
  6. do the task 3, 4 and 5 repeatedly.

I think the concept is simple to understand. observe the below source code for further clarification.

#include<ncurses.h>
void print_triangle(int startRow,int startCol,int height);      //function declaration to print triangle
void erase_triangle(int startRow,int startCol,int height);     //function declaration to erase triangle

int main()

{
int sr=10;                                        //variable which holds the starting row value
initscr();
for(int m=1;m<=15;m++)                //this loop decides how many times we need to move the triangle
{
print_triangle(sr,45,4);             //print triangle
refresh();                                 //refresh the screen

for(int s=1;s<=500000000;s++);   //loop which controls the speed of the moving triangle

erase_triangle(sr,45,4);           //erase the triangle which is drawn before
refresh();                                //refresh the screen
sr++;                                             //increment the starting row by one
}
getch();
endwin();
return 0;
}

//----------------------------------------------------------------------------------
void print_triangle(int startRow,int startCol,int height)
{
int x=startCol;
for(int r=startRow;r>=startRow-height;r--)
{
for(int c=startCol;c<=x;c++)
{
move(r,c);
printw("*");
}
x++;
startCol--;
}

}

//----------------------------------------------------------------------------------
void erase_triangle(int startRow,int startCol,int height)
{
        int x=startCol;
        for(int r=startRow;r>=startRow-height;r--)
        {
                for(int c=startCol;c<=x;c++)
                {
                        move(r,c);
                        printw(" ");
                }
                x++;
                startCol--;
        }

}

think what you need to do to,
  1. move the triangle faster
  2. move the triangle slower
It's really simple. note the line of code below,

for(int s=1;s<=500000000;s++);   

by increasing the highlighted value (in blue), you can slow down the triangle's movement and by decreasing it, you can move the triangle faster. Also note that the above loop is like the Thread.sleep() method in other languages like c# and java which pauses the program between two actions to keep it idle for sometimes.

Moving an upside down 'T' shape horizontally

















It's again the combination of two rectangles that are moving together.we need to increment the starting column here to move it horizontally.

Source Code :


#include<ncurses.h>
void printbox(int startrow,int startcolumn,int height,int width);
void erasebox(int startrow,int startcolumn,int height,int width);
int main()
{
initscr();

int col1=45,w1=3,col2=42,w2=9;
for(int x=1;x<=10;x++)
{
printbox(5,col1,3,w1);
printbox(9,col2,1,w2);
refresh();

for(int s=1;s<=500000000;s++);

erasebox(5,col1,3,w1);
erasebox(9,col2,1,w2);
refresh();

col1++;
col2++;


}

getch();
endwin();
return 0;
}

//----------------------------------------------------------------------------------
void printbox(int startrow,int startcolumn,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcolumn;c<=startcolumn+width;c++)
{
move(r,c);
printw("*");
}

}

}

//----------------------------------------------------------------------------------
void erasebox(int startrow,int startcolumn,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
        {
                for(int c=startcolumn;c<=startcolumn+width;c++)
                {       
                        move(r,c);
                        printw(" ");
                }

        }

}

Moving an upside down 'T' shape vertically




Source code :

#include<ncurses.h>
void printbox(int startrow,int startcolumn,int height,int width);
void erasebox(int startrow,int startcolumn,int height,int width);
int main()
{
initscr();

int row1=5,h1=3,row2=9,h2=1;
for(int x=1;x<=10;x++)
{
printbox(row1,45,h1,3);
printbox(row2,42,h2,9);
refresh();

for(int s=1;s<=500000000;s++);

erasebox(row1,45,h1,3);
erasebox(row2,42,h2,9);
refresh();

row1++;
row2++;


}

getch();
endwin();
return 0;
}

//----------------------------------------------------------------------------------
void printbox(int startrow,int startcolumn,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcolumn;c<=startcolumn+width;c++)
{
move(r,c);
printw("*");
}

}

}

//----------------------------------------------------------------------------------
void erasebox(int startrow,int startcolumn,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
        {
                for(int c=startcolumn;c<=startcolumn+width;c++)
                {       
                        move(r,c);
                        printw(" ");
                }

        }

}



Moving a fish horizontally















Source Code :

#include<ncurses.h>
void print_triangle(int startRow,int startCol,int width);
void erase__triangle(int startRow,int startCol,int width);
int main()
{
int sc1=15,w1=3,sc2=21,w2=5;
initscr();
start_color();
init_pair(1,COLOR_RED,COLOR_WHITE);
init_pair(2,COLOR_MAGENTA,COLOR_BLUE);
init_pair(3,COLOR_BLACK,COLOR_BLACK);
for(int m=1;m<=20;m++)
{ attrset(COLOR_PAIR(1)); print_triangle(10,sc1,w1);
attrset(COLOR_PAIR(2));
print_triangle(10,sc2,w2);
refresh();
for(int s=1;s<=300000000;s++);
attrset(COLOR_PAIR(3));
erase__triangle(10,sc1,w1);
attrset(COLOR_PAIR(3));
erase__triangle(10,sc2,w2);
refresh();
sc1=sc1+2;
sc2=sc2+2;
}
getch();
endwin();
return 0;
}
//----------------------------------------------------------------------------------
void print_triangle(int startRow,int startCol,int width)
{
int x=startRow;
for(int c=startCol;c>=startCol-width;c--)
{
for(int r=startRow;r<=x;r++)
{
move(r,c);
printw("*");
}
x++;
startRow--;
}
}

//----------------------------------------------------------------------------------
void erase__triangle(int startRow,int startCol,int width)
{
int x=startRow;
        for(int c=startCol;c>=startCol-width;c--)
        {
                for(int r=startRow;r<=x;r++)
                {
                        move(r,c);
                        printw(" ");
                }
        x++;
        startRow--;
        }
}


Moving multiple objects to different directions simultaneously

Here the blue color frame moves horizontally, Cyan colored frame moves vertically and the magenta colored frame moves diagonally. Observe the code carefully.














Source Code :

#include<ncurses.h>
void print_boxes(int startrow,int startcol,int height,int width);
void erase_boxes(int startrow,int startcol,int height,int width);

int main()
{
int sr1=10,sr2=1,sr3=5;
int sc1=10,sc2=3,sc3=7;
initscr();
start_color();
init_pair(1,0,6);
init_pair(2,0,4);
init_pair(3,0,5);
init_pair(4,0,0);
for(int m=1;m<=20;m++)
{
attrset(COLOR_PAIR(1));
print_boxes(sr1,sc1,5,20);

attrset(COLOR_PAIR(2));
print_boxes(sr2,sc2,12,5);

attrset(COLOR_PAIR(3));
print_boxes(sr3,sc3,10,20);
refresh();

for(int s=1;s<=400000000;s++);
attrset(COLOR_PAIR(4));
                erase_boxes(sr1,sc1,5,20);
attrset(COLOR_PAIR(4));
                erase_boxes(sr2,sc2,12,5);

attrset(COLOR_PAIR(4));
                erase_boxes(sr3,sc3,10,20);
                refresh();

sr1++;
sc2++;
sr3++;
sc3=sc3+2;
}
getch();
endwin();
return 0;

}

//----------------------------------------------------------------------------------
void print_boxes(int startrow,int startcol,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=startcol+width;c=c+width)
{
move(r,c);
printw("*");
}
}

for(int c=startcol;c<=startcol+width;c++)
{
for(int r=startrow;r<=startrow+height;r=r+height)
{
move(r,c);
printw("*");
}
}

}

//----------------------------------------------------------------------------------
void erase_boxes(int startrow,int startcol,int height,int width)
{
        for(int r=startrow;r<=startrow+height;r++)
        {
                for(int c=startcol;c<=startcol+width;c=c+width)
                {
                        move(r,c);
                        printw(" ");
                }
        }

        for(int c=startcol;c<=startcol+width;c++)
        {
                for(int r=startrow;r<=startrow+height;r=r+height)
                {
                        move(r,c);
                        printw(" ");
                }
        }

}


Wednesday, January 2, 2013

Creating more Interesting shapes in ncurses programs

Ok guys, I think after following my previous posts on ncurses, you are eager to try out some more colorful and interesting programs of ncurses to come up with few more shapes. Let me give you some homework first.

think of building some shapes like a house, Christmas tree, simple rocket etc using ncurses. Before starting, let me explain you the easiest way to do them all.

First of all, think out of the box. I am not asking you to draw perfect shapes but just the sketches of them. OK, think in this way, what if you think they are made of little blocks as we have already discussed. learn how to print squares  triangles, rectangles and so on, then think how you can join them and build some interesting shapes as I asked you to try above.


Printing a Christmas tree in ncurses


It's just a matter of printing three triangles and a rectangle, right. See the output first and then try your own. If you really couldn't figure it out, then go through the code :) 

you need to notice one more point in here. Since I already told you that it is easy if you can separately print your sub shapes to print the entire shape, more efficient way is to print these sub shapes in different functions and calling them in order to complete the entire shape.

If you have more than one rectangles to print in the same picture, you don't need two different functions but you can simply implement one function with four parameters to state the starting column, starting row, height and the width of the triangle you need to print. Call this function to print any number of rectangles passing values to print it in different positions and sizes.

I have commented the first source code for your ease. Others go similarly.





#include<ncurses.h>                                                                 //including ncurses library

void printTriangle(int startrow,int startcol,int height);                //function declaration to print a triangle 
void printRectangle(int startrow,int startcol,int height,int width); //function declaration to print a rectangle

int main()
{
initscr();                                                                       //initializing the screen
start_color();                                                               //starting color mode

init_pair(1,1,2);                                                           //initializing the color pairs
init_pair(2,3,7);
init_pair(3,4,2);
init_pair(4,7,4);

attrset(COLOR_PAIR(1));                                        //using the first color pair as attribute set
printTriangle(5,15,3);                                                 //printing triangle 1 

attrset(COLOR_PAIR(2));                                       //using the second color pair as attribute set
printTriangle(9,15,4);                                                 //printing triangle 2 

attrset(COLOR_PAIR(3));                                      //using the third color pair as attribute set
printTriangle(14,15,5);                                              //printing triangle 3 

attrset(COLOR_PAIR(4));                                     //using the fourth color pair as attribute set
printRectangle(20,12,1,6);                                       //printing rectangle

getch();
endwin();
return 0;
}
//----------------------implementation of printing a triangle

void printTriangle(int startrow,int startcol,int height)
{
int x=startcol;

for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=x;c++)
{
move(r,c);
printw("*");
}
x++;
startcol--;
}

}

//-----------------------implementation of printing a rectangle

void printRectangle(int startrow,int startcol,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=startcol+width;c++)
{
move(r,c);
printw("*");
}
}

}


Printing a house in ncurses.





Source code:

 #include<ncurses.h>                                                                       
void printTriangle(int startrow,int startcol,int height);
void printRectangle(int startrow,int startcol,int height,int width);

int main()
{
initscr();
start_color();

init_pair(1,3,1);
init_pair(2,4,2);
init_pair(3,7,4);


attrset(COLOR_PAIR(1));
printTriangle(3,15,4);


attrset(COLOR_PAIR(2));
printRectangle(8,10,7,10);

attrset(COLOR_PAIR(3));
        printRectangle(11,12,4,2);


getch();
endwin();
return 0;
}
//----------------------------------------------------------------------------------

void printTriangle(int startrow,int startcol,int height)
{
int x=startcol;

for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=x;c++)
{
move(r,c);
printw("*");
}
x++;
startcol--;
}

}

//----------------------------------------------------------------------------------
void printRectangle(int startrow,int startcol,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=startcol+width;c++)
{
move(r,c);
printw("*");
}
}

}


you must note one more important point in the above code. Whatever the task that you have implemented inside your will not be executed unless you call that specific function some where inside your main method. Also, note that you have a door in the house above. You have print the bigger rectangle( in green ) and then the rectangle for the door (in blue) should be printed. 

What I wanted to tell you is, the order that you call your functions is very important. if you call the function for the green rectangle first and then the blue rectangle printing function second, then you can see as above but if you call them in the other order (blue one first and then the green) , you will see only the green box because the smaller blue rectangle would be hidden behind the bigger green rectangle.


 Printing a rocket in ncurses






Source code:

 #include<ncurses.h>                                                                         
void printTriangle(int startrow,int startcol,int height);
void printRectangle(int startrow,int startcol,int height,int width);

int main()
{
initscr();
start_color();

init_pair(1,7,1);
init_pair(2,1,3);
init_pair(3,4,2);
init_pair(4,4,3);

attrset(COLOR_PAIR(1));
printTriangle(2,16,2);

attrset(COLOR_PAIR(4));
printTriangle(17,16,2);

attrset(COLOR_PAIR(2));
        printRectangle(7,10,1,3);

attrset(COLOR_PAIR(2));
        printRectangle(7,19,1,3);


attrset(COLOR_PAIR(3));
printRectangle(5,14,11,4);

getch();
endwin();
return 0;
}
//----------------------------------------------------------------------------------

void printTriangle(int startrow,int startcol,int height)
{
int x=startcol;

for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=x;c++)
{
move(r,c);
printw("*");
}
x++;
startcol--;
}

}

//----------------------------------------------------------------------------------
void printRectangle(int startrow,int startcol,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=startcol+width;c++)
{
move(r,c);
printw("*");
}
}

}


Printing number 1 in other way around in ncurses





  Source code:

#include<ncurses.h>                                                                          
void printTriangle(int startrow,int startcol,int height);                            
void printRectangle(int startrow,int startcol,int height,int width);       

int main()
{
initscr();
start_color();

init_pair(1,4,7);
init_pair(2,4,2);
init_pair(3,2,3);


attrset(COLOR_PAIR(1));
printTriangle(5,18,3);


attrset(COLOR_PAIR(2));
printRectangle(5,15,9,2);

attrset(COLOR_PAIR(3));
        printRectangle(15,13,1,6);

getch();
endwin();
return 0;
}
//----------------------------------------------------------------------------------

void printTriangle(int startrow,int startcol,int height)
{
int x=startcol;

for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=x;c++)
{
move(r,c);
printw("*");
}
x++;

}

}

//----------------------------------------------------------------------------------
void printRectangle(int startrow,int startcol,int height,int width)
{
for(int r=startrow;r<=startrow+height;r++)
{
for(int c=startcol;c<=startcol+width;c++)
{
move(r,c);
printw("*");
}
}

}



Hope you really enjoyed these kind of programming very well.See you in another interesting ncurses programming post.