[gbrainy/gbrainy_15x] Unit testing and some refactorings
- From: Jordi Mas <jmas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gbrainy/gbrainy_15x] Unit testing and some refactorings
- Date: Sat, 8 May 2010 09:49:34 +0000 (UTC)
commit f1f1210b4f528c1f9027e6bf35ecf686bf04414a
Author: Jordi Mas <jmas softcatala org>
Date: Sat May 8 11:50:26 2010 +0200
Unit testing and some refactorings
Makefile.am | 1 +
configure.ac | 34 +++++-
src/Core/Main/GameSession.cs | 231 ++++--------------------------
src/Core/Main/GameSessionHistory.cs | 78 ++++++++++
src/Core/Main/PlayerHistory.cs | 118 ++++------------
src/Core/Main/PlayerPersonalRecord.cs | 87 +++++++++++
src/Core/Main/Preferences.cs | 3 +-
src/Core/Main/Score.cs | 171 ++++++++++++++++++++++
src/Core/Main/Verbal/AnalogiesFactory.cs | 16 ++-
src/Core/Makefile.am | 6 +-
src/Core/Views/FinishView.cs | 24 ++--
src/Core/Views/PlayerHistoryView.cs | 30 ++--
tests/Core/AnalogiesFactoryTest.cs | 55 +++++++
tests/Core/PlayerHistoryTest.cs | 75 ++++++++++
tests/Core/PlayerPersonalRecordTest.cs | 76 ++++++++++
tests/Makefile.am | 36 +++++
tests/README | 7 +
tests/test_analogies.xml | 66 +++++++++
18 files changed, 783 insertions(+), 331 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 3ace8e3..151a302 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,6 @@
SUBDIRS = \
src \
+ tests \
data \
po \
help
diff --git a/configure.ac b/configure.ac
index c757f62..9359faa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -99,6 +99,36 @@ AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
AM_GLIB_GNU_GETTEXT
+
+dnl -- NUnit required for (optional) unit tests
+NUNIT_REQUIRED=2.4.7
+
+AC_ARG_ENABLE(tests, AC_HELP_STRING([--enable-tests], [Enable NUnit tests]),
+ enable_tests=$enableval, enable_tests="no")
+
+if test "x$enable_tests" = "xno"; then
+ do_tests=no
+ AM_CONDITIONAL(ENABLE_TESTS, false)
+else
+ PKG_CHECK_MODULES(NUNIT, nunit >= $NUNIT_REQUIRED,
+ do_tests="yes", do_tests="no")
+
+ AC_SUBST(NUNIT_LIBS)
+ AC_PATH_PROG(NUNIT, nunit-console)
+ AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes")
+
+ if test "x$do_tests" = "xno"; then
+ PKG_CHECK_MODULES(NUNIT, mono-nunit >= 2.4,
+ do_tests="yes", do_tests="no")
+
+ AC_SUBST(NUNIT_LIBS)
+ AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes")
+
+ if test "x$do_tests" = "xno"; then
+ AC_MSG_WARN([Could not find nunit: tests will not be available]) fi
+ fi
+fi
+
dnl --- Prologue
AC_SUBST(CFLAGS)
@@ -133,10 +163,12 @@ src/Makefile
src/Core/Makefile
src/Games/Makefile
src/Clients/Classical/Makefile
+tests/Makefile
data/Makefile
data/gbrainy.pc
help/Makefile
])
-echo "Mono-addins: ${enable_addins_sharp}"
+echo "Mono-addins: ${enable_addins_sharp}"
+echo "NUnit: ${enable_tests}"
diff --git a/src/Core/Main/GameSession.cs b/src/Core/Main/GameSession.cs
index 0b52f35..61fa3da 100644
--- a/src/Core/Main/GameSession.cs
+++ b/src/Core/Main/GameSession.cs
@@ -41,16 +41,6 @@ namespace gbrainy.Core.Main
AllGames = MemoryTrainers | CalculationTrainers | LogicPuzzles | VerbalAnalogies
}
- private enum ScoresType
- {
- None = 0,
- LogicPuzzles,
- MemoryTrainers,
- CalculationTrainers,
- VerbalAnalogies,
- Last
- }
-
public enum SessionStatus
{
NotPlaying,
@@ -59,30 +49,19 @@ namespace gbrainy.Core.Main
Finished,
}
- // Data kept for every game type in raw data (processed with a formula after)
- public class Statistics
- {
- public int Played { get; set; }
- public int Won { get; set; }
- public int Scored { get; set; }
- }
-
private TimeSpan game_time;
- private int games_played;
- private int games_won;
private Game current_game;
private GameManager game_manager;
private System.Timers.Timer timer;
private bool paused;
private string current_time;
private TimeSpan one_sec = TimeSpan.FromSeconds (1);
- private int total_score;
private SessionStatus status;
private ViewsControler controler;
private ISynchronizeInvoke synchronize;
- private PlayerHistory history;
- private Statistics [] statistics;
+ private PlayerHistory player_history;
private int id;
+ private GameSessionHistoryExtended history;
public event EventHandler DrawRequest;
public event EventHandler <UpdateUIStateEventArgs> UpdateUIElement;
@@ -97,27 +76,27 @@ namespace gbrainy.Core.Main
timer.Elapsed += TimerUpdater;
timer.Interval = (1 * 1000); // 1 second
- statistics = new Statistics [(int) ScoresType.Last];
-
- for (int i = 0; i < (int) ScoresType.Last; i++)
- statistics [i] = new Statistics ();
-
controler = new ViewsControler (this);
Status = SessionStatus.NotPlaying;
- history = new PlayerHistory ();
+ player_history = new PlayerHistory ();
+ history = new GameSessionHistoryExtended ();
}
public int ID {
get {return id;}
}
+ public GameSessionHistoryExtended History {
+ get {return history;}
+ }
+
public Game.Types AvailableGames {
get { return game_manager.AvailableGames; }
}
public PlayerHistory PlayerHistory {
- set { history = value; }
- get { return history; }
+ set { player_history = value; }
+ get { return player_history; }
}
public ISynchronizeInvoke SynchronizingObject {
@@ -140,16 +119,6 @@ namespace gbrainy.Core.Main
set {game_time = value; }
}
- public int GamesPlayed {
- get {return games_played; }
- set { games_played = value;}
- }
-
- public int GamesWon {
- get {return games_won; }
- set {games_won = value; }
- }
-
public bool Paused {
get {return paused; }
set {paused = value; }
@@ -183,46 +152,6 @@ namespace gbrainy.Core.Main
get {return game_manager;}
}
- public int TotalScore {
- get {return total_score;}
- }
-
- public int LogicScore {
- get {
- if (statistics [(int) ScoresType.LogicPuzzles].Played == 0)
- return -1;
-
- return ScoreFormula (statistics [(int) ScoresType.LogicPuzzles]);
- }
- }
-
- public int MemoryScore {
- get {
- if (statistics [(int) ScoresType.MemoryTrainers].Played == 0)
- return -1;
-
- return ScoreFormula (statistics [(int) ScoresType.MemoryTrainers]);
- }
- }
-
- public int MathScore {
- get {
- if (statistics [(int) ScoresType.CalculationTrainers].Played == 0)
- return -1;
-
- return ScoreFormula (statistics [(int) ScoresType.CalculationTrainers]);
- }
- }
-
- public int VerbalScore {
- get {
- if (statistics [(int) ScoresType.VerbalAnalogies].Played == 0)
- return -1;
-
- return ScoreFormula (statistics [(int) ScoresType.VerbalAnalogies]);
- }
- }
-
public string TimePlayed {
get {
return (current_time == null) ? TimeSpanToStr (TimeSpan.FromSeconds (0)) : current_time;
@@ -233,7 +162,7 @@ namespace gbrainy.Core.Main
get {
TimeSpan average;
- average = (games_played > 0) ? TimeSpan.FromSeconds (game_time.TotalSeconds / games_played) : game_time;
+ average = (history.GamesPlayed > 0) ? TimeSpan.FromSeconds (game_time.TotalSeconds / history.GamesPlayed) : game_time;
return TimeSpanToStr (average);
}
}
@@ -244,7 +173,7 @@ namespace gbrainy.Core.Main
return string.Empty;
String text;
- text = String.Format (Catalog.GetString ("Games played: {0} ({1}% score)"),games_played, total_score);
+ text = String.Format (Catalog.GetString ("Games played: {0} ({1}% score)"), history.GamesPlayed, history.TotalScore);
text += String.Format (Catalog.GetString (" - Time: {0}"), current_time);
if (CurrentGame != null)
@@ -259,14 +188,14 @@ namespace gbrainy.Core.Main
get {
string s;
- if (GamesPlayed >= 10) {
- if (TotalScore >= 70)
+ if (history.GamesPlayed >= 10) {
+ if (history.TotalScore >= 70)
s = String.Format (Catalog.GetString ("Outstanding results"));
- else if (TotalScore >= 50)
+ else if (history.TotalScore >= 50)
s = String.Format (Catalog.GetString ("Excellent results"));
- else if (TotalScore >= 30)
+ else if (history.TotalScore >= 30)
s = String.Format (Catalog.GetString ("Good results"));
- else if (TotalScore >= 20)
+ else if (history.TotalScore >= 20)
s = String.Format (Catalog.GetString ("Poor results"));
else s = String.Format (Catalog.GetString ("Disappointing results"));
} else
@@ -284,12 +213,7 @@ namespace gbrainy.Core.Main
current_time = TimeSpanToStr (game_time);
- for (int i = 0; i < (int) ScoresType.Last; i++)
- statistics [i] = new Statistics ();
-
- total_score = 0;
- games_played = 0;
- games_won = 0;
+ history.Clear ();
game_time = TimeSpan.Zero;
timer.SynchronizingObject = SynchronizingObject;
EnableTimer = true;
@@ -297,7 +221,8 @@ namespace gbrainy.Core.Main
public void EndSession ()
{
- history.SaveGameSession (this);
+ // Making a deep copy of GameSessionHistory type (base class) for serialization
+ player_history.SaveGameSession (history.Copy ());
if (CurrentGame != null)
CurrentGame.Finish ();
@@ -315,7 +240,7 @@ namespace gbrainy.Core.Main
if (CurrentGame != null)
CurrentGame.Finish ();
- games_played++;
+ history.GamesPlayed++;
CurrentGame = game_manager.GetPuzzle ();
CurrentGame.SynchronizingObject = SynchronizingObject;
CurrentGame.DrawRequest += GameDrawRequest;
@@ -340,122 +265,18 @@ namespace gbrainy.Core.Main
paused = false;
}
- /*
- How the game session is scored
-
- * Every game has a scoring algorithm that scores the player performance within the game.
- This takes into account time used and tips (result is from 0 to 10)
- * The results are added to the games and scores arrays where we store the results for
- the different game types (verbal, logic, etc)
- * We apply a ScoreFormula function that balances the total result with the number of
- games played (is not the same 100% games won playing 2 than 10 games) and the difficulty
-
- The final result is a number from 0 to 100
- */
-
public bool ScoreGame (string answer)
{
- int score;
- bool won;
- int components = 0;
+ int game_score;
- if (CurrentGame == null ||Status == SessionStatus.Answered)
+ if (CurrentGame == null || Status == SessionStatus.Answered)
return false;
- score = CurrentGame.Score (answer);
- if (score > 0) {
- GamesWon++;
- won = true;
- } else
- won = false;
-
- switch (CurrentGame.Type) {
- case Game.Types.LogicPuzzle:
- statistics [(int) ScoresType.LogicPuzzles].Scored += score;
- statistics [(int) ScoresType.LogicPuzzles].Played++;
- if (won) statistics [(int) ScoresType.LogicPuzzles].Won++;
- break;
- case Game.Types.MemoryTrainer:
- statistics [(int) ScoresType.MemoryTrainers].Scored += score;
- statistics [(int) ScoresType.MemoryTrainers].Played++;
- if (won) statistics [(int) ScoresType.MemoryTrainers].Won++;
- break;
- case Game.Types.MathTrainer:
- statistics [(int) ScoresType.CalculationTrainers].Scored += score;
- statistics [(int) ScoresType.CalculationTrainers].Played++;
- if (won) statistics [(int) ScoresType.CalculationTrainers].Won++;
- break;
- case Game.Types.VerbalAnalogy:
- statistics [(int) ScoresType.VerbalAnalogies].Scored += score;
- statistics [(int) ScoresType.VerbalAnalogies].Played++;
- if (won) statistics [(int) ScoresType.VerbalAnalogies].Won++;
- break;
- default:
- break;
- }
-
- total_score = 0;
-
- // Updates total score taking only into account played game types
- if (LogicScore >= 0) {
- total_score += LogicScore;
- components++;
- }
-
- if (MemoryScore >= 0) {
- total_score += MemoryScore;
- components++;
- }
-
- if (MathScore >= 0) {
- total_score += MathScore;
- components++;
- }
-
- if (VerbalScore >= 0) {
- total_score += VerbalScore;
- components++;
- }
-
- total_score = total_score / components;
+ game_score = CurrentGame.Score (answer);
+ history.UpdateScore (CurrentGame.Type, Difficulty, game_score);
Status = SessionStatus.Answered;
- return won;
- }
-
- //
- // Applies scoring formula to the session
- //
- int ScoreFormula (Statistics stats)
- {
- int logbase;
- double score, factor;
-
- switch (Difficulty) {
- case Game.Difficulty.Easy:
- logbase = 10;
- break;
- case Game.Difficulty.Medium:
- logbase = 20;
- break;
- case Game.Difficulty.Master:
- logbase = 30;
- break;
- default:
- throw new InvalidOperationException ("Invalid switch value");
- }
-
- // Simple percentage of games won vs played
- score = stats.Scored > 0 ? stats.Scored / stats.Played * 10 : 0;
-
- // Puts score of the game in prespective for the whole game
- factor = Math.Log (stats.Won + 2, logbase); // +2 to avoid log 0
-
- score = score * factor;
-
- if (score > 100) score = 100;
-
- return (int) score;
+ return (game_score > 0 ? true : false);
}
private void TimerUpdater (object source, ElapsedEventArgs e)
diff --git a/src/Core/Main/GameSessionHistory.cs b/src/Core/Main/GameSessionHistory.cs
new file mode 100644
index 0000000..07dd5cb
--- /dev/null
+++ b/src/Core/Main/GameSessionHistory.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 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 Mono.Unix;
+using System.Timers;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+using gbrainy.Core.Views;
+using gbrainy.Core.Libraries;
+
+namespace gbrainy.Core.Main
+{
+ [Serializable]
+ // Old class name, to keep compatibility when serializing with previous PlayerHistory files
+ [XmlType("GameHistory")]
+ public class GameSessionHistory
+ {
+ [XmlElementAttribute ("games_played")]
+ public int GamesPlayed { get; set; }
+
+ [XmlElementAttribute ("games_won")]
+ public int GamesWon { get; set; }
+
+ [XmlElementAttribute ("total_score")]
+ public int TotalScore { get; set; }
+
+ [XmlElementAttribute ("math_score")]
+ public int MathScore { get; set; }
+
+ [XmlElementAttribute ("logic_score")]
+ public int LogicScore { get; set; }
+
+ [XmlElementAttribute ("memory_score")]
+ public int MemoryScore { get; set; }
+
+ [XmlElementAttribute ("verbal_score")]
+ public int VerbalScore { get; set; }
+
+ public virtual void Clear ()
+ {
+ GamesPlayed = GamesWon = TotalScore = MathScore = LogicScore = MemoryScore = VerbalScore = 0;
+ }
+
+ // Deep copy
+ public GameSessionHistory Copy ()
+ {
+ GameSessionHistory history = new GameSessionHistory ();
+
+ history.GamesPlayed = GamesPlayed;
+ history.GamesWon = GamesWon;
+ history.TotalScore = TotalScore;
+ history.MathScore = MathScore;
+ history.LogicScore = LogicScore;
+ history.MemoryScore = MemoryScore;
+ history.VerbalScore = VerbalScore;
+ return history;
+ }
+ }
+}
+
diff --git a/src/Core/Main/PlayerHistory.cs b/src/Core/Main/PlayerHistory.cs
index 903be5c..a88bcd5 100644
--- a/src/Core/Main/PlayerHistory.cs
+++ b/src/Core/Main/PlayerHistory.cs
@@ -28,50 +28,31 @@ namespace gbrainy.Core.Main
public class PlayerHistory
{
string file, config_path;
- List <GameHistory> games;
+ List <GameSessionHistory> games;
int last_game;
+
- [Serializable]
- public class GameHistory
+ public PlayerHistory ()
{
- public int games_played;
- public int games_won;
- public int total_score;
- public int math_score;
- public int logic_score;
- public int memory_score;
- public int verbal_score;
+ ConfigPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
+ Defines.CONFIG_DIR);
+ last_game = -1;
}
- public class PersonalRecord
- {
- public Game.Types GameType { get; set; }
- public int PreviousScore { get; set; }
- public int NewScore { get; set; }
-
- public PersonalRecord (Game.Types type, int previous_score, int new_score)
- {
- GameType = type;
- PreviousScore = previous_score;
- NewScore = new_score;
+ public string ConfigPath {
+ set {
+ config_path = value;
+ file = Path.Combine (config_path, "PlayerHistory.xml");
}
}
- public PlayerHistory ()
- {
- config_path = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
- config_path = Path.Combine (config_path, Defines.CONFIG_DIR);
- file = Path.Combine (config_path, "PlayerHistory.xml");
- last_game = -1;
- }
-
- public List <GameHistory> Games {
+ public List <GameSessionHistory> Games {
get {
if (games == null)
{
Load ();
if (games == null)
- games = new List <GameHistory> ();
+ games = new List <GameSessionHistory> ();
}
return games;
}
@@ -83,76 +64,29 @@ namespace gbrainy.Core.Main
Save ();
}
- public void SaveGameSession (GameSession session)
+ public void SaveGameSession (GameSessionHistory score)
{
- if (session.GamesPlayed < Preferences.GetIntValue (Preferences.MinPlayedGamesKey)) {
+ if (score.GamesPlayed < Preferences.GetIntValue (Preferences.MinPlayedGamesKey)) {
last_game = -1;
return;
}
- GameHistory history = new GameHistory ();
-
- history.games_played = session.GamesPlayed;
- history.games_won = session.GamesWon;
- history.math_score = session.MathScore;
- history.logic_score = session.LogicScore;
- history.memory_score = session.MemoryScore;
- history.total_score = session.TotalScore;
- history.verbal_score = session.VerbalScore;
-
if (Games.Count >= Preferences.GetIntValue (Preferences.MaxStoredGamesKey))
Games.RemoveAt (0);
- Games.Add (history);
+ // Storing a copy to allow the input object to be modified
+ Games.Add (score.Copy ());
last_game = Games.Count - 1;
Save ();
}
// Check if the last recorded game has been a personal record
- public List <PersonalRecord> GetLastGameRecords ()
+ public List <PlayerPersonalRecord> GetLastGameRecords ()
{
- List <PersonalRecord> records = new List <PersonalRecord> ();
- GameHistory higher;
-
- // We can start to talk about personal records after 5 plays
- if (last_game == -1 || Games.Count < 5)
- return records;
-
- higher = new GameHistory ();
-
- // Find the higher record for every type of game
- for (int i = 0; i < last_game; i++)
- {
- if (Games[i].logic_score > higher.logic_score)
- higher.logic_score = Games[i].logic_score;
-
- if (Games[i].math_score > higher.math_score)
- higher.math_score = Games[i].math_score;
-
- if (Games[i].memory_score > higher.memory_score)
- higher.memory_score = Games[i].memory_score;
-
- if (Games[i].verbal_score > higher.verbal_score)
- higher.verbal_score = Games[i].verbal_score;
- }
-
- // It is a record?
- if (Games[last_game].logic_score > higher.logic_score)
- records.Add (new PersonalRecord (Game.Types.LogicPuzzle, higher.logic_score, Games[last_game].logic_score));
-
- if (Games[last_game].math_score > higher.math_score)
- records.Add (new PersonalRecord (Game.Types.MathTrainer, higher.math_score, Games[last_game].math_score));
-
- if (Games[last_game].memory_score > higher.memory_score)
- records.Add (new PersonalRecord (Game.Types.MemoryTrainer, higher.memory_score, Games[last_game].memory_score));
-
- if (Games[last_game].verbal_score > higher.verbal_score)
- records.Add (new PersonalRecord (Game.Types.VerbalAnalogy, higher.verbal_score, Games[last_game].verbal_score));
-
- return records;
+ return PlayerPersonalRecord.GetLastGameRecords (games, last_game);
}
- private void Save ()
+ public void Save ()
{
try {
if (!Directory.Exists (config_path))
@@ -160,29 +94,29 @@ namespace gbrainy.Core.Main
using (FileStream str = File.Create (file))
{
- XmlSerializer bf = new XmlSerializer (typeof (List <GameHistory>));
+ XmlSerializer bf = new XmlSerializer (typeof (List <GameSessionHistory>));
bf.Serialize (str, Games);
}
}
- catch (Exception)
+ catch (Exception e)
{
+ Console.WriteLine ("PlayerHistory. Cannot save {0}", e);
}
}
- private void Load ()
+ public void Load ()
{
try {
using (FileStream str = File.OpenRead (file))
{
- XmlSerializer bf = new XmlSerializer (typeof (List <GameHistory>));
- games = (List <GameHistory>) bf.Deserialize(str);
+ XmlSerializer bf = new XmlSerializer (typeof (List <GameSessionHistory>));
+ games = (List <GameSessionHistory>) bf.Deserialize(str);
}
}
catch (Exception)
{
}
- }
-
+ }
}
}
diff --git a/src/Core/Main/PlayerPersonalRecord.cs b/src/Core/Main/PlayerPersonalRecord.cs
new file mode 100644
index 0000000..c14d00c
--- /dev/null
+++ b/src/Core/Main/PlayerPersonalRecord.cs
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008-2009 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;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace gbrainy.Core.Main
+{
+ public class PlayerPersonalRecord
+ {
+ public const int MIN_GAMES_RECORD = 5;
+
+ public Game.Types GameType { get; set; }
+ public int PreviousScore { get; set; }
+ public int NewScore { get; set; }
+
+ public PlayerPersonalRecord (Game.Types type, int previous_score, int new_score)
+ {
+ GameType = type;
+ PreviousScore = previous_score;
+ NewScore = new_score;
+ }
+
+ // Check if the last recorded game has been a personal record
+ static public List <PlayerPersonalRecord> GetLastGameRecords (List <GameSessionHistory> games, int last_game)
+ {
+ List <PlayerPersonalRecord> records = new List <PlayerPersonalRecord> ();
+ GameSessionHistory higher;
+
+ // We can start to talk about personal records after 5 plays
+ if (last_game == -1 || games.Count < MIN_GAMES_RECORD)
+ return records;
+
+ higher = new GameSessionHistory ();
+
+ // Find the higher record for every type of game
+ for (int i = 0; i < last_game; i++)
+ {
+ if (games[i].LogicScore > higher.LogicScore)
+ higher.LogicScore = games[i].LogicScore;
+
+ if (games[i].MathScore > higher.MathScore)
+ higher.MathScore = games[i].MathScore;
+
+ if (games[i].MemoryScore > higher.MemoryScore)
+ higher.MemoryScore = games[i].MemoryScore;
+
+ if (games[i].VerbalScore > higher.VerbalScore)
+ higher.VerbalScore = games[i].VerbalScore;
+ }
+
+ // It is a record?
+ if (games[last_game].LogicScore > higher.LogicScore)
+ records.Add (new PlayerPersonalRecord (Game.Types.LogicPuzzle, higher.LogicScore, games[last_game].LogicScore));
+
+ if (games[last_game].MathScore > higher.MathScore)
+ records.Add (new PlayerPersonalRecord (Game.Types.MathTrainer, higher.MathScore, games[last_game].MathScore));
+
+ if (games[last_game].MemoryScore > higher.MemoryScore)
+ records.Add (new PlayerPersonalRecord (Game.Types.MemoryTrainer, higher.MemoryScore, games[last_game].MemoryScore));
+
+ if (games[last_game].VerbalScore > higher.VerbalScore)
+ records.Add (new PlayerPersonalRecord (Game.Types.VerbalAnalogy, higher.VerbalScore, games[last_game].VerbalScore));
+
+ return records;
+ }
+ }
+}
diff --git a/src/Core/Main/Preferences.cs b/src/Core/Main/Preferences.cs
index 9972827..db5e5e9 100644
--- a/src/Core/Main/Preferences.cs
+++ b/src/Core/Main/Preferences.cs
@@ -154,8 +154,9 @@ namespace gbrainy.Core.Main
properties [key] = value.ToString ();
}
- static void LoadDefaultValues ()
+ public static void LoadDefaultValues ()
{
+ properties.Clear ();
properties.Add (MemQuestionWarnKey, true.ToString ());
properties.Add (MemQuestionTimeKey, "4");
properties.Add (DifficultyKey, ((int)(Game.Difficulty.Medium)).ToString ());
diff --git a/src/Core/Main/Score.cs b/src/Core/Main/Score.cs
new file mode 100644
index 0000000..556abc9
--- /dev/null
+++ b/src/Core/Main/Score.cs
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2008-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 Mono.Unix;
+using System.Timers;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+using gbrainy.Core.Views;
+using gbrainy.Core.Libraries;
+
+namespace gbrainy.Core.Main
+{
+ static public class Score
+ {
+ /*
+ How the game session is scored
+
+ * Every game has a scoring algorithm that scores the player performance within the game.
+ This takes into account time used and tips (result is from 0 to 10)
+ * The results are added to the games and scores arrays where we store the results for
+ the different game types (verbal, logic, etc)
+ * We apply a ScoreFormula function that balances the total result with the number of
+ games played (is not the same 100% games won playing 2 than 10 games) and the difficulty
+
+ The final result is a number from 0 to 100
+ */
+ static public void UpdateSessionHistorycore (ref GameSessionHistoryExtended history, Game.Types type, Game.Difficulty difficulty, int game_score)
+ {
+ bool won;
+ int components = 0;
+
+ won = (game_score > 0 ? true : false);
+
+ if (won == true) {
+ history.GamesWon++;
+ }
+
+ switch (type) {
+ case Game.Types.LogicPuzzle:
+ history.LogicRawScore += game_score;
+ history.LogicPlayed++;
+ if (won) history.LogicWon++;
+ history.LogicScore = ScoreFormula (ref history, type, difficulty);
+ break;
+ case Game.Types.MemoryTrainer:
+ history.MemoryRawScore += game_score;
+ history.MemoryPlayed++;
+ if (won) history.MemoryWon++;
+ history.MemoryScore = ScoreFormula (ref history, type, difficulty);
+ break;
+ case Game.Types.MathTrainer:
+ history.MathRawScore += game_score;
+ history.MathPlayed++;
+ if (won) history.MathWon++;
+ history.MathScore = ScoreFormula (ref history, type, difficulty);
+ break;
+ case Game.Types.VerbalAnalogy:
+ history.VerbalRawScore += game_score;
+ history.VerbalPlayed++;
+ if (won) history.VerbalWon++;
+ history.VerbalScore = ScoreFormula (ref history, type, difficulty);
+ break;
+ default:
+ throw new InvalidOperationException ("Invalid switch value");
+ }
+
+ history.TotalScore = 0;
+
+ // Updates total score taking only into account played game types
+ if (history.LogicScore >= 0) {
+ history.TotalScore += history.LogicScore;
+ components++;
+ }
+
+ if (history.MemoryScore >= 0) {
+ history.TotalScore += history.MemoryScore;
+ components++;
+ }
+
+ if (history.MathScore >= 0) {
+ history.TotalScore += history.MathScore;
+ components++;
+ }
+
+ if (history.VerbalScore >= 0) {
+ history.TotalScore += history.VerbalScore;
+ components++;
+ }
+
+ history.TotalScore = history.TotalScore / components;
+ }
+
+ //
+ // Applies scoring formula to the session
+ //
+ static int ScoreFormula (ref GameSessionHistoryExtended history, Game.Types type, Game.Difficulty difficulty)
+ {
+ int logbase, scored, played, won;
+ double score, factor;
+
+ switch (difficulty) {
+ case Game.Difficulty.Easy:
+ logbase = 10;
+ break;
+ case Game.Difficulty.Medium:
+ logbase = 20;
+ break;
+ case Game.Difficulty.Master:
+ logbase = 30;
+ break;
+ default:
+ throw new InvalidOperationException ("Invalid switch value");
+ }
+
+ switch (type) {
+ case Game.Types.LogicPuzzle:
+ scored = history.LogicRawScore;
+ played = history.LogicPlayed;
+ won = history.LogicWon;
+ break;
+ case Game.Types.MemoryTrainer:
+ scored = history.MemoryRawScore;
+ played = history.MemoryPlayed;
+ won = history.MemoryWon;
+ break;
+ case Game.Types.MathTrainer:
+ scored = history.MathRawScore;
+ played = history.MathPlayed;
+ won = history.MathWon;
+ break;
+ case Game.Types.VerbalAnalogy:
+ scored = history.VerbalRawScore;
+ played = history.VerbalPlayed;
+ won = history.VerbalWon;
+ break;
+ default:
+ throw new InvalidOperationException ("Invalid switch value");
+ }
+
+ // Simple percentage of games won vs played
+ score = scored > 0 ? scored / played * 10 : 0;
+
+ // Puts score of the game in prespective for the whole game
+ factor = Math.Log (won + 2, logbase); // +2 to avoid log 0
+
+ score = score * factor;
+
+ if (score > 100) score = 100;
+
+ return (int) score;
+ }
+ }
+}
diff --git a/src/Core/Main/Verbal/AnalogiesFactory.cs b/src/Core/Main/Verbal/AnalogiesFactory.cs
index b33604e..bad4b8b 100644
--- a/src/Core/Main/Verbal/AnalogiesFactory.cs
+++ b/src/Core/Main/Verbal/AnalogiesFactory.cs
@@ -51,18 +51,26 @@ namespace gbrainy.Core.Main.Verbal
return analogies_arrays [(int) type];
}
- static public void Read ()
+ static void Read ()
+ {
+ Read (Defines.DATA_DIR + Defines.VERBAL_ANALOGIES);
+ }
+
+ static public void Read (string file)
{
Analogy analogy;
string name;
List <string> answers;
- try
+ try
{
- StreamReader myStream = new StreamReader (Defines.DATA_DIR + Defines.VERBAL_ANALOGIES);
+ StreamReader myStream = new StreamReader (file);
XmlTextReader reader = new XmlTextReader (myStream);
answers = new List <string> ();
+ for (int i = 0; i < (int) Analogy.Type.Last; i++)
+ analogies_arrays[i].Clear ();
+
analogy = new Analogy ();
while (reader.Read ())
{
@@ -155,7 +163,7 @@ namespace gbrainy.Core.Main.Verbal
catch (Exception e)
{
- Console.WriteLine ("Error loading {0}. Exception {1}", Defines.DATA_DIR + Defines.VERBAL_ANALOGIES, e.Message);
+ Console.WriteLine ("Error loading {0}. Exception {1}", file, e.Message);
}
}
}
diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am
index afebef2..27c9ae4 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -13,10 +13,14 @@ CSDISTFILES = \
$(srcdir)/Main/Game.cs \
$(srcdir)/Main/GameManager.cs \
$(srcdir)/Main/GameSession.cs \
+ $(srcdir)/Main/GameSessionHistory.cs \
+ $(srcdir)/Main/GameSessionHistoryExtended.cs \
$(srcdir)/Main/GameTips.cs \
- $(srcdir)/Main/Memory.cs \
+ $(srcdir)/Main/Memory.cs \
$(srcdir)/Main/PlayerHistory.cs \
+ $(srcdir)/Main/PlayerPersonalRecord.cs \
$(srcdir)/Main/Preferences.cs \
+ $(srcdir)/Main/Score.cs \
$(srcdir)/Main/UpdateUIStateEventArgs.cs \
$(srcdir)/Main/Verbal/Analogies.cs \
$(srcdir)/Main/Verbal/AnalogiesFactory.cs \
diff --git a/src/Core/Views/FinishView.cs b/src/Core/Views/FinishView.cs
index ef127b0..0a5a581 100644
--- a/src/Core/Views/FinishView.cs
+++ b/src/Core/Views/FinishView.cs
@@ -88,34 +88,34 @@ namespace gbrainy.Core.Views
gr.Stroke ();
x = x + space_x;
- DrawBar (gr, x, y + area_h, bar_w, bar_h, session.TotalScore);
+ DrawBar (gr, x, y + area_h, bar_w, bar_h, session.History.TotalScore);
gr.DrawTextCentered (x + bar_w / 2, y + area_h + 0.03, Catalog.GetString ("Total"));
x = x + space_x * 2;
- if (session.LogicScore >= 0)
- DrawBar (gr, x, y + area_h, bar_w, bar_h, session.LogicScore);
+ if (session.History.LogicPlayed > 0)
+ DrawBar (gr, x, y + area_h, bar_w, bar_h, session.History.LogicScore);
gr.DrawTextCentered (x + bar_w / 2, y + area_h + 0.03, Catalog.GetString ("Logic"));
x = x + space_x * 2;
- if (session.MathScore >= 0)
- DrawBar (gr, x, y + area_h, bar_w, bar_h, session.MathScore);
+ if (session.History.MathPlayed > 0)
+ DrawBar (gr, x, y + area_h, bar_w, bar_h, session.History.MathScore);
gr.DrawTextCentered (x + bar_w / 2, y + area_h + 0.03, Catalog.GetString ("Calculation"));
x = x + space_x * 2;
- if (session.MemoryScore >= 0)
- DrawBar (gr, x, y + area_h, bar_w, bar_h, session.MemoryScore);
+ if (session.History.MemoryPlayed > 0)
+ DrawBar (gr, x, y + area_h, bar_w, bar_h, session.History.MemoryScore);
gr.DrawTextCentered (x + bar_w / 2, y + area_h + 0.03, Catalog.GetString ("Memory"));
x = x + space_x * 2;
- if (session.VerbalScore >= 0)
- DrawBar (gr, x, y + area_h, bar_w, bar_h, session.VerbalScore);
+ if (session.History.VerbalPlayed > 0)
+ DrawBar (gr, x, y + area_h, bar_w, bar_h, session.History.VerbalScore);
gr.DrawTextCentered (x + bar_w / 2, y + area_h + 0.03, Catalog.GetString ("Verbal"));
}
@@ -124,7 +124,7 @@ namespace gbrainy.Core.Views
{
double y = 0.04, x = 0.05;
const double space_small = 0.02;
- List <PlayerHistory.PersonalRecord> records;
+ List <PlayerPersonalRecord> records;
string s, tip;
double width, height;
@@ -143,9 +143,9 @@ namespace gbrainy.Core.Views
s = session.Result;
if (s == string.Empty)
- gr.ShowPangoText (String.Format (Catalog.GetString ("Games won: {0} ({1} played)"), session.GamesWon, session.GamesPlayed));
+ gr.ShowPangoText (String.Format (Catalog.GetString ("Games won: {0} ({1} played)"), session.History.GamesWon, session.History.GamesPlayed));
else
- gr.ShowPangoText (String.Format (Catalog.GetString ("{0}. Games won: {1} ({2} played)"), s, session.GamesWon, session.GamesPlayed));
+ gr.ShowPangoText (String.Format (Catalog.GetString ("{0}. Games won: {1} ({2} played)"), s, session.History.GamesWon, session.History.GamesPlayed));
y += 0.06;
gr.MoveTo (x, y);
diff --git a/src/Core/Views/PlayerHistoryView.cs b/src/Core/Views/PlayerHistoryView.cs
index 61046ec..9882aa3 100644
--- a/src/Core/Views/PlayerHistoryView.cs
+++ b/src/Core/Views/PlayerHistoryView.cs
@@ -122,16 +122,16 @@ namespace gbrainy.Core.Views
if (ShowLogic) {
cr.Color = logic_color;
- cr.MoveTo (x, area_h - (area_h * history.Games[0].logic_score / 100));
+ cr.MoveTo (x, area_h - (area_h * history.Games[0].LogicScore / 100));
pos = 1;
for (int i = 1; i < history.Games.Count; i++)
{
- if (history.Games[i].logic_score < 0)
+ if (history.Games[i].LogicScore < 0)
continue;
px = x + (ratio * pos);
- py = y + area_h - (area_h * history.Games[i].logic_score / 100);
+ py = y + area_h - (area_h * history.Games[i].LogicScore / 100);
cr.LineTo (px, py);
pos++;
}
@@ -140,16 +140,16 @@ namespace gbrainy.Core.Views
if (ShowCalculation) {
cr.Color = math_color;
- cr.MoveTo (x, area_h - (area_h * history.Games[0].math_score / 100));
+ cr.MoveTo (x, area_h - (area_h * history.Games[0].MathScore / 100));
pos = 1;
for (int i = 1; i < history.Games.Count; i++)
{
- if (history.Games[i].math_score < 0)
+ if (history.Games[i].MathScore < 0)
continue;
px = x + (ratio * pos);
- py = y + area_h - (area_h * history.Games[i].math_score / 100);
+ py = y + area_h - (area_h * history.Games[i].MathScore / 100);
cr.LineTo (px, py);
pos++;
}
@@ -158,16 +158,16 @@ namespace gbrainy.Core.Views
if (ShowMemory) {
cr.Color = memory_color;
- cr.MoveTo (x, area_h - (area_h * history.Games[0].memory_score / 100));
+ cr.MoveTo (x, area_h - (area_h * history.Games[0].MemoryScore / 100));
pos = 1;
for (int i = 1; i < history.Games.Count; i++)
{
- if (history.Games[i].memory_score < 0)
+ if (history.Games[i].MemoryScore < 0)
continue;
px = x + (ratio * pos);
- py = y + area_h - (area_h * history.Games[i].memory_score / 100);
+ py = y + area_h - (area_h * history.Games[i].MemoryScore / 100);
cr.LineTo (px, py);
pos++;
}
@@ -176,16 +176,16 @@ namespace gbrainy.Core.Views
if (ShowVerbal) {
cr.Color = verbal_color;
- cr.MoveTo (x, area_h - (area_h * history.Games[0].verbal_score / 100));
+ cr.MoveTo (x, area_h - (area_h * history.Games[0].VerbalScore / 100));
pos = 1;
for (int i = 1; i < history.Games.Count; i++)
{
- if (history.Games[i].verbal_score < 0)
+ if (history.Games[i].VerbalScore < 0)
continue;
px = x + (ratio * i);
- py = y + area_h - (area_h * history.Games[i].verbal_score / 100);
+ py = y + area_h - (area_h * history.Games[i].VerbalScore / 100);
cr.LineTo (px, py);
pos++;
}
@@ -194,16 +194,16 @@ namespace gbrainy.Core.Views
if (ShowTotal) {
cr.Color = total_color;
- cr.MoveTo (x, area_h - (area_h * history.Games[0].total_score / 100));
+ cr.MoveTo (x, area_h - (area_h * history.Games[0].TotalScore / 100));
pos = 1;
for (int i = 1; i < history.Games.Count; i++)
{
- if (history.Games[pos].total_score < 0)
+ if (history.Games[pos].TotalScore < 0)
continue;
px = x + (ratio * pos);
- py = y + area_h - (area_h * history.Games[i].total_score / 100);
+ py = y + area_h - (area_h * history.Games[i].TotalScore / 100);
cr.LineTo (px, py);
pos++;
}
diff --git a/tests/Core/AnalogiesFactoryTest.cs b/tests/Core/AnalogiesFactoryTest.cs
new file mode 100644
index 0000000..b25cfa1
--- /dev/null
+++ b/tests/Core/AnalogiesFactoryTest.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using NUnit.Framework;
+
+using gbrainy.Core.Main.Verbal;
+
+namespace gbrainyTest
+{
+ [TestFixture]
+ public class AnalogiesFactoryTest
+ {
+ [TestFixtureSetUp]
+ public void Construct ()
+ {
+ AnalogiesFactory.Read ("test_analogies.xml");
+ }
+
+ [Test]
+ public void MultipleOptionsWithIngore ()
+ {
+ Dictionary <int, Analogy> analogies;
+
+ // Checks also the <ignore> parameter
+ analogies = AnalogiesFactory.Get (Analogy.Type.MultipleOptions);
+ Assert.AreEqual (2, analogies.Count);
+ }
+
+ [Test]
+ public void PairOfWordsOptions ()
+ {
+ Dictionary <int, Analogy> analogies;
+
+ analogies = AnalogiesFactory.Get (Analogy.Type.PairOfWordsOptions);
+ Assert.AreEqual (1, analogies.Count);
+ }
+
+ [Test]
+ public void QuestionAnswer ()
+ {
+ Dictionary <int, Analogy> analogies;
+
+ analogies = AnalogiesFactory.Get (Analogy.Type.QuestionAnswer);
+ Assert.AreEqual (1, analogies.Count);
+ }
+
+ [Test]
+ public void PairOfWordsCompare ()
+ {
+ Dictionary <int, Analogy> analogies;
+
+ analogies = AnalogiesFactory.Get (Analogy.Type.PairOfWordsCompare);
+ Assert.AreEqual (2, analogies.Count);
+ }
+ }
+}
diff --git a/tests/Core/PlayerHistoryTest.cs b/tests/Core/PlayerHistoryTest.cs
new file mode 100644
index 0000000..74856c7
--- /dev/null
+++ b/tests/Core/PlayerHistoryTest.cs
@@ -0,0 +1,75 @@
+/*
+ * 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;
+using NUnit.Framework;
+
+using gbrainy.Core.Main;
+
+namespace gbrainyTest
+{
+ [TestFixture]
+ public class PlayerHistoryTest
+ {
+ PlayerHistory history;
+
+ [TestFixtureSetUp]
+ public void Construct ()
+ {
+ // Ignore gbrainy instance preferences
+ Preferences.LoadDefaultValues ();
+ }
+
+ [Test]
+ public void Clean ()
+ {
+ GameSessionHistory game = new GameSessionHistory ();
+ game.GamesPlayed = Preferences.GetIntValue (Preferences.MinPlayedGamesKey);
+
+ history = new PlayerHistory ();
+ history.ConfigPath = ".";
+ history.Clean ();
+ history.SaveGameSession (game);
+
+ Assert.AreEqual (1, history.Games.Count);
+ history.Clean ();
+ Assert.AreEqual (0, history.Games.Count);
+ }
+
+ [Test]
+ public void SaveLoad ()
+ {
+ GameSessionHistory game = new GameSessionHistory ();
+ game.GamesPlayed = Preferences.GetIntValue (Preferences.MinPlayedGamesKey);
+ game.MemoryScore = 20;
+
+ history = new PlayerHistory ();
+ history.ConfigPath = ".";
+ history.SaveGameSession (game);
+
+ history = new PlayerHistory ();
+ history.ConfigPath = ".";
+ history.Load ();
+
+ Assert.AreEqual (1, history.Games.Count);
+ Assert.AreEqual (20, history.Games[0].MemoryScore);
+ }
+ }
+}
diff --git a/tests/Core/PlayerPersonalRecordTest.cs b/tests/Core/PlayerPersonalRecordTest.cs
new file mode 100644
index 0000000..2720d11
--- /dev/null
+++ b/tests/Core/PlayerPersonalRecordTest.cs
@@ -0,0 +1,76 @@
+/*
+ * 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;
+using NUnit.Framework;
+
+using gbrainy.Core.Main;
+
+namespace gbrainyTest
+{
+ [TestFixture]
+ public class PlayerPersonalRecordTest
+ {
+ PlayerHistory history;
+
+ [TestFixtureSetUp]
+ public void Construct ()
+ {
+ // Ignore gbrainy instance preferences
+ Preferences.LoadDefaultValues ();
+ }
+
+ [Test]
+ public void MinGamesRecord ()
+ {
+ PlayerHistory history;
+
+ GameSessionHistory game = new GameSessionHistory ();
+ game.GamesPlayed = Preferences.GetIntValue (Preferences.MinPlayedGamesKey);
+
+ history = new PlayerHistory ();
+ history.ConfigPath = ".";
+ history.Clean ();
+
+ for (int i = 0; i < PlayerPersonalRecord.MIN_GAMES_RECORD - 2; i++)
+ {
+ history.SaveGameSession (game);
+ }
+
+ game.LogicScore = 10;
+ history.SaveGameSession (game);
+
+ Assert.AreEqual (0, history.GetLastGameRecords ().Count,
+ "Did not reach MinPlayedGamesKey, the game should not be a person record yet");
+
+ game.LogicScore = 30;
+ history.SaveGameSession (game);
+
+ Assert.AreEqual (1, history.GetLastGameRecords ().Count,
+ "We have just recorded a personal record");
+
+ game.LogicScore = 20;
+ history.SaveGameSession (game);
+
+ Assert.AreEqual (0, history.GetLastGameRecords ().Count,
+ "Score saved was lower than previous, no record");
+ }
+ }
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..7d6bea7
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,36 @@
+TARGET = gbrainy.Core.Test.dll
+
+CSFLAGS = \
+ -debug \
+ -define:DEBUG \
+ -target:library
+
+CSFILES = \
+ $(srcdir)/Core/AnalogiesFactoryTest.cs \
+ $(srcdir)/Core/PlayerHistoryTest.cs \
+ $(srcdir)/Core/PlayerPersonalRecordTest.cs
+
+ASSEMBLIES = \
+ $(NUNIT_LIBS) \
+ $(MONO_ADDINS_LIBS) \
+ -pkg:gbrainy
+
+MONO_PATH = .:$(top_builddir)/src:
+
+RESSOURCES =
+
+$(TARGET): $(CSFILES) $(top_builddir)/src/gbrainy.exe
+ $(CSC) -out:$@ $(CSFLAGS) $(CSFILES) $(ASSEMBLIES) $(RESSOURCES)
+
+test: $(TARGET)
+ MONO_PATH=$(MONO_PATH) $(NUNIT) $(TARGET) -nologo
+
+EXTRA_DIST = \
+ $(CSFILES)
+
+CLEANFILES = \
+ $(TARGET) \
+ $(TARGET).mdb \
+ TestResult.xml
+
+.PHONY: test
diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..5b195fe
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,7 @@
+
+This is a collection of unit tests to verify that the key features of gbrainy
+behave as intended.
+
+To run the tests use:
+
+make rest
diff --git a/tests/test_analogies.xml b/tests/test_analogies.xml
new file mode 100644
index 0000000..86ace71
--- /dev/null
+++ b/tests/test_analogies.xml
@@ -0,0 +1,66 @@
+<analogies>
+ <!---
+ gbrainy Verbal Analogies test file
+ -->
+
+ <!--- Multiple options -->
+
+ <analogy>
+ <_question type = "MultipleOptions">Which of the following sports is the odd one?</_question>
+ <_tip>Think of the items used in the game.</_tip>
+ <_answer>Water polo</_answer>
+ <_answer>Basketball</_answer>
+ <_answer>Tennis</_answer>
+ <_answer correct = "yes">Cycling</_answer>
+ <_rationale>It is the only one that does not use a ball in the game.</_rationale>
+ </analogy>
+
+ <analogy>
+ <_question type = "MultipleOptions">The word 'taxidermist' is used to define a person that?</_question>
+ <_answer correct ="yes">Works with dead animals</_answer>
+ <_answer>Specializes in skin diseases</_answer>
+ <_answer>Suffers a skin disease</_answer>
+ <_answer>Works with leather</_answer>
+ </analogy>
+
+ <analogy>
+ <_question type = "MultipleOptions"><ignore></_question>
+ <_answer correct ="yes">simplistic</_answer>
+ <_answer>erroneous</_answer>
+ <_answer>broken</_answer>
+ <_answer>unorthodox</_answer>
+ </analogy>
+
+ <!--- Pair of words options -->
+
+ <analogy>
+ <_question type = "PairOfWordsOptions">moratorium / payment</_question>
+ <_answer correct ="yes">reprieve / punishment</_answer>
+ <_answer>amnesty / prisoner</_answer>
+ <_answer>date / meeting</_answer>
+ <_answer>sentence / prison</_answer>
+ </analogy>
+
+ <!--- Pair of words compare -->
+
+ <analogy>
+ <_question type = "PairOfWordsCompare">car / road | train</_question>
+ <_answer correct ="yes">track | railway</_answer>
+ </analogy>
+
+ <analogy>
+ <_question type = "PairOfWordsCompare">pediatrics / children | numismatics</_question>
+ <_answer correct ="yes">coins</_answer>
+ </analogy>
+
+ <!--- QuestionAnswer -->
+
+ <analogy>
+ <_question>A restaurant is to a dinner like a park is to?</_question>
+ <_answer correct ="yes">picnic</_answer>
+ </analogy>
+
+
+</analogies>
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]