/* CSC15 Lab9 : Horse Race Due 5/2/2001 For this lab you are to use arrays and loops to complete a horse race simulation. The lab is roughly similar to the florida recount simulation we did a few weeks ago, except it involves an array of horses. Download this file and the files "horseframe1.gif", "horseframe2.gif", and "hrbackground.gif" from the homepage. I have defined the following class, included below: class horse: This class contains information pertaining to a specific horse; The expression that creates a horse object is: horse("my horse", 0,60); The first argument to the constructor is a string representing the name of this horse, the 2nd and 3rd arguments are the initial x and y coordinates of the position of the horse. Initially, the x coordinate should be 0. The y coordinate depends on the horse (see below). Each horse object has the following public methods that you can call: void moveForward(int step); // increases x coordinate by step. int position() // returns the current x coordinate of the horse // The x coordinate is private and can't be accessed directly This program basically consists of two functions, both are part of the "horserace class", and are marked below in the code. The first function, determineleader, must return a number from 0-4, indicating which horse is in the lead. If there's a tie, it must return -1. The second, and main function, is called startrace. This function will have access to the following variables, which are already declared in the class (so you don't have to have parameters that redefine them): int winner; // this variable represents the current leader in the race It can be 0-4, or -1 if there is a tie. int HN; // number of horses in the race; THIS CAN BE CHANGED! horse H[5]; // an array of 5 horses. (assuming HN==5, but can be different) Note that this array has been declared, but NOT initialized. In the startrace function you will have to call the constructor of the horse class to create each horse object, such as H[0] = horse("Speedy Racer",0,60); //, and etc ... You should create all HN horses, with different names. The x coordinates of the horses should all be 0 (representing the starting position). The y coordinates of the nth horse should be set to n*60 - for example, the 0th horse will have y coordinate 0, the 3rd horse will have 180. You can also call the following functions: int randomnum(int min, int max) returns a random integer between min and max, inclusive. void update(int delay) will update the graphical representation of the race. delay is a value in millseconds that defines the gap between animation frames. This value should be about 30-50, depending on your machine. Your startrace function should consist of the following components: 1. You need to declare additional variables. One of these variables should be a boolean variable called stoprace, which should be initially set to false. This variable should be used as the test of a while loop 2. Initialize the H (horses) array as explained above 3. Call the update function once initially before starting the main loop. This will make sure that the horses are displayed in their starting positions. 4. Write a while loop that continues until the stoprace bool variable becomes true. inside this loop, you need to: write an *inner loop* that goes through the array of horses, and call moveForward on each horse object, giving it a random number between 0 and 5. If the x position of any horse becomes greater than 728, you should set stoprace to true. After this inner loop, you then need to reset the winner variable by calling the determineleader function you defined above. Finally, at the end of the (outer) while loop you should call update to display the race graphically. For the determineleader function, you likewise have access to the H (horses) array, and therefore the current positions of all the horses (H[i].position()). You need to use this information to determine the current winner (0-4), or a tie (-1). Note: this function should not set the winner variable directly: it should return an integer representing the winner. REMEMBER: your program must work with different number of horses. To change of the number of horses in the race, you have to: 1. change the declaration of the H[] array in the private section of the horserace class. 2. change the initial value of HN in the constructor of the horserace class 3. create the right number of horse objects in your startrace function. YOUR PROGRAM MUST BE VISUALLY CHECKED BY INSTRUCTOR OR A TA. Turn in your well-commented code (just your code, not mine). */ // Horse Race by Chuck Liang. For Academic Uses Only. // gif images were downloaded from the web #include #include #include #include #include #include #include #include #include // for random number generation #include #include #include // Some commonly used constants ; ignore #define myblack QColor(0,0,0) #define myblue QColor(0,0,255) #define myred QColor(255,0,0) #define mygreen QColor(0,255,0) #define mywhite QColor(255,255,255) #define standardGap 120 // time (ms) gap between animation frames #define standardRot 10 // degree of rotation of figures #define TW 800 #define LH 60 #define STEP 6 class horse { private: int x, y; // x and y coordinates of horse public: QString name; // name for horse int frameswitch; // controls which frame to show (-1 or +1); horse(const char n[64], int x0, int y0) // constructor { name = QString(n); x = x0; y = y0; frameswitch = -1; } // end constructor horse() { } // alternate, dummy constructor ~horse() {} // this method draws horse at new x coord on double buffer void moveForward(int steps) { x = x + steps; // advance x coordinate; } // end moveForward int position() { return x; } // returns current x coordinate }; // end class horse // main Qt application class: class horserace : public QWidget { private: QPixmap* canvas; // off-screen graphics buffer QTime curTime; // time used for delaying purposes QPainter* display; // displays canvas on screen QImage* backimg; // background image QImage* horseimg; // 1st animation frame QImage* horseimg2; // 2nd animation frame QPainter* brush; // used to draw to canvas buffer int winner; QString ws; horse H[6]; // **change this line to alter number of horses** int HN, TH; public: horserace() { struct timeval tv; HN = 6; // **also change this line to alter number of horses** TH = (LH*HN)+50; resize(TW,TH); // sets size of the screen canvas = new QPixmap(TW,TH); // canvas->setOptimization(QPixmap::BestOptim); brush = new QPainter; // draws to buffer horseimg = new QImage("horseframe1.gif","gif"); horseimg2 = new QImage("horseframe2.gif","gif"); backimg = new QImage("hrbackground.gif", "gif"); display = new QPainter; // draws to screen setUpdatesEnabled( FALSE ); gettimeofday(&tv,NULL); // for random see generation srandom((int) tv.tv_usec % 100); // set random seed winner = -1; // -1 means no winner } void update(int sleeptime) // draw to screen, then delay by arg ms. { int i; // reset background: /* brush->setBrush(QBrush(green,SolidPattern)); brush->drawRect(0,0,TW,TH); // restart with white background brush->setBrush(QBrush(NoBrush)); */ brush->scale(TW/800.0, TH/350.0); // resize image to be drawn brush->drawImage(0,0,*backimg); brush->scale(800.0/TW, 350.0/TH); // reset size brush->setPen(QPen(black)); brush->setFont(QFont()); for(int i=1;i<=HN;i++) { brush->drawLine(0,(i*60)-5,TW-1,(i*60)-5); brush->drawText(0,(i*60)-7,H[i-1].name); } brush->drawLine(TW-15,0,TW-15,TH-1); // finish line for(i=0;idrawImage(H[i].position(),i*60,*horseimg); else brush->drawImage(H[i].position(),i*60,*horseimg2); H[i].frameswitch = H[i].frameswitch * -1; } brush->setPen(QPen(green)); brush->setFont(QFont("Times", 18, QFont::Bold)); if (winner >= 0) { // ws.sprintf("The Leader Is %s",H[winner].name); ws = QString("The leader is ") + H[winner].name; brush->drawText(200, TH-25,ws); } else brush->drawText(200,TH-25,"It's a Tie for the Lead"); brush->flush(); // forces immediate effect display->drawPixmap(0,0,*canvas); // draws to screen display->flush(); // forces immediate effect // delay by approx sleeptime milliseconds: delayby(sleeptime); } // end update void delayby(int ms) { int t; curTime.start(); while ( curTime.elapsed() < ms ) { } } int randomnum(int min, int max); int determineleader(); void startrace(); void paintEvent(QPaintEvent *) // overidden drawing procedure { int i; // Qt expects this procedure display->begin(this); // prepares the brush brush->begin(canvas); startrace(); brush->end(); display->end(); } }; // end class horserace int horserace::randomnum(int min, int max) { int j; j = ( random() % (max-min+1) ) + min; return j; } int main(int argc, char **argv) // main is entry point of entire program { QApplication theprogram(argc, argv); // but the real program is a Qt one horserace thewindow; // that uses a window! theprogram.setMainWidget(&thewindow); // sets the main window thewindow.show(); // shows and executes the Qt app. theprogram.exec(); return 0; // exists gracefully } /* *********************************************************************** */ /* YOUR CODE STARTS HERE */ /* ********* Write the determineleader function here ********** */ // determine leader of the race; // 0-4 indicates leader, -1 means tie. // Remember: this function is inside horserace class, so it has access // to the Horse array H directly. int horserace::determineleader() { } // end horserace::determineleader /* ********* Write the horserace function here ********** */ // Do not re-declare the H array, or variables winner and HN. // They're already declared in the class void horserace::startrace() { } // end horserace::startrace