1 /*
2  * Copyright (C) 2007-2011 Jordi Mas i Hernàndez <jmas@softcatala.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 using System;
19 using Cairo;
20 
21 using gbrainy.Core.Main;
22 using gbrainy.Core.Toolkit;
23 using gbrainy.Core.Services;
24 
25 namespace gbrainy.Games.Logic
26 {
27 	public class PuzzleGridDots : Game
28 	{
29 		const double figure_size = 0.25;
30 		const int lines = 6;
31 		const int columns = 6;
32 		static bool X = true;
33 		static bool O = false;
34 		const double space_figures = 0.05;
35 		ArrayListIndicesRandom possible_answers;
36 		int puzzle_index;
37 
38 		bool [] [] puzzles = new bool [] []
39 		{
40 			puzzle_a,
41 			puzzle_b,
42 			puzzle_c,
43 		};
44 
45 		bool [] puzzle;
46 
47 		static bool [] puzzle_a  = new bool []
48 		{
49 			// Figure A
50 			O, O, O, O, O, O,
51 			O, O, O, O, O, O,
52 			O, O, X, X, O, O,	// Down, Diagonal down left
53 			O, O, X, X, O, O,	// Up, Diagonal up left
54 			O, O, O, O, O, O,
55 			O, O, O, O, O, O,
56 
57 			// Figure B
58 			O, O, O, O, O, O,
59 			O, O, O, O, O, O,
60 			O, O, X, O, O, O,
61 			O, O, X, O, O, O,
62 			O, O, O, O, O, O,
63 			O, O, O, O, O, O,
64 
65 			// Figure C
66 			O, O, O, O, O, O,
67 			O, X, X, O, O, O,
68 			O, O, O, O, O, O,
69 			O, O, O, O, O, O,
70 			O, X, X, O, O, O,
71 			O, O, O, O, O, O,
72 
73 			// Wrong answer 1
74 			O, X, X, O, O, O,
75 			O, O, O, O, O, O,
76 			O, O, O, O, O, O,
77 			O, O, O, O, O, O,
78 			O, O, O, O, O, O,
79 			O, X, X, O, O, O,
80 
81 			// Correct Answer
82 			X, O, X, O, O, O,
83 			O, O, O, O, O, O,
84 			O, O, O, O, O, O,
85 			O, O, O, O, O, O,
86 			O, O, O, O, O, O,
87 			X, O, X, O, O, O,
88 
89 			// Wrong answer 2
90 			O, O, O, O, O, O,
91 			O, X, X, O, O, O,
92 			O, O, O, O, O, O,
93 			O, O, O, O, O, O,
94 			O, O, O, O, O, O,
95 			O, X, X, O, O, O,
96 		};
97 
98 		static bool [] puzzle_b = new bool []
99 		{
100 			// Figure A
101 			X, O, O, O, O, O,
102 			X, O, O, O, O, O,
103 			X, O, O, O, O, O,
104 			X, O, O, O, O, O,
105 			X, O, O, O, O, O,
106 			X, O, O, O, O, O,
107 
108 			// Figure B
109 			O, O, X, X, X, X,
110 			O, O, O, O, O, X,
111 			O, O, O, O, O, X,
112 			O, O, O, O, O, O,
113 			O, O, O, O, O, O,
114 			O, O, O, O, O, O,
115 
116 			// Figure C
117 			O, O, O, O, O, O,
118 			O, O, O, O, O, O,
119 			O, O, O, O, O, O,
120 			O, O, O, O, O, O,
121 			O, O, O, O, O, O,
122 			X, X, X, X, X, X,
123 
124 			// Wrong answer 1
125 			O, O, O, O, O, O,
126 			O, O, O, O, O, O,
127 			O, O, O, O, O, O,
128 			X, O, O, O, O, O,
129 			X, O, O, O, O, O,
130 			X, X, X, X, O, O,
131 
132 			// Correct Answer
133 			O, O, O, O, O, O,
134 			O, O, O, O, O, O,
135 			X, O, O, O, O, O,
136 			X, O, O, O, O, O,
137 			X, O, O, O, O, O,
138 			X, X, X, O, O, O,
139 
140 			// Wrong answer 2
141 			O, O, O, O, O, O,
142 			O, O, O, O, O, O,
143 			O, O, O, O, O, O,
144 			O, O, O, O, O, O,
145 			X, O, O, O, O, O,
146 			X, X, X, X, X, O,
147 		};
148 
149 		static bool [] puzzle_c = new bool []
150 		{
151 			// Figure A
152 			O, O, O, O, O, O,
153 			O, O, O, O, O, O,
154 			O, O, O, O, O, O,
155 			O, O, O, O, O, O,
156 			O, O, O, O, O, X,
157 			O, O, X, X, X, X,
158 
159 			// Figure B
160 			O, O, O, O, O, O,
161 			O, O, O, O, O, O,
162 			O, O, O, O, X, X,
163 			O, O, O, O, O, X,
164 			O, O, O, O, O, X,
165 			O, O, O, O, O, X,
166 
167 			// Figure C
168 			O, O, O, O, O, O,
169 			O, O, O, O, O, O,
170 			O, O, X, X, X, X,
171 			O, O, X, O, O, O,
172 			O, O, O, O, O, O,
173 			O, O, O, O, O, O,
174 
175 			// Wrong answer 1
176 			O, O, O, O, O, O,
177 			O, O, O, O, O, O,
178 			O, O, O, O, O, O,
179 			O, O, X, O, O, O,
180 			O, O, X, O, O, O,
181 			O, O, X, X, X, O,
182 
183 			// Correct Answer
184 			O, O, O, O, O, O,
185 			O, O, O, O, O, O,
186 			O, O, X, O, O, O,
187 			O, O, X, O, O, O,
188 			O, O, X, O, O, O,
189 			O, O, X, X, O, O,
190 
191 
192 			// Wrong answer 2
193 			O, O, O, O, O, O,
194 			O, O, O, O, O, O,
195 			O, O, X, X, O, O,
196 			O, O, X, O, O, O,
197 			O, O, X, O, O, O,
198 			O, O, X, O, O, O,
199 		};
200 
201 		public override string Name {
202 			get {return Translations.GetString ("Square with dots");}
203 		}
204 
205 		public override string Question {
206 			get {return (String.Format (
207 				Translations.GetString ("Which is the next logical figure in the sequence? Answer {0}, {1} or {2}."),
208 				Answer.GetMultiOption (0), Answer.GetMultiOption (1), Answer.GetMultiOption (2)));}
209 		}
210 
211 
212 		public override string Rationale {
213 			get {
214 				switch (puzzle_index) {
215 				case 0:
216 					return Translations.GetString ("From the top-left figure, the top-left circle moves down, the bottom-left circle moves up, the bottom-right moves diagonally up-left and the top-right moves diagonally down-left.");
217 				case 2:
218 					return Translations.GetString
219 					("From the top-left figure, the figure is rotated counterclockwise 90 degrees.");
220 				case 1: // TODO
221 				default:
222 					return string.Empty;
223 				}
224 			}
225 		}
226 
Initialize()227 		protected override void Initialize ()
228 		{
229 			Answer.CheckAttributes |= GameAnswerCheckAttributes.MultiOption | GameAnswerCheckAttributes.IgnoreSpaces;
230 			possible_answers = new ArrayListIndicesRandom (3);
231 			possible_answers.Initialize ();
232 
233 			puzzle_index = random.Next (puzzles.Length);
234 			puzzle = puzzles [puzzle_index];
235 
236 			DrawableArea drawable_area;
237 			HorizontalContainer container = new HorizontalContainer (0.05, 0.5, 0.9, figure_size + 0.1);
238 			AddWidget (container);
239 
240 			for (int i = 0; i < possible_answers.Count; i++) {
241 
242 				drawable_area = new DrawableArea (figure_size + space_figures, figure_size + 0.1);
243 				drawable_area.Data = i;
244 				drawable_area.DataEx = Answer.GetMultiOption (i);
245 				drawable_area.SelectedArea = new Rectangle (space_figures / 2, space_figures / 2, figure_size, figure_size);
246 
247 				container.AddChild (drawable_area);
248 
249 				drawable_area.DrawEventHandler += delegate (object sender, DrawEventArgs e)
250 				{
251 					DrawPossibleAnswer (e.Context, space_figures / 2, space_figures / 2, possible_answers [(int)e.Data]);
252 					e.Context.DrawTextCentered (space_figures / 2 + figure_size / 2, space_figures + figure_size + 0.02,
253 						Answer.GetFigureName ((int)e.Data));
254 				};
255 			}
256 
257 			for (int i = 0; i < possible_answers.Count; i++) {
258 				if (possible_answers[i] == 0) {
259 					Answer.SetMultiOptionAnswer (i, Answer.GetFigureName (i));
260 					break;
261 				}
262 			}
263 		}
264 
DrawFigure(CairoContextEx gr, double x, double y, bool [] puzzle, int index)265 		public void DrawFigure (CairoContextEx gr, double x, double y, bool [] puzzle, int index)
266 		{
267 			double pos_x = x, pos_y = y;
268 			double square_size = figure_size / lines;
269 			double center_square = square_size / 2;
270 			double radius_square = (square_size - (LineWidth *2)) / 2.5;
271 
272 			gr.Rectangle (pos_x, pos_y, figure_size, figure_size);
273 			gr.Stroke ();
274 
275 			for (int line = 0; line < lines - 1; line++) // Horizontal
276 			{
277 				pos_y += square_size;
278 				gr.MoveTo (pos_x, pos_y);
279 				gr.LineTo (pos_x + figure_size, pos_y);
280 				gr.Stroke ();
281 			}
282 
283 			pos_y = y;
284 			for (int column = 0; column < columns - 1; column++) // Vertical
285 			{
286 				pos_x += square_size;
287 				gr.MoveTo (pos_x, pos_y);
288 				gr.LineTo (pos_x, pos_y + figure_size);
289 				gr.Stroke ();
290 			}
291 
292 			pos_y = y + center_square;
293 			pos_x = x + center_square;
294 
295 			for (int line = 0; line < lines; line++) // Circles
296 			{
297 				for (int column = 0; column < columns; column++)
298 				{
299 					if (puzzle[index + (columns * line) + column] == false)
300 						continue;
301 
302 					gr.Arc (pos_x + (square_size * column), pos_y, radius_square, 0, 2 * Math.PI);
303 					gr.Fill ();
304 					gr.Stroke ();
305 				}
306 				pos_y += square_size;
307 			}
308 		}
309 
DrawPossibleAnswer(CairoContextEx gr, double x, double y, int figure)310 		public void DrawPossibleAnswer (CairoContextEx gr, double x, double y, int figure)
311 		{
312 			switch (figure) {
313 			case 0: // Good answer
314 				DrawFigure (gr, x, y, puzzle, columns * lines * 4);
315 				break;
316 			case 1:
317 				DrawFigure (gr, x, y, puzzle,  columns * lines * 3);
318 				break;
319 			case 2:
320 				DrawFigure (gr, x, y, puzzle, columns * lines * 5);
321 				break;
322 			}
323 		}
324 
Draw(CairoContextEx gr, int area_width, int area_height, bool rtl)325 		public override void Draw (CairoContextEx gr, int area_width, int area_height, bool rtl)
326 		{
327 			double x = 0.05 + space_figures / 2, y = DrawAreaY;
328 
329 			base.Draw (gr, area_width, area_height, rtl);
330 
331 			DrawFigure (gr, x, y, puzzle, 0);
332 			DrawFigure (gr, x + figure_size + space_figures, y, puzzle, columns * lines);
333 			DrawFigure (gr, x + (figure_size + space_figures) * 2, y, puzzle, columns * lines * 2);
334 
335 			y += figure_size + 0.10;
336 			gr.MoveTo (x, y - 0.02);
337 			gr.ShowPangoText (Translations.GetString ("Choose one of the following:"));
338 		}
339 	}
340 }
341