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