1 /*
2     Bastet - tetris clone with embedded bastard block chooser
3     (c) 2005-2009 Federico Poloni <f.polonithirtyseven@sns.it> minus 37
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef WELL_HPP
20 #define WELL_HPP
21 
22 #include "Block.hpp" //for Color
23 #include "BlockPosition.hpp"
24 #include <cstddef> //size_t
25 #include <vector>
26 #include <bitset>
27 #include <boost/array.hpp>
28 
29 //DBG
30 #include <iostream>
31 
32 namespace Bastet{
33 
34   class GameOver{}; //used as an exception
35 
36   class WellLine: public std::bitset<WellWidth>{
37   public:
38     std::string PrettyPrint() const;
39   };
40 
41   ///complex type that holds which lines are completed
42   ///if _completed[k]==true, then line _baseY+k exists and is completed
43   class LinesCompleted{
44   public:
45     int _baseY;
46     std::bitset<4> _completed;
47     ///clear, returns iterator such that the segment [it, rend) is "new" (to be zeroed out by hand)
48     template<typename Iterator> Iterator Clear(Iterator rbegin, Iterator rend) const;
49   };
50 
51 
52   /*
53    * the real height of the well is _height+2, with the top two rows( -1 and -2) hidden (see guidelines)
54    */
55   class Well{
56   private:
57     typedef boost::array<WellLine,RealWellHeight> WellType;
58     WellType _well;
59   public:
60     Well();
61     ~Well();
62     void Clear();
63     bool Accomodates(const DotMatrix &d) const; //true if the given tetromino fits into the well
IsValidLine(int y) const64     bool IsValidLine(int y) const{return (y>=-2) && (y<WellHeight);};
65     bool IsLineComplete(int y) const;
66     LinesCompleted Lock(BlockType t, const BlockPosition &p); //permanently adds a tetromino to the well; returns a bitset of 4 bits where return[i]==1 iff line (start of fb)+i is complete
67     void ClearLines(const LinesCompleted &lc); //removes the given lines from the well (whether they are completed or not)
68     int LockAndClearLines(BlockType t, const BlockPosition &p); //locks, clear lines, returns number of lines cleared
69     friend long Evaluate(const Well *w, int extralines); //for BastetBlockChooser
70     std::string PrettyPrint() const;
71   };
72 
Clear(Iterator rbegin,Iterator rend) const73   template <typename Iterator> Iterator LinesCompleted::Clear(Iterator rbegin, Iterator rend) const{
74     if(_completed.none()) return rend;
75     Iterator orig=rbegin;
76     Iterator dest=rbegin;
77     int j=WellHeight-1;
78     while(orig<rend){
79       if(j-_baseY>=0 && j-_baseY<4 && _completed[j-_baseY]){
80 	//skip
81       }
82       else{
83 	*dest=*orig;
84 	dest++;
85       }
86       j--;
87       orig++;
88     }
89     return dest++;
90   }
91 
92 }
93 
94 #endif //WELL_HPP
95