#include <stdlib.h>
#include <stdio.h>
#include <math.h>

/*****************
 *   constants   *
 *****************/

#define SAVE_FMT         "%10s %d %d %d %d %d %d %d %d %d %d\n"
#define TEAM_SAVE_FMT    "%10s %d %d %d\n"
#define ROSTER_FMT       "%10s\n"

#define TRUE  1                  /*   logical constants                */
#define FALSE 0

#define GAMETIME 60              /*   initial game clock setting       */
#define SEC      .15             /*   game clock decrement             */
#define LDELAY   15000           /*   long time delay setting          */
#define SDELAY   0               /*   short delay setting              */

#define DRIVE 0                  /*   player action codes              */
#define PASS  1
#define SHOOT 2

#define DEF_FOUL    0            /*   result codes for player actions  */
#define FG2         1
#define FG3         2
#define TURNOVER    3
#define NO_CHANGE   4

/*************************
 *   System structures   *
 *************************/

typedef struct players {

   char name[10];         /*   player's name                    */
   int num;               /*   player's number                  */
   int perc_fg2;          /*   player skills : 2 pt FG%         */
   int perc_fg3;          /*                   3 pt FG%         */
   int perc_ft;           /*                   FT%              */
   int perc_reb;          /*                   rebound %        */
   int perc_blk;          /*                   block shot %     */
   int perc_steal;        /*                   steal ball %     */
   int perc_shoot;        /*   player actions: shoot the ball % */
   int perc_pass;         /*                   pass the ball %  */
   int perc_drive;        /*                   drive to basket% */
   int fg2_made;          /*   game stats : 2 pt FGs made       */
   int fg2_att;           /*                2 pt FGs attempted  */
   int fg3_made;          /*                3 pt FGs made       */
   int fg3_att;           /*                3 pt FGs attempted  */
   int ft_made;           /*                FTs made            */
   int ft_att;            /*                FTs attempted       */
   int num_reb;           /*                number of rebounds  */
   int num_blk;           /*                number of blocks    */
   int num_steal;         /*                number of steals    */

} PLAYER, *PLAYER_PTR;

typedef struct teams {

   char team_name[10];        /*   name of team           */
   struct players *(pl[5]);   /*   players on that team   */
   int score;                 /*   current score          */
   int foul;
   int win;                   /*   number of wins         */
   int loss;                  /*   number of losses       */
   int tie;                   /*   number of ties         */

} TEAM, *TEAM_PTR;

/************************
 *   Global variables   *
 ************************/

int ball = 0;
TEAM_PTR team_a = NULL, team_b = NULL;
float time;
int delay = 0;
int back_court;                    /*   to force at least one pass   */
int shooting;                      /*   in the act of shooting ?     */

/********************
 *   main program   *
 ********************/

main()

{
   char dummy[1];
   int act = 0, seed = 0, ans = 0;
   int i,games = 0;
   int menu(), opt = 0;
   TEAM_PTR off, def;
   TEAM_PTR maketeam(), load_team(), jump_ball(), proc_action();

   printf("Enter RANDOM number seed = ");
   scanf("%d",&seed);
   srand(seed);

   while (opt != 3) {
      opt = menu();               /*   show menu & get option   */
      switch (opt) {
         case 0 :
            exit(0);
            break;
         case 1 :
            new_player();
            break;
         case 2 :
            new_team();
            break;
         case 3 :
            team_a = load_team();
            team_b = load_team();
            if ((team_a != NULL) && (team_b != NULL)) {
               show_team(team_a);
               show_team(team_b);
               printf("\nPress <enter> to continue");
               scanf("%s",dummy);
               }
            else
               opt = 0;
            break;
         case 4 :
            team_a = load_team();
            if (team_a != NULL) {
               show_team(team_a);
               printf("\nPress <enter> to continue");
               scanf("%s",dummy);
               }
            break;
         case 5 :
            list_players();
            printf("\nPress <enter> to continue");
            scanf("%s",dummy);
            break;
         }
      }

   printf("\nDo you want a Long time delay ? (0 - NO, 1 - YES) ");
   scanf("%d",&ans);
   if (ans)
      delay = LDELAY;
   else
      delay = SDELAY;
   printf("Enter number of games to be played : ");
   scanf("%d",&games);

   for (i = 0;i < games; i++) {

      time = GAMETIME;
      team_a->score = 0;
      team_b->score = 0;
      team_a->foul = 0;
      team_b->foul = 0;
      printf("\n\nGame time !!!\n\n");
      printf("The %s vs. the %s\n",team_a->team_name,team_b->team_name);
      
      off = jump_ball(team_a,team_b);
      def = (off == team_a) ? team_b : team_a ;
      
      while (time > 0) {
         shooting = FALSE;
         act = action(off);                            /*   determine action   */
         off = proc_action(off,def,act);               /*   do action          */
         def = (off == team_a) ? team_b : team_a ;
         time -= SEC;                                  /*   decrement time     */
         }
      
      printf("\nBZZZZZZZZZZZZ...the game is over !!!\n");
      
      if (team_a->score > team_b->score) {
         printf("\n*** The %s win it !!!\n",team_a->team_name);
         (team_a->win)++;
         (team_b->loss)++;
         }
      else if (team_b->score > team_a->score) {
         printf("\n*** The %s win it !!!\n",team_b->team_name);
         (team_b->win)++;
         (team_a->loss)++;
         }
      else {
         printf("*** Its a TIE !!!\n");
         (team_a->tie)++;
         (team_b->tie)++;
         }
      
      printf("\n*** Final Score : %s %d   %s %d\n",team_a->team_name,team_a->score,team_b->team_name,team_b->score);
      
      show_game(team_a);
      show_game(team_b);

      }       /*   next    i   */

   printf("Press <enter> to continue");
   scanf("%s",dummy);

   printf("\n*** Final Statistics ***\n");
   show_game(team_a);
   show_game(team_b);

   printf("\nDo you wish to save the team records ? ");
   scanf("%d",&ans);
   if (ans) {
      save_team(team_a);
      save_team(team_b);
      }

}   /*   end of main program   */

