[gbrainy] Initial support for XML defined games
- From: Jordi Mas <jmas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gbrainy] Initial support for XML defined games
- Date: Sat, 5 Jun 2010 07:33:56 +0000 (UTC)
commit 1d26f03a06f180aa2f32d83807e91590494e8813
Author: Jordi Mas <jmas softcatala org>
Date: Sat Jun 5 09:34:41 2010 +0200
Initial support for XML defined games
src/Clients/Classical/Dialogs/CustomGameDialog.cs | 59 ++--
src/Clients/Classical/gbrainy.cs | 5 +-
src/Core/Libraries/CairoContext.cs | 4 +-
src/Core/Main/Game.cs | 29 ++-
src/Core/Main/GameManager.cs | 427 +++++++++-----------
src/Core/Main/GameSession.cs | 4 +-
src/Core/Main/Verbal/Analogies.cs | 47 +--
src/Core/Main/Verbal/AnalogiesFactory.cs | 5 +-
src/Core/Main/Verbal/AnalogiesMultipleOptions.cs | 12 -
.../Main/Verbal/AnalogiesPairOfWordsCompare.cs | 11 -
.../Main/Verbal/AnalogiesPairOfWordsOptions.cs | 12 -
src/Core/Main/Verbal/AnalogiesQuestionAnswer.cs | 12 -
src/Core/Main/Xml/GameXml.cs | 145 +++++++
src/Core/Main/Xml/GameXmlDefinition.cs | 96 +++++
src/Core/Main/Xml/GameXmlFactory.cs | 209 ++++++++++
src/Core/Makefile.am | 3 +
tests/Core/GameManagerTest.cs | 19 +-
17 files changed, 728 insertions(+), 371 deletions(-)
---
diff --git a/src/Clients/Classical/Dialogs/CustomGameDialog.cs b/src/Clients/Classical/Dialogs/CustomGameDialog.cs
index fd759f0..9dc8642 100644
--- a/src/Clients/Classical/Dialogs/CustomGameDialog.cs
+++ b/src/Clients/Classical/Dialogs/CustomGameDialog.cs
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Jordi Mas i Hernà ndez <jmas softcatala org>
+ * Copyright (C) 2007-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
@@ -20,7 +20,7 @@
using System;
using Gtk;
using Mono.Unix;
-using System.Collections;
+using System.Collections.Generic;
using gbrainy.Core.Main;
using gbrainy.Core.Libraries;
@@ -36,22 +36,23 @@ namespace gbrainy.Clients.Classical
CairoPreview drawing_area;
SimpleLabel question_label;
GameManager manager;
- int ngames, npos;
- Type [] custom_games;
+ GameManager.GameLocator [] games;
+ bool selection_done;
const int COL_ENABLED = 2;
const int COL_OBJECT = 3;
+ const int COL_INDEX = 4;
public CustomGameDialog (GameManager manager) : base ("CustomGameDialog.ui", "customgame")
{
Game game;
- Type[] games;
GameManager gm;
+ selection_done = false;
this.manager = manager;
gm = new GameManager ();
gm.GameType = GameSession.Types.AllGames;
- games = gm.CustomGames;
+ games = gm.AvailableGames;
drawing_area = new CairoPreview ();
preview_vbox.Add (drawing_area);
@@ -85,28 +86,33 @@ namespace gbrainy.Clients.Classical
treeview.AppendColumn (toggle_column);
if (games_store == null) {
- games_store = new ListStore (typeof(string), typeof (string), typeof(bool), typeof (Game));
+ games_store = new ListStore (typeof(string), typeof (string), typeof(bool), typeof (Game), typeof (int));
// Data
string type;
for (int i = 0; i < games.Length; i++)
- {
- game = (Game) Activator.CreateInstance (games [i], true);
+ {
+ if (games [i].IsGame == false)
+ continue;
+
+ game = (Game) Activator.CreateInstance (games [i].TypeOf, true);
+ game.Variant = games [i].Variant;
type = GameTypesDescription.Get (game.Type);
- games_store.AppendValues (game.Name, type, true, game);
+ games_store.AppendValues (game.Name, type, true, game, i);
}
}
treeview.Model = games_store;
- game = (Game) Activator.CreateInstance (games [0], true);
- game.Initialize ();
+ game = (Game) Activator.CreateInstance (games [0].TypeOf, true);
+ game.Variant = 0;
+ game.Begin ();
drawing_area.puzzle = game;
question_label.Text = game.Question;
treeview.ColumnsAutosize ();
}
- public int NumOfGames {
- get { return ngames;}
+ public bool SelectionDone {
+ get { return selection_done;}
}
private void OnCursorChanged (object o, EventArgs args)
@@ -123,7 +129,7 @@ namespace gbrainy.Clients.Classical
if (game.IsPreviewMode == false)
{
game.IsPreviewMode = true;
- game.Initialize ();
+ game.Begin ();
}
question_label.Text = game.Question;
@@ -160,33 +166,24 @@ namespace gbrainy.Clients.Classical
void OnOK (object sender, EventArgs args)
{
- ngames = 0;
- npos = 0;
-
- games_store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) {
- if ((bool) games_store.GetValue (iter, COL_ENABLED) == true)
- ngames++;
+ List <int> play_list;
- return false;
- });
-
- if (ngames == 0)
- return;
+ play_list = new List <int> ();
- custom_games = new Type [ngames];
games_store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) {
Game game = games_store.GetValue (iter, COL_OBJECT) as Game;
bool enabled = (bool) games_store.GetValue (iter, COL_ENABLED);
if (enabled == true) {
- custom_games[npos] = game.GetType ();
- npos++;
+ selection_done = true;
+ int idx = (int) games_store.GetValue (iter, COL_INDEX);
+ play_list.Add (idx);
}
return false;
});
-
- manager.CustomGames = custom_games;
+ if (selection_done == true)
+ manager.PlayList = play_list.ToArray ();
}
public class CairoPreview : DrawingArea
diff --git a/src/Clients/Classical/gbrainy.cs b/src/Clients/Classical/gbrainy.cs
index 6bc2346..d6287da 100644
--- a/src/Clients/Classical/gbrainy.cs
+++ b/src/Clients/Classical/gbrainy.cs
@@ -522,14 +522,13 @@ namespace gbrainy.Clients.Classical
void OnCustomGame (object sender, EventArgs args)
{
- ResponseType rslt;
CustomGameDialog dialog;
dialog = new CustomGameDialog (session.GameManager);
- rslt = (Gtk.ResponseType) dialog.Run ();
+ dialog.Run ();
dialog.Destroy ();
- if (rslt == ResponseType.Ok && dialog.NumOfGames > 0)
+ if (dialog.SelectionDone == true)
OnNewGame (GameSession.Types.Custom);
}
diff --git a/src/Core/Libraries/CairoContext.cs b/src/Core/Libraries/CairoContext.cs
index ddd434d..615df2d 100644
--- a/src/Core/Libraries/CairoContext.cs
+++ b/src/Core/Libraries/CairoContext.cs
@@ -256,9 +256,9 @@ namespace gbrainy.Core.Libraries
DrawImage (image, x, y, width, height);
}
}
- catch (Exception)
+ catch (Exception e)
{
- return;
+ Console.WriteLine ("CairoContext. Error '{0}' when drawing image from filename {1}", e.Message, filename);
}
}
diff --git a/src/Core/Main/Game.cs b/src/Core/Main/Game.cs
index beda11d..cb03dbf 100644
--- a/src/Core/Main/Game.cs
+++ b/src/Core/Main/Game.cs
@@ -39,6 +39,7 @@ namespace gbrainy.Core.Main
Easy = 2,
Medium = 4,
Master = 8,
+ All = Easy | Medium | Master,
}
[Flags]
@@ -75,6 +76,7 @@ namespace gbrainy.Core.Main
private Difficulty difficulty;
private ISynchronizeInvoke synchronize;
private List <Toolkit.Container> containers;
+ private int variant;
public event EventHandler DrawRequest;
public event EventHandler <UpdateUIStateEventArgs> UpdateUIElement;
@@ -82,10 +84,7 @@ namespace gbrainy.Core.Main
protected Game ()
{
- random = new Random ();
- default_color = new Cairo.Color (0, 0, 0);
difficulty = Difficulty.Medium;
- containers = new List <Toolkit.Container> ();
}
#region Methods to override in your own games
@@ -108,7 +107,12 @@ namespace gbrainy.Core.Main
get { return string.Empty;}
}
+ // TODO: This should be protected since we should use Begin
public abstract void Initialize ();
+
+ public virtual int Variants {
+ get { return 1;}
+ }
#endregion
#region Methods that you can optionally override
@@ -143,6 +147,25 @@ namespace gbrainy.Core.Main
get { return false;}
}
#endregion
+
+ public void Begin ()
+ {
+ random = new Random ();
+ default_color = new Cairo.Color (0, 0, 0);
+ containers = new List <Toolkit.Container> ();
+ Initialize ();
+ }
+
+ public virtual int Variant {
+ protected get { return variant; }
+ set {
+ if (value < 0 || value > Variants)
+ throw new ArgumentOutOfRangeException (String.Format ("Variant out of range {0}", value));
+
+ variant = value;
+ }
+ }
+
// Builds a text answer for the puzzle
public virtual string Answer {
get {
diff --git a/src/Core/Main/GameManager.cs b/src/Core/Main/GameManager.cs
index da76d76..a3d1031 100644
--- a/src/Core/Main/GameManager.cs
+++ b/src/Core/Main/GameManager.cs
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2009 Jordi Mas i Hernà ndez <jmas softcatala org>
+ * Copyright (C) 2007-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
@@ -41,58 +41,7 @@ namespace gbrainy.Core.Main
{
public class GameManager
{
- // Serves analogies as their container class is still not exhausted
- // This is used to make sure that the analogies are not repeated within a game session
- public class AnalogiesManager
- {
- List <Analogies> analogies;
-
- public AnalogiesManager (Type [] types)
- {
- analogies = new List <Analogies> ();
-
- foreach (Type type in types)
- {
- Analogies analogy;
-
- analogy = (Analogies) Activator.CreateInstance (type, true);
- analogies.Add (analogy);
- }
- }
-
- public void Initialize ()
- {
- foreach (Analogies analogy in analogies)
- analogy.CurrentIndex = 0;
- }
-
- public Type [] AvailableTypes {
- get {
- List <Type> types = new List <Type> ();
-
- foreach (Analogies analogy in analogies)
- {
- if (analogy.List.Count > 0)
- types.Add (analogy.GetType ());
- }
-
- return types.ToArray ();
- }
- }
-
- public bool IsExhausted {
- get {
- foreach (Analogies analogy in analogies)
- {
- if (analogy.IsExhausted == false)
- return false;
- }
- return true;
- }
- }
- }
-
- static Type[] VerbalAnalogiesInternal = new Type[]
+ static Type[] VerbalAnalogiesInternal = new Type[]
{
typeof (AnalogiesQuestionAnswer),
typeof (AnalogiesMultipleOptions),
@@ -100,69 +49,79 @@ namespace gbrainy.Core.Main
typeof (AnalogiesPairOfWordsCompare),
};
+ public class GameLocator
+ {
+ public Type TypeOf { get; set; }
+ public int Variant { get; set; }
+ public GameTypes GameType { get; set; }
+ public bool IsGame { get; set; }
+
+ public GameLocator (Type type, int variant, GameTypes game_type, bool isGame)
+ {
+ TypeOf = type;
+ Variant = variant;
+ GameType = game_type;
+ IsGame = isGame;
+ }
+ }
+
bool once;
GameSession.Types game_type;
ArrayListIndicesRandom list;
- IEnumerator enumerator;
- List <Type> games;
+ IEnumerator <int> enumerator;
Game.Difficulty difficulty;
- List <Type> LogicPuzzles;
- List <Type> CalculationTrainers;
- List <Type> MemoryTrainers;
- List <Type> VerbalAnalogies;
- AnalogiesManager analogies_manager;
-
+
+ List <GameLocator> available_games; // List of all available games in the system
+ List <int> play_list; // Play list for the Selected difficulty, game types
+ int cnt_logic, cnt_memory, cnt_calculation, cnt_verbal;
+
public GameManager ()
{
game_type = GameSession.Types.None;
difficulty = Game.Difficulty.Medium;
- games = new List <Type> ();
- VerbalAnalogies = new List <Type> ();
- analogies_manager = new AnalogiesManager (VerbalAnalogiesInternal);
-
- foreach (Type type in analogies_manager.AvailableTypes)
- VerbalAnalogies.Add (type);
+ available_games = new List <GameLocator> ();
+ play_list = new List <int> ();
+ cnt_logic = cnt_memory = cnt_calculation = cnt_verbal = 0;
- LoadAssemblyGame ();
+ GamesXmlFactory.Read ();
- if (LogicPuzzles == null)
- LogicPuzzles = new List <Type> ();
+ LoadAssemblyGames ();
- if (MemoryTrainers == null)
- MemoryTrainers = new List <Type> ();
+ // Load Analogies
+ cnt_verbal += AddGamesAndVariations (VerbalAnalogiesInternal);
- if (CalculationTrainers == null)
- CalculationTrainers = new List <Type> ();
+ // Load defined XML games
+ cnt_logic += LoadXmlGames ();
LoadPlugins ();
if (once == false) {
once = true;
- Console.WriteLine (Catalog.GetString ("Games registered: {0}: {1} logic puzzles, {2} calculation trainers, {3} memory trainers, {4} verbal analogies"),
- LogicPuzzles.Count + CalculationTrainers.Count + MemoryTrainers.Count + VerbalAnalogies.Count,
- LogicPuzzles.Count, CalculationTrainers.Count, MemoryTrainers.Count, VerbalAnalogies.Count);
+ Console.WriteLine (Catalog.GetString ("Games registered: {0}: {1} logic puzzles, {2} calculation trainers, {3} memory trainers, {4} verbal analogies"),
+ cnt_logic + cnt_memory + cnt_calculation + cnt_verbal,
+ cnt_logic, cnt_calculation, cnt_memory, cnt_verbal);
}
#if PDF_DUMP
GeneratePDF ();
#endif
}
-
- public GameTypes AvailableGames {
+
+ public GameTypes AvailableGameTypes {
get {
GameTypes types = GameTypes.None;
- if (LogicPuzzles.Count > 0)
+ if (cnt_logic > 0)
types |= GameTypes.LogicPuzzle;
- if (CalculationTrainers.Count > 0)
+ if (cnt_calculation > 0)
types |= GameTypes.MathTrainer;
- if (MemoryTrainers.Count > 0)
+ if (cnt_memory > 0)
types |= GameTypes.MemoryTrainer;
- if (analogies_manager.AvailableTypes.Length > 0)
+ if (cnt_verbal > 0)
types |= GameTypes.VerbalAnalogy;
-
+
return types;
}
}
@@ -172,54 +131,41 @@ namespace gbrainy.Core.Main
set {
if (game_type == value)
return;
-
+
game_type = value;
- BuildGameList ();
+
+ if ((game_type & GameSession.Types.Custom) != GameSession.Types.Custom)
+ BuildPlayList (available_games);
}
}
public Game.Difficulty Difficulty {
set {
+ if (difficulty == value)
+ return;
+
difficulty = value;
- BuildGameList ();
- }
- get {
- return difficulty;
+ BuildPlayList (available_games);
}
+ get { return difficulty; }
}
- // Used from CustomGameDialog only
- public Type[] CustomGames {
- get {
- Type[] list = new Type [LogicPuzzles.Count + CalculationTrainers.Count + MemoryTrainers.Count + VerbalAnalogies.Count];
- int idx = 0;
-
- for (int i = 0; i < LogicPuzzles.Count; i++, idx++)
- list[idx] = LogicPuzzles [i];
-
- for (int i = 0; i < CalculationTrainers.Count; i++, idx++)
- list[idx] = CalculationTrainers [i];
-
- for (int i = 0; i < MemoryTrainers.Count; i++, idx++)
- list[idx] = MemoryTrainers [i];
-
- for (int i = 0; i < VerbalAnalogies.Count; i++, idx++)
- list[idx] = VerbalAnalogies [i];
-
- return list;
- }
+ // Establish the PlayList (the indices of the array to available games)
+ public int [] PlayList {
+ get { return play_list.ToArray ();}
set {
- games = new List <Type> (value.Length);
- for (int i = 0; i < value.Length; i++)
- games.Add (value[i]);
-
- list = new ArrayListIndicesRandom (games.Count);
- Initialize ();
+ play_list = new List <int> (value);
+ enumerator = play_list.GetEnumerator ();
}
}
+ // Returns all the games available for playing
+ public GameLocator [] AvailableGames {
+ get { return available_games.ToArray (); }
+ }
+
// Dynamic load of the gbrainy.Games.Dll assembly
- void LoadAssemblyGame ()
+ void LoadAssemblyGames ()
{
const string ASSEMBLY = "gbrainy.Games.dll";
const string CLASS = "gbrainy.Games.GameList";
@@ -240,7 +186,7 @@ namespace gbrainy.Core.Main
asem = Assembly.LoadFrom (System.IO.Path.Combine (asm_dir, ASSEMBLY));
- foreach (Type t in asem.GetTypes())
+ foreach (Type t in asem.GetTypes())
{
if (t.FullName == CLASS)
{
@@ -253,15 +199,15 @@ namespace gbrainy.Core.Main
prop = type.GetProperty (LOGIC_METHOD);
if (prop != null)
- LogicPuzzles = new List <Type> ((Type []) prop.GetValue (obj, null));
+ cnt_logic += AddGamesAndVariations ((Type []) prop.GetValue (obj, null));
prop = type.GetProperty (MEMORY_METHOD);
if (prop != null)
- MemoryTrainers = new List <Type> ((Type []) prop.GetValue (obj, null));
+ cnt_memory += AddGamesAndVariations ((Type []) prop.GetValue (obj, null));
prop = type.GetProperty (CALCULATION_METHOD);
if (prop != null)
- CalculationTrainers = new List <Type> ((Type []) prop.GetValue (obj, null));
+ cnt_calculation += AddGamesAndVariations ((Type []) prop.GetValue (obj, null));
}
catch (Exception e)
@@ -270,15 +216,52 @@ namespace gbrainy.Core.Main
}
}
+ // Adds all the games and its variants into the available games list
+ int AddGamesAndVariations (Type [] types)
+ {
+ Game game;
+ int cnt = 0;
+
+ foreach (Type type in types)
+ {
+ game = (Game) Activator.CreateInstance (type, true);
+ for (int i = 0; i < game.Variants; i++)
+ {
+ available_games.Add (new GameLocator (type, i, game.Type, game.Variants == 1));
+ }
+ cnt += game.Variants;
+ }
+ return cnt;
+ }
+
+ // XML are stored using the Variant as a pointer to the game + the internal variant
+ int LoadXmlGames ()
+ {
+ Type type = typeof (GameXml);
+ int cnt = 0;
+
+ foreach (GameXmlDefinition game in GamesXmlFactory.Definitions)
+ {
+ available_games.Add (new GameLocator (type, cnt++, game.Type, true));
+ for (int i = 0; i < game.Variants.Count; i++)
+ {
+ available_games.Add (new GameLocator (type, cnt++, game.Type, false));
+ }
+ }
+ return cnt;
+ }
+
void LoadPlugins ()
{
#if MONO_ADDINS
+
try {
ExtensionNodeList addins;
Game game;
+ Type [] type = new Type [1];
string dir = System.IO.Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), "gbrainy");
-
+
AddinManager.Initialize (dir);
Console.WriteLine ("Pluggin database:" + dir);
AddinManager.Registry.Update (null);
@@ -288,28 +271,32 @@ namespace gbrainy.Core.Main
foreach (TypeExtensionNode node in addins) {
game = (Game) node.CreateInstance ();
Console.WriteLine ("Loading external logic game: {0}", game);
- LogicPuzzles.Add (game.GetType ());
+ type [0] = game.GetType ();
+ AddGamesAndVariations (type);
}
-
+
addins = AddinManager.GetExtensionNodes ("/gbrainy/games/memory");
foreach (TypeExtensionNode node in addins) {
game = (Game) node.CreateInstance ();
Console.WriteLine ("Loading external memory game: {0}", game);
- MemoryTrainers.Add (game.GetType ());
+ type [0] = game.GetType ();
+ AddGamesAndVariations (type);
}
addins = AddinManager.GetExtensionNodes ("/gbrainy/games/calculation");
foreach (TypeExtensionNode node in addins) {
game = (Game) node.CreateInstance ();
Console.WriteLine ("Loading external calculation game: {0}", game);
- CalculationTrainers.Add (game.GetType ());
+ type [0] = game.GetType ();
+ AddGamesAndVariations (type);
}
addins = AddinManager.GetExtensionNodes ("/gbrainy/games/verbal");
foreach (TypeExtensionNode node in addins) {
game = (Game) node.CreateInstance ();
Console.WriteLine ("Loading external verbal analogy game: {0}", game);
- VerbalAnalogies.Add (game.GetType ());
+ type [0] = game.GetType ();
+ AddGamesAndVariations (type);
}
}
catch (Exception e)
@@ -319,140 +306,119 @@ namespace gbrainy.Core.Main
#endif
}
- void BuildGameList ()
+ // Taking a GameLocator list builds the play_list
+ void BuildPlayList (List <GameLocator> all_games)
{
- analogies_manager.Initialize ();
-
- if (GameType == GameSession.Types.Custom)
- return;
+ if ((game_type & GameSession.Types.Custom) == GameSession.Types.Custom)
+ throw new InvalidOperationException ();
- games.Clear ();
- Random random = new Random ();
+ play_list.Clear ();
- // For all games, 1/4 of the total are logic, 1/4 Memory, 1/4 calculation, 1/4 verbal analogies
- if (((game_type & GameSession.Types.AllGames) == GameSession.Types.AllGames) &&
- LogicPuzzles.Count > 0 && MemoryTrainers.Count > 0 &&
- CalculationTrainers.Count > 0 && VerbalAnalogies.Count > 0) {
-
- int idx_cal = 0, idx_mem = 0, idx_verb = 0;
- ArrayListIndicesRandom idx_logic = new ArrayListIndicesRandom (LogicPuzzles.Count);
- ArrayListIndicesRandom idx_memory = new ArrayListIndicesRandom (MemoryTrainers.Count);
- ArrayListIndicesRandom idx_calculation = new ArrayListIndicesRandom (CalculationTrainers.Count);
- ArrayListIndicesRandom idx_verbal = new ArrayListIndicesRandom (VerbalAnalogies.Count);
-
- games.Clear ();
- idx_memory.Initialize ();
- idx_logic.Initialize ();
- idx_calculation.Initialize ();
- idx_verbal.Initialize ();
-
- for (int i = 0; i < LogicPuzzles.Count; i++, idx_mem++, idx_cal++, idx_verb++) {
-
- if (idx_cal == CalculationTrainers.Count) {
- idx_cal = 0;
- idx_calculation.Initialize ();
- }
+ ArrayListIndicesRandom indices = new ArrayListIndicesRandom (all_games.Count);
+ indices.Initialize ();
- if (idx_mem == MemoryTrainers.Count) {
- idx_mem = 0;
- idx_memory.Initialize ();
- }
-
- if (idx_verb == VerbalAnalogies.Count) {
- idx_verb = 0;
- idx_verbal.Initialize ();
- }
+ List <int> logic_indices = new List <int> (cnt_logic);
+ List <int> calculation_indices = new List <int> (cnt_calculation);
+ List <int> memory_indices = new List <int> (cnt_memory);
+ List <int> verbal_indices = new List <int> (cnt_verbal);
+ bool logic, memory, calculation, verbal;
- switch (random.Next (3)) {
- case 0:
- games.Add (CalculationTrainers [idx_calculation[idx_cal]]);
- games.Add (LogicPuzzles [idx_logic[i]]);
- games.Add (MemoryTrainers [idx_memory[idx_mem]]);
- games.Add (VerbalAnalogies [idx_verbal[idx_verb]]);
- break;
- case 1:
- games.Add (MemoryTrainers [idx_memory[idx_mem]]);
- games.Add (CalculationTrainers [idx_calculation[idx_cal]]);
- games.Add (VerbalAnalogies [idx_verbal[idx_verb]]);
- games.Add (LogicPuzzles [idx_logic[i]]);
- break;
- case 2:
- games.Add (CalculationTrainers [idx_calculation[idx_cal]]);
- games.Add (VerbalAnalogies [idx_verbal[idx_verb]]);
- games.Add (MemoryTrainers [idx_memory[idx_mem]]);
- games.Add (LogicPuzzles [idx_logic[i]]);
- break;
- }
- }
- } else {
+ // Decide which game_types are part of the game
+ if ((game_type & GameSession.Types.AllGames) == GameSession.Types.AllGames)
+ {
+ logic = memory = calculation = verbal = true;
+ }
+ else
+ {
+ logic = (game_type & GameSession.Types.LogicPuzzles) == GameSession.Types.LogicPuzzles;
+ calculation = (game_type & GameSession.Types.CalculationTrainers) == GameSession.Types.CalculationTrainers;
+ memory = (game_type & GameSession.Types.MemoryTrainers) == GameSession.Types.MemoryTrainers;
+ verbal = (game_type & GameSession.Types.VerbalAnalogies) == GameSession.Types.VerbalAnalogies;
+ }
- if ((game_type & GameSession.Types.LogicPuzzles) == GameSession.Types.LogicPuzzles) {
- for (int i = 0; i < LogicPuzzles.Count; i++)
- games.Add (LogicPuzzles [i]);
+ // Create arrays by game type
+ for (int n = 0; n < all_games.Count; n++)
+ {
+ switch (all_games [indices [n]].GameType) {
+ case GameTypes.LogicPuzzle:
+ if (logic)
+ logic_indices.Add (indices [n]);
+ break;
+ case GameTypes.MemoryTrainer:
+ if (memory)
+ memory_indices.Add (indices [n]);
+ break;
+ case GameTypes.MathTrainer:
+ if (calculation)
+ calculation_indices.Add (indices [n]);
+ break;
+ case GameTypes.VerbalAnalogy:
+ if (verbal)
+ verbal_indices.Add (indices [n]);
+ break;
+ default:
+ throw new InvalidOperationException ("Unknown value");
}
+ }
- if ((game_type & GameSession.Types.CalculationTrainers) == GameSession.Types.CalculationTrainers) {
- for (int i = 0; i < CalculationTrainers.Count; i++)
- games.Add (CalculationTrainers [i]);
- }
+ int total = logic_indices.Count + memory_indices.Count + calculation_indices.Count + verbal_indices.Count;
+ int pos_logic, pos_memory, pos_calculation, pos_verbal;
+ Random random = new Random ();
- if ((game_type & GameSession.Types.MemoryTrainers) == GameSession.Types.MemoryTrainers) {
- for (int i = 0; i < MemoryTrainers.Count; i++)
- games.Add (MemoryTrainers [i]);
- }
+ pos_logic = pos_memory = pos_calculation = pos_verbal = 0;
- if ((game_type & GameSession.Types.VerbalAnalogies) == GameSession.Types.VerbalAnalogies) {
- for (int i = 0; i < VerbalAnalogies.Count; i++)
- games.Add (VerbalAnalogies [i]);
+ while (play_list.Count < total)
+ {
+ switch (random.Next (3)) {
+ case 0:
+ if (pos_calculation < calculation_indices.Count) play_list.Add (calculation_indices[pos_calculation++]);
+ if (pos_logic < logic_indices.Count) play_list.Add (logic_indices[pos_logic++]);
+ if (pos_memory < memory_indices.Count) play_list.Add (memory_indices[pos_memory++]);
+ if (pos_verbal < verbal_indices.Count) play_list.Add (verbal_indices[pos_verbal++]);
+ break;
+ case 1:
+ if (pos_memory < memory_indices.Count) play_list.Add (memory_indices[pos_memory++]);
+ if (pos_calculation < calculation_indices.Count) play_list.Add (calculation_indices[pos_calculation++]);
+ if (pos_verbal < verbal_indices.Count) play_list.Add (verbal_indices[pos_verbal++]);
+ if (pos_logic < logic_indices.Count) play_list.Add (logic_indices[pos_logic++]);
+ break;
+ case 2:
+ if (pos_calculation < calculation_indices.Count) play_list.Add (calculation_indices[pos_calculation++]);
+ if (pos_verbal < verbal_indices.Count) play_list.Add (verbal_indices[pos_verbal++]);
+ if (pos_memory < memory_indices.Count) play_list.Add (memory_indices[pos_memory++]);
+ if (pos_logic < logic_indices.Count) play_list.Add (logic_indices[pos_logic++]);
+ break;
}
-
}
- list = new ArrayListIndicesRandom (games.Count);
- Initialize ();
+ enumerator = play_list.GetEnumerator ();
}
- void Initialize ()
- {
- if ((game_type & GameSession.Types.AllGames) == GameSession.Types.AllGames) { // The game list has been already randomized
- list.Clear ();
- for (int i = 0; i < games.Count; i++)
- list.Add (i);
- } else
- list.Initialize ();
-
- enumerator = list.GetEnumerator ();
- }
-
public Game GetPuzzle ()
{
Game puzzle, first = null;
while (true) {
- if (enumerator.MoveNext () == false) { // All the games have been played, restart again
- Initialize ();
+ if (enumerator.MoveNext () == false) { // All the games have been played, restart again
+ enumerator = play_list.GetEnumerator ();
enumerator.MoveNext ();
-
- if (analogies_manager.IsExhausted == true)
- analogies_manager.Initialize ();
}
- puzzle = (Game) Activator.CreateInstance ((Type) games [(int) enumerator.Current], true);
+
+ puzzle = (Game) Activator.CreateInstance ((Type) available_games [enumerator.Current].TypeOf, true);
//puzzle = (Game) Activator.CreateInstance (LogicPuzzles [37], true);
+ puzzle.Variant = available_games [enumerator.Current].Variant;
+
if (first != null && first.GetType () == puzzle.GetType ())
break;
if (puzzle.IsPlayable == false)
continue;
-
+
if ((Preferences.GetBoolValue (Preferences.ColorBlindKey) == true) && puzzle.UsesColors == true)
continue;
- Analogies analogy = puzzle as Analogies;
- if (analogy != null && analogy.IsExhausted == true)
- continue;
-
if (first == null)
first = puzzle;
@@ -463,7 +429,6 @@ namespace gbrainy.Core.Main
puzzle.CurrentDifficulty = Difficulty;
return puzzle;
}
-
#if PDF_DUMP
// Generates a single PDF document with all the puzzles contained in gbrainy (4 games per page)
public void GeneratePDF ()
@@ -472,7 +437,7 @@ namespace gbrainy.Core.Main
Game puzzle;
game_type = GameSession.Types.AllGames;
Type [] allgames = CustomGames;
-
+
for (int i = 0; i < allgames.Length; i++)
games.Add (allgames [i]);
@@ -486,7 +451,7 @@ namespace gbrainy.Core.Main
cnt++;
cr.Save ();
cr.Translate (x, y);
- cr.Rectangle (0, 0, width, height);;
+ cr.Rectangle (0, 0, width, height);;
cr.Clip ();
cr.Save ();
puzzle.DrawPreview (cr, width, height, false);
diff --git a/src/Core/Main/GameSession.cs b/src/Core/Main/GameSession.cs
index e09ce73..c176560 100644
--- a/src/Core/Main/GameSession.cs
+++ b/src/Core/Main/GameSession.cs
@@ -91,7 +91,7 @@ namespace gbrainy.Core.Main
}
public GameTypes AvailableGames {
- get { return game_manager.AvailableGames; }
+ get { return game_manager.AvailableGameTypes; }
}
public PlayerHistory PlayerHistory {
@@ -249,7 +249,7 @@ namespace gbrainy.Core.Main
CurrentGame.DrawRequest += GameDrawRequest;
CurrentGame.UpdateUIElement += GameUpdateUIElement;
- CurrentGame.Initialize ();
+ CurrentGame.Begin ();
CurrentGame.GameTime = TimeSpan.Zero;
Status = SessionStatus.Playing;
diff --git a/src/Core/Main/Verbal/Analogies.cs b/src/Core/Main/Verbal/Analogies.cs
index a4df6c7..c393d9c 100644
--- a/src/Core/Main/Verbal/Analogies.cs
+++ b/src/Core/Main/Verbal/Analogies.cs
@@ -51,10 +51,6 @@ namespace gbrainy.Core.Main.Verbal
}
}
- public override bool IsPlayable {
- get { return List.Count > 0;}
- }
-
public override string Answer {
get {
string str;
@@ -106,56 +102,23 @@ namespace gbrainy.Core.Main.Verbal
get { return GameTypes.VerbalAnalogy;}
}
- public abstract ArrayListIndicesRandom Indices {
- get;
- set;
- }
-
- public abstract int CurrentIndex {
+ public abstract Dictionary <int, Analogy> List {
get;
- set;
- }
-
- // Returns true when this game manager has no more games to server
- public bool IsExhausted {
- get { return CurrentIndex + 1 >= List.Count;}
}
- public abstract Dictionary <int, Analogy> List {
- get;
+ public override int Variants {
+ get { return List.Count;}
}
public Analogy GetNext ()
{
- int idx;
Analogy analogy; // Holds a deep copy
Analogy analogy_ref; // Holds reference to the object
ArrayListIndicesRandom indices = null;
int new_right = 0;
bool localized = true;
- if (List.Count == 0)
- return null;
-
- if (Indices == null || CurrentIndex + 1 >= List.Count) {
- Indices = new ArrayListIndicesRandom (List.Count);
- Indices.Initialize ();
- }
- else
- CurrentIndex++;
-
- idx = Indices [CurrentIndex];
-
- try
- {
- List.TryGetValue (idx, out analogy_ref);
- }
-
- catch (KeyNotFoundException)
- {
- return null;
- }
-
+ List.TryGetValue (Variant, out analogy_ref);
analogy = analogy_ref.Copy ();
if (analogy.answers != null) { // Randomize answers order
@@ -195,7 +158,7 @@ namespace gbrainy.Core.Main.Verbal
} else {
// Get analogy again
- List.TryGetValue (idx, out analogy_ref);
+ List.TryGetValue (Variant, out analogy_ref);
analogy = analogy_ref.Copy ();
if (analogy.answers != null) { // Randomize answers order
diff --git a/src/Core/Main/Verbal/AnalogiesFactory.cs b/src/Core/Main/Verbal/AnalogiesFactory.cs
index bad4b8b..5f6d953 100644
--- a/src/Core/Main/Verbal/AnalogiesFactory.cs
+++ b/src/Core/Main/Verbal/AnalogiesFactory.cs
@@ -22,7 +22,6 @@ using System.Xml;
using System.IO;
using System.Collections.Generic;
-using Cairo;
using Mono.Unix;
namespace gbrainy.Core.Main.Verbal
@@ -53,7 +52,7 @@ namespace gbrainy.Core.Main.Verbal
static void Read ()
{
- Read (Defines.DATA_DIR + Defines.VERBAL_ANALOGIES);
+ Read (Path.Combine (Defines.DATA_DIR, Defines.VERBAL_ANALOGIES));
}
static public void Read (string file)
@@ -163,7 +162,7 @@ namespace gbrainy.Core.Main.Verbal
catch (Exception e)
{
- Console.WriteLine ("Error loading {0}. Exception {1}", file, e.Message);
+ Console.WriteLine ("AnalogiesFactory. Error loading file: {0}", e.Message);
}
}
}
diff --git a/src/Core/Main/Verbal/AnalogiesMultipleOptions.cs b/src/Core/Main/Verbal/AnalogiesMultipleOptions.cs
index 6bceef4..2050dbc 100644
--- a/src/Core/Main/Verbal/AnalogiesMultipleOptions.cs
+++ b/src/Core/Main/Verbal/AnalogiesMultipleOptions.cs
@@ -32,8 +32,6 @@ namespace gbrainy.Core.Main.Verbal
public class AnalogiesMultipleOptions : Analogies
{
static protected Dictionary <int, Analogy> analogies;
- static protected ArrayListIndicesRandom analogies_indices;
- static protected int analogies_index = 0;
public AnalogiesMultipleOptions ()
{
@@ -74,16 +72,6 @@ namespace gbrainy.Core.Main.Verbal
}
}
- public override ArrayListIndicesRandom Indices {
- get { return analogies_indices; }
- set { analogies_indices = value; }
- }
-
- public override int CurrentIndex {
- get { return analogies_index; }
- set { analogies_index = value; }
- }
-
public override Dictionary <int, Analogy> List {
get { return analogies; }
}
diff --git a/src/Core/Main/Verbal/AnalogiesPairOfWordsCompare.cs b/src/Core/Main/Verbal/AnalogiesPairOfWordsCompare.cs
index 93b53c5..f0ec6dd 100644
--- a/src/Core/Main/Verbal/AnalogiesPairOfWordsCompare.cs
+++ b/src/Core/Main/Verbal/AnalogiesPairOfWordsCompare.cs
@@ -32,7 +32,6 @@ namespace gbrainy.Core.Main.Verbal
{
static protected Dictionary <int, Analogy> analogies;
static protected ArrayListIndicesRandom analogies_indices;
- static protected int analogies_index = 0;
string samples, sample;
@@ -46,16 +45,6 @@ namespace gbrainy.Core.Main.Verbal
get { return Catalog.GetString ("Pair of words compare");}
}
- public override ArrayListIndicesRandom Indices {
- get { return analogies_indices; }
- set { analogies_indices = value; }
- }
-
- public override int CurrentIndex {
- get { return analogies_index; }
- set { analogies_index = value; }
- }
-
public override Dictionary <int, Analogy> List {
get { return analogies; }
}
diff --git a/src/Core/Main/Verbal/AnalogiesPairOfWordsOptions.cs b/src/Core/Main/Verbal/AnalogiesPairOfWordsOptions.cs
index 2d27207..5210fa2 100644
--- a/src/Core/Main/Verbal/AnalogiesPairOfWordsOptions.cs
+++ b/src/Core/Main/Verbal/AnalogiesPairOfWordsOptions.cs
@@ -31,8 +31,6 @@ namespace gbrainy.Core.Main.Verbal
public class AnalogiesPairOfWordsOptions : Analogies
{
static protected Dictionary <int, Analogy> analogies;
- static protected ArrayListIndicesRandom analogies_indices;
- static protected int analogies_index = 0;
public AnalogiesPairOfWordsOptions ()
{
@@ -44,16 +42,6 @@ namespace gbrainy.Core.Main.Verbal
get { return Catalog.GetString ("Pair of words");}
}
- public override ArrayListIndicesRandom Indices {
- get { return analogies_indices; }
- set { analogies_indices = value; }
- }
-
- public override int CurrentIndex {
- get { return analogies_index; }
- set { analogies_index = value; }
- }
-
public override Dictionary <int, Analogy> List {
get { return analogies; }
}
diff --git a/src/Core/Main/Verbal/AnalogiesQuestionAnswer.cs b/src/Core/Main/Verbal/AnalogiesQuestionAnswer.cs
index 963cf36..cfcbf05 100644
--- a/src/Core/Main/Verbal/AnalogiesQuestionAnswer.cs
+++ b/src/Core/Main/Verbal/AnalogiesQuestionAnswer.cs
@@ -29,8 +29,6 @@ namespace gbrainy.Core.Main.Verbal
public class AnalogiesQuestionAnswer : Analogies
{
static protected Dictionary <int, Analogy> analogies;
- static protected ArrayListIndicesRandom analogies_indices;
- static protected int analogies_index = 0;
public AnalogiesQuestionAnswer ()
{
@@ -42,16 +40,6 @@ namespace gbrainy.Core.Main.Verbal
get { return Catalog.GetString ("Question and answer");}
}
- public override ArrayListIndicesRandom Indices {
- get { return analogies_indices; }
- set { analogies_indices = value; }
- }
-
- public override int CurrentIndex {
- get { return analogies_index; }
- set { analogies_index = value; }
- }
-
public override Dictionary <int, Analogy> List {
get { return analogies; }
}
diff --git a/src/Core/Main/Xml/GameXml.cs b/src/Core/Main/Xml/GameXml.cs
new file mode 100644
index 0000000..af5f9e5
--- /dev/null
+++ b/src/Core/Main/Xml/GameXml.cs
@@ -0,0 +1,145 @@
+/*
+ * 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 Mono.Unix;
+
+namespace gbrainy.Core.Main
+{
+ public class GameXml : Game
+ {
+ // Every GameXml instance is capable of locating any XML defined game
+ // This struct translates from a Variant that is global to all games
+ // to a specific game + variant
+ public struct DefinitionLocator
+ {
+ public int Game { get; set; }
+ public int Variant { get; set; }
+
+ public DefinitionLocator (int game, int variant)
+ {
+ Game = game;
+ Variant = variant;
+ }
+ };
+
+ // Shared with all instances
+ static List <GameXmlDefinition> games;
+ static List <DefinitionLocator> locators;
+
+ DefinitionLocator current;
+ GameXmlDefinition game;
+
+ static public List <GameXmlDefinition> Definitions {
+ set {
+ games = value;
+ locators = new List <DefinitionLocator> ();
+ }
+ }
+
+ public override GameTypes Type {
+ get { return game.Type;}
+ }
+
+ public override string Name {
+ get { return game.Name; }
+ }
+
+ public override string Question {
+ get {
+ if (game.Variants.Count > 0 && game.Variants[current.Variant].Question != null)
+ return game.Variants[current.Variant].Question;
+ else
+ return game.Question;
+ }
+ }
+
+ public override string Rationale {
+ get {
+ if (game.Variants.Count > 0 && game.Variants[current.Variant].Rationale != null)
+ return game.Variants[current.Variant].Rationale;
+ else
+ return game.Rationale;
+ }
+ }
+
+ public override string Tip {
+ get {
+ if (game.Variants.Count > 0 && game.Variants[current.Variant].Tip != null)
+ return game.Variants[current.Variant].Tip;
+ else
+ return game.Tip;
+ }
+ }
+
+ public override void Initialize ()
+ {
+ if (game.Variants.Count > 0 && game.Variants[current.Variant].Answer != null)
+ right_answer = game.Variants[current.Variant].Answer;
+ else
+ right_answer = game.Answer;
+ }
+
+ public override int Variants {
+ get {
+ if (locators.Count == 0)
+ BuildLocationList ();
+
+ return locators.Count;
+ }
+ }
+
+ public override int Variant {
+ set {
+ base.Variant = value;
+
+ DefinitionLocator locator;
+
+ locator = locators [Variant];
+ current.Game = locator.Game;
+ current.Variant = locator.Variant;
+ game = games [locator.Game];
+ }
+ }
+
+ public override void Draw (CairoContextEx gr, int area_width, int area_height, bool rtl)
+ {
+ 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);
+ }
+
+ void BuildLocationList ()
+ {
+ locators.Clear ();
+
+ for (int game = 0; game < games.Count; game++)
+ {
+ locators.Add (new DefinitionLocator (game, 0));
+ for (int variant = 0; variant < games[game].Variants.Count; variant++)
+ locators.Add (new DefinitionLocator (game, variant));
+ }
+ }
+ }
+}
diff --git a/src/Core/Main/Xml/GameXmlDefinition.cs b/src/Core/Main/Xml/GameXmlDefinition.cs
new file mode 100644
index 0000000..49339de
--- /dev/null
+++ b/src/Core/Main/Xml/GameXmlDefinition.cs
@@ -0,0 +1,96 @@
+/*
+ * 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.Text;
+using System.Collections.Generic;
+
+namespace gbrainy.Core.Main
+{
+ public class GameXmlDefinitionVariant
+ {
+ 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 string Question { get; set; }
+ public string Tip { get; set; }
+ public string Rationale { get; set; }
+ public string Answer { get; set; }
+
+ public SVGImage Image;
+
+ public override string ToString ()
+ {
+ StringBuilder str = new StringBuilder ();
+
+ str.AppendLine ("Question: " + Question);
+ str.AppendLine ("Tip: " + Tip);
+ str.AppendLine ("Rationale: " + Rationale);
+ str.AppendLine ("Answer: " + Answer);
+
+ return str.ToString ();
+ }
+ }
+
+ // Container for a game defined in an Xml file
+ public class GameXmlDefinition : GameXmlDefinitionVariant
+ {
+ public string Name { get; set; }
+ public Game.Difficulty Difficulty { get; set; }
+ public GameTypes Type { get; set; }
+
+ public List <GameXmlDefinitionVariant> Variants { get; set; }
+
+ public GameXmlDefinition ()
+ {
+ Difficulty = Game.Difficulty.Medium;
+ Type = GameTypes.LogicPuzzle; // TODO: temporary, should be mandatory in games.xml
+ Variants = new List <GameXmlDefinitionVariant> ();
+ }
+
+ public void NewVariant ()
+ {
+ Variants.Add (new GameXmlDefinitionVariant ());
+ }
+
+ public override string ToString ()
+ {
+ StringBuilder str = new StringBuilder ();
+
+ str.AppendLine ("Name: " + Name);
+ str.AppendLine ("Difficulty: " + Difficulty);
+ str.AppendLine (base.ToString ());
+
+ foreach (GameXmlDefinitionVariant variant in Variants)
+ {
+ str.AppendLine ("---");
+ str.AppendLine (variant.ToString ());
+ str.AppendLine ("---");
+ }
+
+ return str.ToString ();
+ }
+ }
+}
diff --git a/src/Core/Main/Xml/GameXmlFactory.cs b/src/Core/Main/Xml/GameXmlFactory.cs
new file mode 100644
index 0000000..23a697b
--- /dev/null
+++ b/src/Core/Main/Xml/GameXmlFactory.cs
@@ -0,0 +1,209 @@
+/*
+ * 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.Xml;
+using System.IO;
+using System.Collections.Generic;
+
+using Mono.Unix;
+
+namespace gbrainy.Core.Main
+{
+ static public class GamesXmlFactory
+ {
+ static List <GameXmlDefinition> games;
+ static bool read = false;
+
+ static GamesXmlFactory ()
+ {
+ games = new List <GameXmlDefinition> ();
+ }
+
+ static public List <GameXmlDefinition> Definitions {
+ get {
+ Read ();
+ return games;
+ }
+ }
+
+ static public void Read ()
+ {
+ Read (Path.Combine (Defines.DATA_DIR, "games.xml"));
+ }
+
+ static void Read (string file)
+ {
+ GameXmlDefinition game;
+ string name, str;
+ List <string> answers;
+ bool processing_variant = false;
+ int variant = 0;
+
+ if (read == true)
+ return;
+
+ try
+ {
+ StreamReader myStream = new StreamReader (file);
+ XmlTextReader reader = new XmlTextReader (myStream);
+ game = null;
+
+ while (reader.Read ())
+ {
+ name = reader.Name.ToLower ();
+ switch (name) {
+ case "game":
+ if (reader.NodeType == XmlNodeType.Element) {
+ game = new GameXmlDefinition ();
+ } else if (reader.NodeType == XmlNodeType.EndElement) {
+ games.Add (game);
+ }
+ break;
+ case "_name":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ game.Name = reader.ReadElementString ();
+ break;
+ case "_difficulty":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ str = reader.ReadElementString ();
+ str.Trim ();
+
+ switch (str) {
+ case "Easy":
+ game.Difficulty = Game.Difficulty.Easy;
+ break;
+ case "Medium":
+ game.Difficulty = Game.Difficulty.Medium;
+ break;
+ case "Master":
+ game.Difficulty = Game.Difficulty.Master;
+ break;
+ case "All":
+ game.Difficulty = Game.Difficulty.All;
+ break;
+ default:
+ Console.WriteLine ("GameXmlFactory. Unknown difficulty level: {0}", str);
+ break;
+ }
+
+ break;
+ case "svg":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ game.Image.Filename = reader.GetAttribute ("file");
+
+ str = reader.GetAttribute ("X");
+ if (String.IsNullOrEmpty (str) == false)
+ game.Image.X = Double.Parse (str);
+ else
+ game.Image.X = 0.1;
+
+ str = reader.GetAttribute ("Y");
+ if (String.IsNullOrEmpty (str) == false)
+ game.Image.Y = Double.Parse (str);
+ else
+ game.Image.Y = 0.1;
+
+ str = reader.GetAttribute ("width");
+ if (String.IsNullOrEmpty (str) == false)
+ game.Image.Width = Double.Parse (str);
+ else
+ game.Image.Width = 0.8;
+
+ str = reader.GetAttribute ("height");
+ if (String.IsNullOrEmpty (str) == false)
+ game.Image.Height = Double.Parse (str);
+ else
+ game.Image.Height = 0.8;
+
+ break;
+ case "_question":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ if (processing_variant)
+ game.Variants[variant].Question = reader.ReadElementString ();
+ else
+ game.Question = reader.ReadElementString ();
+
+ break;
+ case "_rationale":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ if (processing_variant)
+ game.Variants[variant].Rationale = reader.ReadElementString ();
+ else
+ game.Rationale = reader.ReadElementString ();
+
+ break;
+ case "_answer":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ if (processing_variant)
+ game.Variants[variant].Answer = reader.ReadElementString ();
+ else
+ game.Answer = reader.ReadElementString ();
+
+ break;
+ case "_tip":
+ if (reader.NodeType != XmlNodeType.Element)
+ break;
+
+ if (processing_variant)
+ game.Variants[variant].Tip = reader.ReadElementString ();
+ else
+ game.Tip = reader.ReadElementString ();
+
+ break;
+ case "variant":
+ if (reader.NodeType == XmlNodeType.Element) {
+ game.NewVariant ();
+ variant = game.Variants.Count - 1;
+ processing_variant = true;
+ } else if (reader.NodeType == XmlNodeType.EndElement) {
+ processing_variant = false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ reader.Close ();
+ read = true;
+
+ GameXml.Definitions = games;
+ }
+
+ catch (Exception e)
+ {
+ read = true;
+ Console.WriteLine ("GameXmlFactory. Error loading: {0}", e.Message);
+ }
+ }
+ }
+}
diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am
index 01495b3..4e20481 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -18,6 +18,9 @@ CSDISTFILES = \
$(srcdir)/Main/GameSessionHistoryExtended.cs \
$(srcdir)/Main/GameTypes.cs \
$(srcdir)/Main/GameTips.cs \
+ $(srcdir)/Main/Xml/GameXml.cs \
+ $(srcdir)/Main/Xml/GameXmlFactory.cs \
+ $(srcdir)/Main/Xml/GameXmlDefinition.cs \
$(srcdir)/Main/Memory.cs \
$(srcdir)/Main/PlayerHistory.cs \
$(srcdir)/Main/PlayerPersonalRecord.cs \
diff --git a/tests/Core/GameManagerTest.cs b/tests/Core/GameManagerTest.cs
index 1f7d246..48900a2 100644
--- a/tests/Core/GameManagerTest.cs
+++ b/tests/Core/GameManagerTest.cs
@@ -40,11 +40,12 @@ namespace gbrainyTest
int notip = 0;
GameManager manager = new GameManager ();
- Type[] games = manager.CustomGames;
+ GameManager.GameLocator [] games = manager.AvailableGames;
- foreach (Type type in games)
+ foreach (GameManager.GameLocator locator in games)
{
- Game game = (Game) Activator.CreateInstance (type, true);
+ Game game = (Game) Activator.CreateInstance (locator.TypeOf, true);
+ game.Variant = locator.Variant;
if (game.TipString == String.Empty)
{
notip++;
@@ -59,19 +60,23 @@ namespace gbrainyTest
{
Dictionary <string, bool> dictionary;
GameManager manager = new GameManager ();
- Type[] games = manager.CustomGames;
-
+ GameManager.GameLocator [] games = manager.AvailableGames;
dictionary = new Dictionary <string, bool> (games.Length);
- foreach (Type type in games)
+ foreach (GameManager.GameLocator locator in games)
{
- Game game = (Game) Activator.CreateInstance (type, true);
+ if (locator.IsGame == false)
+ continue;
+ Game game = (Game) Activator.CreateInstance (locator.TypeOf, true);
+ game.Variant = locator.Variant;
+
Assert.AreEqual (false, dictionary.ContainsKey (game.Name),
String.Format ("Game name {0} is duplicated", game.Name));
dictionary.Add (game.Name, true);
}
+
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]