1 #ifndef _global_h
2 # include "global.h"
3 #endif
4
5 #ifndef _pool8_h
6 # include "pool8.h"
7 #endif
8 #ifndef _graph_h
9 # include "graph.h"
10 #endif
11 #ifndef _mover_h
12 # include "mover.h"
13 #endif
14 #ifndef _ball_h
15 # include "ball.h"
16 #endif
17
Pool8(double ft)18 Pool8::Pool8(double ft) :
19 Pool( ft*2.54*12, ft*2.54*6 )
20 {
21 SelectTable(-1);
22
23 black_col = AddBallColor( "black" );
24 cueball=0;
25
26 if (!deluxe) {
27 // Pool-Kugeln: "Television"
28 full_col = AddBallColor( "yellow" );
29 half_col = AddBallColor( "red" );
30 }
31 else {
32 // normale Pool-Kugeln
33 ball_col[0] = AddBallColor( "gold1" ); // yellow
34 ball_col[1] = AddBallColor( "blue" ); // blue
35 ball_col[2] = AddBallColor( "red" ); // red
36 ball_col[3] = AddBallColor( "DarkViolet" ); // dark violett
37 ball_col[4] = AddBallColor( "orange" ); // orange
38 ball_col[5] = AddBallColor( "MediumForestGreen" ); // dark green
39 ball_col[6] = AddBallColor( "brown" ); // brown
40 }
41
42 mh = 0;
43 balls_in_pocket = 0;
44 for (int i=0;i<15;i++) ball[i]=NULL;
45 }
46
~Pool8()47 Pool8::~Pool8() {
48 if (cueball) {
49 delete cueball;
50 for (int i=0;i<15;i++) if (ball[i]) delete ball[i];
51 cueball=0;
52 }
53 if (mh) delete mh;
54 }
55
56
Triangle(const Vec2 & vec)57 void Pool8::Triangle( const Vec2 &vec )
58 {
59 static int t[15] = { 1,
60 -1, -2,
61 2, 0, 3,
62 -3, 4, -4, -5,
63 5, -6, 6, 7, -7 };
64
65 Real x = vec.X();
66 Real y = vec.Y();
67 const int count = 5;
68 int c=0;
69 double cdist = sqrt( 3.*(GetNormalBallSize()+Offset)*(GetNormalBallSize()+Offset) );
70 Ball *r;
71
72 // x-=(cdist*(count-1)/2);
73 for( int col=0; col<count; col++ ) {
74 for( int row=0; row<=col; row++ ) {
75 Vec2 pos(x+col*cdist,y+(row-col/2.0)*2*(GetNormalBallSize()+Offset));
76 r=new Ball( pos, GetNormalBallSize() );
77 if (t[c]>0) {
78 if (!deluxe)
79 r->state = new BallState( m, full_col, r->P() );
80 else r->state = new HalfBallState( m, ball_col[t[c]-1], r->P() );
81 ball[t[c]-1] = r;
82 ball_p[t[c]-1] = pos;
83 }
84 else if (t[c]<0) {
85 if (!deluxe)
86 r->state = new BallState( m, half_col, r->P() );
87 else r->state = new HalfBallState( mh, ball_col[-t[c]-1], r->P() );
88 ball[8-t[c]-1] = r;
89 ball_p[8-t[c]-1] = pos;
90 }
91 else {
92 if (!deluxe)
93 r->state = new BallState( m, black_col, r->P() );
94 else r->state = new HalfBallState( m, black_col, r->P() );
95 ball[7] = r;
96 ball_p[7] = pos;
97 }
98 c++;
99 }
100 }
101 }
102
103
InitPlayground()104 void Pool8::InitPlayground() {
105
106 if (deluxe) {
107 mh = HalfBallMover::Create( GetNormalBallSize(), (deluxe==3)?2:4 );
108 mh->Init();
109 m = HalfBallMover::Create( GetNormalBallSize(), (deluxe==2)?3:((deluxe==3)?1:0) );
110 m->Init();
111 BallRadius = m->GetActRadius()-Offset;
112 }
113 Pool::InitPlayground();
114
115 tridef = Vec2(AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()/2.);
116 Triangle(tridef);
117 cuedef = Vec2(AreaOffX()+AreaWidth()*0.125,AreaOffY()+AreaHeight()*0.375);
118 cueball = new Ball( cuedef.X(), cuedef.Y(), RealZero, RealZero, BallRadius );
119 if (!deluxe)
120 cueball->state = new BallState( m, cue_col, cueball->P() );
121 else cueball->state = new HalfBallState( m, cue_col, cueball->P() );
122
123 #ifdef DEBUG
124 if (deluxe) {
125 if (debug&ShowTurns) mh->CreateTurnWindow();
126 if (debug&ShowRings) mh->CreateRingWindow();
127 }
128 #endif
129 }
130
131
DrawBackground()132 void Pool8::DrawBackground() const {
133 Pool::DrawBackground();
134 SetBgColor(table_line_col);
135 DrawLine( AreaOffX()+AreaWidth()*0.25, AreaOffY(),
136 AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight() );
137 FillCircle( AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight()*0.50, 1.0 );
138 FillCircle( AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()*0.50, 1.0 );
139 }
140
ResetGame()141 void Pool8::ResetGame() {
142 for (int i=0;i<15;i++)
143 if (ball[i]) ball[i]->SetPV( ball_p[i] );
144 balls_in_pocket = 0;
145 Pool::ResetGame();
146 }
147
148 ////////////////////////////////////////////////////////////////////////////
149
InPocket(Ball * b)150 void Pool8::InPocket( Ball *b ) {
151 for (int i=0;i<15;i++) {
152 if (b==ball[i]) {
153 balls_in_pocket |= (1<<i);
154 return;
155 }
156 }
157 Pool::InPocket(b);
158 }
159
IsSelectable(Ball * b)160 int Pool8::IsSelectable(Ball *b) {
161 for (int i=0;i<15;i++) {
162 if (b==ball[i]) {
163 if (balls_in_pocket & (1<<i)) {
164 Vec2 newpos;
165 b->FitsNextTo(tridef,Vec2(1.0,RealZero),&newpos);
166 b->SetP(newpos); // closer to right wall
167
168 b->ChgV(Vec2Zero);
169 balls_in_pocket &= ~(1<<i); // it's back in the game
170
171 return 0;
172 }
173 else {
174 return 1;
175 }
176 }
177 }
178
179 return Pool::IsSelectable(b);
180 }
181
182 // -------------------------------------------------------------------------
183
~Pool9()184 Pool9::~Pool9() {
185 }
186
Triangle(const Vec2 & vec)187 void Pool9::Triangle( const Vec2 &vec )
188 {
189 static int t[9] = { 1,
190 2, 3,
191 4, -1, 5,
192 6, 7,
193 0 };
194
195 Real x = vec.X();
196 Real y = vec.Y();
197 const int count = 5;
198 int c=0;
199 double cdist = sqrt( 3.*(GetNormalBallSize()+Offset)*(GetNormalBallSize()+Offset) );
200 Ball *r;
201
202 // x-=(cdist*(count-1)/2);
203 for( int col=0; col<count; col++ ) {
204 int per_col = 2-abs(2-col);
205 for( int row=0; row<=per_col; row++ ) {
206 Vec2 pos( x+col*cdist, y+(row-per_col/2.0)*2*(GetNormalBallSize()+Offset) );
207 r=new Ball( pos, GetNormalBallSize() );
208 if (t[c]>0) {
209 if (!deluxe)
210 r->state = new BallState( m, full_col, r->P() );
211 else r->state = new HalfBallState( m, ball_col[t[c]-1], r->P() );
212 ball[t[c]-1] = r;
213 ball_p[t[c]-1] = pos;
214 }
215 else if (t[c]<0) {
216 if (!deluxe)
217 r->state = new BallState( m, half_col, r->P() );
218 else r->state = new HalfBallState( mh, ball_col[-t[c]-1], r->P() );
219 ball[8-t[c]-1] = r;
220 ball_p[8-t[c]-1] = pos;
221 }
222 else {
223 if (!deluxe)
224 r->state = new BallState( m, black_col, r->P() );
225 else r->state = new HalfBallState( m, black_col, r->P() );
226 ball[7] = r;
227 ball_p[7] = pos;
228 }
229 c++;
230 }
231 }
232 }
233
234 // -------------------------------------------------------------------------
235
~Pool8Demo()236 Pool8Demo::~Pool8Demo() {}
237
GetPresetA()238 const Real &Pool8Demo::GetPresetA() const { return PresetA; }
GetSlowGranularity()239 const Real &Pool8Demo::GetSlowGranularity() const { return SlowGranularity; }
240
InitPlayground()241 void Pool8Demo::InitPlayground() {
242
243 if (deluxe) {
244 mh = HalfBallMover::Create( GetNormalBallSize(), (deluxe==3)?2:4 );
245 mh->Init();
246 m = HalfBallMover::Create( GetNormalBallSize(), (deluxe==2)?3:((deluxe==3)?1:0) );
247 m->Init();
248 BallRadius = m->GetActRadius()-Offset;
249 }
250 Billard::InitPlayground();
251 BallRadius = m->GetActRadius();
252 Billard::InitTable();
253
254 Triangle( Vec2(AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()/2.) );
255 cueball = new Ball( AreaOffX()+AreaWidth()*0.125, AreaOffY()+AreaHeight()*0.375,
256 shot_speed, shot_speed, BallRadius );
257 if (!deluxe)
258 cueball->state = new BallState( m, cue_col, cueball->P() );
259 else cueball->state = new HalfBallState( m, cue_col, cueball->P() );
260 }
261
DrawBackground()262 void Pool8Demo::DrawBackground() const {
263 Billard::DrawBackground();
264 SetBgColor(table_line_col);
265 DrawLine( AreaOffX()+AreaWidth()*0.25, AreaOffY(),
266 AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight() );
267 FillCircle( AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight()*0.50, 1.0 );
268 FillCircle( AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()*0.50, 1.0 );
269 }
270
271 // -------------------------------------------------------------------------
272
273 #ifdef DEBUG
274
275 #ifndef _wall_h
276 # include "wall.h"
277 #endif
278
279
280 class TestField {
281 public:
282 TestField( const Vec2 &p1, const Vec2 &p2, const Real &len,
283 Pool8Test *d );
284 ~TestField();
285
286 void Draw() const;
Insert(TestField * n)287 void Insert( TestField *n ) { n->next = next; next = n; }
288
289 private:
290 Vec2 e[4];
291 Wall *w[4];
292 int nballs;
293 Ball **b;
294 TestField *next;
295 };
296
TestField(const Vec2 & p1,const Vec2 & p2,const Real & len,Pool8Test * d)297 TestField::TestField( const Vec2 &p1, const Vec2 &p2, const Real &len,
298 Pool8Test *d ) {
299 Vec2 dist = (p2-p1);
300 Vec2 dir_x = dist.TurnRight().Norm1();
301 Vec2 dir_y = dist.Norm1();
302
303 const double SPEED = 20.0;
304
305 next = 0l;
306 e[0] = p1;
307 e[1] = p1+dir_x*len;
308 e[2] = p2+dir_x*len;
309 e[3] = p2;
310 for (int i=0;i<4;i++) w[i] = new Wall( e[i], e[(i+1)%4] );
311
312 nballs = (int)(dist.Norm()/Pool8Test::BallRadius/3.);
313 b = new Ball*[nballs];
314 for (i=0;i<nballs;i++) {
315 Vec2 pos = e[0]
316 + 3.*Pool8Test::BallRadius*dir_x
317 + Real((i+1)*3)*Pool8Test::BallRadius * dir_y;
318 b[i] = new Ball( pos.X()+((rand()%150)/100.0), pos.Y(),
319 dir_x.X()*SPEED, dir_x.Y()*SPEED,
320 Pool8Test::BallRadius );
321 b[i]->state = new HalfBallState( d->mh, d->ball_col[i%7], b[i]->P() );
322 ((HalfBallState*)b[i]->state)->st = d->mh->AngVec2St(0,i*d->mh->vecs_b/nballs);
323
324 }
325 }
326
~TestField()327 TestField::~TestField() {
328 for (int i=0;i<nballs;i++) delete b[i];
329 delete b;
330 for (i=0;i<4;i++) delete w[i];
331 if (next) delete next;
332 }
333
Draw()334 void TestField::Draw() const {
335 for (int i=0;i<4;i++) DrawLine( e[i], e[(i+1)%4] );
336 if (next) next->Draw();
337 }
338
339
~Pool8Test()340 Pool8Test::~Pool8Test()
341 {
342 delete field_queue;
343 }
344
InitPlayground()345 void Pool8Test::InitPlayground() {
346
347 if (deluxe) {
348 mh = HalfBallMover::Create( GetNormalBallSize(), 2 );
349 mh->Init();
350 BallRadius = mh->GetActRadius()-Offset;
351 }
352 Billard::InitPlayground();
353 BallRadius = m->GetActRadius();
354 Billard::InitTable();
355
356 Vec2 dir = (Mid(2)-Mid(0))*3.0/4.0;
357 if (shot_speed>=RealZero&&shot_speed<=90.)
358 dir=dir.TurnAngleDeg(-shot_speed);
359
360 #if (1)
361 field_queue = new TestField( Mid(0), Mid(0)+dir, AreaWidth()/4., this );
362 #else
363 field_queue = new TestField( Edge(0), Edge(3), AreaWidth(), this );
364 field_queue->Insert( new TestField( Mid(2), Mid(1), AreaWidth()/5, this ) );
365 #endif
366 }
367
DrawBackground()368 void Pool8Test::DrawBackground() const {
369 Pool8Demo::DrawBackground();
370 SetBgColor(marker_col);
371 field_queue->Draw();
372 }
373 #endif
374