/*****************
 *   main menu   *
 *****************/

int menu()

{
   int ret_val = 0;

   printf("\n\n\n\n\n");
   printf("                   COMPUTER BASKETBALL 2.0\n\n");
   printf("                       0) EXIT\n");
   printf("                       1) Create new player\n");
   printf("                       2) Create new team\n");
   printf("                       3) Pick teams/play game\n");
   printf("                       4) Show a team\n");
   printf("                       5) List players\n");
   printf("\n                       Select : ");
   scanf("%d",&ret_val);

   return(ret_val);
}

/******************
 *   new player   *
 ******************/

new_player()

{
   char *calloc();
   int ans = 0;
   PLAYER_PTR rand_player(), enter_player(), pp;

   printf("\nDo you want a randomly generated player (1 - yes/0 - no) ? ");
   scanf("%d",&ans);
   if (ans)
      pp = rand_player();
   else
      pp = enter_player();
   show_player(pp);

   printf("\nDo you wish to save this player (1 - yes/0 - no) ? ");
   scanf("%d",&ans);
   if (ans)
      save_player(pp);
}

/*********************
 *   random player   *
 *********************/

PLAYER_PTR rand_player()

{
   int i;
   PLAYER_PTR pp;

   pp = (PLAYER_PTR) calloc(1,sizeof(PLAYER));

   printf("\nEnter name of player : ");
   scanf("%s",pp->name);
   printf("Enter number of player : ");
   scanf("%d",&(pp->num));

   pp->perc_fg3 = random(0,50);
   pp->perc_ft = random(60,95);
   pp->perc_fg2 = random(40,70);
   pp->perc_reb = random(5,50);
   pp->perc_steal = random(5,50);
   pp->perc_blk = (int) (.25 * (pp->perc_reb));
   pp->perc_shoot = (int) (pp->perc_fg2);
   pp->perc_drive = (int) (pp->perc_reb / 2);
   pp->perc_pass = (100 - (pp->perc_shoot) - (pp->perc_drive));

   return(pp);
}

/**********************
 *   enter a player   *
 **********************/

PLAYER_PTR enter_player()

{
   PLAYER_PTR pp;

   pp = (PLAYER_PTR) calloc(1,sizeof(PLAYER));

   printf("\nEnter name of player : ");
   scanf("%s",pp->name);
   printf("Enter number of player : ");
   scanf("%d",&(pp->num));
   printf("Enter 2 point FG %% : ");
   scanf("%d",&(pp->perc_fg2));
   printf("Enter 3 point FG %% : ");
   scanf("%d",&(pp->perc_fg3));
   printf("Enter free throw %% : ");
   scanf("%d",&(pp->perc_ft));
   printf("Enter rebounding %% (5 - 50) : ");
   scanf("%d",&(pp->perc_reb));
   printf("Enter ball stealing %% (5 - 50) : ");
   scanf("%d",&(pp->perc_steal));
   pp->perc_blk = (int) (.25 * (pp->perc_reb));
   pp->perc_shoot = (int) (pp->perc_fg2);
   pp->perc_drive = (int) (pp->perc_reb / 2);
   pp->perc_pass = (100 - (pp->perc_shoot) - (pp->perc_drive));

   return(pp);
}

/*******************
 *   show player   *
 *******************/

show_player(pp)

PLAYER_PTR pp;

