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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#include "Puzzle.h"
#include <algorithm>
#include <stdlib.h> // for random
#include <ClanLib/core.h> // for get_time
// private namespace
namespace
{
int Random(int range)
{
return static_cast<int>(double(rand()) / RAND_MAX * range);
}
}
//--------------------------------------------------------------------------
Puzzle::Puzzle(int width, int height)
: map(width, std::vector<bool>(height, false))
, width(width)
, height(height)
, is_solved(false)
{
srand(CL_System::get_time());
do
{
Shuffle();
} while(IsSolved());
}
//--------------------------------------------------------------------------
Puzzle::~Puzzle()
{
}
//--------------------------------------------------------------------------
int Puzzle::Width() const
{
return width;
}
//--------------------------------------------------------------------------
int Puzzle::Height() const
{
return height;
}
//--------------------------------------------------------------------------
Puzzle::HintVectorType const & Puzzle::Hints() const
{
return hints;
}
//--------------------------------------------------------------------------
bool Puzzle::IsSolved() const
{
// the Hints are not necessary the best way to solve
//return hints.empty();
return is_solved;
}
//--------------------------------------------------------------------------
bool Puzzle::operator()(int x, int y) const
{
if (x < width && y < height)
return map[x][y];
return false; // or throw error ?
}
//--------------------------------------------------------------------------
void Puzzle::FlipAt(int x, int y)
{
if ( x >= 0 && x < width
&& y >= 0 && y < height)
{
// if it was in hints, remove
// otherwise, add
HintVectorType::value_type move(x, y);
HintVectorType::iterator hint_iterator = std::find(hints.begin(), hints.end(), move);
if (hint_iterator == hints.end())
// not found, add move to hints
hints.push_back(move);
else
// ok, remove hint
hints.erase(hint_iterator);
// Fliping row
for(int row = 0; row < height; ++row)
map[x][row] = !map[x][row];
// Fliping column
for(int column = 0; column < width; ++column)
map[column][y] = !map[column][y];
// Flip coord itself
map[x][y] = !map[x][y];
// Updating solution status
is_solved = CheckSolution();
}
}
//--------------------------------------------------------------------------
void Puzzle::Shuffle()
{
int shuffle_times = 10 + Random(width * height);
for(int i = 0; i < shuffle_times; ++i)
FlipAt(Random(width), Random(height));
}
//--------------------------------------------------------------------------
//void Puzzle::Solve()
//{
//}
//--------------------------------------------------------------------------
bool Puzzle::CheckSolution() const
{
for(int y = 0; y < height; ++y)
for(int x = 0; x < width; ++x)
if (map[x][y])
return false;
return true;
}
|