1 /***************************************************************************
2                           pipequeue.cpp  -  description
3                              -------------------
4     begin                : Sat Sep 30 2000
5     copyright            : (C) 2000 by Waldemar Baraldi
6     email                : baraldi@lacasilla.com.ar
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "pipequeue.h"
19 #include "cross.h"
20 #include "horizontal.h"
21 #include "vertical.h"
22 #include "elbowupright.h"
23 #include "elbowdownright.h"
24 #include "elbowupleft.h"
25 #include "elbowdownleft.h"
26 #include "horizontalbowl.h"
27 #include "verticalbowl.h"
28 #include "random.h"
29 
PipeQueue()30 PipeQueue::PipeQueue():AnimatedCanvas(){
31   index=0;
32   change=true;
33   res_coef=0;
34   fixed_coef=0;
35   filled=false;
36 }
37 
~PipeQueue()38 PipeQueue::~PipeQueue(){
39   if (filled)
40     for (int i=0;i<MaxPipes;i++)
41       delete queue[i];
42 }
43 
width()44 int PipeQueue::width(){
45   return PipeWidth;
46 }
47 
height()48 int PipeQueue::height(){
49   return PipeHeight;
50 }
51 
getPipe(int pos)52 Pipe * PipeQueue::getPipe(int pos){
53   change=true;
54   if (!filled) fillUp();
55   return queue[(pos+index)%MaxPipes];
56 }
57 
getHead()58 Pipe * PipeQueue::getHead(){
59   if (!filled) fillUp();
60 
61   Pipe * aux=queue[index];
62   queue[index]=generatePipe();
63   index=(index+1)% MaxPipes;
64   change=true;
65   return aux;
66 }
67 
setRestrictionCoef(unsigned int coef)68 void PipeQueue::setRestrictionCoef(unsigned int coef){
69   if (coef > 100)
70     res_coef=100;
71   else res_coef=coef;
72 }
73 
setFixedCoef(unsigned int coef)74 void PipeQueue::setFixedCoef(unsigned int coef){
75   if (coef > 100)
76     fixed_coef=100;
77   else fixed_coef=coef;
78 
79 }
80 
isChanged()81 bool PipeQueue::isChanged(){
82   return change;
83 }
84 
fillUp()85 void PipeQueue::fillUp(){
86   for (index=0;index<MaxPipes;index++)
87     queue[index]=generatePipe();
88   index=0;
89   change=true;
90   filled=true;
91 }
92 
paint(VideoManager * vm)93 void PipeQueue::paint(VideoManager * vm){
94   if (change){
95     int i,j;
96     Image * ima=vm->getImageManager()->getImage(new Str("queue_one.png"));
97     vm->blit(ima, x,y);
98 
99   //Pintar los pipes
100     j=index;
101     for (i=0;i<MaxPipes;i++){
102       j=(j+MaxPipes -1)% MaxPipes;
103       queue[j]->setPos(x+27, y+5+i*queue[j]->height());
104       queue[j]->paint(vm);
105     }
106   }
107   change=false;
108 }
109 
generatePipe()110 Pipe * PipeQueue::generatePipe(){
111 
112  Pipe * aux=NULL;
113  Random * r=new Random();
114  switch ((r->getRandomNumber(0, 6))){
115 
116    case 0: {
117      aux=new Cross();
118      if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
119        aux->setFixed(true);
120      for (int i=0;i<2;i++)
121        if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
122          switch (r->getRandomNumber(0, 3)){
123            case 0:{
124              if (!aux->isRestrictedAsOutput(South))
125                aux->restrictAsOutput(North);
126              break;
127            }
128            case 1:{
129              if (!aux->isRestrictedAsOutput(North))
130                aux->restrictAsOutput(South);
131              break;
132            }
133            case 2:{
134              if (!aux->isRestrictedAsOutput(East))
135                aux->restrictAsOutput(West);
136              break;
137            }
138            case 3:{
139              if (!aux->isRestrictedAsOutput(West))
140                aux->restrictAsOutput(East);
141              break;
142            }
143            default:break;
144          }
145      break;
146    }
147    case 1: {
148     if ((unsigned int)r->getRandomNumber(0,3))
149       aux=new Horizontal();
150     else aux= new HorizontalBowl();
151     if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
152        aux->setFixed(true);
153     if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
154       switch (r->getRandomNumber(0, 1)){
155         case 0:{
156           aux->restrictAsOutput(West);
157           break;
158         }
159         case 1:{
160           aux->restrictAsOutput(East);
161           break;
162         }
163         default:break;
164       }
165      break;
166    }
167    case 2: {
168     if ((unsigned int)r->getRandomNumber(0,3))
169       aux= new Vertical();
170     else aux= new VerticalBowl();
171     if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
172        aux->setFixed(true);
173     if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
174       switch (r->getRandomNumber(0, 1)){
175         case 0:{
176           aux->restrictAsOutput(North);
177           break;
178         }
179         case 1:{
180           aux->restrictAsOutput(South);
181           break;
182         }
183         default:break;
184       }
185      break;
186    }
187    case 3: {
188      aux= new ElbowUpRight();
189      if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
190        aux->setFixed(true);
191      if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
192        switch (r->getRandomNumber(0, 1)){
193          case 0:{
194            aux->restrictAsOutput(North);
195            break;
196          }
197          case 1:{
198            aux->restrictAsOutput(East);
199            break;
200          }
201          default:break;
202        }
203      break;
204    }
205    case 4: {
206      aux= new ElbowUpLeft();
207      if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
208        aux->setFixed(true);
209      if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
210        switch (r->getRandomNumber(0, 1)){
211          case 0:{
212            aux->restrictAsOutput(North);
213            break;
214          }
215          case 1:{
216            aux->restrictAsOutput(West);
217            break;
218          }
219          default:break;
220        }
221      break;
222    }
223    case 5: {
224      aux= new ElbowDownRight();
225      if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
226        aux->setFixed(true);
227      if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
228        switch (r->getRandomNumber(0, 1)){
229          case 0:{
230            aux->restrictAsOutput(South);
231            break;
232          }
233          case 1:{
234            aux->restrictAsOutput(East);
235            break;
236          }
237          default:break;
238        }
239      break;
240    }
241    case 6: {
242      aux= new ElbowDownLeft();
243      if ((unsigned int)r->getRandomNumber(1,100)<=fixed_coef)
244        aux->setFixed(true);
245      if ((unsigned int)r->getRandomNumber(1,100)<=res_coef)
246        switch (r->getRandomNumber(0, 1)){
247          case 0:{
248            aux->restrictAsOutput(South);
249            break;
250          }
251          case 1:{
252            aux->restrictAsOutput(West);
253            break;
254          }
255          default:break;
256        }
257    }
258      break;
259  }
260  delete r;
261  return aux;
262 }
263 
264