{
   printf("\nName : %s     Number : %d\n",pp->name,pp->num);
   printf("   2 pt FG%% : %d\n",pp->perc_fg2);
   printf("   3 pt FG%% : %d\n",pp->perc_fg3);
   printf("   FT %%     : %d\n",pp->perc_ft);
   printf("   Reb %%    : %d\n",pp->perc_reb);
   printf("   Steal %%  : %d\n",pp->perc_steal);
   printf("   Block %%  : %d\n",pp->perc_blk);
   printf("   Player action - Shoot %% : %d\n",pp->perc_shoot);
   printf("                   Drive %% : %d\n",pp->perc_drive);
   printf("                   Pass %%  : %d\n",pp->perc_pass);
}

/*********************
 *   save a player   *
 *********************/

save_player(pp)

PLAYER_PTR pp;

{
   int ans;
   FILE *fopen(), *fp;

   ans = 0;
   if ((fp = fopen(pp->name,"r")) != NULL) {
      printf("\nPlayer already exists, Overwrite (1 - yes/0 - no) ? ");
      scanf("%d",&ans);
      }
   if ((fp == NULL) || (ans)) {
      printf("\nSaving...\n");
      fclose(fp);
      fp = fopen(pp->name,"w");
      fprintf(fp,SAVE_FMT,pp->name,pp->num,pp->perc_fg2,pp->perc_fg3,
                          pp->perc_ft,pp->perc_reb,pp->perc_steal,
                          pp->perc_blk,pp->perc_shoot,pp->perc_drive,
                          pp->perc_pass);
      printf("\nDone...\n");
      }
   else
      printf("\nPlayer NOT saved...\n");
   fclose(fp);
}

/*********************
 *   load a player   *
 *********************/

PLAYER_PTR load_player()

{
   PLAYER_PTR pp = NULL;
   char name[10], *calloc();
   FILE *fopen(), *fp;

   printf("\nEnter name of player to load : ");
   scanf("%s",name);
   if ((fp = fopen(name,"r")) == NULL)
      printf("\nPlayer does NOT exist...\n");
   else {
      printf("\nLoading...\n");
      pp = (PLAYER_PTR) calloc(1,sizeof(PLAYER));
      fscanf(fp,SAVE_FMT,pp->name,&(pp->num),&(pp->perc_fg2),&(pp->perc_fg3),
                         &(pp->perc_ft),&(pp->perc_reb),&(pp->perc_steal),
                         &(pp->perc_blk),&(pp->perc_shoot),&(pp->perc_drive),
                         &(pp->perc_pass));
      printf("\nDone...\n");  
      }                       
   fclose(fp);                
                              
   return(pp);                
}                             

/***********************
 *   list of players   *
 ***********************/

list_players()

{
   FILE *fopen(), *fp, *rp;
   PLAYER_PTR pp;
   char name[10];

   pp = (PLAYER_PTR) calloc(1,sizeof(PLAYER));
   printf("\nName        #    2 pt FG%%   3 pt FG%%   FT%%   Reb%%   Blk%%   Steal%%\n");
   printf("-----------------------------------------------------------------------\n");
   if ((rp = fopen("ROSTER.DIR","r")) == NULL)
      printf("Unable to open file ROSTER.DIR\n");
   else {
      while ((fscanf(rp,ROSTER_FMT,name)) != EOF) {
         if ((fp = fopen(name,"r")) == NULL)
            printf("\nPlayer : %10s does NOT exist...\n",name);
         else {
            fscanf(fp,SAVE_FMT,pp->name,&(pp->num),&(pp->perc_fg2),&(pp->perc_fg3),
                               &(pp->perc_ft),&(pp->perc_reb),&(pp->perc_steal),
                               &(pp->perc_blk),&(pp->perc_shoot),&(pp->perc_drive),
                               &(pp->perc_pass));
            fclose(fp);
            printf("%10s  %2d ",pp->name,pp->num);
            printf("    %2d %%",pp->perc_fg2);
            printf("       %2d %%",pp->perc_fg3);
            printf("     %2d %%",pp->perc_ft);
            printf("  %2d %%",pp->perc_reb);
            printf("   %2d %%",pp->perc_blk);
            printf("     %2d %%\n",pp->perc_steal);
            }
         }
      fclose(rp);
      }
}
                              
/****************             
 *   new team   *             
 ****************/

new_team()

{
   int i, ans = 0;
   char *calloc(), name[10];
   PLAYER_PTR load_player();
   TEAM_PTR maketeam(), tp = NULL;

   printf("\nDo you wish a randomly created team (1 - yes/0 - no) ? ");
   scanf("%d",&ans);
   if (ans) {
      printf("\nGenerating a new team...\n");
      tp = maketeam();
      }
   else {
      printf("\nLoading players to form a team :\n ");
      tp = (TEAM_PTR) calloc(1,sizeof(TEAM));
      printf("\nEnter team name : ");
      scanf("%s",tp->team_name);
      for (i = 0;i < 5; i++) {
         while ((tp->pl[i]) == NULL) {
            (tp->pl[i]) = load_player();
            show_player(tp->pl[i]);
            }
         }         /*   next i   */
      }            /*   endif    */
   show_team(tp);
   printf("\nDo you wish to save this team (1 - yes/0 - no) ? ");
   scanf("%d",&ans);
   if (ans)
      save_team(tp);
}

