#include <vector>
#include <iostream>
#include <string>
#include <utility>
#include <memory>
#include <map>
#include <set>
using std::string;
using std::vector;
using std::map;
using std::cout; using std::endl;
using std::pair; using std::multiset;
using std::shared_ptr;
typedef pair<int, int> range;
typedef pair<int,int> dims; // rows then cols
enum colors { RED, BLUE, BLACK, GREEN };
typedef vector< vector<colors> > colorGrid;
class SetGrid {
protected:
int priority;
colors c;
public:
SetGrid(colors clr ) : c(clr){};
int getPriority() const;
virtual void apply( colorGrid & cg) const=0;
};
int SetGrid::getPriority() const{
return this->priority;
}
struct comp{
bool operator()( const shared_ptr< SetGrid > & lhs, const shared_ptr<SetGrid> & rhs){
return lhs->getPriority() < rhs->getPriority() ;
};
};
class SetRowRange : public SetGrid {
private:
range rg;
int colNum;
public:
void apply( colorGrid & cg) const;
SetRowRange(colors clr, range & distance, int colIdx ) :
SetGrid(clr), rg(distance), colNum(colIdx) {
this->priority = 0;
}
};
void SetRowRange::apply( colorGrid & cg ) const{
// No range checking yet... don't break...
for(int i = rg.first ; i <= rg.second; ++i)
cg[i][colNum] = this->c;
}
class SetColRange : public SetGrid {
private:
range rg;
int rowNum;
public:
void apply( colorGrid & cg) const;
SetColRange( colors clr, range & distance, int rowIdx ) :
SetGrid(clr), rg(distance), rowNum(rowIdx) {
this->priority = 1;
}
};
void SetColRange::apply( colorGrid & cg ) const{
// No range checking yet... don't break me yet ...
for(int i = rg.first ; i <= rg.second; ++i)
cg[rowNum][i] = this->c;
}
class Grid {
private:
dims dimension;
static const map< colors, string > colorMap;
vector< vector< colors > > colorGrid;
multiset< shared_ptr< SetGrid >, comp > setRules;
private:
typedef vector< vector<colors> >::iterator rIter;
typedef vector<colors>::iterator cIter;
public:
Grid( dims d2 );
void setColor( colors c );
void addSetRule( shared_ptr< SetGrid > sg );
void applyRules( );
void printGrid(void);
void addSetMethod();
};
const map< colors, string> Grid::colorMap = { { RED, "RED" },
{ BLUE, "BLUE" },
{ BLACK, "BLACK" },
{ GREEN, "GREEN" } };
Grid::Grid( dims d2 ){
dimension = d2;
colorGrid.resize( d2.first );
rIter it;
for( it = colorGrid.begin(); it != colorGrid.end();
++it )
it->resize( d2.second );
}
void Grid::printGrid(void){
cIter cit;
rIter rit;
for( rit = colorGrid.begin(); rit!= colorGrid.end(); ++rit){
for ( cit = rit->begin(); cit != rit->end(); ++cit){
cout << colorMap.find( *cit )->second << "\t" ;
}
cout << "\n";
}
cout.flush();
}
void Grid::setColor( colors c ){
cIter cit;
rIter rit;
for( rit = colorGrid.begin(); rit!= colorGrid.end(); ++rit){
for ( cit = rit->begin(); cit != rit->end(); ++cit){
*cit = c;
}
}
}
void Grid::applyRules( ){
multiset< shared_ptr< SetGrid >,comp >::iterator it;
for (it = setRules.begin(); it != setRules.end(); ++it)
(*it)->apply( colorGrid );
}
void Grid::addSetRule( shared_ptr< SetGrid > sg ){
setRules.insert(sg);
}
int main( int argc, char * argv[]){
Grid g( pair<int,int>(5,4) );
g.setColor( BLUE );
g.printGrid();
range r1 = { 0, 2};
range r2 = { 1, 3};
g.addSetRule( shared_ptr< SetGrid > ( (new SetColRange( BLACK, r2 , 1 ) ) ) );
g.addSetRule( shared_ptr< SetGrid > ( (new SetRowRange( RED, r1 , 2 ) ) ) );
g.applyRules();
g.printGrid();
}