1 /*
2  * Copyright (C) 2007 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 
20 using gbrainy.Core.Main;
21 using gbrainy.Core.Toolkit;
22 using gbrainy.Core.Services;
23 
24 namespace gbrainy.Games.Calculation
25 {
26 	public class CalculationCloserFraction : Game
27 	{
28 		private double question_num;
29 		private const int options_cnt = 4;
30 		private double []options;
31 		private ArrayListIndicesRandom random_indices;
32 		private int which;
33 
34 		public override string Name {
35 			get {return Translations.GetString ("Closer fraction");}
36 		}
37 
38 		public override GameTypes Type {
39 			get { return GameTypes.Calculation;}
40 		}
41 
42 		public override string Question {
43 			get {return String.Format (
44 				Translations.GetString ("Which of the following numbers is closer to {0}? Answer {1}, {2}, {3} or {4}."),
45 				String.Format ("{0:##0.###}", question_num),
46 				Answer.GetMultiOption (0), Answer.GetMultiOption (1), Answer.GetMultiOption (2), Answer.GetMultiOption (3));}
47 		}
48 
49 		public override string Rationale {
50 			get {
51 				int ans_idx = random_indices[which];
52 
53 				return String.Format (Translations.GetString ("The result of the operation {0} / {1} is '{2}'."),
54 					options[ans_idx * 2], options[(ans_idx * 2) + 1], String.Format ("{0:##0.###}", question_num));
55 			}
56 		}
57 
Initialize()58 		protected override void Initialize ()
59 		{
60 			Answer.CheckAttributes |= GameAnswerCheckAttributes.MultiOption | GameAnswerCheckAttributes.IgnoreSpaces;
61 			options = new double [options_cnt * 2];
62 			bool duplicated;
63 			bool done = false;
64 			int i, ans_idx, basenum, randnum;
65 
66 			switch (CurrentDifficulty) {
67 			case GameDifficulty.Easy:
68 				basenum = 5;
69 				randnum = 10;
70 				break;
71 			default:
72 			case GameDifficulty.Medium:
73 				basenum = 5;
74 				randnum = 30;
75 				break;
76 			case GameDifficulty.Master:
77 				basenum = 9;
78 				randnum = 60;
79 				break;
80 			}
81 
82 			while (done == false) {
83 				duplicated = false;
84 				options[0 + 0] = basenum + random.Next (randnum);
85 				options[0 + 1] = basenum + random.Next (randnum);
86 
87 				options[2 + 0] = options[0 + 0] + random.Next (2);
88 				options[2 + 1] = options[0 + 1] + random.Next (2);
89 
90 				options[(2 * 2) + 0] = options[0 + 0] - random.Next (5);
91 				options[(2 * 2) + 1] = options[0 + 1] - random.Next (5);
92 
93 				options[(3 * 2) + 0] = options[0 + 0] +  random.Next (5);
94 				options[(3 * 2) + 1] = options[0 + 1] +  random.Next (5);
95 
96 				// No repeated answers
97 				for (int num = 0; num < options_cnt; num++)
98 				{
99 					for (int n = 0; n < options_cnt; n++)
100 					{
101 						if (n == num) continue;
102 
103 						if (options [(num * 2) + 0] / options [(num * 2) + 1] ==
104 							options [(n * 2) + 0] / options [(n * 2) + 1]) {
105 							duplicated = true;
106 							break;
107 						}
108 					}
109 				}
110 
111 				if (duplicated)
112 					continue;
113 
114 				// No numerator = denominator (1 value)
115 				if (options [0 + 0] == options [0 + 1]) continue;
116 				if (options [(1 * 2) + 0] == options [(1 * 2) + 1]) continue;
117 				if (options [(2 * 2) + 0] == options [(2 * 2) + 1]) continue;
118 				if (options [(3 * 2) + 0] == options [(3 * 2) + 1]) continue;
119 
120 				// No < 2
121 				for (i = 0; i < options_cnt * 2; i++) {
122 					if (options [i] < 2)
123 						break;
124 				}
125 
126 				if (i < options_cnt * 2)
127 					continue;
128 
129 				done = true;
130 			}
131 
132 			random_indices = new ArrayListIndicesRandom (4);
133 			random_indices.Initialize ();
134 
135 			which = random.Next (options_cnt);
136 			ans_idx = random_indices[which];
137 			question_num = options[ans_idx * 2] / options[(ans_idx * 2) + 1];
138 
139 			Answer.SetMultiOptionAnswer (which, options [ans_idx * 2] +  " / " + options [(ans_idx  * 2) +1]);
140 
141 			// Options
142 			double x = DrawAreaX + 0.25, y = DrawAreaY + 0.16;
143 			Container container = new Container (x, y,  1 - (x * 2), 0.6);
144 			AddWidget (container);
145 
146 			for (i = 0; i < options_cnt; i++)
147 			{
148 				DrawableArea drawable_area = new DrawableArea (0.3, 0.1);
149 				drawable_area.X = x;
150 				drawable_area.Y = y + i * 0.15;
151 				container.AddChild (drawable_area);
152 				drawable_area.Data = i;
153 				drawable_area.DataEx = Answer.GetMultiOption (i);
154 
155 				drawable_area.DrawEventHandler += delegate (object sender, DrawEventArgs e)
156 				{
157 					int n = (int) e.Data;
158 					int indx = random_indices[n];
159 
160 					e.Context.SetPangoLargeFontSize ();
161 					e.Context.MoveTo (0.02, 0.02);
162 					e.Context.ShowPangoText (String.Format (Translations.GetString ("{0}) {1}"), Answer.GetMultiOption (n) ,
163 						options [indx * 2] +  " / " + options [(indx  * 2) +1]));
164 				};
165 			}
166 		}
167 
Draw(CairoContextEx gr, int area_width, int area_height, bool rtl)168 		public override void Draw (CairoContextEx gr, int area_width, int area_height, bool rtl)
169 		{
170 			base.Draw (gr, area_width, area_height, rtl);
171 
172 			gr.SetPangoLargeFontSize ();
173 
174 			gr.MoveTo (0.1, 0.15);
175 			gr.ShowPangoText (Translations.GetString ("Choose one of the following:"));
176 		}
177 	}
178 }
179