/*****************
 *   load team   *
 *****************/

TEAM_PTR load_team()

{
   char name[10], *calloc();
   int i;
   PLAYER_PTR pp = NULL;
   TEAM_PTR tp = NULL;
   FILE *fopen(), *fp;

   printf("\nEnter name of team to load : ");
   scanf("%s",name);
   if ((fp = fopen(name,"r")) == NULL)
      printf("\nTeam does NOT exist\n");
   else {
      printf("\nLoading...\n");
      tp = (TEAM_PTR) calloc(1,sizeof(TEAM));
      fscanf(fp,TEAM_SAVE_FMT,tp->team_name,&(tp->win),&(tp->loss),&(tp->tie));
      for (i = 0;i < 5; i++) {
         pp = (PLAYER_PTR) calloc(1,sizeof(PLAYER));
         fscanf(fp,SAVE_FMT,pp->name,&(pp->num),&(pp->perc_fg2),&(pp->perc_fg3),
                            &(pp->perc_ft),&(pp->perc_reb),&(pp->perc_steal),
                            &(pp->perc_blk),&(pp->perc_shoot),&(pp->perc_drive),
                            &(pp->perc_pass));
         (tp->pl[i]) = pp;
         }
      printf("\nDone...\n");
      }
   fclose(fp);

   return(tp);
}

/*****************
 *   save team   *
 *****************/

save_team(tp)

TEAM_PTR tp;

{
   int i, ans = 0;
   PLAYER_PTR pp;
   FILE *fopen(), *fp;

   if ((fp = fopen(tp->team_name,"r")) != NULL) {
      printf("\nTeam already exists, Overwrite (1 - yes/0 - no) ? ");
      scanf("%d",&ans);
      }
   if ((fp == NULL) || (ans)) {
      printf("\nSaving...\n");
      fclose(fp);
      fp = fopen(tp->team_name,"w");
      fprintf(fp,TEAM_SAVE_FMT,tp->team_name,tp->win,tp->loss,tp->tie);
      for (i = 0;i < 5; i++) {
         pp = tp->pl[i];
         fprintf(fp,SAVE_FMT,pp->name,pp->num,pp->perc_fg2,pp->perc_fg3,
                             pp->perc_ft,pp->perc_reb,pp->perc_steal,
                             pp->perc_blk,pp->perc_shoot,pp->perc_drive,
                             pp->perc_pass);
         }
      printf("\nDone...\n");
      }
   else
      printf("\nTeam NOT saved...\n");
   fclose(fp);
}

/*******************
 *   make a team   *
 *******************/

TEAM_PTR maketeam()

{
   int i;
   char *calloc();
   TEAM_PTR tp;
   PLAYER_PTR pp, rand_player();

   tp = (TEAM_PTR) calloc(1,sizeof(TEAM));

   printf("\nEnter Team name : ");
   scanf("%s",tp->team_name);
   for (i = 0; i < 5; i++) {
      pp = (PLAYER_PTR) calloc(1,sizeof(PLAYER));

      tp->pl[i] = rand_player();
      }
   return(tp);
}

/*****************
 *   show team   *
 *****************/

show_team(tp)

TEAM_PTR tp;

{
   int i;
   PLAYER_PTR pp;

   printf("\n*** Team : %s ***   Record : %2d - %2d - %2d\n",tp->team_name,tp->win,tp->loss,tp->tie);
   printf("\nName        #  Posi     2 pt FG%%   3 pt FG%%   FT%%   Reb%%   Blk%%   Steal%%\n");
   for (i = 0;i < 5; i++) {
      pp = tp->pl[i];
      printf("%10s  %2d ",pp->name,pp->num);
      if ((i == 0) || (i == 1))
         printf("guard  ");
      else if ((i == 2) || (i == 3))
         printf("forward");
      else if (i == 4)
         printf("center ");
      printf("    %2d %%",pp->perc_fg2);
      printf("       %2d %%",pp->perc_fg3);
      printf("     %2d %%",pp->perc_ft);
      printf("  %2d %%",pp->perc_reb);
      printf("   %2d %%",pp->perc_blk);
      printf("     %2d %%\n",pp->perc_steal);
      }
}

/***********************
 *   show game stats   *
 ***********************/

show_game(tp)

TEAM_PTR tp;

