1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
#include <bitset>
#include <cstdlib>
#include <deque>
#include <iostream>
#include <set>
template< size_t Width, size_t Height >
struct Grid
{
enum { W = Width, H = Height };
Grid() { bits.flip(); }
void set( size_t w, size_t h ) { bits.set( make_index( w, h ) ); }
void reset( size_t w, size_t h ) { bits.reset( make_index( w, h ) ); }
void flip( size_t w, size_t h ) { bits.flip( make_index( w, h ) ); }
bool zero() const { return bits.none(); }
uint32_t hash() const { return bits.to_ulong(); }
private:
size_t make_index( size_t w, size_t h ) const { return h * W + w; }
std::bitset<W*H> bits;
};
typedef Grid< 3, 3 > grid_t;
grid_t flip( grid_t grid, size_t w, size_t h ) {
grid.flip( w, h ); // Center
if( w ) grid.flip( w - 1, h ); // Left
if( h ) grid.flip( w, h - 1 ); // Top
if( w < grid_t::W - 1 ) grid.flip( w + 1, h ); // Right
if( h < grid_t::H - 1 ) grid.flip( w, h + 1 ); // Bottom
return grid;
}
void solve( std::deque< grid_t > grid, size_t depth = 0 ) {
static std::set<uint32_t> seen;
std::deque< grid_t > new_grids;
for( std::deque<grid_t>::iterator g = grid.begin(); g != grid.end(); ++g ) {
if( g->zero() ) {
std::cout << "Solved in " << depth << " moves." << std::endl;
exit( 0 );
}
for( size_t w = 0; w < grid_t::W; ++w )
for( size_t h = 0; h < grid_t::H; ++h ) {
grid_t candidate( flip( *g, w, h ) );
if( seen.find( candidate.hash() ) == seen.end() ) {
seen.insert( candidate.hash() );
new_grids.push_back( candidate );
}
}
}
solve( new_grids, depth + 1 );
}
int main() {
std::cout << "Mini-Game Solver" << std::endl;
solve( std::deque<grid_t>( 1, grid_t() ) );
std::cout << "No solution found." << std::endl;
}
|