[gbrainy] New games + allow to draw text from xml definitions + fixes
- From: Jordi Mas <jmas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gbrainy] New games + allow to draw text from xml definitions + fixes
- Date: Sun, 4 Jul 2010 19:14:17 +0000 (UTC)
commit 40b05fdaa6d6499381fb6fafe48ddaf1002bbf86
Author: Jordi Mas <jmas softcatala org>
Date: Sun Jul 4 21:15:05 2010 +0200
New games + allow to draw text from xml definitions + fixes
data/Makefile.am | 4 +-
data/game-graphics/box.svg | 59 ++++++
data/games.xml | 79 ++++++++
gbrainy.csproj | 5 +-
src/Clients/Classical/Dialogs/CustomGameDialog.cs | 2 +-
.../Classical/Dialogs/PlayerHistoryDialog.cs | 8 +-
src/Core/Core.csproj | 1 +
src/Core/Main/GameManager.cs | 17 ++-
src/Core/Main/GameTypes.cs | 22 ++-
src/Core/Main/Xml/CodeEvaluation.cs | 175 +++++++++++++++++
src/Core/Main/Xml/GameXml.cs | 200 +++++---------------
src/Core/Main/Xml/GameXmlDefinition.cs | 51 ++++-
src/Core/Main/Xml/GameXmlFactory.cs | 71 ++++++-
src/Core/Makefile.am | 1 +
src/Core/Views/PlayerHistoryView.cs | 8 +-
15 files changed, 515 insertions(+), 188 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index c3b7bd6..2ade944 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -49,7 +49,8 @@ analogies_DATA = \
game-graphics/password.svg \
game-graphics/tennis.svg \
game-graphics/father_son.svg \
- game-graphics/money.svg
+ game-graphics/money.svg \
+ game-graphics/box.svg
install-data-local:
@@ -70,6 +71,7 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/game-graphics/tennis.svg $(DESTDIR)$(images)/tennis.svg
$(INSTALL_DATA) $(srcdir)/game-graphics/father_son.svg $(DESTDIR)$(images)/father_son.svg
$(INSTALL_DATA) $(srcdir)/game-graphics/money.svg $(DESTDIR)$(images)/money.svg
+ $(INSTALL_DATA) $(srcdir)/game-graphics/box.svg $(DESTDIR)$(images)/box.svg
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
diff --git a/data/game-graphics/box.svg b/data/game-graphics/box.svg
new file mode 100644
index 0000000..c614bb2
--- /dev/null
+++ b/data/game-graphics/box.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="500"
+ id="svg548"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="box.svg"
+ sodipodi:version="0.32"
+ width="500"
+ version="1.1">
+ <defs
+ id="defs550">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 500 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="500 : 500 : 1"
+ inkscape:persp3d-origin="250 : 333.33333 : 1"
+ id="perspective26" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ inkscape:cx="301.39179"
+ inkscape:cy="203.66957"
+ inkscape:window-height="694"
+ inkscape:window-width="1152"
+ inkscape:window-x="0"
+ inkscape:window-y="52"
+ inkscape:zoom="0.472"
+ showgrid="true"
+ showguides="true"
+ snaptoguides="true"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg548" />
+ <path
+ d="m 84.7922,148.96 c 0.8479,0 239.9618,105.143 239.9618,105.143 L 485.012,111.652 268.791,53.1451 84.7922,148.96 z"
+ id="path554"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:9.45112896;stroke-linejoin:round;stroke-dasharray:none"
+ transform="matrix(1,0,0,1.119522,-36.46066,-46.20438)" />
+ <path
+ d="m 49.17954,121.509 c 0,0.9493 1.6958,230.6719 0.8479,229.7225 L 289.9893,488.8756 286.5973,237.3202 49.17954,121.509 z"
+ id="path555"
+ sodipodi:nodetypes="ccccc"
+ style="font-size:12px;fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-dasharray:none" />
+ <path
+ d="M 326.45,478.802 323.906,254.103 485.012,111.652 482.468,328.72 326.45,478.802 z"
+ id="path557"
+ style="font-size:12px;fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:9.45112896;stroke-linejoin:round;stroke-dasharray:none"
+ transform="matrix(1,0,0,1.119522,-36.46066,-46.20438)" />
+</svg>
diff --git a/data/games.xml b/data/games.xml
index c26dc8a..0c26526 100644
--- a/data/games.xml
+++ b/data/games.xml
@@ -145,4 +145,83 @@
<_rationale>Compound interest is paid on the original amount and on the accumulated past interest.</_rationale>
</variant>
</game>
+
+ <game>
+ <_name>Simple equations</_name>
+ <type>Calculation</type>
+ <difficulty>All</difficulty>
+
+ <!-- Addition -->
+ <variant>
+ <variables>
+ int num_a = 30 + random.Next (20);
+ int num_b = 60 + random.Next (20);
+ int rslt = num_b - num_a;
+ </variables>
+ <_question>What number plus [num_a] equals [num_b]?</_question>
+ <string _text = "x + [num_a] = [num_b]" x = "0.5" y = "0.4" centered = "yes" size = "big"/>
+ <answer>[rslt]</answer>
+ <_rationale>It is the result of the operation [num_b] - [num_a].</_rationale>
+ </variant>
+
+ <!-- Subtraction -->
+ <variant>
+ <variables>
+ int num_a = 30 + random.Next (20);
+ int num_b = 60 + random.Next (20);
+ int rslt = num_b + num_a;
+ </variables>
+ <_question>What number minus [num_a] equals [num_b]?</_question>
+ <string _text = "x - [num_a] = [num_b]" x = "0.5" y = "0.4" centered = "yes" size = "big"/>
+ <answer>[rslt]</answer>
+ <_rationale>It is the result of the operation [num_a] + [num_b].</_rationale>
+ </variant>
+
+ <!-- Multiplication -->
+ <variant>
+ <variables>
+ int num_a = 3 + random.Next (5);
+ int num_b = (30 + random.Next (20)) * num_a;
+ int rslt = num_b / num_a;
+ </variables>
+ <_question>What number multiplied by [num_a] equals [num_b]?</_question>
+ <string _text = "x * [num_a] = [num_b]" x = "0.5" y = "0.4" centered = "yes" size = "big"/>
+ <answer>[rslt]</answer>
+ <_rationale>It is the result of the operation [num_b] / [num_a].</_rationale>
+ </variant>
+
+ <!-- Division -->
+ <variant>
+ <variables>
+ int num_a = 3 + random.Next (5);
+ int num_b = 3 + random.Next (5);
+ int rslt = num_a * num_b;
+ </variables>
+ <_question>What number divided by [num_a] equals [num_b]?</_question>
+ <string _text = "x / [num_a] = [num_b]" x = "0.5" y = "0.4" centered = "yes" size = "big"/>
+ <answer>[rslt]</answer>
+ <_rationale>It is the result of the operation [num_a] * [num_b].</_rationale>
+ </variant>
+ </game>
+
+ <game>
+ <_name>Boxes</_name>
+ <type>Logic</type>
+ <difficulty>All</difficulty>
+ <variant>
+ <svg file = "box.svg" x = "0.1" y = "0.1" width = "0.6" height = "0.5"/>
+ <string _text = "Container" x = "0.4" y = "0.62" centered = "yes" />
+ <svg file = "box.svg" x = "0.75" y = "0.2" width = "0.1" height = "0.1"/>
+ <string _text = "Box" x = "0.8" y = "0.32" centered = "yes" />
+ <variables>
+ double z = 4 + random.Next (5);
+ double big_box = 6 * 5 * z;
+ double small_box = 1 * 1 * 0.5;
+ double rslt = big_box / small_box;
+ </variables>
+ <_question>How many boxes measuring 1 x 1 x 0.5 can be packed into a container measuring 6 x 5 x [z]?</_question>
+ <answer>[rslt]</answer>
+ <_rationale>You can pack 6 * 5 boxes multiplied by the depth [z] * 2.</_rationale>
+ </variant>
+ </game>
</games>
diff --git a/gbrainy.csproj b/gbrainy.csproj
index 277413d..65d72be 100644
--- a/gbrainy.csproj
+++ b/gbrainy.csproj
@@ -85,6 +85,7 @@
<Compile Include="src\Clients\Classical\Builder\BuilderConnectFunc.cs" />
<Compile Include="src\Clients\Classical\Defines.cs" />
<Compile Include="src\Clients\Classical\Dialogs\HigMessageDialog.cs" />
+ <Compile Include="src\Clients\Classical\CommandLine.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -97,7 +98,9 @@
</EmbeddedResource>
<EmbeddedResource Include="src\Clients\Classical\Dialogs\ui\PreferencesDialog.ui" />
<EmbeddedResource Include="src\Clients\Classical\Dialogs\ui\PlayerHistoryDialog.ui" />
- <EmbeddedResource Include="src\Clients\Classical\Dialogs\ui\CustomGameDialog.ui" />
+ <EmbeddedResource Include="src\Clients\Classical\Dialogs\ui\CustomGameDialog.ui">
+ <LogicalName>CustomGameDialog.ui</LogicalName>
+ </EmbeddedResource>
<EmbeddedResource Include="data\app-graphics\allgames-32.png">
<LogicalName>allgames-32.png</LogicalName>
</EmbeddedResource>
diff --git a/src/Clients/Classical/Dialogs/CustomGameDialog.cs b/src/Clients/Classical/Dialogs/CustomGameDialog.cs
index 07e8234..78ac383 100644
--- a/src/Clients/Classical/Dialogs/CustomGameDialog.cs
+++ b/src/Clients/Classical/Dialogs/CustomGameDialog.cs
@@ -94,7 +94,7 @@ namespace gbrainy.Clients.Classical
game = (Game) Activator.CreateInstance (games [i].TypeOf, true);
game.Variant = games [i].Variant;
- type = GameTypesDescription.Get (game.Type);
+ type = GameTypesDescription.GetLocalized(game.Type);
games_store.AppendValues (game.Name, type, true, game, i);
}
}
diff --git a/src/Clients/Classical/Dialogs/PlayerHistoryDialog.cs b/src/Clients/Classical/Dialogs/PlayerHistoryDialog.cs
index 23d862f..a3f52a8 100644
--- a/src/Clients/Classical/Dialogs/PlayerHistoryDialog.cs
+++ b/src/Clients/Classical/Dialogs/PlayerHistoryDialog.cs
@@ -64,10 +64,10 @@ namespace gbrainy.Clients.Classical
drawing_area.Visible = true;
checkbutton_total.Label = Catalog.GetString ("Total");
- checkbutton_logic.Label = GameTypesDescription.Get (GameTypes.LogicPuzzle);
- checkbutton_calculation.Label = GameTypesDescription.Get (GameTypes.MathTrainer);
- checkbutton_memory.Label = GameTypesDescription.Get (GameTypes.MemoryTrainer);
- checkbutton_verbal.Label = GameTypesDescription.Get (GameTypes.VerbalAnalogy);
+ checkbutton_logic.Label = GameTypesDescription.GetLocalized (GameTypes.LogicPuzzle);
+ checkbutton_calculation.Label = GameTypesDescription.GetLocalized (GameTypes.MathTrainer);
+ checkbutton_memory.Label = GameTypesDescription.GetLocalized (GameTypes.MemoryTrainer);
+ checkbutton_verbal.Label = GameTypesDescription.GetLocalized (GameTypes.VerbalAnalogy);
checkbutton_total.Active = checkbutton_memory.Active = checkbutton_logic.Active = checkbutton_calculation.Active = checkbutton_verbal.Active = true;
}
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index 2687b60..d7316bf 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -94,6 +94,7 @@
<Compile Include="Libraries\SVGImage.cs" />
<Compile Include="Libraries\GetText.cs" />
<Compile Include="Platform\Unix.cs" />
+ <Compile Include="Main\Xml\CodeEvaluation.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
diff --git a/src/Core/Main/GameManager.cs b/src/Core/Main/GameManager.cs
index 984b59f..d39b223 100644
--- a/src/Core/Main/GameManager.cs
+++ b/src/Core/Main/GameManager.cs
@@ -94,7 +94,7 @@ namespace gbrainy.Core.Main
cnt_verbal += AddVerbalGamesAndVariations (VerbalAnalogiesInternal);
// Load defined XML games
- cnt_logic += LoadXmlGames ();
+ LoadXmlGames ();
LoadPlugins ();
@@ -267,7 +267,7 @@ namespace gbrainy.Core.Main
}
// XML are stored using the Variant as a pointer to the game + the internal variant
- int LoadXmlGames ()
+ void LoadXmlGames ()
{
Type type = typeof (GameXml);
int cnt = 0;
@@ -278,9 +278,19 @@ namespace gbrainy.Core.Main
for (int i = 0; i < game.Variants.Count; i++)
{
available_games.Add (new GameLocator (type, cnt++, game.Type, false));
+
+ switch (game.Type) {
+ case GameTypes.LogicPuzzle:
+ cnt_logic++;
+ break;
+ case GameTypes.MathTrainer:
+ cnt_calculation++;
+ break;
+ default:
+ break;
+ }
}
}
- return cnt;
}
void LoadPlugins ()
@@ -422,7 +432,6 @@ namespace gbrainy.Core.Main
break;
}
}
-
enumerator = play_list.GetEnumerator ();
}
diff --git a/src/Core/Main/GameTypes.cs b/src/Core/Main/GameTypes.cs
index e380771..9216477 100644
--- a/src/Core/Main/GameTypes.cs
+++ b/src/Core/Main/GameTypes.cs
@@ -35,8 +35,8 @@ namespace gbrainy.Core.Main
// Since we cannot override ToString in an enum type we use a helper class
public static class GameTypesDescription
{
- // Type enum to string representation
- static public string Get (GameTypes type)
+ // Type enum to string representation (locale sensitive)
+ static public string GetLocalized (GameTypes type)
{
switch (type)
{
@@ -52,5 +52,23 @@ namespace gbrainy.Core.Main
throw new InvalidOperationException ("Unknown game type");
}
}
+
+ // string (not localized) to enum representation
+ static public GameTypes FromString (string type)
+ {
+ switch (type)
+ {
+ case "Logic":
+ return GameTypes.LogicPuzzle;
+ case "Memory":
+ return GameTypes.MemoryTrainer;
+ case "Calculation":
+ return GameTypes.MathTrainer;
+ case "Verbal":
+ return GameTypes.VerbalAnalogy;
+ default:
+ throw new InvalidOperationException ("Unknown game type");
+ }
+ }
}
}
diff --git a/src/Core/Main/Xml/CodeEvaluation.cs b/src/Core/Main/Xml/CodeEvaluation.cs
new file mode 100644
index 0000000..cb7c03a
--- /dev/null
+++ b/src/Core/Main/Xml/CodeEvaluation.cs
@@ -0,0 +1,175 @@
+/*
+ * 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.ComponentModel;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using Mono.CSharp;
+using Mono.Unix;
+
+namespace gbrainy.Core.Main.Xml
+{
+ // Code evaluation functions
+ public static class CodeEvaluation
+ {
+ static bool? monofix_needed;
+
+ static public void EvaluateVariables (string code)
+ {
+ string eval;
+
+ try
+ {
+ // Using's for the variables section
+ // We need to evaluate either declarations (like using) or expression/statements separately
+ eval = "using System;\n";
+ Mono.CSharp.Evaluator.Run (eval);
+
+ // Infrastructure for the user available
+ eval = "Random random = new Random ();\n";
+ Mono.CSharp.Evaluator.Run (eval);
+ Mono.CSharp.Evaluator.Run (code);
+ }
+
+ catch (Exception e)
+ {
+ Console.WriteLine ("GameXml. Error in games.xml: {0} when evaluating variable definition [{1}]", e.Message, code);
+ }
+ }
+
+ static public string ReplaceVariables (string str)
+ {
+ const string exp = "\\[[a-z_]+\\]+";
+ string var, vars, var_value;
+ Regex regex;
+ Match match;
+
+ if (String.IsNullOrEmpty (str))
+ return str;
+
+ regex = new Regex (exp, RegexOptions.IgnoreCase);
+ match = regex.Match (str);
+
+ vars = Evaluator.GetVars ();
+ vars = FixGetVars (vars);
+
+ while (String.IsNullOrEmpty (match.Value) == false)
+ {
+ var = match.Value.Substring (1, match.Value.Length - 2);
+ var_value = GetVarValue (vars, var);
+
+ if (String.IsNullOrEmpty (var_value) == false)
+ str = str.Replace (match.Value, var_value);
+
+ match = match.NextMatch ();
+ }
+ return str;
+ }
+
+ // Before Mono 2.6 (rev. 156533) there is no line separator between vars
+ static string FixGetVars (string str)
+ {
+ if (monofix_needed == null)
+ {
+ string eval, vars;
+
+ eval = "int a = 1; int b = 1;";
+ Evaluator.Run (eval);
+ vars = Evaluator.GetVars ();
+
+ monofix_needed = vars.IndexOf (System.Environment.NewLine) == -1;
+ }
+
+ if (monofix_needed == false)
+ return str;
+
+ // We just guarantee that int, doubles, and float are separated as modern Mono versions do
+ StringBuilder output = new StringBuilder ();
+ string [] keywords = new string [] {"int", "double", "float"};
+ int pos = 0, cur = 0, tmp_pos, keyword;
+
+ while (pos != -1)
+ {
+ pos = keyword = -1;
+ // Look for the nearest of these keywords
+ for (int i = 0; i < keywords.Length; i++)
+ {
+ tmp_pos = str.IndexOf (keywords [i], cur);
+ if (tmp_pos == -1)
+ continue;
+
+ if (pos == -1 || pos > 0 && tmp_pos < pos) {
+ keyword = i;
+ pos = tmp_pos;
+ }
+ }
+
+ if (pos == -1)
+ continue;
+
+ output.Append (str.Substring (cur, pos - cur));
+ output.AppendLine ();
+ output.Append (str.Substring (pos, keywords[keyword].Length));
+ cur = pos + keywords[keyword].Length;
+ }
+
+ output.Append (str.Substring (cur, str.Length - cur));
+ return output.ToString ();
+ }
+
+ static string GetVarValue (string vars, string _var)
+ {
+ const string exp = "([a-z0-9._%+-]+) ([a-z0-9._%+-]+) (=) ([0-9]+)";
+ Match match;
+ int idx, cur, newline_len;
+ string line;
+
+ Regex regex = new Regex (exp, RegexOptions.IgnoreCase);
+
+ newline_len = System.Environment.NewLine.Length;
+ cur = 0;
+
+ do
+ {
+ // Process a line
+ idx = vars.IndexOf (System.Environment.NewLine, cur);
+ if (idx == -1) idx = vars.Length;
+
+ line = vars.Substring (cur, idx - cur);
+ cur = idx + newline_len;
+ match = regex.Match (line);
+
+ // "int num = 2";
+ // group 1 -> int, group 2 -> num, group 3 -> =, group 4 -> 2
+ if (match.Groups.Count == 5)
+ {
+ if (match.Groups[2].Value == _var)
+ return match.Groups[4].Value;
+ }
+
+ } while (cur < vars.Length);
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/src/Core/Main/Xml/GameXml.cs b/src/Core/Main/Xml/GameXml.cs
index 4f748cd..bf2e0fb 100644
--- a/src/Core/Main/Xml/GameXml.cs
+++ b/src/Core/Main/Xml/GameXml.cs
@@ -49,7 +49,6 @@ namespace gbrainy.Core.Main.Xml
// Shared with all instances
static List <GameXmlDefinition> games;
static List <DefinitionLocator> locators;
- static bool? monofix_needed;
DefinitionLocator current;
GameXmlDefinition game;
@@ -120,10 +119,10 @@ namespace gbrainy.Core.Main.Xml
if (String.IsNullOrEmpty (variables) == false)
{
// Evaluate code
- EvaluateVariables (variables);
- question = ReplaceVariables (question);
- answer = ReplaceVariables (answer);
- rationale = ReplaceVariables (rationale);
+ CodeEvaluation.EvaluateVariables (variables);
+ question = CodeEvaluation.ReplaceVariables (question);
+ answer = CodeEvaluation.ReplaceVariables (answer);
+ rationale = CodeEvaluation.ReplaceVariables (rationale);
}
right_answer = answer;
@@ -155,9 +154,51 @@ namespace gbrainy.Core.Main.Xml
{
base.Draw (gr, area_width, area_height, rtl);
- if (String.IsNullOrEmpty (game.Image.Filename) == false)
- gr.DrawImageFromFile (Path.Combine (Defines.DATA_DIR, game.Image.Filename),
- game.Image.X, game.Image.Y, game.Image.Width, game.Image.Height);
+ DrawObjects (gr, game); // Draw objects shared by all variants
+
+ if (game.Variants.Count > 0)
+ DrawObjects (gr, game.Variants[current.Variant]); // Draw variant specific objects
+ }
+
+ void DrawObjects (CairoContextEx gr, GameXmlDefinitionVariant definition)
+ {
+ if (definition.DrawingObjects != null)
+ {
+ foreach (DrawingObject draw_object in definition.DrawingObjects)
+ {
+ if (draw_object is TextDrawingObject)
+ {
+ string text;
+ TextDrawingObject draw_string = draw_object as TextDrawingObject;
+
+ text = CatalogGetString (draw_string.Text);
+ text = CodeEvaluation.ReplaceVariables (text);
+
+ if (draw_string.Big)
+ gr.SetPangoLargeFontSize ();
+ else
+ gr.SetPangoNormalFontSize ();
+
+ if (draw_string.Centered) {
+ gr.DrawTextCentered (draw_string.X, draw_string.Y, text);
+ } else {
+ gr.MoveTo (draw_string.X, draw_string.Y);
+ gr.ShowPangoText (text);
+ gr.Stroke ();
+ }
+ }
+ 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);
+ }
+ }
+ }
+ }
}
void BuildLocationList ()
@@ -180,148 +221,5 @@ namespace gbrainy.Core.Main.Xml
return Catalog.GetString (str);
}
-
- /*
- Code evaluation functions
- */
-
- static void EvaluateVariables (string code)
- {
- string eval;
-
- try
- {
- // Using's for the variables section
- // We need to evaluate either declarations (like using) or expression/statements separately
- eval = "using System;\n";
- Mono.CSharp.Evaluator.Run (eval);
-
- // Infrastructure for the user available
- eval = "Random random = new Random ();\n";
- Mono.CSharp.Evaluator.Run (eval);
- Mono.CSharp.Evaluator.Run (code);
- }
-
- catch (Exception e)
- {
- Console.WriteLine ("GameXml. Error in games.xml: {0} when evaluating variable definition [{1}]", e.Message, code);
- }
- }
-
- // Before Mono 2.6 (rev. 156533) there is no line separator between vars
- static string FixGetVars (string str)
- {
- if (monofix_needed == null)
- {
- string eval, vars;
-
- eval = "int a = 1; int b = 1;";
- Evaluator.Run (eval);
- vars = Evaluator.GetVars ();
-
- monofix_needed = vars.IndexOf (System.Environment.NewLine) == -1;
- }
-
- if (monofix_needed == false)
- return str;
-
- // We just guarantee that int, doubles, and float are separated as modern Mono versions do
- StringBuilder output = new StringBuilder ();
- string [] keywords = new string [] {"int", "double", "float"};
- int pos = 0, cur = 0, tmp_pos, keyword;
-
- while (pos != -1)
- {
- pos = keyword = -1;
- // Look for the nearest of these keywords
- for (int i = 0; i < keywords.Length; i++)
- {
- tmp_pos = str.IndexOf (keywords [i], cur);
- if (tmp_pos == -1)
- continue;
-
- if (pos == -1 || pos > 0 && tmp_pos < pos) {
- keyword = i;
- pos = tmp_pos;
- }
- }
-
- if (pos == -1)
- continue;
-
- output.Append (str.Substring (cur, pos - cur));
- output.AppendLine ();
- output.Append (str.Substring (pos, keywords[keyword].Length));
- cur = pos + keywords[keyword].Length;
- }
-
- output.Append (str.Substring (cur, str.Length - cur));
- return output.ToString ();
- }
-
- static string GetVarValue (string vars, string _var)
- {
- const string exp = "([a-z0-9._%+-]+) ([a-z0-9._%+-]+) (=) ([0-9]+)";
- Match match;
- int idx, cur, newline_len;
- string line;
-
- Regex regex = new Regex (exp, RegexOptions.IgnoreCase);
-
- newline_len = System.Environment.NewLine.Length;
- cur = 0;
-
- do
- {
- // Process a line
- idx = vars.IndexOf (System.Environment.NewLine, cur);
- if (idx == -1) idx = vars.Length;
-
- line = vars.Substring (cur, idx - cur);
- cur = idx + newline_len;
- match = regex.Match (line);
-
- // "int num = 2";
- // group 1 -> int, group 2 -> num, group 3 -> =, group 4 -> 2
- if (match.Groups.Count == 5)
- {
- if (match.Groups[2].Value == _var)
- return match.Groups[4].Value;
- }
-
- } while (cur < vars.Length);
-
- return string.Empty;
- }
-
- static string ReplaceVariables (string str)
- {
- const string exp = "\\[[a-z_]+\\]+";
- string var, vars, var_value;
- Regex regex;
- Match match;
-
- if (String.IsNullOrEmpty (str))
- return str;
-
- regex = new Regex (exp, RegexOptions.IgnoreCase);
- match = regex.Match (str);
-
- vars = Evaluator.GetVars ();
- vars = FixGetVars (vars);
-
- while (String.IsNullOrEmpty (match.Value) == false)
- {
- var = match.Value.Substring (1, match.Value.Length - 2);
- var_value = GetVarValue (vars, var);
-
- if (String.IsNullOrEmpty (var_value) == false)
- str = str.Replace (match.Value, var_value);
-
- match = match.NextMatch ();
- }
- return str;
- }
-
}
}
diff --git a/src/Core/Main/Xml/GameXmlDefinition.cs b/src/Core/Main/Xml/GameXmlDefinition.cs
index 5176f0c..e1437ad 100644
--- a/src/Core/Main/Xml/GameXmlDefinition.cs
+++ b/src/Core/Main/Xml/GameXmlDefinition.cs
@@ -23,24 +23,55 @@ using System.Collections.Generic;
namespace gbrainy.Core.Main.Xml
{
- public class GameXmlDefinitionVariant
+ public class DrawingObject
{
- public struct SVGImage
- {
- public string Filename { get; set; }
- public double X { get; set; }
- public double Y { get; set; }
- public double Width { get; set; }
- public double Height { get; set; }
- };
+ }
+
+ public class ImageDrawingObject : DrawingObject
+ {
+ public string Filename { get; set; }
+ public double X { get; set; }
+ public double Y { get; set; }
+ public double Width { get; set; }
+ public double Height { get; set; }
+ };
+
+ public class TextDrawingObject : DrawingObject
+ {
+ public string Text { get; set; }
+ public double X { get; set; }
+ public double Y { get; set; }
+ public bool Centered { get; set; }
+ public bool Big { get; set; }
+ };
+
+ public class GameXmlDefinitionVariant
+ {
public string Question { get; set; }
public string Tip { get; set; }
public string Rationale { get; set; }
public string Answer { get; set; }
public string Variables { get; set; }
- public SVGImage Image;
+ 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 override string ToString ()
{
diff --git a/src/Core/Main/Xml/GameXmlFactory.cs b/src/Core/Main/Xml/GameXmlFactory.cs
index 12f7433..b8e94b5 100644
--- a/src/Core/Main/Xml/GameXmlFactory.cs
+++ b/src/Core/Main/Xml/GameXmlFactory.cs
@@ -62,12 +62,15 @@ namespace gbrainy.Core.Main.Xml
case "games":
break;
case "type":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ game.Type = GameTypesDescription.FromString (reader.ReadElementString ());
break;
case "game":
if (reader.NodeType == XmlNodeType.Element) {
game = new GameXmlDefinition ();
} else if (reader.NodeType == XmlNodeType.EndElement) {
-
games.Add (game);
}
break;
@@ -107,31 +110,79 @@ namespace gbrainy.Core.Main.Xml
if (reader.NodeType != XmlNodeType.Element)
break;
- game.Image.Filename = reader.GetAttribute ("file");
+ ImageDrawingObject draw_image = new ImageDrawingObject ();
+
+ if (processing_variant)
+ game.Variants[variant].AddDrawingObject (draw_image);
+ else
+ game.AddDrawingObject (draw_image);
+
+ draw_image.Filename = reader.GetAttribute ("file");
str = reader.GetAttribute ("x");
if (String.IsNullOrEmpty (str) == false)
- game.Image.X = Double.Parse (str, CultureInfo.InvariantCulture);
+ draw_image.X = Double.Parse (str, CultureInfo.InvariantCulture);
else
- game.Image.X = 0.1;
+ draw_image.X = 0.1;
str = reader.GetAttribute ("y");
if (String.IsNullOrEmpty (str) == false)
- game.Image.Y = Double.Parse (str, CultureInfo.InvariantCulture);
+ draw_image.Y = Double.Parse (str, CultureInfo.InvariantCulture);
else
- game.Image.Y = 0.1;
+ draw_image.Y = 0.1;
str = reader.GetAttribute ("width");
if (String.IsNullOrEmpty (str) == false)
- game.Image.Width = Double.Parse (str, CultureInfo.InvariantCulture);
+ draw_image.Width = Double.Parse (str, CultureInfo.InvariantCulture);
else
- game.Image.Width = 0.8;
+ draw_image.Width = 0.8;
str = reader.GetAttribute ("height");
if (String.IsNullOrEmpty (str) == false)
- game.Image.Height = Double.Parse (str, CultureInfo.InvariantCulture);
+ draw_image.Height = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ draw_image.Height = 0.8;
+
+ break;
+ case "string":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ TextDrawingObject draw_string = new TextDrawingObject ();
+
+ if (processing_variant)
+ game.Variants[variant].AddDrawingObject (draw_string);
+ else
+ game.AddDrawingObject (draw_string);
+
+ draw_string.Text = reader.GetAttribute ("text");
+
+ if (String.IsNullOrEmpty (draw_string.Text))
+ draw_string.Text = reader.GetAttribute ("_text");
+
+ str = reader.GetAttribute ("x");
+ if (String.IsNullOrEmpty (str) == false)
+ draw_string.X = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ draw_string.X = 0.1;
+
+ str = reader.GetAttribute ("y");
+ if (String.IsNullOrEmpty (str) == false)
+ draw_string.Y = Double.Parse (str, CultureInfo.InvariantCulture);
+ else
+ draw_string.Y = 0.1;
+
+ str = reader.GetAttribute ("centered");
+ if (String.Compare (str, "yes", true) == 0)
+ draw_string.Centered = true;
+ else
+ draw_string.Centered = false;
+
+ str = reader.GetAttribute ("size");
+ if (String.Compare (str, "big", true) == 0)
+ draw_string.Big = true;
else
- game.Image.Height = 0.8;
+ draw_string.Big = false;
break;
case "_question":
diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am
index b613a75..2ad2d90 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -18,6 +18,7 @@ CSDISTFILES = \
$(srcdir)/Main/GameSessionHistoryExtended.cs \
$(srcdir)/Main/GameTypes.cs \
$(srcdir)/Main/GameTips.cs \
+ $(srcdir)/Main/Xml/CodeEvaluation.cs \
$(srcdir)/Main/Xml/GameXml.cs \
$(srcdir)/Main/Xml/GameXmlFactory.cs \
$(srcdir)/Main/Xml/GameXmlDefinition.cs \
diff --git a/src/Core/Views/PlayerHistoryView.cs b/src/Core/Views/PlayerHistoryView.cs
index afaff17..afbf3c0 100644
--- a/src/Core/Views/PlayerHistoryView.cs
+++ b/src/Core/Views/PlayerHistoryView.cs
@@ -74,7 +74,7 @@ namespace gbrainy.Core.Views
cr.Stroke ();
cr.Color = text_color;
cr.MoveTo (x + line_size + offset_x, y - 0.01 + second_row);
- cr.ShowPangoText (GameTypesDescription.Get (GameTypes.LogicPuzzle));
+ cr.ShowPangoText (GameTypesDescription.GetLocalized (GameTypes.LogicPuzzle));
cr.Stroke ();
x += space_hor;
@@ -84,7 +84,7 @@ namespace gbrainy.Core.Views
cr.Stroke ();
cr.Color = text_color;
cr.MoveTo (x + line_size + offset_x, y - 0.01);
- cr.ShowPangoText (GameTypesDescription.Get (GameTypes.MemoryTrainer));
+ cr.ShowPangoText (GameTypesDescription.GetLocalized (GameTypes.MemoryTrainer));
cr.Stroke ();
cr.Color = math_color;
@@ -93,7 +93,7 @@ namespace gbrainy.Core.Views
cr.Stroke ();
cr.Color = text_color;
cr.MoveTo (x + line_size + offset_x, y - 0.01 + second_row);
- cr.ShowPangoText (GameTypesDescription.Get (GameTypes.MathTrainer));
+ cr.ShowPangoText (GameTypesDescription.GetLocalized (GameTypes.MathTrainer));
cr.Stroke ();
x += space_hor;
@@ -103,7 +103,7 @@ namespace gbrainy.Core.Views
cr.Stroke ();
cr.Color = text_color;
cr.MoveTo (x + line_size + offset_x, y - 0.01);
- cr.ShowPangoText (GameTypesDescription.Get (GameTypes.VerbalAnalogy));
+ cr.ShowPangoText (GameTypesDescription.GetLocalized (GameTypes.VerbalAnalogy));
cr.Stroke ();
cr.LineWidth = old_width;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]