home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Select: Games 9
/
CD_1.iso
/
kids
/
apool
/
apool.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-23
|
11KB
|
330 lines
/* This is "apool.c", main-fragment of the pool (billiards)-program
"ANOTHER POOL" (V 0.97).
Copyright (C) 1995 by Gerrit Jahn (email: ub1g@rz.uni-karlsruhe.de)
"ANOTHER POOL" (V 0.97) is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ------------------------------ apool.c -------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <random.h>
#include "apool.h"
double ALPHA, BETA, DELTA, ETA, CETA, THETA, BANDES, BANDEREF,
SPINC, MASSE_WEISS; /* eigentlich Konstanten, werden es später wieder !!! */
int first_hit, bande_hit, col_in, last_foul, freeball, extra_shot,ende,
BREMSE, PAINT, CLEV, act=1, new_col, c_player=-1, anstoss, demo = 0,
undo_freeball, undo_extra_shot, undo_act, undo_color, last_anstoss=0,
last_pocketed_balls;
struct ball k[BALLS];
struct player ply[2];
FILE *datei;
struct vect old_pos[BALLS]; int old_stat[BALLS]; /* f. undo().. */
struct statistic stats[2] = {{{0,0,0,0},0,0,0,0,0},{{0,0,0,0},0,0,0,-1,0}};
void init_table( void )
/* Hier wird alles, was es so an Variablen bezüglich Lage der Kugeln gibt,
neu initialisiert. init_table() wird immer beim Neustart aufgerufen */
{
int i, j, l=0;
for(i=0;i<5;i++)
for(j=-i;j<=i;j+=2) /* Lage der Kugeln am Anfang */
{
k[l].p.x = 0.75+((i-2)*XAB/DIFFX) + 0.25 * RND / DIFFX;
k[l].p.y = 0.25+j/2.0*((2*RADIUS+2))/DIFFX + 0.25 * RND / DIFFX;
k[l].v.x = k[l].v.y = k[l].e.x = k[l].e.y = k[l].ez = k[l].vr.x =
k[l].vr.y = k[l].ve.x = k[l].ve.y = k[l].col = 0.0;
k[l].stat = 0; k[l++].m = 1.0;
}
k[4].col = COL_BLACK; l = 0;
do /* Farbe der Kugeln, zufallsgesteuert */
{
while( (i = 15.0*rand()/(RAND_MAX+1) ) == BLACK );
if( !k[i].col ) { k[i].col = COL_RED; l++; }
}
while( l < (BALLS-2)/2 );
for( i=0;i<WHITE;i++ ) if( !k[i].col ) k[i].col = COL_YELLOW;
k[WHITE].stat = 1; /* Weiße ist anfangs NICHT auf dem Tisch */
k[WHITE].m = MASSE_WEISS;
k[WHITE].col = COL_WHITE;
for( i=0;i<2;i++)
{ ply[i].stat = ply[i].wait = ply[i].col = ply[i].hole_black = 0; }
first_hit = bande_hit = anstoss = 1;
plot_table(); /* oben: damit nicht VOR dem Anfang bereits gefoult wurde */
ply[0].speed = ply[1].speed = spd = 0.75; speed( spd );
wink( alph );
for( i=0;i<WHITE;i++) plot_one_ball( i );
freeball = extra_shot = last_foul = col_in = 0;
if( demo ) msg("press any key to stop demo");
}
void save_actual_position( void )
{ /* sichert die aktuelle Position der Kugeln, für undo() */
int i;
for( i=0;i<BALLS;i++ ) { old_pos[i].x = k[i].p.x; old_pos[i].y = k[i].p.y;
old_stat[i] = k[i].stat; }
undo_act = act;
undo_freeball = freeball;
undo_extra_shot = extra_shot;
undo_color = ply[act].col;
}
void undo( void )
{ /* naja, was wohl */
int i;
mouse_off();
for( i=0;i<BALLS;i++ )
{
if( !k[i].stat ) plot_one_ball( i );
k[i].p.x = old_pos[i].x;
k[i].p.y = old_pos[i].y;
k[i].stat = old_stat[i];
if( !k[i].stat ) plot_one_ball( i );
}
act = undo_act;
freeball = undo_freeball;
extra_shot = undo_extra_shot;
ply[act].col = undo_color;
plot_act_player( act );
if( ply[act].col == COL_RED ) i = 4;
else if( ply[act].col == COL_YELLOW ) i = 11;
else i = 6;
if( freeball ) err2("free-ball", i);
else if( extra_shot) err2("extra_shot", i);
else err2(" ", 0);
mouse_on();
}
void test_for_play_on_black( void )
/* Wenn alle Kugeln einer Farbe verschwinden sind, wird auf die Schwarze
gespielt. Wann das der Fall ist, und wer Schwarz spielen muß, ermittelt
dies Prozedur */
{
int i, j;
for( j=0;j<2;j++ )
if( (ply[j].col != COL_BLACK) && (ply[j].col) )
{
ply[j].hole_black = 0;
for(i=0;i<WHITE;i++)
if( k[i].stat && (k[i].col == ply[j].col) ) ply[j].hole_black++;
if( ply[j].hole_black == (BALLS-2)/2 )
{
ply[j].col = COL_BLACK;
/* ply[j].hole_black = last_hole gegenüber; */ /* SPÄTER !!! */
}
}
}
char *str_player( char *out2, int act )
{
sprintf(out2, "Player %d%s", act+1, (c_player==act) ? " (Computer)" : "");
return out2;
}
int test_if_game_is_over( void )
{ /* Wie der Name schon sagt, testet, ob Spiel zu Ende */
char out[80], out2[30];
int loser;
if( k[BLACK].stat )
{
if( !(ply[act].stat & FOUL_ANY_FOUL) )
{ /* Schwarze wurde KORREKT eingelocht */
loser = 1 - act;
sprintf(out,"%s wins!", str_player( out2, act) );
ply[act].points += 1;
stats[act].wins += 1;
stats[act].pots += 1;
}
else
{
loser = act;
sprintf(out,"black ball illegaly pocketed; %s loses!",
str_player( out2, act ) );
ply[act].points += 10000;
stats[act].losses += 1;
act = 1 - act;
}
err(out);
if( loser == last_anstoss ) stats[act].slosses += 1;
else last_anstoss = loser;
if( demo || c_player == loser ) { msg("wait..."); wait_user_time( 5.0 ); }
else wait_for_click();
init_table();
return 1;
}
return 0;
}
void rules( void )
/* Die Regeln, nach einem Stoß wird überprüft, ob keine Fouls aufgetreten
sind. Sollte dies so sein, so erfolgen die "Strafen". Ruft die obigen
Test-Prozeduren, das Menu und den Stoß auf ... */
{
int spielende=0, color;
init_table();
ply[0].points = ply[0].points = 0;
do
{
first_hit = bande_hit = 0;
if( ply[act].stat & FOUL_WHITE_POCKETED ) /* hier kommen die Fouls... */
{
err("white ball pocketed, foul!");
last_foul = 1;
stats[act].fouls.whited += 1;
}
else if( ply[act].stat & FOUL_NO_TOUCH )
{
err("no ball or no side touched, foul!");
last_foul = 1;
stats[act].fouls.notouch += 1;
}
else if( ply[act].stat & FOUL_WRONG_COLOR_POCKETED)
{
if( !freeball )
{
err("wrong color pocketed, foul!");
last_foul = 1;
stats[act].fouls.wrongcp += 1;
}
else { ply[1-act].wait = 1; }
}
else if( ply[act].stat & FOUL_WRONG_COLOR_TOUCHED )
{
if( !freeball )
{
err("wrong color touched first, foul!");
last_foul = 1;
stats[act].fouls.wrongct += 1;
}
else { extra_shot = 1; }
}
else if( !(ply[act].stat & FOUL_ANY_FOUL) ) /* kein Foul gemacht */
{
if( ply[act].stat & FOUL_CORRECT_POT )
{
last_foul = 0;
stats[act].pots += last_pocketed_balls;
err("OK!"); /* Kugel eingelocht */
}
else /* keine Kugel eingelocht */
{
stats[act].nopots += 1;
if( ply[1-act].wait == 1 ) { extra_shot = 1; ply[1-act].wait = 0; }
else act = 1 - act;
}
}
if( col_in && last_foul ) { ply[act].col = ply[1-act].col = 0; }
if( last_foul )
{
ply[act].wait = 1; act = 1 - act;
if( ply[act].col == COL_RED ) color = 4;
else if( ply[act].col == COL_YELLOW ) color = 11;
else color = 6;
err2("free-ball", color );
freeball = 1;
}
else if( extra_shot )
{
ply[act].wait = 0;
freeball = 0;
if( ply[act].col == COL_RED ) color = 4;
else if( ply[act].col == COL_YELLOW ) color = 11;
else color = 6;
err2("extra-shot", color);
}
else freeball = 0;
if( !freeball && !extra_shot) err2(" ", 0);
new_col = col_in = last_foul