{
   int i;
   float att2 = 0, made2 = 0, att3 = 0, made3 = 0, attft = 0, madeft = 0, rebs = 0, blks = 0, steals = 0;
   float fg2perc, fg3perc, ftperc;
   PLAYER_PTR pp;

   printf("\n*** Team : %s ***   Record : %2d - %2d - %2d\n",tp->team_name,tp->win,tp->loss,tp->tie);
   printf("                           2 pt.      3 pt.       FT\n");
   printf("Name        #  Posi     made  att  made  att  made  att  Rebs  Blks  Stls\n");
   for (i = 0;i < 5; i++) {
      pp = tp->pl[i];
      printf("%10s  %2d ",pp->name,pp->num);
      if ((i == 0) || (i == 1))
         printf("guard  ");
      else if ((i == 2) || (i == 3))
         printf("forward");
      else if (i == 4)
         printf("center ");
      printf("   %2d",pp->fg2_made);
      printf("   %2d",pp->fg2_att);
      printf("    %2d",pp->fg3_made);
      printf("   %2d",pp->fg3_att);
      printf("    %2d",pp->ft_made);
      printf("   %2d",pp->ft_att);
      printf("    %2d",pp->num_reb);
      printf("    %2d",pp->num_blk);
      printf("    %2d\n",pp->num_steal);

      att2   += pp->fg2_att;                /*   keep track of totals   */
      made2  += pp->fg2_made;
      att3   += pp->fg3_att;
      made3  += pp->fg3_made;
      attft  += pp->ft_att;
      madeft += pp->ft_made;
      rebs   += pp->num_reb;
      blks   += pp->num_blk;
      steals += pp->num_steal;
      }
   if (att2 != 0)
      fg2perc = made2 / att2;                  /*   calc. shot percentages   */
   else
      fg2perc = 0;
   if (att3 != 0)
      fg3perc = made3 / att3;
   else
      fg3perc = 0;
   if (attft != 0)
      ftperc  = madeft / attft;
   else
      ftperc = 0;

   printf("------------------------------------------------------------------------------\n");

   printf("TEAM TOTALS :         ");
   printf("   %2.0f",made2);
   printf("   %2.0f",att2);
   printf("    %2.0f",made3);
   printf("   %2.0f",att3);
   printf("    %2.0f",madeft);
   printf("   %2.0f",attft);
   printf("    %2.0f",rebs);
   printf("    %2.0f",blks);
   printf("    %2.0f\n",steals);

   printf("SHOOTING PERCENTAGES :");
   printf("   %3.1f",(fg2perc * 100));
   printf("        %3.1f",(fg3perc * 100));
   printf("        %3.1f\n",(ftperc * 100));
}

/*****************
 *   jump ball   *
 *****************/

TEAM_PTR jump_ball(a,b)

TEAM_PTR a,b;

{
   int a_ball = 0, b_ball = 0;
   PLAYER_PTR a_pl, b_pl;
   TEAM_PTR got_it = NULL;

   a_pl = a->pl[4];
   b_pl = b->pl[4];
   while (a_ball == b_ball) {
      a_ball = random(0,(a_pl->perc_reb));
      b_ball = random(0,(b_pl->perc_reb));
      }

   if (a_ball > b_ball)
      got_it = a;
   else
      got_it = b;
   printf("\nThe %s win the TIP...\n",got_it->team_name);
   ball = random(0,3);      /*   randomize person who got the ball   */

   return(got_it);
}

/*******************************
 *   determine player action   *
 *******************************/

int action(tp)

TEAM_PTR tp;

{
   int r = 0, value = 0;
   PLAYER_PTR p;

   p = tp->pl[ball];
   if (back_court) {
      back_court = FALSE;
      r = random(0,100);
      if (r <= (2 * p->perc_drive))
         value = DRIVE;
      else
         value = PASS;
      }
   else {
      r = random(0,100);
      if (r <= (p->perc_drive))
         value = DRIVE;
      else if (r <= (p->perc_drive + p->perc_shoot))
         value = SHOOT;
      else
         value = PASS;
      }

   return(value);      
}

/*****************************
 *   process player action   *
 *****************************/

TEAM_PTR proc_action(tp,dtp,act)

int act;
TEAM_PTR tp, dtp;

