1 /*
2  * GarbageQueue.cxx
3  *
4  * Crack Attack! is the legal property of its developers, whose names
5  * are too numerous to list here.  Please refer to the COPYRIGHT file
6  * distributed with this source distribution for a full listing.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22 #include "GarbageQueue.h"
23 #include "GarbageGenerator.h"
24 #include "GarbageManager.h"
25 
26 #include <cassert>
27 
GarbageQueue()28 GarbageQueue::GarbageQueue () {
29   //garbage_queue// = new vector<GarbageQueueElement();
30   cached_height = -1;
31 }
32 
~GarbageQueue()33 GarbageQueue::~GarbageQueue () {
34   reset();
35 }
36 
reset()37 void GarbageQueue::reset () {
38   garbage_queue.clear();
39   cached_height = -1;
40 }
41 
42 // FIXME: This makes xtreme an error condition
removeWithSpecials()43 int GarbageQueue::removeWithSpecials ()
44 {
45   if ((*(garbage_queue.begin())).flavor == GF_GRAY) {
46     return removeToFirst(GF_NORMAL);
47   } else {
48     return removeToFirst(GF_GRAY);
49   }
50   return 0;
51 }
52 
removeToFirst(int flavor)53 int GarbageQueue::removeToFirst ( int flavor )
54 {
55   int num_removed = 0;
56   assert((*(garbage_queue.begin())).flavor != flavor);
57   if (garbage_queue.empty()) return 0;
58   vector<GarbageQueueElement>::iterator iter;
59   for (iter = garbage_queue.begin(); iter != garbage_queue.end(); ++iter) {
60     if ((*iter).flavor == flavor) break;
61     ++num_removed;
62   }
63   if (num_removed == 0) return 0;
64 #ifdef DEVELOPMENT
65   int prev_height = height();
66   cached_height = -1;
67   MESSAGE("Removing " << num_removed);
68   MESSAGE("Height before erase " << height());
69 #endif
70   garbage_queue.erase(garbage_queue.begin(), iter);
71   cached_height = -1;
72 #ifdef DEVELOPMENT
73   int current_height = height();
74   MESSAGE("Height after erase " << current_height);
75   //assert((prev_height - num_removed)==current_height);
76 	if (prev_height - num_removed != current_height) {
77 		MESSAGE("***********Assertion would've failed here in GarbageQueue.cxx:75***********");
78 		MESSAGE("prev_height - num_removed != current_height (" <<
79 				prev_height << " - " << num_removed << " != " <<
80 				current_height << ")");
81 	}
82 #endif
83   return num_removed;
84 }
85 
add(int height,int width,int flavor)86 void GarbageQueue::add ( int height, int width, int flavor)
87 {
88   GarbageQueueElement e;
89   e.active = true;
90   e.height = height;
91   e.width = width;
92   e.flavor = flavor;
93   add(e);
94 }
95 
show_element(GarbageQueueElement & e)96 static void show_element (GarbageQueueElement &e) {
97 #ifndef NDEBUG
98   printf("Element: h %d w %d f %d\n",+
99     e.height,
100     e.width,
101     e.flavor);
102 #endif
103 }
104 
add(GarbageQueueElement & element)105 void GarbageQueue::add ( GarbageQueueElement &element )
106 {
107   element.active = true;
108   MESSAGE("Adding garbage with height " << element.height);
109   show_element(element);
110   assert(element.height <= GC_PLAY_HEIGHT);
111   assert(element.width  <= GC_PLAY_WIDTH);
112   garbage_queue.push_back(element);
113   //int old_height = cached_height;
114   cached_height = -1;
115   //assert(height()-element.height == old_height);
116 }
117 
height()118 int GarbageQueue::height ( )
119 {
120   int garbage_height = 0;
121   vector<GarbageQueueElement>::iterator iter;
122   if (cached_height != -1) return cached_height;
123   for (iter = garbage_queue.begin(); iter != garbage_queue.end(); ++iter) {
124     garbage_height += (*iter).height;
125   }
126   cached_height = garbage_height;
127   return garbage_height;
128 }
129 
specialHeight()130 int GarbageQueue::specialHeight ( )
131 {
132   int garbage_height = 0;
133   vector<GarbageQueueElement>::iterator iter;
134   if (cached_height != -1) return cached_height;
135   for (iter = garbage_queue.begin(); iter != garbage_queue.end(); ++iter) {
136     if (GarbageManager::isSpecialFlavor((*iter).flavor))
137       garbage_height += (*iter).height;
138   }
139   return garbage_height;
140 }
141 
sendToGenerator()142 void GarbageQueue::sendToGenerator ( )
143 {
144   vector<GarbageQueueElement>::iterator iter;
145   for (iter = garbage_queue.begin(); iter != garbage_queue.end(); ++iter) {
146     GarbageGenerator::addToQueue(*iter);
147   }
148 }
149