**Updated to clarify** Note: My professor uses only Linux and although he does n
ID: 3784259 • Letter: #
Question
**Updated to clarify** Note: My professor uses only Linux and although he does not expect us to use Linux, he expects our programs to run properly on his end. Also, this is an introductory C++ class so I cannot used advanced libraries. This is an animation program without any specific guidelines as to what the animation has to be, only that it has to read a command file and animate based on the input file.
Update: To answer the question, the screen size is 80x25 (80 chars across by 25 lines) and I've bolded it below.
Description
This project is meant to display animation on the screen based upon commands provided by an input file. It will read in a command file and perform each action, line by line. In this way, the program will act as an "animation engine".
You may assume a screen size of 80x25 (80 chars across by 25 lines).
Input
The command file is a file containing keywords followed by arguments. It may also contain blank lines and/or comments. Both are optional but your program must be able to support them.
Also, the command input file will be provided via a "command line parameter" (see below).
Commands
The following commands are the minimal set your program must support:
* After any cursor involved action, put the cursor back at (0,0). It will improve the visual.
Output
The output of your program is two-fold. On screen, the user will see your beautiful animated artwork. Additionally, you will output information to a log file. The log file shall be namedproject2.log and will contain information of any erroneous commands encountered.
For example, consider the following input file:
The output log file should contain something like:
The log file should be re-created/overwritten for every execution of the program.
Execution
I will be running your programs in one of the following two ways:
Input File as Command-Line Parameter
To get the input file as a command-line parameter, we need to now add parameters to the main() and use those like so:
Don't worry about what the params mean, we'll learn those next week (but would have been too close to the due date).
WARNING: if you don't put a filename as the command line parameter, the program will crash. Don't worry about this, you are not currently responsible for handling that:
Assumptions
You may assume the following:
The screen is 80 characters across by 25 lines down.
The commands in the command file are all lower-case.
The row and col arguments to the commands are within valid ranges (i.e. no "negative" rows or cols)
Any char argument is in fact only 1 character
Any deviations in a command file that violate these assumptions are not your responsibility to handle in code.
You may not assume the following:
The command keywords are typed correctly (i.e. no typos)…this is the purpose of the log file.
Color arguments are in valid ranges (log errors)
Command Args Description clear* Clears the screen setms n Sets the pause milliseconds to n. setfg n Sets the text color to n (should only be 30-39) setbg n Sets the background color to n (should only be 40-49) pause Pauses the processing for whatever time last setms value was. slow Pause afer every line of command input (not including blanks and comments) fast Pause only when the pause command is encountered (i.e. turns off pause after every command) plot* row col char Places the cursor at (row, col) and prints char hplot* row col char cnt Places the cursor at (row, col) and prints cnt /char/s to the right. vplot* row col char cnt Places the cursor at (row, col) and prints cnt /char/s down. text* row col string Places the cursor at (row, col) and prints string move* row col h w Dr Dc Moves the contents of the box at (row, col), with height h and width w, Dr and Dc spaces copy* row col h w Dr Dc Copies the box at (row, col), with height h and width w, to (row + Dr, col + Dc) // {comment} Comment line; entire line is ignored by program quit Notifies the program to stop reading inputExplanation / Answer
Here is complete code for your requirement. For your information you might want to split the commands into different questions as it is not possible to code for all of them in a short duration. Since there was no sample commands file, just created a dummy file and tested. Play with the program by changing the commands in the file. Any errors are logged into projects.log fileYou may test it with your file and please do rate teh answer if it works as intended. Please do leave a feedback in comments section on how the program works or any errors.Thanks
compile the program using
g++ <filename>.cpp
execute the program
./a.out sample.txt
=======================
sample.txt
=========
clear*
setms 250
plo 10 10 ^
pause
cop 10 20 5 5 20 10
// dkf;sksf
///
/dkdfflds
setms 1000
slow
setfg 35
setbg 44
hplot* 12 10 * 15
vplot* 12 10 * 15
hplot* 13 13 + 3
move* 13 13 3 1 0 4
//fast
setfg 33
hplot* 10 10 * 10
setfg 32
hplot* 15 10 * 10
setbg 45
vplot* 10 10 * 5
//setbg 42
vplot* 10 20 * 5
quit
================
engine.cpp
==========
/* This porgram using ANSI escape code to make strings to output on console.
string formats are as follows:
[2J - to clear screen
[F;Bm - to display with foreground and background, where F is foreground color starting at 30, and B is background color starting at 40
[R;Cf - to position cursor, R is row adC is coloumn
*/
#include <iostream>
#include <fstream>
#include <cstdlib>
/*Defining these constants will help later to change it when ever needed without touching the rest of code*/
#define MAX_COMMAND_SIZE 30
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 25
using namespace std;
//function to pause the system
void pause( int milliseconds )
{
int limit = clock() + milliseconds *CLOCKS_PER_SEC/ 1000.0;
while ( clock() < limit ) {
; // Do nothing...just wait
}
}
//function to remove any extra spaces in being , etween and end
void cutExtraSpaces(char buff[],string &newstr)
{
newstr.clear();
int i=0;
//remove spaces in beginnning
for(;buff[i]!='';i++)
{
if(buff[i]==' ' || buff[i]==' ' || buff[i]==' ')
continue;
else
break;
}
bool separatorSeen=false;
for(;buff[i]!='';i++)
{
if(buff[i]==' ' || buff[i]==' ' || buff[i]==' ')
{
if(!separatorSeen)
separatorSeen=true;
}
else
{
//add only a single space if a separator was seen earlier
if(separatorSeen)
{
newstr.append(" ");
separatorSeen=false;
}
newstr+=buff[i];
}
}
}
void process(ifstream &cmd, ofstream &log)
{
string commandline="",command;
char buffer[MAX_COMMAND_SIZE];
int line=0,index,num,arg[10];
char commandformat[MAX_COMMAND_SIZE]="";
const char *args;
int pausetime=0;
bool slow=false;
char ch;
int fore=39,back=40;
//because we cant get the characters on screen, we maintain to store the characters displayed on screen, update this buffer whenever you display on the screen
char screen[SCREEN_HEIGHT+1][SCREEN_WIDTH+1];
//initialize screen bufffer with space
for(int i=0;i<SCREEN_HEIGHT+1;i++)
for(int j=0;j<SCREEN_WIDTH+1;j++)
screen[i][j]=' ';
while(!cmd.eof())
{
line++;
sprintf(commandformat,"");
if(cmd.getline(buffer,MAX_COMMAND_SIZE)==0)
return;
//remove all extra space characters before processing
cutExtraSpaces(buffer,commandline);
if(commandline.length()!=0) //skip empty line
{
index=commandline.find(" ");
if(index==string::npos)//only command name found , no arguments
{
command=commandline;
}
else
{
command=commandline.substr(0,index);
args=commandline.substr(index+1).data();
}
if(command.compare("clear*")==0)
{
sprintf(commandformat,"[2J");//ANSCI sequence for clearing screen
cout<<commandformat<<flush;
}
else if(command.compare("setms")==0)
{
sscanf(args,"%d",&arg[0]);
pausetime=arg[0];
cout<<commandformat<<flush;
}
else if(command.compare("setfg")==0)
{
sscanf(args,"%d",&arg[0]);
fore=arg[0];
}
else if(command.compare("setbg")==0)
{
sscanf(args,"%d",&arg[0]);
back=arg[0];
}
else if(command.compare("pause")==0)
{
pause(pausetime);
}
else if(command.compare("slow")==0)
{
slow=true;
}
else if(command.compare("fast")==0)
{
slow=false;
}
else if(command.compare("plot*")==0)
{
sscanf(args,"%d %d %c",&arg[0],&arg[1],&ch);
sprintf(commandformat,"[%d;%df[%d;%dm%c",arg[0],arg[1],fore,back,ch);
screen[arg[0]][arg[1]]=ch;
cout<<commandformat<<flush;
}
else if(command.compare("hplot*")==0)
{
sscanf(args,"%d %d %c %d",&arg[0],&arg[1],&ch,&arg[2]);
//using [R;Cf format along with [F;Bm format
for(int i=0;i<arg[2];i++)
{
sprintf(commandformat,"[%d;%df[%d;%dm%c",arg[0],arg[1]+i,fore,back,ch);
screen[arg[0]][arg[1]+i] =ch;
cout<<commandformat<<flush;
}
}
else if(command.compare("vplot*")==0)
{
sscanf(args,"%d %d %c %d",&arg[0],&arg[1],&ch,&arg[2]);
for(int i=0;i<arg[2];i++)
{
//using [R;Cf format along with [F;Bm format
sprintf(commandformat,"[%d;%df[%d;%dm%c",arg[0]+i,arg[1],fore,back,ch);
screen[arg[0]+i][arg[1]]=ch;
cout<<commandformat<<flush;
}
}
else if(command.compare("move*")==0 || command.compare("copy*") ==0)
{
sscanf(args,"%d %d %d %d %d %d",&arg[0],&arg[1],&arg[2],&arg[3],&arg[4],&arg[5]);
for(int row=arg[0],i=0;i<arg[4];i++)
{
for(int col=arg[1],j=0;j<arg[5];j++)
{
ch=screen[row+i][col+j];
//if move wipe out character place cursor in same location and erase out by printing space
if(command.compare("move*")==0)
{
//using [R;Cf format along with [F;Bm format
sprintf(commandformat,"[%d;%df[%d;%dm%c",row+i,col+j,fore,back,' '); //put a space character to erase
screen[row+i][col+j]=' ';
cout<<commandformat<<flush;
}
//now move to new location and write out the character read before
sprintf(commandformat,"[%d;%df[%d;%dm%c",row+arg[4]+i,col+arg[5]+j,fore,back,ch);
screen[row+arg[4]+i][col+arg[5]+j]=ch;
cout<<commandformat<<flush;
}
}
}
else if(command.substr(0,2).compare("//")==0) //check if command is comment
{
//do nothing
}
else if(command.compare("quit")==0)
{
return;
}
else //invalid command, enter into log file
{
log<<"Error: Line "<<line<<"- bad command ""<<command<<"",skipping"<<endl;
}
}
if(slow)
pause(pausetime);
}
}
int main(int c, char * argv[])
{
ifstream cmd;
ofstream log; //output file
//open the command file
cmd.open(argv[1]);
log.open("project2.log");
int line=0;
/* if fopen( ) was not successful there was an error, so exit with error */
if(!cmd.is_open() )
{
cout<<"Error opening command file";
exit(1);
}
if(!log.is_open())
{
cout<<"Error opening log file ";
exit(1);
}
/*Now continue reading the file till end of file reached*/
process(cmd,log);
cout<<" Quitting."<<endl;
cmd.close();
log.close();
exit(0);
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.