1 /* 2 * Copyright (C) 2010 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 22 namespace gbrainy.Games.Logic 23 { 24 public class PuzzleTrains : Game 25 { 26 enum GameType 27 { 28 Overtake, 29 Meet, 30 Apart, 31 Total 32 } 33 34 string question, answer; 35 GameType gametype; 36 37 public override string Name { 38 get {return Translations.GetString ("Trains");} 39 } 40 41 public override string Question { 42 get {return question; } 43 } 44 45 public override string Rationale { 46 get { return answer;} 47 } 48 49 public override string Tip { 50 get { return Translations.GetString ("The distance formula is 'distance = rate x time'.");} 51 } 52 Initialize()53 protected override void Initialize () 54 { 55 int ans; 56 double speed_a, speed_b, rslt; 57 58 gametype = (GameType) random.Next ((int) GameType.Total); 59 60 switch (gametype) 61 { 62 case GameType.Overtake: 63 { 64 double hours; 65 66 do 67 { 68 speed_a = 20 + (5 * random.Next (5)); 69 speed_b = 50 + (5 * random.Next (5)); 70 hours = 2 * (1 + random.Next (3)); 71 rslt = speed_a * hours / (speed_b - speed_a); 72 73 } while (rslt != Math.Truncate (rslt)); 74 75 question = String.Format ( 76 // Translators: 77 // - mph (miles per hour). You must localize this using the right unit of speed for your locale 78 // - The translated string should not use more characters than the original sentence 79 Translations.GetPluralString ("A train leaves the station traveling at {0} mph. {1} hour later a second train leaves the station traveling in the same direction at {2} mph. How many hours does it take the second train, since it starts moving, to overtake the first train?", 80 "A train leaves the station traveling at {0} mph. {1} hours later a second train leaves the station traveling in the same direction at {2} mph. How many hours does it take the second train, since it starts moving, to overtake the first train?", (int) hours), 81 speed_a, hours, speed_b); 82 83 answer = Translations.GetString ("You can calculate the answer by multiplying the speed of the first train by the time and dividing it by the difference of speeds."); 84 break; 85 } 86 case GameType.Meet: 87 { 88 double distance, hours; 89 90 speed_a = 20 + (5 * random.Next (5)); 91 speed_b = 50 + (5 * random.Next (5)); 92 hours = 2 + random.Next (5); 93 distance = hours * (speed_b + speed_a); 94 rslt = hours; 95 96 question = String.Format ( 97 // Translators: 98 // - mph (miles per hour) and miles must be localized this using the right unit of speed for your locale 99 Translations.GetPluralString ("Two trains separated by {0} mile are heading towards each other on straight parallel tracks. One travels at {1} mph and the other at {2} mph. In how many hours will they meet?", 100 "Two trains separated by {0} miles are heading towards each other on straight parallel tracks. One travels at {1} mph and the other at {2} mph. In how many hours will they meet?", 101 (int) distance), 102 distance, speed_a, speed_b); 103 104 answer = Translations.GetString ("You can calculate the answer by dividing the distance by the sum of both speeds."); 105 break; 106 } 107 case GameType.Apart: 108 { 109 double distance; 110 111 speed_a = 10 + (2 * random.Next (5)); 112 speed_b = 20 + (2 * random.Next (5)); 113 distance = (speed_a + speed_b) * (2 + random.Next (5)); 114 115 // Time in hours 116 rslt = distance / (speed_a + speed_b); 117 118 question = String.Format ( 119 // Translators: 120 // - mph (miles per hour) and miles must be localized this using the right unit of speed for your locale 121 Translations.GetPluralString ("Two trains on straight parallel tracks leave from the same point and time traveling in opposite directions at {0} and {1} mph respectively. In how many hours will they be {2} mile apart?", 122 "Two trains on straight parallel tracks leave from the same point and time traveling in opposite directions at {0} and {1} mph respectively. In how many hours will they be {2} miles apart?", 123 (int) distance), 124 speed_a, speed_b, distance); 125 126 answer = Translations.GetString ("You can calculate the answer by dividing the distance by the sum of both speeds."); 127 break; 128 } 129 default: 130 throw new Exception ("Unexpected value"); 131 } 132 133 ans = (int) rslt; 134 Answer.Correct = (ans).ToString (); 135 } 136 Draw(CairoContextEx gr, int area_width, int area_height, bool rtl)137 public override void Draw (CairoContextEx gr, int area_width, int area_height, bool rtl) 138 { 139 string train_right = "train_right.svg"; 140 string train_left = "train_left.svg"; 141 142 base.Draw (gr, area_width, area_height, rtl); 143 144 switch (gametype) 145 { 146 case GameType.Overtake: 147 gr.DrawImageFromAssembly (train_right, 0, 0.1, 0.5, 0.55); 148 gr.MoveTo (0.1, 0.45); 149 gr.LineTo (0.9, 0.45); 150 gr.Stroke (); 151 152 gr.DrawImageFromAssembly (train_right, 0.5, 0.1, 0.5, 0.55); 153 break; 154 155 case GameType.Meet: 156 gr.DrawImageFromAssembly (train_right, 0, 0.1, 0.5, 0.55); 157 gr.MoveTo (0.1, 0.45); 158 gr.LineTo (0.9, 0.45); 159 gr.Stroke (); 160 161 gr.DrawImageFromAssembly (train_left, 0.55, 0.3, 0.5, 0.55); 162 gr.MoveTo (0.1, 0.65); 163 gr.LineTo (0.9, 0.65); 164 gr.Stroke (); 165 break; 166 167 case GameType.Apart: 168 gr.DrawImageFromAssembly (train_right, 0.35, 0.1, 0.5, 0.55); 169 gr.MoveTo (0.1, 0.45); 170 gr.LineTo (0.9, 0.45); 171 gr.Stroke (); 172 173 gr.DrawImageFromAssembly (train_left, 0.15, 0.3, 0.5, 0.55); 174 gr.MoveTo (0.1, 0.65); 175 gr.LineTo (0.9, 0.65); 176 gr.Stroke (); 177 break; 178 default: 179 throw new Exception ("Unexpected value"); 180 } 181 } 182 CheckAnswer(string answer)183 public override bool CheckAnswer (string answer) 184 { 185 string num = string.Empty; 186 187 // Clean the answer from every non-numeric values after the numbers (like 5 hours) 188 for (int c = 0; c < answer.Length; c++) 189 { 190 if (answer[c] < '0' || answer[c] > '9') 191 break; 192 193 num += answer[c]; 194 } 195 196 return base.CheckAnswer (num); 197 } 198 } 199 } 200