{
   int result, r1, val;
   PLAYER_PTR op, dp;
   TEAM_PTR ret_ptr = NULL;

   op = tp->pl[ball];           /*   offensive player   */
   dp = dtp->pl[ball];          /*   defensive player   */
   switch (act) {
      case DRIVE :
         printf("%s dribbles the ball...\n",op->name);
         pause();
         printf("He spots an opening, drives...\n");
         pause();
         result = proc_drive(tp,dtp);
         break;
      case PASS :
         printf("%s passes the ball to ",op->name);
         pause();
         result = proc_pass(tp,dtp);
         break;
      case SHOOT :
         printf("%s puts up a ",op->name);
         r1 = random(0,5);
         switch (r1) {
            case 0 :
               printf("hook shot...\n");
               break;
            case 1 :
               printf("long jump shot...\n");
               break;
            case 2 :
               printf("short jump shot...\n");
               break;
            case 3 :
               printf("fall away jumper...\n");
               break;
            case 4 :
               printf("turn around jumper...\n");
               break;
            case 5 :
               printf("pull up jumper...\n");
               break;
            }
         pause();
         result = proc_shot(tp,dtp);
         break;
      }  /*   end of action   */

   switch (result) {
      case DEF_FOUL :
         if (shooting)
            val = 2;
         else if (dtp->foul >= 7)
            val = 1;
         else {
            val = 0;
            ret_ptr = tp;
            if (dtp->foul == 6) {
               printf("*** The next foul will put the %s into the bonus...\n",ret_ptr->team_name);
               pause();
               }
            }
         if (val != 0) {
            if ((result = free_throw(tp,dtp,val)) == NO_CHANGE)
               ret_ptr = tp;
            else {
               ret_ptr = dtp;
               op = ret_ptr->pl[ball];
               if (result == TURNOVER)
                  printf("%s dribbles the ball and brings it up court...\n",op->name);
               }
            }
         break;
      case FG2 :
         tp->score += 2;
         ret_ptr = dtp;
         break;
      case FG3 :
         tp->score += 3;
         ret_ptr = dtp;
         break;
      case TURNOVER :
         printf("Turnover !!!, %s ball...\n",dtp->team_name);
         pause();
         ball = 0;              /*   player 0 is the point guard   */
         ret_ptr = dtp;
         op = ret_ptr->pl[ball];
         printf("%s brings the ball up court...\n",op->name);
         back_court = TRUE;
         break;
      case NO_CHANGE :
         ret_ptr = tp;
         break;
      }
   pause();

   if ((result != TURNOVER) && (result != NO_CHANGE)) {
      printf("\n*** %s %d   %s %d   Time left : %4.2f\n",team_a->team_name,team_a->score,team_b->team_name,team_b->score,time);
      pause();
      ball = 0;
      op = ret_ptr->pl[ball];
      printf("The inbound pass goes to %s...and he brings the ball up the court...\n",op->name);
      back_court = TRUE;
      pause();
      }

   return(ret_ptr);
}

/*********************
 *   process drive   *
 *********************/

int proc_drive(tp,dtp)

TEAM_PTR tp, dtp;

{
   int r1,r2;
   int ret_val = 99;
   PLAYER_PTR op, dp;

   op = tp->pl[ball];
   dp = dtp->pl[ball];
   r1 = random(0,100);
   r2 = random(0,100);
   if ((r1 > op->perc_steal) && (r2 <= (dp->perc_steal / 5))) {
      printf("The ball is stolen by %s !!!\n",dp->name);
      (dp->num_steal)++;
      pause();
      ret_val = TURNOVER;
      }
   else if ((r1 <= op->perc_steal) && (r2 <= dp->perc_steal)) {
      printf("FOUL - Reaching in, #%2d of the %s\n",dp->num,dtp->team_name);
      pause();
      (dtp->foul)++;
      ret_val = DEF_FOUL;
      }
   else {
      dp = dtp->pl[4];             /*   blocked by center ?   */
      r1 = random(0,100);
      r2 = random(0,100);
      (op->fg2_att)++;
      if ((r1 > op->perc_blk) && (r2 <= dp->perc_blk)) {
         printf("Its blocked by %s !!!\n",dp->name);
         (dp->num_blk)++;
         pause();
         r2 = random(0,100);
         ball = random(0,4);
         if (r2 > 50) {
            ret_val = TURNOVER;
            op = dtp->pl[ball];
            }
         else {
            ret_val = NO_CHANGE;
            op = tp->pl[ball];
            }
         printf("Loose ball picked up by %s...\n",op->name);
         }
      else if ((r1 <= op->perc_blk) && (r2 <= dp->perc_blk)) {   /*   foul ?   */
         if (op->perc_steal > dp->perc_steal) {
            printf("FOUL - Hacking, #%2d of the %s\n",dp->num,dtp->team_name);
            pause();
            (dtp->foul)++;
            shooting = TRUE;
            ret_val = DEF_FOUL;
            }
         else if (op->perc_steal < dp->perc_steal) {
            printf("OFFENSIVE FOUL - Charging, #%2d of the %s\n",op->num,tp->team_name);
            pause();
            (tp->foul)++;
            ret_val = TURNOVER;
            }
         else {
            printf("FOUL - Blocking, #%2d of the %s\n",dp->num,dtp->team_name);
            pause();
            (dtp->foul)++;
            shooting = TRUE;
            ret_val = DEF_FOUL;
            }
         }
      else {                       /*   else shot is up...   */
         r1 = random(0,100);
         if (r1 > 25) {            /*   shot is a layup      */
            r2 = random(0,100);
            if (r2 <= ((op->perc_fg2) * 2)) {
               printf("The layup is good...\n");
               (op->fg2_made)++;
               ret_val = FG2;
               }
            else {
               printf("He blows the easy layup !!!\n");
               pause();
               ret_val = chk_reb(tp,dtp);
               }
            }
         else {                    /*   shot is a slam       */
            r1 = random(0,100);
            if (r1 <= ((op->perc_fg2) * 2)) {      /*   slam is good   */
               r2 = random(0,5);
               switch (r2) {
                  case 0 :
                     printf("A reverse ");
                     break;
                  case 1 :
                     printf("A double pump ");
                     break;
                  case 2 :
                     printf("A spinning reverse ");
                     break;
                  case 3 :
                     printf("A two handed ");
                     break;
                  case 4 :
                     printf("A one handed ");
                     break;
                  case 5 :
                     printf("A ");
                     break;
                  }
               printf("Slam Dunk !!!\n");
               if (r2 <= 2)
                  printf("*** The crowd ROARS !!!\n");
               (op->fg2_made)++;
               ret_val = FG2;
               }
            else {
               printf("He blows the easy Slam !!!\n");
               ret_val = chk_reb(tp,dtp);
               }          /*   endif slam         */
            }             /*   endif layup/slam ? */
         pause();
         }                /*   endif shot is up   */
      }                   /*   endif blocked ?    */
   return(ret_val);
}

