1 #ifndef _global_h
2 #	include "global.h"
3 #endif
4 
5 #ifndef _snooker_h
6 #	include "snooker.h"
7 #endif
8 #ifndef _pocket_
9 #	include "pocket.h"
10 #endif
11 #ifndef _graph_h
12 #	include "graph.h"
13 #endif
14 #ifndef _mover_h
15 #	include "mover.h"
16 #endif
17 
18 
19 //
20 // Voreinstellungen
21 //
22 
23 
Snooker(double wx,double wy)24 Snooker::Snooker(double wx, double wy) :
25 Pool(wx,wy)
26 {
27 	InitArea( TableWidth, TableHeight );
28 
29 	SelectTable(-1);
30 
31 #ifndef __TURBOC__
32 	red_col = AddBallColor( "red3" );
33 	cols[0] = AddBallColor( "yellow1" );
34 	cols[1] = AddBallColor( "green4" );
35 	cols[2] = AddBallColor( "brown4" );
36 	cols[3] = AddBallColor( "blue" );
37 	cols[4] = AddBallColor( "HotPink3" );
38 	cols[5] = AddBallColor( "black" );
39 #else
40 	red_col = AddBallColor( "red3" );
41 	floor   = CreateColorMix( table_col, table_line_col );
42 
43 	cols[5] = AddBallColor( "black" );
44 	cols[0] = AddBallColor( "yellow1" );
45 	cols[1] = AddBallColor( "green4" );
46 	cols[2] = CreateColorMix( red_col, cols[5] );		// braun
47 	cols[3] = AddBallColor( "blue" );
48 	cols[4] = CreateColorMix( red_col, cue_col );	// Pink
49 #endif
50 
51 	cueball=0;
52 	color_in_pocket = 0;
53 	reds_in_pocket  = 0;
54 }
55 
56 
~Snooker()57 Snooker::~Snooker() {
58 	if (cueball) {
59 		delete cueball;
60 		for (int c=0;c<6;c++)		delete colored[c];
61 		for (int r=0;r<15;r++)		delete red[r];
62 		cueball=0;
63 	}
64 }
65 
GetNormalBallSize()66 const Real & Snooker::GetNormalBallSize() const {
67 	return BallRadius;
68 }
69 
70 
Triangle(double x,double y)71 void Snooker::Triangle( double x, double y )
72 {
73 const int count = 5;
74 int		c=0;
75 double	cdist = sqrt( 3.*(GetNormalBallSize()+Offset)*(GetNormalBallSize()+Offset) );
76 
77 //	x-=(cdist*(count-1)/2);
78 	for( int col=0; col<count; col++ ) {
79 		for( int row=0; row<=col; row++ ) {
80 			reddefs[c] = Vec2( x+col*cdist, y+(row-col/2.0)*2*(GetNormalBallSize()+Offset) );
81 			red[c]=new Ball( reddefs[c], GetNormalBallSize() );
82 			red[c]->state = new BallState( m, red_col, red[c]->P() );
83 			c++;
84 		}
85 	}
86 }
87 
SetupBalls()88 void Snooker::SetupBalls() {
89 	defs[0] = Vec2( AreaOffX()+AreaWidth()*0.25,  AreaOffY()+AreaHeight()/2.+14.6 );
90 	defs[1] = Vec2( AreaOffX()+AreaWidth()*0.25,  AreaOffY()+AreaHeight()/2.-14.6 );
91 	defs[2] = Vec2( AreaOffX()+AreaWidth()*0.25,  AreaOffY()+AreaHeight()*0.50 );
92 	defs[3] = Vec2( AreaOffX()+AreaWidth()*0.50,  AreaOffY()+AreaHeight()*0.50 );
93 	defs[4] = Vec2( AreaOffX()+AreaWidth()*0.75,  AreaOffY()+AreaHeight()*0.50 );
94 	defs[5] = Vec2( AreaOffX()+AreaWidth()-32.0, AreaOffY()+AreaHeight()*0.50 );
95 
96 	for (int i=0;i<6;i++) {
97 		colored[i] = new Ball( defs[i], BallRadius );
98 		colored[i]->state = new BallState( m, cols[i], colored[i]->P() );
99 	}
100 
101 	cuedef  = Vec2( AreaOffX()+AreaWidth()*0.125, AreaOffY()+AreaHeight()*0.375 );
102 	cueball = new Ball( cuedef, BallRadius );
103 	cueball->state = new BallState( m, cue_col, cueball->P() );
104 
105 	tridef  = Vec2(	AreaOffX()+AreaWidth()*0.75+GetNormalBallSize()*2.5,
106 							AreaOffY()+AreaHeight()/2. );
107 	Triangle(tridef);
108 }
109 
InitPlayground()110 void Snooker::InitPlayground() {
111 	Billard::InitPlayground();
112 	BallRadius = m->GetActRadius();
113 	InitTable(6.0);
114 	SetupBalls();
115 }
116 
DrawBackground()117 void Snooker::DrawBackground() const {
118 	Pool::DrawBackground();
119 	SetBgColor(table_line_col);
120 	DrawLine( defs[0], defs[1] );
121 	DrawArc( defs[2], 14.6, 90.0, 180.0 );
122 	for (int i=0;i<6;i++) 	FillCircle( defs[i], 1.0 );
123 }
124 
ResetGame()125 void Snooker::ResetGame() {
126 int i;
127 	cueball->SetPV( cuedef );
128 	for (i=0;i<6;i++)			colored[i]->SetPV( defs[i] );
129 	for (i=0;i<15;i++)		red[i]->SetPV( reddefs[i] );
130 
131 	reds_in_pocket  = 0;
132 	color_in_pocket = 0;
133 
134 	Billard::ResetGame();
135 }
136 
137 // -------------------------------------------------------------------------
138 
~SnookerDemo()139 SnookerDemo::~SnookerDemo() {}
140 
GetPresetA()141 const Real &SnookerDemo::GetPresetA() const			{ return PresetA; }
GetSlowGranularity()142 const Real &SnookerDemo::GetSlowGranularity() const	{ return SlowGranularity; }
143 
InitPlayground()144 void SnookerDemo::InitPlayground() {
145 	Billard::InitPlayground();
146 	BallRadius = m->GetActRadius();
147 	Billard::InitTable();
148 	SetupBalls();
149 	cueball->v = Vec2( shot_speed, shot_speed );
150 }
151 
DrawBackground()152 void SnookerDemo::DrawBackground() const {
153 	Billard::DrawBackground();
154 	SetBgColor(table_line_col);
155 	DrawLine( defs[0], defs[1] );
156 	DrawArc( defs[2], 14.6, 90.0, 180.0 );
157 	for (int i=0;i<6;i++) 	FillCircle( defs[i], 1.0 );
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////
161 
InPocket(Ball * b)162 void Snooker::InPocket( Ball *b ) {
163 int i;
164 	for (i=0;i<6;i++) {
165 		if (b==colored[i]) {
166 			color_in_pocket |= (1<<i);
167 			return;
168 		}
169 	}
170 	for (i=0;i<15;i++) {
171 		if (b==red[i]) {
172 			reds_in_pocket  |= (1<<i);
173 			return;
174 		}
175 	}
176 	Pool::InPocket(b);
177 }
178 
AllBallsStopped()179 void Snooker::AllBallsStopped() {
180 	if (color_in_pocket) {
181 		int	mask=0;
182 		for (int i=0;i<6;i++) {
183 			if ((reds_in_pocket!=0x7fff)||((color_in_pocket&mask)!=mask)) {
184 				if (color_in_pocket & (1<<i)) {
185 					(void)IsSelectable(colored[i]);
186 				}
187 			}
188 			mask = (mask<<1)|1;
189 		}
190 	}
191 	Pool::AllBallsStopped();
192 }
193 
IsSelectable(Ball * b)194 int Snooker::IsSelectable(Ball *b) {
195 int i;
196 	for (i=0;i<6;i++) {
197 		if (b==colored[i]) {
198 			if (color_in_pocket & (1<<i)) {
199 				if (b->FitsAt(defs[i])) {
200 					b->SetP(defs[i]);		// reset to default position
201 				}
202 				else if (b->FitsAt(defs[5])) {
203 					b->SetP(defs[5]);		// reset to black position
204 				}
205 				else if (i<4) {
206 					Vec2	newpos;
207 					b->FitsNextTo(defs[i],Vec2(-1.0,RealZero),&newpos);
208 					b->SetP(newpos);		// closer to left wall
209 				}
210 				else {
211 					Vec2	newpos;
212 					b->FitsNextTo(defs[i],Vec2(1.0,RealZero),&newpos);
213 					b->SetP(newpos);		// closer to right wall
214 				}
215 
216 				b->ChgV(Vec2Zero);
217 				color_in_pocket &= ~(1<<i);		// it's back in the game
218 
219 				return 0;
220 			}
221 			else {
222 				return 1;
223 			}
224 		}
225 	}
226 	for (i=0;i<15;i++) {
227 		if (b==red[i]) {
228 			if (reds_in_pocket & (1<<i)) {
229 				Vec2	newpos;
230 				b->FitsNextTo(tridef,Vec2(1.0,RealZero),&newpos);
231 				b->SetP(newpos);					// closer to right wall
232 
233 				b->ChgV(Vec2Zero);
234 				reds_in_pocket &= ~(1<<i);		// it's back in the game
235 
236 				return 0;
237 			}
238 			else {
239 				return 1;
240 			}
241 		}
242 	}
243 
244 	return Pool::IsSelectable(b);
245 }
246