Bug 123358

Summary: More intelligent quiz design
Product: [Applications] kgeography Reporter: Sam <handsclark>
Component: generalAssignee: Albert Astals Cid <aacid>
Status: RESOLVED FIXED    
Severity: wishlist    
Priority: NOR    
Version: 0.4   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In:

Description Sam 2006-03-09 23:32:18 UTC
Version:           0.4 (using KDE KDE 3.5.1)
Installed from:    SuSE RPMs

I was looking at your nice work with KGeography, and I had a thought about a possible improvement.

As I took some of the quizzes, I realized that even though I was able to get all of the answers correct for the USA map, I probably wouldn't have if there had been some options other than just cities that were state capitols.  Many of the state capitols are far from being the largest city.  So, it would be more difficult if some non-capitol cities were also included.

Example:
The capitol of Nevada is Carson City.  However, there are two large and well known cities in Nevada (Reno and Las Vegas) that could be used to try and throw a person off track if they don't really know the capitol.

As it is, getting all of the answers correct is fairly simple even if you just know most of the answers.  I would feel more confident that getting all of the answers correct meant something if it were a bit trickier to do so.

It is fairly obvious that the answers for the quiz are simply pulled from the correct answers to other possible questions.  It could be good to have a list of other cities within a state/region/country that could be used for possible answers.
Comment 1 Laurent G. 2006-07-21 21:42:33 UTC
It would be more fun, I fully agree.
That it would be "more intelligent design" is more subject to controversy,
as you find this software in edu part, not in games or fun part of kde.
May be this is an excuse to try and see if a plug-in architecture %-) has a sense for kgeography as it seems to be backed by many supporters...
Comment 2 Albert Astals Cid 2006-12-28 23:57:14 UTC
SVN commit 617383 by aacid:

Add the possibility of adding false capitals for a given division instead of pulling capitals from other divisions on the map, this can make it more interesting for divisions where the capital is a small city compared to others in falseCapital tags.
Now only need people to come and use the falseCapital tag all around on the existing maps :-D
FEATURE: 123358


 M  +14 -9     boxasker.cpp  
 M  +13 -2     division.cpp  
 M  +5 -2      division.h  
 M  +15 -0     divisioncapitalasker.cpp  
 M  +5 -0      map.cpp  
 M  +1 -0      map.h  
 M  +11 -0     mapparser.cpp  


--- trunk/KDE/kdeedu/kgeography/src/boxasker.cpp #617382:617383
@@ -64,24 +64,29 @@
 	
 	for(int i = 0; i < 4; i++) p_rb[i] -> setAutoExclusive(false);
 	for(int i = 0; i < 4; i++) p_rb[i] -> setChecked(false);
+	for(int i = 0; i < 4; i++) p_rb[i] -> setText(QString());
 	for(int i = 0; i < 4; i++) p_rb[i] -> setAutoExclusive(true);
 	
+	
 	auxList << division;
-		
+	
 	// we put the division in a random place
 	p_position = (int)((float)4 * KRandom::random() / (RAND_MAX + 1.0));
 	nextBoxAskerQuestionHook(division, p_position, true);
-		
-	// we put other 3 names
+	
+	// fill the other names
 	i = 0;
 	while (i < 4)
 	{
-		// false because boxaskers never are clickOnDivision
-		otherDivision = p_map -> getRandomDivision(false);
-		while (auxList.indexOf(otherDivision) != -1) otherDivision = p_map -> getRandomDivision(false);
-		if (i == p_position) i++;
-		if (i < 4 && nextBoxAskerQuestionHook(otherDivision, i, false)) i++;
-		auxList << otherDivision;
+		if (p_rb[i] -> text().isNull())
+		{
+			// false because boxaskers never are clickOnDivision
+			otherDivision = p_map -> getRandomDivision(false);
+			while (auxList.contains(otherDivision)) otherDivision = p_map -> getRandomDivision(false);
+			if (nextBoxAskerQuestionHook(otherDivision, i, false)) i++;
+			auxList << otherDivision;
+		}
+		else ++i;
 	}
 }
 
--- trunk/KDE/kdeedu/kgeography/src/division.cpp #617382:617383
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2004 by Albert Astals Cid                               *
- *   tsdgeos@terra.es                                                      *
+ *   Copyright (C) 2004-2006 by Albert Astals Cid                          *
+ *   aacid@kde.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  *
@@ -46,11 +46,22 @@
 	return p_capital;
 }
 
