[gbrainy] Support for options in XML game types
- From: Jordi Mas <jmas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gbrainy] Support for options in XML game types
- Date: Sun, 31 Oct 2010 13:04:52 +0000 (UTC)
commit 3d18a86385e6140f3a2af25dab09b975e5b3a4a4
Author: Jordi Mas <jmas softcatala org>
Date: Sun Oct 31 14:06:46 2010 +0100
Support for options in XML game types
po/POTFILES.in | 1 +
src/Core/Core.csproj | 9 +
src/Core/Main/Game.cs | 2 +-
src/Core/Main/Xml/GameXml.cs | 286 ++++++++++++++++----
src/Core/Main/Xml/GameXmlFactory.cs | 70 +++++-
src/Core/Main/Xml/OptionDrawingObject.cs | 80 ++++++
src/Core/Makefile.am | 1 +
.../Calculation/CalculationGreatestDivisor.cs | 2 -
8 files changed, 395 insertions(+), 56 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4b68021..3258ac1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -24,6 +24,7 @@ src/Core/Main/Verbal/AnalogiesPairOfWordsCompare.cs
src/Core/Main/Verbal/AnalogiesPairOfWordsOptions.cs
src/Core/Main/Verbal/AnalogiesQuestionAnswer.cs
src/Core/Main/Verbal/AnalogiesFactory.cs
+src/Core/Main/Xml/GameXml.cs
src/Clients/Classical/gbrainy.cs
src/Clients/Classical/CommandLine.cs
src/Clients/Classical/Dialogs/AboutDialog.cs
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index 21fd673..30c8f99 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -36,10 +36,13 @@
<Reference Include="Mono.Posix" />
<Reference Include="System.Xml" />
<Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="Mono.CSharp" />
<Reference Include="Mono.Cairo" />
@@ -93,6 +96,12 @@
<Compile Include="Main\Xml\CodeEvaluation.cs" />
<Compile Include="Main\GameAnswerCheckAttributes.cs" />
<Compile Include="Main\GameDifficulty.cs" />
+ <Compile Include="Main\Xml\OptionDrawingObject.cs" />
+ <Compile Include="Main\Xml\GameXmlDefinitionVariant.cs" />
+ <Compile Include="Main\Xml\ImageDrawingObject.cs" />
+ <Compile Include="Main\Xml\LocalizableString.cs" />
+ <Compile Include="Main\Xml\TextDrawingObject.cs" />
+ <Compile Include="Main\Xml\DrawingObject.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
diff --git a/src/Core/Main/Game.cs b/src/Core/Main/Game.cs
index eec8568..6270c6d 100644
--- a/src/Core/Main/Game.cs
+++ b/src/Core/Main/Game.cs
@@ -62,6 +62,7 @@ namespace gbrainy.Core.Main
protected Game ()
{
+ containers = new List <Toolkit.Container> ();
difficulty = GameDifficulty.Medium;
}
@@ -129,7 +130,6 @@ namespace gbrainy.Core.Main
{
random = new Random ();
default_color = new Cairo.Color (0, 0, 0);
- containers = new List <Toolkit.Container> ();
Initialize ();
}
diff --git a/src/Core/Main/Xml/GameXml.cs b/src/Core/Main/Xml/GameXml.cs
index 384d1e3..23eef4d 100644
--- a/src/Core/Main/Xml/GameXml.cs
+++ b/src/Core/Main/Xml/GameXml.cs
@@ -23,6 +23,8 @@ using System.IO;
using Mono.Unix;
+using gbrainy.Core.Toolkit;
+
namespace gbrainy.Core.Main.Xml
{
public class GameXml : Game
@@ -46,9 +48,13 @@ namespace gbrainy.Core.Main.Xml
static List <GameXmlDefinition> games;
static List <DefinitionLocator> locators;
+ static string option_prefix = "[option_prefix]";
+ static string option_answers = "[option_answers]";
+
DefinitionLocator current;
GameXmlDefinition game;
string question, answer, rationale, answer_value;
+ List <OptionDrawingObject> options;
public override GameAnswerCheckAttributes CheckAttributes {
get {
@@ -196,7 +202,167 @@ namespace gbrainy.Core.Main.Xml
answer_value = CodeEvaluation.ReplaceVariables (answer_value);
}
- right_answer = answer;
+ if (options != null && options.Count > 0)
+ {
+ string answers = string.Empty;
+
+ foreach (OptionDrawingObject option in options)
+ {
+ if (option.Correct == true)
+ {
+ right_answer = option.Answer;
+ break;
+ }
+ }
+
+ string q;
+
+ for (int i = 0; i < options.Count - 1; i++)
+ answers += String.Format (Catalog.GetString ("{0}, "), GetPossibleAnswer (i));
+
+ answers += String.Format (Catalog.GetString ("{0}."), GetPossibleAnswer (options.Count - 1));
+
+ // Translators {0}: list of options (A, B, C)
+ answers = String.Format (Catalog.GetString ("Answer {0}"), answers);
+ question = question.Replace (option_answers, answers);
+ }
+ else
+ {
+ right_answer = answer;
+ }
+ }
+
+ void CreateDrawingObjects (GameXmlDefinitionVariant game)
+ {
+ OptionDrawingObject option;
+ double x = 0, y = 0, width = 0, height = 0;
+ bool first = true;
+ int randomized_options = 0;
+
+ if (game.DrawingObjects == null)
+ return;
+
+ // Calculate the size of container from the options and count the number of random options
+ foreach (DrawingObject draw_object in game.DrawingObjects)
+ {
+ option = draw_object as OptionDrawingObject;
+
+ if (option == null)
+ continue;
+
+ if (option.RandomizedOrder)
+ randomized_options++;
+
+ if (first == true)
+ {
+ x = option.X;
+ y = option.Y;
+ width = option.Width;
+ height = option.Height;
+ first = false;
+ continue;
+ }
+
+ if (option.X < x)
+ x = option.X;
+
+ if (option.Y < y)
+ y = option.Y;
+
+ if (option.X + option.Width > width)
+ width = option.X + option.Width;
+
+ if (option.Y + option.Height > height)
+ height = option.Y + option.Height;
+ }
+
+ if (first == true)
+ return;
+
+ // Randomize the order of the options
+ if (randomized_options > 0)
+ {
+ OptionDrawingObject [] originals;
+ ArrayListIndicesRandom random_indices;
+ DrawingObject temporary;
+ int index = 0;
+
+ random_indices = new ArrayListIndicesRandom (randomized_options);
+ originals = new OptionDrawingObject [randomized_options];
+ random_indices.Initialize ();
+
+ // Backup originals
+ for (int i = 0; i < game.DrawingObjects.Length; i++)
+ {
+ option = game.DrawingObjects[i] as OptionDrawingObject;
+
+ if (option == null)
+ continue;
+
+ originals[index] = option.Copy ();
+ index++;
+ }
+
+ // Swap
+ index = 0;
+ for (int i = 0; i < game.DrawingObjects.Length; i++)
+ {
+ option = game.DrawingObjects[i] as OptionDrawingObject;
+
+ if (option == null)
+ continue;
+
+ option.CopyRandomizedProperties (originals [random_indices [index]]);
+
+ // For randomized options the answer is always the option letter
+ option.Answer = GetPossibleAnswer (index);
+ index++;
+ }
+ }
+
+ Container container = new Container (x, y, width - x, height - y);
+ AddWidget (container);
+
+ if (options == null)
+ options = new List <OptionDrawingObject> ();
+
+ int idx = 0;
+
+ // Create drawing widgets objects
+ foreach (DrawingObject draw_object in game.DrawingObjects)
+ {
+ option = draw_object as OptionDrawingObject;
+
+ if (option == null)
+ continue;
+
+ DrawableArea drawable_area = new DrawableArea (option.Width, option.Height);
+ drawable_area.X = option.X;
+ drawable_area.Y = option.Y; // + i * 0.15;
+ container.AddChild (drawable_area);
+
+ drawable_area.Data = idx;
+ drawable_area.DataEx = GetPossibleAnswer (idx);
+ options.Add (option);
+
+ idx++;
+ drawable_area.DrawEventHandler += DrawOption;
+ }
+ }
+
+ void DrawOption (object sender, DrawEventArgs e)
+ {
+ int idx = (int) e.Data;
+
+ if (options.Count == 0)
+ return;
+
+ OptionDrawingObject _option = options [idx];
+ Widget widget = (Widget) sender;
+
+ e.Context.SetPangoLargeFontSize ();
+
+ DrawObjects (e.Context, _option.DrawingObjects, idx);
}
public override int Variants {
@@ -218,6 +384,11 @@ namespace gbrainy.Core.Main.Xml
current.Game = locator.Game;
current.Variant = locator.Variant;
game = games [locator.Game];
+
+ CreateDrawingObjects (game); // Draw objects shared by all variants
+
+ if (game.Variants.Count > 0)
+ CreateDrawingObjects (game.Variants[current.Variant]); // Draw variant specific objects
}
}
@@ -225,68 +396,83 @@ namespace gbrainy.Core.Main.Xml
{
base.Draw (gr, area_width, area_height, rtl);
- DrawObjects (gr, game); // Draw objects shared by all variants
+ DrawObjects (gr, game.DrawingObjects, null); // Draw objects shared by all variants
if (game.Variants.Count > 0)
- DrawObjects (gr, game.Variants[current.Variant]); // Draw variant specific objects
+ DrawObjects (gr, game.Variants[current.Variant].DrawingObjects, null); // Draw variant specific objects
}
- void DrawObjects (CairoContextEx gr, GameXmlDefinitionVariant definition)
+ static void DrawObjects (CairoContextEx gr, DrawingObject [] drawing_objects, int? option)
{
- if (definition.DrawingObjects != null)
+ if (drawing_objects == null)
+ return;
+
+ foreach (DrawingObject draw_object in drawing_objects)
{
- foreach (DrawingObject draw_object in definition.DrawingObjects)
+ if (draw_object is OptionDrawingObject)
+ continue;
+
+ if (draw_object is TextDrawingObject)
{
- if (draw_object is TextDrawingObject)
- {
- string text;
- TextDrawingObject draw_string = draw_object as TextDrawingObject;
-
- text = CatalogGetString (draw_string.Text);
- text = CodeEvaluation.ReplaceVariables (text);
-
- switch (draw_string.Size) {
- case TextDrawingObject.Sizes.Small:
- gr.SetPangoFontSize (0.018);
- break;
- case TextDrawingObject.Sizes.Medium:
- gr.SetPangoNormalFontSize (); // 0.022
- break;
- case TextDrawingObject.Sizes.Large:
- gr.SetPangoLargeFontSize (); // 0.0325
- break;
- case TextDrawingObject.Sizes.XLarge:
- gr.SetPangoFontSize (0.06);
- break;
- case TextDrawingObject.Sizes.XXLarge:
- gr.SetPangoFontSize (0.08);
- break;
- default:
- throw new InvalidOperationException ("Invalid value");
- }
-
- if (draw_string.Centered) {
- gr.DrawTextCentered (draw_string.X, draw_string.Y, text);
- } else {
- gr.MoveTo (draw_string.X, draw_string.Y);
+ string text;
+ TextDrawingObject draw_string = draw_object as TextDrawingObject;
+
+ text = CatalogGetString (draw_string.Text);
+ text = CodeEvaluation.ReplaceVariables (text);
+
+ switch (draw_string.Size) {
+ case TextDrawingObject.Sizes.Small:
+ gr.SetPangoFontSize (0.018);
+ break;
+ case TextDrawingObject.Sizes.Medium:
+ gr.SetPangoNormalFontSize (); // 0.022
+ break;
+ case TextDrawingObject.Sizes.Large:
+ gr.SetPangoLargeFontSize (); // 0.0325
+ break;
+ case TextDrawingObject.Sizes.XLarge:
+ gr.SetPangoFontSize (0.06);
+ break;
+ case TextDrawingObject.Sizes.XXLarge:
+ gr.SetPangoFontSize (0.08);
+ break;
+ default:
+ throw new InvalidOperationException ("Invalid value");
+ }
+
+ if (draw_string.Centered) {
+ gr.DrawTextCentered (draw_string.X, draw_string.Y, text);
+ } else {
+ gr.MoveTo (draw_string.X, draw_string.Y);
+ if (option == null)
gr.ShowPangoText (text);
- gr.Stroke ();
- }
+ else
+ gr.ShowPangoText (GetOptionPrefix (text, (int) option));
+
+ gr.Stroke ();
}
- else if (draw_object is ImageDrawingObject)
- {
- ImageDrawingObject image = draw_object as ImageDrawingObject;
+ }
+ else if (draw_object is ImageDrawingObject)
+ {
+ ImageDrawingObject image = draw_object as ImageDrawingObject;
- if (String.IsNullOrEmpty (image.Filename) == false)
- {
- gr.DrawImageFromFile (Path.Combine (Defines.DATA_DIR, image.Filename),
- image.X, image.Y, image.Width, image.Height);
- }
+ if (String.IsNullOrEmpty (image.Filename) == false)
+ {
+ gr.DrawImageFromFile (Path.Combine (Defines.DATA_DIR, image.Filename),
+ image.X, image.Y, image.Width, image.Height);
}
}
}
}
+ static string GetOptionPrefix (string str, int option)
+ {
+ string answer;
+
+ answer = String.Format (Catalog.GetString ("{0}) "), GetPossibleAnswer (option));
+ return str.Replace (option_prefix, answer);
+ }
+
void BuildLocationList ()
{
locators.Clear ();
@@ -300,7 +486,7 @@ namespace gbrainy.Core.Main.Xml
}
// Protect from calling with null (exception)
- string CatalogGetString (string str)
+ static string CatalogGetString (string str)
{
if (String.IsNullOrEmpty (str))
return str;
@@ -309,7 +495,7 @@ namespace gbrainy.Core.Main.Xml
}
// Protect from calling with null + resolve plurals
- string CatalogGetString (LocalizableString localizable)
+ static string CatalogGetString (LocalizableString localizable)
{
if (localizable == null)
return string.Empty;
diff --git a/src/Core/Main/Xml/GameXmlFactory.cs b/src/Core/Main/Xml/GameXmlFactory.cs
index a87854d..bf3cc46 100644
--- a/src/Core/Main/Xml/GameXmlFactory.cs
+++ b/src/Core/Main/Xml/GameXmlFactory.cs
@@ -45,6 +45,7 @@ namespace gbrainy.Core.Main.Xml
string name, str, plural;
bool processing_variant = false;
int variant = 0;
+ OptionDrawingObject option = null;
if (read == true)
return;
@@ -132,10 +133,17 @@ namespace gbrainy.Core.Main.Xml
TextDrawingObject draw_string = new TextDrawingObject ();
- if (processing_variant)
- game.Variants[variant].AddDrawingObject (draw_string);
+ if (option != null)
+ {
+ option.AddDrawingObject (draw_string);
+ }
else
- game.AddDrawingObject (draw_string);
+ {
+ if (processing_variant)
+ game.Variants[variant].AddDrawingObject (draw_string);
+ else
+ game.AddDrawingObject (draw_string);
+ }
draw_string.Text = reader.GetAttribute ("text");
@@ -321,6 +329,62 @@ namespace gbrainy.Core.Main.Xml
else
game.Variables = reader.ReadElementString ();
break;
+ case "option":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ OptionDrawingObject option_draw = new OptionDrawingObject ();
+
+ if (reader.NodeType == XmlNodeType.Element) {
+ option = option_draw;
+ } else if (reader.NodeType == XmlNodeType.EndElement) {
+ option = null;
+ break;
+ }
+
+ if (processing_variant)
+ game.Variants[variant].AddDrawingObject (option_draw);
+ else
+ game.AddDrawingObject (option_draw);
+
+ option_draw.Answer = reader.GetAttribute ("answer");
+
+ if (String.IsNullOrEmpty (option_draw.Answer))
+ option_draw.Answer = reader.GetAttribute ("_answer");
+
+ str = reader.GetAttribute ("x");
+ if (String.IsNullOrEmpty (str) == false)
+ option_draw.X = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ option_draw.X = 0.1;
+
+ str = reader.GetAttribute ("y");
+ if (String.IsNullOrEmpty (str) == false)
+ option_draw.Y = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ option_draw.Y = 0.1;
+
+ str = reader.GetAttribute ("width");
+ if (String.IsNullOrEmpty (str) == false)
+ option_draw.Width = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ option_draw.Width = 0.1;
+
+ str = reader.GetAttribute ("height");
+ if (String.IsNullOrEmpty (str) == false)
+ option_draw.Height = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ option_draw.Height = 0.1;
+
+ str = reader.GetAttribute ("order");
+ if (String.IsNullOrEmpty (str) == false)
+ option_draw.RandomizedOrder = true;
+
+ str = reader.GetAttribute ("correct");
+ if (String.Compare (str, "yes", true) == 0)
+ option_draw.Correct = true;
+
+ break;
default:
if (String.IsNullOrEmpty (name) == false)
Console.WriteLine ("GameXmlFactory. Unsupported tag: {0}", name);
diff --git a/src/Core/Main/Xml/OptionDrawingObject.cs b/src/Core/Main/Xml/OptionDrawingObject.cs
new file mode 100644
index 0000000..2f932e2
--- /dev/null
+++ b/src/Core/Main/Xml/OptionDrawingObject.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 Jordi Mas i Hernà ndez <jmas softcatala org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace gbrainy.Core.Main.Xml
+{
+ public class OptionDrawingObject : DrawingObject
+ {
+ public double X { get; set; }
+ public double Y { get; set; }
+ public double Width { get; set; }
+ public double Height { get; set; }
+ public string Answer { get; set; }
+ public bool Correct { get; set; }
+ public bool RandomizedOrder { get; set; }
+
+ List <DrawingObject> drawing_objects;
+
+ public DrawingObject [] DrawingObjects {
+ get {
+ if (drawing_objects == null)
+ return null;
+
+ return drawing_objects.ToArray ();
+ }
+ }
+
+ public void AddDrawingObject (DrawingObject obj)
+ {
+ if (drawing_objects == null)
+ drawing_objects = new List <DrawingObject> ();
+
+ drawing_objects.Add (obj);
+ }
+
+ public void CopyRandomizedProperties (OptionDrawingObject obj)
+ {
+ Answer = obj.Answer;
+ Correct = obj.Correct;
+ drawing_objects = obj.drawing_objects;
+ }
+
+ // Deep copy
+ public OptionDrawingObject Copy ()
+ {
+ OptionDrawingObject option = new OptionDrawingObject ();
+
+ option.X = X;
+ option.Y = Y;
+ option.Width = Width;
+ option.Height = Height;
+ option.Answer = Answer;
+ option.Correct = Correct;
+ option.RandomizedOrder = RandomizedOrder;
+
+ foreach (DrawingObject obj in DrawingObjects)
+ option.AddDrawingObject (obj);
+
+ return option;
+ }
+ }
+}
diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am
index ae5108e..cec80e5 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -28,6 +28,7 @@ CSDISTFILES = \
$(srcdir)/Main/Xml/GameXmlFactory.cs \
$(srcdir)/Main/Xml/GameXmlDefinition.cs \
$(srcdir)/Main/Xml/GameXmlDefinitionVariant.cs \
+ $(srcdir)/Main/Xml/OptionDrawingObject.cs \
$(srcdir)/Main/Xml/TextDrawingObject.cs \
$(srcdir)/Main/Memory.cs \
$(srcdir)/Main/PlayerHistory.cs \
diff --git a/src/Games/Calculation/CalculationGreatestDivisor.cs b/src/Games/Calculation/CalculationGreatestDivisor.cs
index fca821f..c968415 100644
--- a/src/Games/Calculation/CalculationGreatestDivisor.cs
+++ b/src/Games/Calculation/CalculationGreatestDivisor.cs
@@ -229,8 +229,6 @@ namespace gbrainy.Games.Calculation
base.Draw (gr, area_width, area_height, rtl);
-
-
gr.MoveTo (0.05, y);
gr.SetPangoLargeFontSize ();
gr.ShowPangoText (Catalog.GetString ("Numbers"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]