Index: cpp/frams/genetics/genman.cpp
===================================================================
--- cpp/frams/genetics/genman.cpp	(revision 760)
+++ cpp/frams/genetics/genman.cpp	(revision 761)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -10,4 +10,10 @@
 #include "common/stl-util.h"
 #include <common/loggers/loggers.h>
+
+
+#define GENMAN_REPEAT_FAILED 10 //how many times GenMan tries to repeat a mutation or crossover when the operator does not return acceptable genotype
+#define STRINGIFY_1(x) #x
+#define STRINGIFY(x) STRINGIFY_1(x) //this second-level macro allows the parameter to be a macro itself and to stringify its value, not its name
+#define GENMAN_REPEAT_FAILED_STR STRINGIFY(GENMAN_REPEAT_FAILED)
 
 
@@ -164,7 +170,7 @@
 			if (oper_fx_list[i]->supported_format == oper_fx_list[j]->supported_format)
 			{
-				type += "~";
-				type += oper_fx_list[j]->name;
-				dup++;
+			type += "~";
+			type += oper_fx_list[j]->name;
+			dup++;
 			}
 		type = ssprintf("d 0 %d ", dup) + type;
@@ -206,14 +212,14 @@
 int GenMan::testValidity(Geno &g, bool &canvalidate)
 {
-	SString ggs=g.getGenes();
+	SString ggs = g.getGenes();
 	const char *gg = ggs.c_str();
 	GenoOperators *gf = getOper_f(g.getFormat());
 	int check1;
 	if (!gf) { canvalidate = false; return GENOPER_NOOPER; }
-	else check1 = gf->checkValidity(gg,g.getName().c_str());
+	else check1 = gf->checkValidity(gg, g.getName().c_str());
 	if (!canvalidate) return check1; //just checking
 	if (check1 == GENOPER_OK) { canvalidate = false; return check1; }
 	char *g2 = strdup(gg);
-	if (gf->validate(g2,g.getName().c_str()) == GENOPER_NOOPER) { free(g2); canvalidate = false; return check1; }
+	if (gf->validate(g2, g.getName().c_str()) == GENOPER_NOOPER) { free(g2); canvalidate = false; return check1; }
 	if (check1 == GENOPER_NOOPER) //disaster: cannot check because there is no check operator
 	{
@@ -283,5 +289,5 @@
 				if (res > 0 && canvalidate == false) invalid_m++; else
 				{
-					validated_m++; ok = true;
+				validated_m++; ok = true;
 				}
 			if (ok) gv = G;
@@ -290,8 +296,8 @@
 		free(gn);
 		count++;
-		if (!ok && (count - pcount > 100))
-		{
-			logPrintf("GenMan", "Mutate", 2, "Tried 100x and failed: %s", g.getGenes().c_str());
-			return Geno("", -1, "", "GENOPER_OPFAIL: Mutate() tried 100x and failed");
+		if (!ok && (count - pcount > GENMAN_REPEAT_FAILED))
+		{
+			logPrintf("GenMan", "Mutate", 2, "Tried " GENMAN_REPEAT_FAILED_STR "x and failed: %s", g.getGenes().c_str());
+			return Geno("", -1, "", "GENOPER_OPFAIL: Mutate() tried " GENMAN_REPEAT_FAILED_STR "x and failed");
 		}
 	}
@@ -349,5 +355,5 @@
 				if (res > 0 && canvalidate == false) invalid_xo++; else
 				{
-					validated_xo++; ok = true;
+				validated_xo++; ok = true;
 				}
 			if (ok) g1v = G;
@@ -357,8 +363,8 @@
 		free(g2n);
 		count++;
-		if (!ok && (count - pcount > 100))
-		{
-			logPrintf("GenMan", "CrossOver", 2, "Tried 100x and failed: %s and %s", g1.getGenes().c_str(), g2.getGenes().c_str());
-			return Geno("", -1, "", "GENOPER_OPFAIL: CrossOver() tried 100x and failed");
+		if (!ok && (count - pcount > GENMAN_REPEAT_FAILED))
+		{
+			logPrintf("GenMan", "CrossOver", 2, "Tried " GENMAN_REPEAT_FAILED_STR "x and failed: %s and %s", g1.getGenes().c_str(), g2.getGenes().c_str());
+			return Geno("", -1, "", "GENOPER_OPFAIL: CrossOver() tried " GENMAN_REPEAT_FAILED_STR "x and failed");
 		}
 	}
@@ -407,5 +413,5 @@
 	}
 	GenoOperators *gf = getOper_f(format);
-	SString geny=G->getGenes();
+	SString geny = G->getGenes();
 	for (unsigned int pos = 0; pos < strlen(g); pos++)
 	{
@@ -438,7 +444,7 @@
 	string html = "\n<div style=\"background:white;padding:0.2em;font-family:arial,helvetica,sans-serif;font-size:90%\">";
 	uint32_t prevstyle, prevcolor, style = 0, color = 0;
-	for (int i = 0; i<len; i++)
-	{
-		if (shorten && ((lines == 0 && chars>160) || (lines > 5 || chars > 300))) { shortened = true; break; }
+	for (int i = 0; i < len; i++)
+	{
+		if (shorten && ((lines == 0 && chars > 160) || (lines > 5 || chars > 300))) { shortened = true; break; }
 		if (g[i] == '\r') continue;
 		if (g[i] == '\n') { html += "<br>\n"; lines++; continue; }
@@ -566,10 +572,10 @@
 	{
 		string l;
-		if (oper_fx_list[i]->checkValidity("","") != GENOPER_NOOPER) l += " checkValidity";
+		if (oper_fx_list[i]->checkValidity("", "") != GENOPER_NOOPER) l += " checkValidity";
 		if (oper_fx_list[i]->getSimplest())
 		{
 			g = strdup(oper_fx_list[i]->getSimplest());
 			g2 = strdup(g);
-			if (oper_fx_list[i]->validate(g,"") != GENOPER_NOOPER) l += " validate";
+			if (oper_fx_list[i]->validate(g, "") != GENOPER_NOOPER) l += " validate";
 			if (oper_fx_list[i]->mutate(g, f1, m) != GENOPER_NOOPER) l += " mutate";
 			if (oper_fx_list[i]->crossOver(g, g2, f1, f2) != GENOPER_NOOPER) l += " crossover";
