ELEC2645 (2018/19) / Mbed 2 deprecated el17szs

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Cricket.cpp Source File

Cricket.cpp

00001 #include "Cricket.h"
00002 
00003 #define BALL_LIIMT 10
00004 
00005 //Constructor for the Cricket Object
00006 Cricket::Cricket()
00007 {
00008 
00009 }
00010 //Deconstructor for the Cricket Object
00011 Cricket::~Cricket()
00012 {
00013 
00014 }
00015 /*Initialises the Ball Object
00016   Initialises all the game objects
00017   sets the cricekt game variabes to intitial values
00018 */
00019 void Cricket::init(int ball_size,int bat_width,int bat_height)
00020 {
00021    _ux.init();
00022    _bat.init(bat_width,bat_height);
00023    _ball.init(ball_size);
00024    _scoreboard.init();
00025    _new_round=1;
00026    direction_set=0;
00027    _new_game=1;
00028    _fielders_count=0;
00029    _init_field_counter=0;
00030    init_positions();  //sets the positions for ball to be hit
00031    _set_hit=0;
00032    _set_loft=0;
00033    _position_no=-1;
00034    _check_bowled=0;
00035    _ball_limit=BALL_LIIMT;
00036    _check_hit=0;
00037    _loft_check=0;
00038    _check_update=-1;
00039 }
00040 
00041 //Resets the game variables for each round
00042 void Cricket::round_reset(){
00043    _ball.reset();
00044    _bat.reset();
00045    _new_round=0;
00046    direction_set=0;
00047    _fielders_count=0;
00048    _loft_check=0;
00049    _check_hit=0;
00050    _set_hit=0;
00051    _set_loft=
00052    _init_field_counter=0;
00053    init_positions();
00054    _position_no=-1;
00055    _check_bowled=0;
00056    _check_update=-1;
00057 }
00058 //resets the ux method and the game variables for start of new game.
00059 void Cricket::game_reset(){
00060     //pad.leds_off();
00061     _ux.reset();
00062     round_reset();
00063     _new_game=1;
00064     _scoreboard.reset(); //sets score to 0
00065     _ball.reset_ball_count(); //sets ball count to 0
00066 }
00067 
00068 //Calls the first menu when game is booted up
00069 
00070 void Cricket::intro(N5110 &lcd){
00071     _ux.first_menu(lcd);
00072 }
00073 /* Method checks the state of the game (start of new game or round) 
00074    and calls play_game() accordingly. */
00075 void Cricket::game(N5110 &lcd,Gamepad &pad){
00076      if (_new_game==1){  //_new_game acts as a flag to start a new game
00077          _scoreboard.generate_target();
00078          _ux.second_menu(lcd);  //calls the second menu giving user option to start game or read options 
00079          _new_game=0;
00080      }
00081      if (_new_round==1){
00082         if (game_status(lcd)==false){ //game_status returns false if the game is over
00083             game_reset(); //resets the game
00084         }
00085         else{  
00086           pad.leds_off();
00087           round_reset();  //resets the round variables
00088           set_field(lcd); //randomly sets a new field for each round
00089           _ball.increment_ball_count(); 
00090           play_game(lcd,pad); 
00091           _new_round=0;
00092         }
00093     }
00094     else{
00095         play_game(lcd,pad);
00096     }
00097 }
00098 /*Method to check current status of the game
00099   returns false is game is over and true if not */
00100 bool Cricket::game_status(N5110 &lcd){
00101     if (_scoreboard.compare_target()==true){   //checks if the player has reached the target score
00102              //printf("TARGET BLOCK"); //used for debugging
00103              _ux.victory_menu(lcd);
00104              game_reset();
00105              return false;
00106         }
00107         //checks if player has balls played has reached the limit
00108         else if(check_ball_count(lcd)==true){
00109            _ux.game_over_menu(lcd,1);
00110            game_reset();
00111            return false;
00112         }
00113         else{
00114             return true;
00115         }
00116 }
00117 /*Boolean function that checks if the current ball count has reached ball limit
00118  returns true if ball limit has been reached */
00119 bool Cricket::check_ball_count(N5110 &lcd){
00120     int count=_ball.get_ball_count(); //gets ball_count from ball object
00121     if (count==_ball_limit){
00122         _new_round=1;
00123         _ball.reset_ball_count();
00124         _new_game=1;
00125         return true;
00126     }
00127     else{
00128         return false;
00129     }
00130 }
00131 /*Method that checks if the target score has been accomplished
00132   and if true prints the Game Won screen */
00133 void Cricket::check_victory(N5110 &lcd){
00134     bool _victory_check=_scoreboard.compare_target();
00135         if (_victory_check==true){
00136             _ux.victory_menu(lcd);
00137             _new_game=1;
00138             _ball.reset_ball_count();
00139         }
00140 }
00141 
00142 /*Initialises te positions for the ball to be hit
00143   The ball can be hit in 7 positions in the game 
00144   according to the joystick orientation */
00145 void Cricket::init_positions(){
00146     set_init_positions(42,15,N,1);
00147     set_init_positions(84,30,E,2);
00148     set_init_positions(0,30,W,3);
00149     set_init_positions(2,44,SW,4);
00150     set_init_positions(0,2,NW,5);
00151     set_init_positions(65,2,NE,6);
00152     set_init_positions(60,44,SE,7);
00153 }
00154 /*Method to set the ball hit positions*/
00155 void Cricket::set_init_positions(int x,int y, Direction direction,int no){
00156     positions[_init_field_counter].x=x;
00157     positions[_init_field_counter].y=y;
00158     positions[_init_field_counter].dir=direction;
00159     positions[_init_field_counter].no=no;
00160     _init_field_counter++;
00161 }
00162 /*Method takes user input and sets the flags for the game accordingly */
00163 void Cricket::play_game(N5110 &lcd,Gamepad &pad){
00164     _check_hit=_bat.get_hit_ball(_ux); //checks if the ball has been hit
00165     if (_check_hit==1){
00166         _set_hit=1;
00167     }
00168     _loft_check=_bat.get_loft_ball(_ux); //checks if the ball hit is lofted
00169     if (_loft_check==1){
00170         _set_loft=1;
00171     }
00172     Direction dir=pad.get_direction(); //sets ball direction 
00173     if (_check_bowled!=1){ //checks if the ball has been bowled
00174         _check_bowled=_ball.ball_start(pad);
00175     }
00176     else{
00177         update_game(_set_hit, _set_loft, dir,pad,lcd); //updates the game
00178     }
00179 }
00180 void Cricket::update_game(int checkHit,int _loft_check, Direction dir,Gamepad &pad,N5110 &lcd){
00181   set_ball_direction(dir); //sets the direction for ball to be hit
00182   int fielder_check=check_fielder(ball_direction); //checks if there is a fielder in direction of ball
00183   
00184   if (checkHit!=1){ //checks if ball has been hit
00185       batsman_out(2,pad,lcd); //if false, batsman is out and game over
00186   }    
00187   if(direction_set==1 && checkHit==1){ //if direction is set and ball is hit game continues
00188   // checks if there is a fielder present in the direction of ball hit
00189   if (fielder_check!=-1){ 
00190      int _check_update=_ball.update_ball(field[fielder_check].x,field[fielder_check].y); //checks for position of ball
00191      
00192      //printf("Location x %i y %i\n",field[fielder_check].x,field[fielder_check].y);
00193      
00194      if (_loft_check==1){ //checks if hit is lofted
00195          if (_check_update==1) 
00196            batsman_out(3,pad,lcd); //lofted hit to a fielder is out and game over
00197      }
00198      //if batsman is not out, scoreboard is updating according to the runs scored
00199      else
00200          update_scoreboard(_check_update,field[fielder_check].position+1,pad);
00201         /*position+1 is used for runs argument  because a fielder inside the circle has position 0 and prodices 1 run
00202           whereas a fielder outside the circle has position number 1 and produces 2 runs. */
00203   }
00204   //If there is no fielder present
00205   if (fielder_check==-1){
00206         _check_update=_ball.update_ball(positions[_position_no].x,positions[_position_no].y);
00207         //printf("location x %i y %i\n  update %i\n",positions[_position_no].x,positions[_position_no].y,_check_update);
00208         if (_loft_check==1)
00209          update_scoreboard(_check_update,6,pad); //lofted shot in the gap is 6 runs
00210         else
00211             update_scoreboard(_check_update,4,pad); //normal shot in the gap is 4 runs
00212     }
00213 }
00214 }
00215 
00216 /* Method to update the score of the game
00217    Takes runs and check_update as arguments */
00218 void Cricket::update_scoreboard(int check_update, int runs,Gamepad &pad){
00219     //runs can only be updated after the ball has reached the destination co-ordinates
00220     if (check_update==1){ 
00221        /* if ball is hit straight there are no runs given
00222           This was done because hitting straight would form an easy way
00223           of scoring runs every round and would not make the game challenging */
00224         if (ball_direction==N){
00225             _scoreboard.update_score(0);
00226             pad.led(3,1.0);
00227             wait(0.5);
00228             _new_round=1;
00229         }
00230         else{
00231             _scoreboard.update_score(runs);
00232             pad.led(3,1.0);  //LED flashes to inform user that runs has been updated and get ready for new round
00233             wait(0.5);
00234             _new_round=1;
00235         }
00236     }
00237     pad.leds_off();
00238 }
00239 /*Method when batsman is out and game is over
00240   Method resets game and prints a screen to the LCD to inform user that game is over
00241 */
00242 void Cricket::batsman_out(int option,Gamepad &pad, N5110 &lcd){
00243     _scoreboard.reset();
00244     pad.led(1,1.0); //red LED indicates that the game is over
00245     pad.tone(750.0,0.5); //tone indicates that game is over
00246     _ball.reset_ball_count();
00247     _ux.game_over_menu(lcd,option);
00248     game_reset();
00249     _new_game=1;
00250     wait(2);
00251     pad.leds_off();
00252 }
00253 //Draws all the components of the Cricket to the LCD
00254 void Cricket::draw(N5110 &lcd){
00255     lcd.drawCircle((WIDTH/2),HEIGHT/2,23,FILL_TRANSPARENT);
00256     lcd.drawRect(37,11,12,30,FILL_TRANSPARENT);
00257     //calls draw method of game objects
00258     _ball.draw(lcd);
00259     draw_field(lcd);
00260     _bat.draw(lcd);
00261     _scoreboard.draw(lcd);
00262 }
00263 //Method to set the ball direction
00264 void Cricket::set_ball_direction(Direction dir){
00265     if (direction_set!=1){
00266         for (int i=0;i<_init_field_counter+1;i++){
00267             if(dir==positions[i].dir){
00268                 ball_direction=dir;
00269                 printf(" BALL DIRECTION %i x %i y %i \n",positions[i].no,positions[i].x,positions[i].y);
00270                 _position_no=i; //index of direction in array is stoed in the variable
00271                 direction_set=1; //toggles direction_set flag
00272                 break;
00273             }
00274         }
00275     }
00276 }
00277 /*Method that checks if a fielder is present in the direction of the ball*/
00278 int Cricket::check_fielder(Direction dir){
00279     if (dir==N){
00280         return -1;
00281     }
00282     /*loops through fielder array and checks if fielder is present in the direction*/
00283     for (int i=0;i<8;i++){
00284       if(dir == field[i].dir){
00285          return i;
00286      }
00287    }
00288    //returns -1 if no fielder is present
00289    return -1;
00290   }
00291 /*Draws the fielders by printing each fielder in the array to the LCD*/
00292 void Cricket::draw_field(N5110 &lcd){
00293     lcd.drawCircle(field[0].x,field[0].y,2,FILL_TRANSPARENT);
00294     lcd.drawCircle(field[1].x,field[1].y,2,FILL_TRANSPARENT);
00295     lcd.drawCircle(field[2].x,field[2].y,2,FILL_TRANSPARENT);
00296     lcd.drawCircle(field[3].x,field[3].y,2,FILL_TRANSPARENT);
00297     lcd.drawCircle(field[4].x,field[4].y,2,FILL_TRANSPARENT);
00298 }
00299 /*Method to set the fielders for the game 
00300  Loops through a for loop 6 times, generating a random number each time
00301  and sets a fielder based on the randon number*/
00302 void Cricket::set_field(N5110 &lcd){
00303     int d=0;
00304     int pos=0;
00305     int i=0;
00306     int continueCount=0;
00307     srand(time(NULL));
00308     while (_fielders_count!=5){
00309         d = 1+ rand() % 6;
00310         pos=rand()%2;
00311         for (int j=0;j<10;j++){
00312            //checks if the number generated has already been used to set a fielder
00313            if (fieldNumbers[j]==d){
00314                 continueCount=1;
00315             }
00316         }
00317         if (continueCount==1){
00318             continueCount=0;
00319             continue;
00320         }
00321         //sets fielders based on random number generated
00322         if (d==1){ //NW
00323             if (pos==1){
00324               field[i].dir=NW;
00325               field[i].x=30;
00326               field[i].y=9;
00327               field[i].position=1;
00328               fieldNumbers[i]=d;
00329               i++;
00330               _fielders_count++;
00331             }
00332             else{
00333               field[i].dir=NW;
00334               field[i].x=25;
00335               field[i].y=2;
00336               field[i].position=0;
00337               fieldNumbers[i]=d;
00338               i++;
00339               _fielders_count++;
00340             }
00341         }
00342 
00343         if (d==2){ //NE
00344             if (pos==1){
00345             field[i].dir=NE;
00346             field[i].x=55;
00347             field[i].y=9;
00348             field[i].position=1;
00349             fieldNumbers[i]=d;
00350               i++;
00351               _fielders_count++;
00352             }
00353             else{
00354             field[i].dir=NE;
00355                 field[i].x=65;
00356                  field[i].y=2;
00357                  field[i].position=0;
00358                  fieldNumbers[i]=d;
00359                   i++;
00360                   _fielders_count++;
00361             }
00362         }
00363         if (d==3){ //SW
00364             if (pos==1){
00365                 field[i].dir=SW;
00366                 field[i].x=33;
00367                 field[i].y=40;
00368                 field[i].position=1;
00369                 fieldNumbers[i]=d;
00370                 i++;
00371                 _fielders_count++;
00372             }
00373 
00374             else{
00375               field[i].dir=SW;
00376               field[i].x=25;
00377               field[i].y=44;
00378               field[i].position=0;
00379               fieldNumbers[i]=d;
00380               i++;
00381               _fielders_count++;
00382             }
00383         }
00384         if (d==4){ //SE
00385             if (pos==1){
00386               field[i].dir=SE;
00387               field[i].x=55;
00388               field[i].y=40;
00389               field[i].position=1;
00390               fieldNumbers[i]=d;
00391               i++;
00392               _fielders_count++;
00393             }
00394             else{
00395               field[i].dir=SE;
00396               field[i].x=65;
00397               field[i].y=44;
00398               field[i].position=0;
00399               fieldNumbers[i]=d;
00400               i++;
00401               _fielders_count++;
00402             }
00403         }
00404 
00405         if (d==5){ //W
00406             if (pos==1){
00407               field[i].dir=W;
00408               field[i].x=3;
00409               field[i].y=30;
00410               field[i].position=1;
00411               fieldNumbers[i]=d;
00412               i++;
00413               _fielders_count++;
00414             }
00415             else{
00416               field[i].dir=W;
00417               field[i].x=25;
00418               field[i].y=30;
00419               field[i].position=0;
00420               fieldNumbers[i]=d;
00421               i++;
00422               _fielders_count++;
00423             }
00424         }
00425         if (d==6){ //W
00426             if (pos==1){
00427                 field[i].dir=E;
00428                 field[i].x=80;
00429                 field[i].y=30;
00430                 field[i].position=1;
00431                 fieldNumbers[i]=d;
00432                 i++;
00433                 _fielders_count++;
00434             }
00435             else{
00436                  field[i].dir=E;
00437                 field[i].x=60;
00438                 field[i].y=30;
00439                 field[i].position=0;
00440                 fieldNumbers[i]=d;
00441                 i++;
00442                 _fielders_count++;
00443             }
00444         }
00445   }
00446 }
00447