[gbrainy] Avoid sequences that are valid with other logics at PuzzleNumericRelation



commit 4d5c4643cc9122bf863faaa9a3ad40a98be03d0a
Author: Jordi Mas <jmas softcatala org>
Date:   Tue Nov 9 08:57:03 2010 +0100

    Avoid sequences that are valid with other logics at PuzzleNumericRelation

 src/Games/Logic/PuzzleNumericRelation.cs       |  124 ++++++++++++++++++-----
 tests/Games/Logic/PuzzleNumericRelationTest.cs |   55 +++++++++++
 tests/Makefile.am                              |   14 ++-
 3 files changed, 163 insertions(+), 30 deletions(-)
---
diff --git a/src/Games/Logic/PuzzleNumericRelation.cs b/src/Games/Logic/PuzzleNumericRelation.cs
index 5ad20eb..cc02e08 100644
--- a/src/Games/Logic/PuzzleNumericRelation.cs
+++ b/src/Games/Logic/PuzzleNumericRelation.cs
@@ -31,9 +31,17 @@ namespace gbrainy.Games.Logic
 		private int sum_value;
 		private int question;
 		private int[] numbers;
-		private int formula;
+		private Formula formula;
 		private const int max_num = 9;
 
+		public enum Formula
+		{
+			AllAdding,
+			ThirdMultiply,
+			ThirdSubstracting,
+			Length
+		};
+
 		public override string Name {
 			get {return Catalog.GetString ("Numeric relation");}
 		}
@@ -49,21 +57,22 @@ namespace gbrainy.Games.Logic
 		public override string Rationale {
 			get {
 				switch (formula) {
-				case 0:
+				case Formula.AllAdding:
 					return String.Format (Catalog.GetString ("Every group of {0} numbers sums exactly {1}."), group_size, sum_value);
-				case 1:
+				case Formula.ThirdMultiply:
 					return Catalog.GetString ("Divide the sequence in groups of three numbers. Every third number is calculated by multiplying by the two previous ones.");
-				case 2:
+				case Formula.ThirdSubstracting:
 					return Catalog.GetString ("Divide the sequence in groups of three numbers. Every third number is calculated by subtracting the second number from the first.");
 				default:
-					return String.Empty;
+					throw new InvalidOperationException ("Invalid Value");
 				}
 			}
 		}
 
 		protected override void Initialize ()
 		{
-			int group = 0, inc = 0;
+			bool validate = false;
+			int group = 0, inc;
 
 			if (CurrentDifficulty == GameDifficulty.Easy) {
 				sum_value = 10 + random.Next (10);
@@ -74,34 +83,37 @@ namespace gbrainy.Games.Logic
 				inc = 12;
 			}
 
-			question = 1 + random.Next (max_num - 2);
-			formula = random.Next (3);
-			numbers =  new int [max_num];
+			while (validate == false)
+			{
+				question = 1 + random.Next (max_num - 2);
+				formula = (Formula) random.Next ((int) Formula.Length);
+				numbers =  new int [max_num];
 		
-			for (int i = 0; i < max_num; i++) {
-				if (group == group_size - 1) {	
-					switch (formula) {
-					case 0:
-						numbers[i] = sum_value - numbers[i - 1] - numbers[i - 2];
-						break;
-					case 1:
-						numbers[i] = numbers[i - 1] * numbers[i - 2];
-						break;
-					case 2:
-						numbers[i] = numbers[i - 2] - numbers[i - 1];
-						break;
+				for (int i = 0; i < max_num; i++) {
+					if (group == group_size - 1) {	
+						switch (formula) {
+						case Formula.AllAdding:
+							numbers[i] = sum_value - numbers[i - 1] - numbers[i - 2];
+							break;
+						case Formula.ThirdMultiply:
+							numbers[i] = numbers[i - 1] * numbers[i - 2];
+							break;
+						case Formula.ThirdSubstracting:
+							numbers[i] = numbers[i - 2] - numbers[i - 1];
+							break;
+						}
+						group = 0;
+						continue;
 					}
-					group = 0;
-					continue;
+					numbers[i] = 1 + random.Next (inc);
+					group++;
 				}
-				numbers[i] = 1 + random.Next (inc);
-				group++;
-			}
 
+				validate = Validate (numbers, formula, question);
+			}
 			right_answer = numbers[question].ToString ();
 		}
 
-
 		public override void Draw (CairoContextEx gr, int area_width, int area_height, bool rtl)
 		{
 			StringBuilder sequence = new StringBuilder (64);
@@ -122,5 +134,63 @@ namespace gbrainy.Games.Logic
 			sequence.Append (numbers[max_num - 1]);
 			gr.DrawTextCentered (0.5, DrawAreaY + 0.3, sequence.ToString ());
 		}
+
+		/*
+			The objective of this validation is to make sure that the sequence
+			presented is not also a valid sequence using other logic criteria
+		*/	
+		public static bool Validate (int[] numbers, Formula formula, int question)
+		{
+			switch (formula) {
+			case Formula.AllAdding:
+				break;
+			case Formula.ThirdMultiply:
+				break;
+			case Formula.ThirdSubstracting:
+				return ValidateAddinginGroupsOfTree (numbers, question);
+			}
+
+			return true;
+		}
+
+		static int SumGroup (int[] numbers, int start, int len)
+		{
+			int sum = 0;
+		
+			for (int n = start; n < len + start; n++)
+				sum += numbers[n];
+
+			return sum;
+		}
+
+		// Taken the sequence (a b c) (d ? f) (g h i)
+		// If a + b + c = g + h = i you can calculate a replament for ? that makes then add too
+		static bool ValidateAddinginGroupsOfTree (int[] numbers, int question)
+		{
+			int group_f1, group_f2, group_q;			
+
+			group_q = question / group_size;
+			switch (group_q) {
+			case 0:
+				group_f1 = 1;
+				group_f2 = 2;
+				break;
+			case 1:
+				group_f1 = 0;
+				group_f2 = 2;
+				break;
+			case 2:
+				group_f1 = 0;
+				group_f2 = 1;
+				break;
+			default:
+				throw new InvalidOperationException ("group_q");
+			}
+
+			if (SumGroup (numbers, group_f1 * group_size, group_size) != SumGroup (numbers, group_f2 * group_size, group_size))
+				return true;
+
+			return false;
+		}
 	}
 }
