home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Games 9 / CD_1.iso / kids / apool / apool.c < prev    next >
C/C++ Source or Header  |  1995-04-23  |  11KB  |  330 lines

  1. /* This is "apool.c", main-fragment of the pool (billiards)-program
  2.                    
  3.                      "ANOTHER POOL" (V 0.97).
  4.  
  5.    Copyright (C) 1995 by Gerrit Jahn (email: ub1g@rz.uni-karlsruhe.de)
  6.  
  7.    "ANOTHER POOL" (V 0.97) is free software; you can redistribute it 
  8.    and/or modify it under the terms of the GNU General Public License 
  9.    as published by the Free Software Foundation; either version 2 of 
  10.    the License, or (at your option) any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with GNU CC; see the file COPYING.  If not, write to
  19.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* ------------------------------ apool.c -------------------------------- */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <time.h>
  26. #include <math.h>
  27. #include <random.h>
  28. #include "apool.h"
  29.  
  30. double ALPHA, BETA, DELTA, ETA, CETA, THETA, BANDES, BANDEREF,
  31.  SPINC, MASSE_WEISS; /* eigentlich Konstanten, werden es später wieder !!! */
  32. int first_hit, bande_hit, col_in, last_foul, freeball, extra_shot,ende,
  33.  BREMSE, PAINT, CLEV, act=1, new_col, c_player=-1, anstoss, demo = 0,
  34.  undo_freeball, undo_extra_shot, undo_act, undo_color, last_anstoss=0,
  35.  last_pocketed_balls;
  36.  
  37. struct ball k[BALLS];
  38. struct player ply[2];
  39. FILE *datei;
  40. struct vect old_pos[BALLS]; int old_stat[BALLS]; /* f. undo().. */
  41. struct statistic stats[2] = {{{0,0,0,0},0,0,0,0,0},{{0,0,0,0},0,0,0,-1,0}};
  42.  
  43. void init_table( void ) 
  44. /* Hier wird alles, was es so an Variablen bezüglich Lage der Kugeln gibt, 
  45.    neu initialisiert. init_table() wird immer beim Neustart aufgerufen */
  46.  { 
  47.   int i, j, l=0;
  48.   for(i=0;i<5;i++) 
  49.    for(j=-i;j<=i;j+=2)        /* Lage der Kugeln am Anfang */
  50.     { 
  51.      k[l].p.x = 0.75+((i-2)*XAB/DIFFX) + 0.25 * RND / DIFFX;
  52.      k[l].p.y = 0.25+j/2.0*((2*RADIUS+2))/DIFFX + 0.25 * RND / DIFFX;
  53.      k[l].v.x = k[l].v.y = k[l].e.x = k[l].e.y = k[l].ez = k[l].vr.x = 
  54.      k[l].vr.y = k[l].ve.x = k[l].ve.y = k[l].col = 0.0; 
  55.      k[l].stat = 0; k[l++].m = 1.0;
  56.     }
  57.   k[4].col = COL_BLACK; l = 0;
  58.   do            /* Farbe der Kugeln, zufallsgesteuert */
  59.    { 
  60.     while( (i = 15.0*rand()/(RAND_MAX+1) ) == BLACK );
  61.     if( !k[i].col ) { k[i].col = COL_RED; l++; }
  62.    }
  63.   while( l < (BALLS-2)/2 );
  64.   for( i=0;i<WHITE;i++ ) if( !k[i].col ) k[i].col = COL_YELLOW;
  65.   k[WHITE].stat = 1; /* Weiße ist anfangs NICHT auf dem Tisch */
  66.   k[WHITE].m = MASSE_WEISS;
  67.   k[WHITE].col = COL_WHITE;
  68.   for( i=0;i<2;i++)
  69.    { ply[i].stat = ply[i].wait = ply[i].col = ply[i].hole_black = 0; }
  70.   first_hit = bande_hit = anstoss = 1;
  71.   plot_table();     /* oben: damit nicht VOR dem Anfang bereits gefoult wurde */
  72.   ply[0].speed = ply[1].speed = spd = 0.75; speed( spd );
  73.   wink( alph );
  74.   for( i=0;i<WHITE;i++) plot_one_ball( i );
  75.   freeball = extra_shot = last_foul = col_in = 0;
  76.   if( demo ) msg("press any key to stop demo");
  77.  }
  78.  
  79. void save_actual_position( void )
  80.  { /* sichert die aktuelle Position der Kugeln, für undo() */
  81.   int i;
  82.   for( i=0;i<BALLS;i++ ) { old_pos[i].x = k[i].p.x; old_pos[i].y = k[i].p.y; 
  83.    old_stat[i] = k[i].stat; }
  84.   undo_act = act;
  85.   undo_freeball = freeball;
  86.   undo_extra_shot = extra_shot;
  87.   undo_color = ply[act].col;
  88.  }
  89.  
  90. void undo( void )
  91.  { /* naja, was wohl */
  92.   int i;
  93.   mouse_off();
  94.   for( i=0;i<BALLS;i++ )
  95.    {
  96.     if( !k[i].stat ) plot_one_ball( i );
  97.     k[i].p.x = old_pos[i].x; 
  98.     k[i].p.y = old_pos[i].y; 
  99.     k[i].stat = old_stat[i]; 
  100.     if( !k[i].stat ) plot_one_ball( i );
  101.    }
  102.   act = undo_act;
  103.   freeball = undo_freeball;
  104.   extra_shot = undo_extra_shot;
  105.   ply[act].col = undo_color;
  106.   plot_act_player( act );
  107.   if( ply[act].col == COL_RED ) i = 4;
  108.   else if( ply[act].col == COL_YELLOW ) i = 11;
  109.   else i = 6;
  110.   if( freeball ) err2("free-ball", i);
  111.   else if( extra_shot) err2("extra_shot", i);
  112.   else err2(" ", 0);
  113.   mouse_on();
  114.  }
  115.  
  116. void test_for_play_on_black( void )
  117. /* Wenn alle Kugeln einer Farbe verschwinden sind, wird auf die Schwarze
  118.    gespielt. Wann das der Fall ist, und wer Schwarz spielen muß, ermittelt
  119.    dies Prozedur */
  120.  {
  121.   int i, j;
  122.   for( j=0;j<2;j++ )
  123.    if( (ply[j].col != COL_BLACK) && (ply[j].col) ) 
  124.     {
  125.      ply[j].hole_black = 0;
  126.      for(i=0;i<WHITE;i++)
  127.       if( k[i].stat && (k[i].col == ply[j].col) ) ply[j].hole_black++;
  128.      if( ply[j].hole_black == (BALLS-2)/2 ) 
  129.       {
  130.        ply[j].col = COL_BLACK;
  131.         /* ply[j].hole_black = last_hole gegenüber; */ /* SPÄTER !!! */
  132.       }
  133.     }
  134.  } 
  135.  
  136. char *str_player( char *out2, int act )
  137.  { 
  138.   sprintf(out2, "Player %d%s", act+1, (c_player==act) ? " (Computer)" : "");
  139.   return out2;
  140.  }
  141.  
  142. int test_if_game_is_over( void ) 
  143.  { /* Wie der Name schon sagt, testet, ob Spiel zu Ende */
  144.  char out[80], out2[30];
  145.  int loser;
  146.  if( k[BLACK].stat )
  147.   {
  148.    if( !(ply[act].stat & FOUL_ANY_FOUL) ) 
  149.     {        /* Schwarze wurde KORREKT eingelocht */
  150.      loser = 1 - act;
  151.      sprintf(out,"%s wins!", str_player( out2, act) );
  152.      ply[act].points += 1;
  153.      stats[act].wins += 1;
  154.      stats[act].pots += 1;
  155.     }
  156.    else
  157.     { 
  158.      loser = act;
  159.      sprintf(out,"black ball illegaly pocketed; %s loses!",
  160.       str_player( out2, act ) );
  161.      ply[act].points += 10000;
  162.      stats[act].losses += 1;
  163.      act = 1 - act;
  164.     }
  165.    err(out);
  166.    if( loser == last_anstoss ) stats[act].slosses += 1;
  167.    else last_anstoss = loser;
  168.    if( demo || c_player == loser ) { msg("wait..."); wait_user_time( 5.0 ); }
  169.    else wait_for_click();
  170.    init_table();
  171.    return 1;
  172.   }
  173.  return 0;
  174. }
  175.  
  176. void rules( void )
  177. /* Die Regeln, nach einem Stoß wird überprüft, ob keine Fouls aufgetreten
  178.    sind. Sollte dies so sein, so erfolgen die "Strafen". Ruft die obigen
  179.    Test-Prozeduren, das Menu und den Stoß auf ... */
  180.  {
  181.  int spielende=0, color; 
  182.  init_table();
  183.  ply[0].points = ply[0].points = 0;
  184.  do
  185.   {
  186.    first_hit = bande_hit =  0;
  187.    if( ply[act].stat & FOUL_WHITE_POCKETED ) /* hier kommen die Fouls... */
  188.     {
  189.      err("white ball pocketed, foul!");
  190.      last_foul = 1;
  191.      stats[act].fouls.whited += 1;
  192.     }
  193.    else if( ply[act].stat & FOUL_NO_TOUCH )
  194.     {
  195.      err("no ball or no side touched, foul!");
  196.      last_foul = 1;
  197.      stats[act].fouls.notouch += 1;
  198.     }
  199.    else if( ply[act].stat & FOUL_WRONG_COLOR_POCKETED)
  200.     {
  201.      if( !freeball )
  202.       {
  203.        err("wrong color pocketed, foul!");
  204.        last_foul = 1;
  205.        stats[act].fouls.wrongcp += 1;
  206.       }
  207.      else { ply[1-act].wait = 1; }
  208.     }
  209.    else if( ply[act].stat & FOUL_WRONG_COLOR_TOUCHED )
  210.     {
  211.      if( !freeball )
  212.       {
  213.        err("wrong color touched first, foul!");
  214.        last_foul = 1;
  215.        stats[act].fouls.wrongct += 1;
  216.       }
  217.      else { extra_shot = 1; }
  218.     }
  219.    else if( !(ply[act].stat & FOUL_ANY_FOUL) ) /* kein Foul gemacht */
  220.     {
  221.     if( ply[act].stat & FOUL_CORRECT_POT )
  222.      {
  223.       last_foul = 0;
  224.       stats[act].pots += last_pocketed_balls;
  225.       err("OK!"); /* Kugel eingelocht */
  226.      }
  227.     else /* keine Kugel eingelocht */
  228.      {
  229.       stats[act].nopots += 1;
  230.       if( ply[1-act].wait == 1 ) { extra_shot = 1; ply[1-act].wait = 0; }
  231.       else act = 1 - act;
  232.      }
  233.     }
  234.    if( col_in && last_foul ) { ply[act].col = ply[1-act].col = 0; }
  235.    if( last_foul ) 
  236.     { 
  237.      ply[act].wait = 1; act = 1 - act;
  238.      if( ply[act].col == COL_RED ) color = 4;
  239.      else if( ply[act].col == COL_YELLOW ) color = 11;
  240.      else color = 6;
  241.      err2("free-ball", color ); 
  242.      freeball = 1; 
  243.     }
  244.    else if( extra_shot )
  245.     {
  246.      ply[act].wait = 0;
  247.      freeball = 0;
  248.      if( ply[act].col == COL_RED ) color = 4;
  249.      else if( ply[act].col == COL_YELLOW ) color = 11;
  250.      else color = 6;
  251.      err2("extra-shot", color);
  252.     }
  253.    else freeball = 0;
  254.    if( !freeball && !extra_shot) err2(" ", 0);
  255.    new_col = col_in = last_foul