/********************
 *   process pass   *
 ********************/

int proc_pass(tp,dtp)

TEAM_PTR tp, dtp;

{
   int r1 = 0, r2 = 0, r;
   int ret_val = 0;
   PLAYER_PTR pp, dpp;

   pp = tp->pl[ball];
   dpp = dtp->pl[ball];
   r1 = random(0,100);
   r2 = random(0,100);
   pause();
   if ((r1 > pp->perc_steal) && (r2 <= (dpp->perc_steal / 5))) {
      printf("...Wait !!!   the pass is stolen by %s !!!\n",dpp->name);
      (dpp->num_steal)++;
      ret_val = TURNOVER;
      }
   else {
      r1 = random(0,100);
      if ((r1 <= (pp->perc_fg3 / 5)) && ((ball == 0) || (ball == 1))) {
         ball = random(2,4);
         pp = tp->pl[ball];
         dpp = dtp->pl[ball];
         printf("...Wait !!!   Its a back door play to %s\n",pp->name);
         pause();
         r2 = random(0,100);
         (pp->fg2_att)++;
         if (r2 <= (pp->perc_reb * 3)){
            printf("Alley Oop !!!   2 points\n");
            pause();
            printf("*** The crowd is cheers !!!\n");
            pause();
            (pp->fg2_made)++;
            ret_val = FG2;
            }
         else {
            r1 = random(0,100);
            if (r1 < 50)
               printf("Awww...He couldn't get the pass, its off the backboard...\n");
            else
               printf("Awww...Good defense by %s...\n",dpp->name);
            ret_val = chk_reb(tp,dtp);
            }
         }
      else {
         ret_val = NO_CHANGE;
         r = ball;
         while (r == ball)           /*   pass ball to another player   */
            r = random(0,4);
         ball = r;
         pp = tp->pl[ball];
         printf("%s\n",pp->name);
         }
      }
   pause();

   return(ret_val);
}

/********************
 *   process shot   *
 ********************/

int proc_shot(tp,dtp)

TEAM_PTR tp, dtp;

{
   int r1, r2, r;
   int ret_val;
   PLAYER_PTR op,dp;

   r1 = random(0,100);
   r2 = random(0,100);
   op = tp->pl[ball];
   dp = dtp->pl[ball];
   if ((r1 > op->perc_blk) && (r2 <= dp->perc_blk)) {
      printf("Its blocked by %s !!!\n",dp->name);
      (dp->num_blk)++;
      pause();
      r2 = random(0,100);
      if (r2 > op->perc_fg3)                    /*   record shot attempt   */
         (op->fg2_att)++;
      else
         (op->fg3_att)++;
      r2 = random(0,100);
      ball = random(0,4);
      if (r2 > 50) {
         ret_val = TURNOVER;
         op = dtp->pl[ball];
         }
      else {
         ret_val = NO_CHANGE;
         op = tp->pl[ball];
         }
      printf("Loose ball picked up by %s...\n",op->name);
      }
   else if ((r1 <= op->perc_blk) && (r2 <= dp->perc_blk)) {   /*   foul   */
      printf("FOUL - Hacking, #%2d of the %s\n",dp->num,dtp->team_name);
      pause();
      (dtp->foul)++;
      shooting = TRUE;
      ret_val = DEF_FOUL;
      }
   else {                         /*   else shot is up   */
      (op->fg2_att)++;
      r2 = random(0,100);
      if (r2 > op->perc_fg3) {              /*   2 point shot      */
         ret_val = FG2;
         printf("Its a 2 pointer...and ");
         pause();
         r2 = random(0,100);
         if (r2 <= op->perc_fg2) {
            printf("its good !!!\n");
            (op->fg2_made)++;
            }
         else
            ret_val = TURNOVER;
         }
      else {                             /*   3 point shot   */
         (op->fg3_att)++;
         ret_val = FG3;
         printf("Its a 3 pointer...and ");
         pause();
         r2 = random(0,100);
         if (r2 <= op->perc_fg3) {
            printf("its good !!!\n");
            (op->fg3_made)++;
            }
         else
            ret_val = TURNOVER;
         }
      pause();

      if ((abs((tp->score) - (dtp->score)) < 3) && (ret_val != TURNOVER)) {
         printf("*** The crowd is going wild !!!\n");
         pause();                            /*   if close game   */
         }

      if (ret_val == TURNOVER) {
         r2 = random(0,3);
         switch (r2) {
            case 0 :
               printf("its an airball !!!\n");
               break;
            case 1 :
               printf("its off the rim !!!\n");
               break;
            case 2 :
               printf("its off the backboard !!!\n");
               break;
            case 3 :
               printf("its a brick !!!\n");
               break;
            }
         pause();
         ret_val = chk_reb(tp,dtp);       /*   check who rebounds   */
         }                   /*   endif turnover       */
      }                      /*   endif shot           */
   pause();

   return(ret_val);
}

