r6058 - in trunk/data/qcsrc: common server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Mar 6 06:07:46 EST 2009


Author: div0
Date: 2009-03-06 06:07:43 -0500 (Fri, 06 Mar 2009)
New Revision: 6058

Modified:
   trunk/data/qcsrc/common/gamecommand.qc
   trunk/data/qcsrc/common/util.qc
   trunk/data/qcsrc/common/util.qh
   trunk/data/qcsrc/server/g_world.qc
Log:
better maplist shffle method


Modified: trunk/data/qcsrc/common/gamecommand.qc
===================================================================
--- trunk/data/qcsrc/common/gamecommand.qc	2009-03-06 10:57:01 UTC (rev 6057)
+++ trunk/data/qcsrc/common/gamecommand.qc	2009-03-06 11:07:43 UTC (rev 6058)
@@ -116,28 +116,12 @@
 		}
 		else if(argv(1) == "shuffle" && argc == 2)
 		{
-			// TODO make this work for huge lists
-			s = cvar_string("g_maplist");
-			for(i = 1; i < (n = tokenizebyseparator(s, " ")); ++i)
-			{
-				// swap i-th item at a random position from 0 to i
-				// proof for even distribution:
-				//   n = 1: obvious
-				//   n -> n+1:
-				//     item n+1 gets at any position with chance 1/(n+1)
-				//     all others will get their 1/n chance reduced by factor n/(n+1)
-				//     to be on place n+1, their chance will be 1/(n+1)
-				//     1/n * n/(n+1) = 1/(n+1)
-				//     q.e.d.
-				f = floor(random() * (i + 1)); // 0 to i
-				if(f == i)
-					continue; // no change
-
-				s2 = "";
-				for(j = 0; j < n; ++j)
-					s2 = strcat(s2, " ", argv((j == i) ? f : (j == f) ? i : j));
-				s = substring(s2, 1, strlen(s2) - 1);
-			}
+			n = tokenizebyseparator(cvar_string("g_maplist"), " ");
+			shufflearray_build(n); 
+			s2 = "";
+			for(i = 0; i < n; ++i)
+				s2 = strcat(s2, " ", argv(shufflearray[i]));
+			s = substring(s2, 1, strlen(s2) - 1);
 			cvar_set("g_maplist", s);
 			return TRUE;
 		}

Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc	2009-03-06 10:57:01 UTC (rev 6057)
+++ trunk/data/qcsrc/common/util.qc	2009-03-06 11:07:43 UTC (rev 6058)
@@ -1498,3 +1498,43 @@
 	}
 	return 1;
 }
+
+void shuffle(float n, shuffle_swapfunc_t swap)
+{
+	float i, j;
+	for(i = 1; i < n; ++i)
+	{
+		// swap i-th item at a random position from 0 to i
+		// proof for even distribution:
+		//   n = 1: obvious
+		//   n -> n+1:
+		//     item n+1 gets at any position with chance 1/(n+1)
+		//     all others will get their 1/n chance reduced by factor n/(n+1)
+		//     to be on place n+1, their chance will be 1/(n+1)
+		//     1/n * n/(n+1) = 1/(n+1)
+		//     q.e.d.
+		j = floor(random() * (i + 1));
+		if(j != i)
+			swap(i, j);
+	}
+}
+
+void shufflearray_init(float n)
+{
+	float i;
+	for(i = 0; i < n; ++i)
+		shufflearray[i] = i;
+}
+void shufflearray_swap(float i, float j)
+{
+	float h;
+	h = shufflearray[i];
+	shufflearray[i] = shufflearray[j];
+	shufflearray[j] = h;
+}
+
+void shufflearray_build(float n)
+{
+	shufflearray_init(n);
+	shuffle(n, shufflearray_swap);
+}

Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh	2009-03-06 10:57:01 UTC (rev 6057)
+++ trunk/data/qcsrc/common/util.qh	2009-03-06 11:07:43 UTC (rev 6058)
@@ -152,3 +152,9 @@
 string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw);
 
 float isGametypeInFilter(float gt, float tp, string pattern);
+
+typedef void(float i1, float i2) shuffle_swapfunc_t;
+void shuffle(float n, shuffle_swapfunc_t swap);
+
+float shufflearray[1024];
+void shufflearray_build(float n);

Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc	2009-03-06 10:57:01 UTC (rev 6057)
+++ trunk/data/qcsrc/server/g_world.qc	2009-03-06 11:07:43 UTC (rev 6058)
@@ -1625,37 +1625,16 @@
 
 void ShuffleMaplist()
 {
-	string result;
-	float start;
-	float litems;
-	float selected;
-	float i;
+	float n, i;
+	string s, s2;
 
-	result = cvar_string("g_maplist");
-	litems = tokenizebyseparator(result, " ");
-
-	for(start = 0; start < litems - 1; ++start)
-	{
-		result = "";
-
-		// select a random item
-		selected = floor(random() * (litems - start) + start);
-
-		// shift this item to the place start
-		for(i = 0; i < start; ++i)
-			result = strcat(result, " ", argv(i));
-		result = strcat(result, " ", argv(selected));
-		for(i = start; i < litems; ++i)
-			if(i != selected)
-				result = strcat(result, " ", argv(i));
-		result = substring(result, 1, strlen(result) - 1);
-
-		litems = tokenizebyseparator(result, " ");
-
-		//dprint(result, "\n");
-	}
-
-	cvar_set("g_maplist", result);
+	n = tokenizebyseparator(cvar_string("g_maplist"), " ");
+	shufflearray_build(n); 
+	s2 = "";
+	for(i = 0; i < n; ++i)
+		s2 = strcat(s2, " ", argv(shufflearray[i]));
+	s = substring(s2, 1, strlen(s2) - 1);
+	cvar_set("g_maplist", s);
 }
 
 float leaderfrags;




More information about the nexuiz-commits mailing list