File: Puzzle.cpp

package info (click to toggle)
clanlib 0.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 28,372 kB
  • ctags: 16,520
  • sloc: cpp: 101,145; sh: 8,752; xml: 6,410; makefile: 1,740; ansic: 463; perl: 424; php: 247
file content (125 lines) | stat: -rw-r--r-- 2,859 bytes parent folder | download | duplicates (7)
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;
}