[gbrainy] Support variables expression in games.xml
- From: Jordi Mas <jmas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gbrainy] Support variables expression in games.xml
- Date: Sun, 13 Jun 2010 22:45:23 +0000 (UTC)
commit 1d280c8193e883ec14925a7475f32ed271d963c9
Author: Jordi Mas <jmas softcatala org>
Date: Mon Jun 14 00:46:20 2010 +0200
Support variables expression in games.xml
configure.ac | 6 +-
data/games.xml | 23 ++----
src/Core/Main/Xml/GameXmlFactory.cs | 144 ++++++++++++++++++++++++++++++++++-
src/Core/Makefile.am | 1 +
4 files changed, 156 insertions(+), 18 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index ef95e33..6183bf7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,10 +41,10 @@ else
AC_MSG_RESULT([found])
fi
-dnl -- check for various mono DLLs that we need.
+dnl -- check for various mono assemblies that we need.
-needed_dlls="Mono.Posix Mono.Cairo"
-for i in $needed_dlls; do
+needed_assemblies="Mono.Posix Mono.Cairo Mono.CSharp"
+for i in $needed_assemblies; do
AC_MSG_CHECKING([for $i.dll])
if test ! \( -e `$PKG_CONFIG --variable=prefix mono`/lib/mono/2.0/$i.dll -o -e `$PKG_CONFIG --variable=prefix mono`/lib64/mono/2.0//$i.dll \); then
AC_MSG_ERROR([missing required mono 2.0 DLL: $i.dll])
diff --git a/data/games.xml b/data/games.xml
index 22f3e4c..0346262 100644
--- a/data/games.xml
+++ b/data/games.xml
@@ -16,19 +16,15 @@
<_name>Clock Rotation</_name>
<type>Logic</type>
<difficulty>All</difficulty>
- <_tip>Think of the items used in the game.</_tip>
+ <variables>
+ int num = random.Next (5) * 10;
+ int rslt = (2 * 360) + (num * 6);
+ </variables>
<_rationale>Every hour rotates 360 degrees.</_rationale>
<svg file = "clock.svg" x = "0.25" y = "0.25" width = "0.5" height = "0.5"/>
- <_question>How many degrees rotates the minute hand of a clock in 2 hours 40 minutes?</_question>
- <answer>960</answer>
- <_question>How many degrees rotates the minute hand of a clock in 2 hours 30 minutes?</_question>
- <answer>900</answer>
- <_question>How many degrees rotates the minute hand of a clock in 1 hours 20 minutes?</_question>
- <answer>480</answer>
- <_question>How many degrees rotates the minute hand of a clock in 1 hours 40 minutes?</_question>
- <answer>600</answer>
+ <_question>How many degrees rotates the minute hand of a clock in 2 hours [num] minutes?</_question>
+ <answer>[rslt]</answer>
</game>
-
<game>
<_name>Family relations</_name>
<type>Logic</type>
@@ -36,14 +32,13 @@
<svg file = "family.svg" x = "0.25" y = "0.25" width = "0.5" height = "0.5"/>
<variant>
<_question>A boy has as many brothers as he has sisters. Each brother has twice as many sisters as brothers. How many brothers and sisters the family has in total?</_question>
- <_answer>7</_answer>
- <_rationale>He has tree brothers and four sisters.</_rationale>
+ <answer>7</answer>
+ <_rationale>He has three brothers and four sisters.</_rationale>
</variant>
<variant>
<_question>John's age is nowadays 5 times his son's age. 4 years ago John was 9 times older than his son. What's is John's age nowadays?</_question>
- <_answer>40</_answer>
+ <answer>40</answer>
</variant>
</game>
-
</games>
diff --git a/src/Core/Main/Xml/GameXmlFactory.cs b/src/Core/Main/Xml/GameXmlFactory.cs
index bc70d21..a7f7017 100644
--- a/src/Core/Main/Xml/GameXmlFactory.cs
+++ b/src/Core/Main/Xml/GameXmlFactory.cs
@@ -20,8 +20,11 @@
using System;
using System.Xml;
using System.IO;
+using System.Text;
using System.Collections.Generic;
using System.Globalization;
+using Mono.CSharp;
+using System.Text.RegularExpressions;
using Mono.Unix;
@@ -31,6 +34,7 @@ namespace gbrainy.Core.Main
{
static List <GameXmlDefinition> games;
static bool read = false;
+ static bool? monofix_needed;
static GamesXmlFactory ()
{
@@ -69,10 +73,23 @@ namespace gbrainy.Core.Main
{
name = reader.Name.ToLower ();
switch (name) {
+ case "games":
+ break;
+ case "type":
+ break;
case "game":
if (reader.NodeType == XmlNodeType.Element) {
game = new GameXmlDefinition ();
} else if (reader.NodeType == XmlNodeType.EndElement) {
+
+ for (int i = 0; i < game.Variants.Count; i++)
+ {
+ game.Variants[i].Question = ReplaceVariables (game.Variants[i].Question);
+ game.Variants[i].Answer = ReplaceVariables (game.Variants[i].Answer);
+ }
+
+ game.Question = ReplaceVariables (game.Question);
+ game.Answer = ReplaceVariables (game.Answer);
games.Add (game);
}
break;
@@ -82,7 +99,7 @@ namespace gbrainy.Core.Main
game.Name = reader.ReadElementString ();
break;
- case "_difficulty":
+ case "difficulty":
if (reader.NodeType != XmlNodeType.Element)
break;
@@ -189,7 +206,26 @@ namespace gbrainy.Core.Main
processing_variant = false;
}
break;
+ case "variables":
+ {
+ string eval;
+
+ // Using's for the variables section
+ 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);
+
+ eval = reader.ReadElementString ();
+ Mono.CSharp.Evaluator.Run (eval);
+ break;
+ }
default:
+ if (String.IsNullOrEmpty (name) == false)
+ Console.WriteLine ("GameXmlFactory. Unsupported tag: {0}", name);
+
break;
}
}
@@ -206,5 +242,111 @@ namespace gbrainy.Core.Main
Console.WriteLine ("GameXmlFactory. Error loading: {0}", e.Message);
}
}
+
+ // 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;
+
+ while (pos != -1)
+ {
+ for (int i = 0; i < keywords.Length; i++)
+ {
+ pos = str.IndexOf (keywords [i], cur);
+ if (pos != -1)
+ {
+ output.Append (str.Substring (cur, pos - cur));
+ output.AppendLine ();
+ output.Append (str.Substring (pos, keywords[i].Length));
+ cur = pos + keywords[i].Length;
+ break;
+ }
+ }
+ }
+
+ 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 eval, var, vars, var_value;
+ Regex regex;
+ Match match;
+
+ if (String.IsNullOrEmpty (str))
+ return str;
+
+ regex = new Regex (exp, RegexOptions.IgnoreCase);
+ match = regex.Match (str);
+
+ while (String.IsNullOrEmpty (match.Value) == false)
+ {
+ var = match.Value.Substring (1, match.Value.Length - 2);
+ vars = Evaluator.GetVars ();
+ vars = FixGetVars (vars);
+
+ 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/Makefile.am b/src/Core/Makefile.am
index 4e20481..b613a75 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -69,6 +69,7 @@ REFS = \
-r:System \
-r:Mono.Cairo.dll \
-r:Mono.Posix \
+ -r:Mono.CSharp.dll \
$(GBRAINY_LIBS) \
$(MONO_ADDINS_LIBS)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]