/*********************
 *   check rebound   *
 *********************/

int chk_reb(tp,dtp)

TEAM_PTR tp,dtp;

{
   int i, ret_val;
   int r1,r2;
   PLAYER_PTR op,dp;
 
   i = 4;
   ret_val = 99;
   printf("The rebound is...");
   while ((i >= 0) && (ret_val != NO_CHANGE) && (ret_val != TURNOVER)) {
      r1 = random(0,100);
      r2 = random(0,100);
      op = tp->pl[i];
      dp = dtp->pl[i];
      if (((r1 <= op->perc_reb) && (r2 <= dp->perc_reb)) || ((r1 > op->perc_reb) && (r2 > dp->perc_reb)))
         printf("tipped by %s and %s...\n",op->name,dp->name);
      else if ((r1 <= op->perc_reb) && (r2 > dp->perc_reb)) {
         printf("grabbed by %s of the %s...\n",op->name,tp->team_name);
         (op->num_reb)++;
         ret_val = NO_CHANGE;
         ball = i;
         }
      else if ((r1 > op->perc_reb) && (r2 <= dp->perc_reb)) {
         printf("grabbed by %s of the %s...\n",dp->name,dtp->team_name);
         (dp->num_reb)++;
         ret_val = TURNOVER;
         ball = i;
         }
      pause();
      --i;
      }

   if ((ret_val != TURNOVER) && (ret_val != NO_CHANGE)) {
      printf("Out of bounds...");
      pause();
      r1 = random(0,100);
      r2 = random(0,4);
      if (r1 > 50) {
         printf("Last touched by %s of the %s...\n",op->name,tp->team_name);
         ret_val = TURNOVER;
         }
      else {
         printf("Last touched by %s of the %s...\n",dp->name,dtp->team_name);
         ret_val = NO_CHANGE;
         }
      pause();
      }
   return(ret_val);
}

/******************
 *   free throw   *
 ******************/

free_throw(tp,dtp,n)

TEAM_PTR tp, dtp;
int n;

{
   int r1, r2, i;
   int another = TRUE, ret_val;
   PLAYER_PTR op;

   printf("*** Free throws...");
   pause();
   if (n == 1)
      printf("one and one\n");
   else
      printf("two shots\n");
   pause();
   op = tp->pl[ball];
   printf("%s steps up to the line...\n",op->name);
   pause();

   i = 0;
   while (another) {
      if (i == 0)
         printf("   The first one is up...");
      else
         printf("   The second one is up...");
      pause();
      (op->ft_att)++;
      r1 = random(0,100);
      if (r1 <= op->perc_ft) {
         printf("its good...\n");
         pause();
         (tp->score)++;
         (op->ft_made)++;
         another = TRUE;
         ret_val = DEF_FOUL;
         }
      else {
         printf("its off the rim !!!\n");
         if ((n == 2) && (i == 0))
            another = TRUE;
         else if ((n == 2) && (i == 1)) {
            another = FALSE;
            ret_val = chk_reb(tp,dtp);
            }
         else if (n == 1) {
            another = FALSE;
            ret_val = chk_reb(tp,dtp);
            }
         }
      pause();
      ++i;
      if (i == 2)
         another = FALSE;
      }

   return(ret_val);
}

/******************
 *   randomizer   *
 ******************/

int random(a,b)        /*   return an integer random number between a & b   */

int a,b;

{
   double r = 0;
   int value = 0;

   r = ((double) rand()) / pow((double) 2, (double) 15);
   value = (a + (int) (((b - a) * r) + .5));

   return(value);
}

/*************
 *   pause   *
 *************/

pause()         /*   pause for DELAY-loops   */

{
   int i;

   for (i = 0;i < delay; i++)
      ;
}

/**********************
 *   end of program   *
 **********************/