+QStringList division::getFalseCapitals() const
+{
+	return p_falseCapitals;
+}
+
 void division::setCapital(const QString &name)
 {
 	p_capital = name;
 }
 
+void division::setFalseCapitals(const QStringList &falseCapitals)
+{
+	p_falseCapitals = falseCapitals;
+}
+
+
 void division::setIgnore(bool ignore, bool canAskClickDivision)
 {
 	if (ignore)
--- trunk/KDE/kdeedu/kgeography/src/division.h #617382:617383
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2004 by Albert Astals Cid                               *
- *   tsdgeos@terra.es                                                      *
+ *   Copyright (C) 2004-2006 by Albert Astals Cid                          *
+ *   aacid@kde.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  *
@@ -24,8 +24,10 @@
 		QRgb getRGB() const;
 		QString getFlagFile() const;
 		QString getCapital() const;
+		QStringList getFalseCapitals() const;
 		
 		void setCapital(const QString &name);
+		void setFalseCapitals(const QStringList &falseCapitals);
 		void setIgnore(bool ignore, bool canAskClickDivision);
 		void setName(const QString &name);
 		void setRGB(int r, int g, int b);
@@ -33,6 +35,7 @@
 		
 	private:
 		QString p_name, p_flagFile, p_capital;
+		QStringList p_falseCapitals;
 		QRgb p_color;
 		bool p_canAskAlways, p_canAskClickDivision;
 };
--- trunk/KDE/kdeedu/kgeography/src/divisioncapitalasker.cpp #617382:617383
@@ -9,6 +9,7 @@
  ***************************************************************************/
 
 #include <klocale.h>
+#include <krandom.h>
 
 #include <qradiobutton.h>
  
@@ -41,6 +42,20 @@
 		p_currentAnswer.setCorrectAnswer(i18nc(p_map -> getFileName().toUtf8(), p_capital.toUtf8()));
 		p_rb[i] -> setText(i18nc(p_map -> getFileName().toUtf8(), p_capital.toUtf8()));
 		b = true;
+		
+		QStringList falseCapitals = p_map -> getDivisionFalseCapitals(division);
+		int index = 0;
+		while (!falseCapitals.isEmpty() && index < 4)
+		{
+			if (index != i)
+			{
+				int random = (int)((float)falseCapitals.size() * KRandom::random() / (RAND_MAX + 1.0));
+				QString falseCapital = falseCapitals.at(random);
+				falseCapitals.removeAt(random);
+				p_rb[index] -> setText(i18nc(p_map -> getFileName().toUtf8(), falseCapital.toUtf8()));
+			}
+			++index;
+		}
 	}
 	else
 	{
--- trunk/KDE/kdeedu/kgeography/src/map.cpp #617382:617383
@@ -89,6 +89,11 @@
 	return getDivision(s) -> getCapital();
 }
 
+QStringList KGmap::getDivisionFalseCapitals(const QString &divisionName) const
+{
+	return getDivision(divisionName) -> getFalseCapitals();
+}
+
 QString KGmap::getFile() const
 {
 	return p_file;
--- trunk/KDE/kdeedu/kgeography/src/map.h #617382:617383
@@ -34,6 +34,7 @@
 		bool hasAllFlags() const;
 		QString getDivisionFlagFile(const QString &divisionName) const;
 		QString getDivisionCapital(const QString &divisionName) const;
+		QStringList getDivisionFalseCapitals(const QString &divisionName) const;
 		QString getFile() const;
 		QString getFileName() const;
 		QString getMapFile() const;
--- trunk/KDE/kdeedu/kgeography/src/mapparser.cpp #617382:617383
@@ -95,6 +95,17 @@
 					                getElementString("green", colorTag, Mandatory).toInt(),
 					                getElementString("blue", colorTag, Mandatory).toInt());
 					
+					// division false capitals
+					QStringList falseCapitals;
+					const QDomNodeList &falseCapitalTags = divisionTag.elementsByTagName("falseCapital");
+					QDomElement falseCapital;
+					for (int i = 0; i < falseCapitalTags.count(); ++i)
+					{
+						falseCapital = falseCapitalTags.item(i).toElement();
+						if (!falseCapital.isNull()) falseCapitals << falseCapital.text();
+					}
+					if (!falseCapitals.isEmpty()) kgdiv->setFalseCapitals(falseCapitals);
+					
 					if (!kgmap -> addDivision(kgdiv))
 					{
 						p_error = i18n("There is already either a division called %1 or a division with the same colors as %2", kgdiv -> getName(), kgdiv -> getName());