diff --git a/tests/Games/Logic/PuzzleNumericRelationTest.cs b/tests/Games/Logic/PuzzleNumericRelationTest.cs
new file mode 100644
index 0000000..ced864c
--- /dev/null
+++ b/tests/Games/Logic/PuzzleNumericRelationTest.cs
@@ -0,0 +1,55 @@
+/*
+ * 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 NUnit.Framework;
+
+using gbrainy.Games.Logic;
+
+namespace gbrainyTest.Games.Logic
+{
+	[TestFixture]
+	public class PuzzleNumericRelationTest
+	{
+		[TestFixtureSetUp]
+		public void Construct ()
+		{
+
+		}
+
+		[Test]
+		public void ValidateThirdSubstracting ()
+		{
+			int [] sequence;
+			bool validates;
+
+			// Invalid Formula.ThirdSubstracting sequence
+			// since it validates 7 + 10 = -3 but (ThirdSubstracting) also 7 + 10 -3 = 7 + 2 + 5 (adding the numbers)
+			sequence = new [] {7, 10, -3, 6, 8, -2, 7, 2, 5};
+			validates = PuzzleNumericRelation.Validate (sequence, PuzzleNumericRelation.Formula.ThirdSubstracting, 5);
+			Assert.AreEqual (false, validates);
+
+			// Valid Formula.ThirdSubstracting sequence
+			sequence = new [] {7, 10, -3, 6, 8, -2, 7, 2, 6};
+			validates = PuzzleNumericRelation.Validate (sequence, PuzzleNumericRelation.Formula.ThirdSubstracting, 5);
+			Assert.AreEqual (true, validates);
+		}
+	}
+}
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 988df11..d08c63b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,5 +1,6 @@
 CORE = gbrainy.Core.Test.dll
-CLASSICAL = gbrainy.Test.dll
+CLASSICAL = gbrainy.ClassicalClient.Test.dll
+GAMES = gbrainy.Games.Test.dll
 
 CSFLAGS =				\
 	-debug				\
@@ -18,6 +19,9 @@ CSFILES_CORE =					\
 CSFILES_CLASSICAL =					\
 	$(srcdir)/Clients/Classical/CommandLineTest.cs
 
+CSFILES_GAMES =						\
+	$(srcdir)/Games/Logic/PuzzleNumericRelationTest.cs
+
 if ENABLE_TESTS
 
 ASSEMBLIES = \
@@ -36,11 +40,15 @@ $(CORE): $(CSFILES_CORE) $(top_builddir)/src/gbrainy.exe
 $(CLASSICAL): $(CSFILES_CLASSICAL) $(top_builddir)/src/gbrainy.exe
 	$(CSC) -out:$@ $(CSFLAGS) $(CSFILES_CLASSICAL) $(ASSEMBLIES) $(RESSOURCES)
 
-all: $(CORE) $(CLASSICAL)
+$(GAMES): $(CSFILES_GAMES) $(top_builddir)/src/gbrainy.exe
+	$(CSC) -out:$@ $(CSFLAGS) $(CSFILES_GAMES) $(ASSEMBLIES) -r:../src/gbrainy.Games.dll $(RESSOURCES)
+
+all: $(CORE) $(CLASSICAL) $(GAMES)
 
-run: $(CORE) $(CLASSICAL)
+run: $(CORE) $(CLASSICAL)  $(GAMES)
 	MONO_PATH=$(MONO_PATH) $(NUNIT) $(CLASSICAL) -nologo
 	MONO_PATH=$(MONO_PATH) $(NUNIT) $(CORE) -nologo
+	MONO_PATH=$(MONO_PATH) $(NUNIT) $(GAMES) -nologo
 
 endif
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]