558 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			558 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * Set random/camera stuff
 | 
						|
 *
 | 
						|
 *
 | 
						|
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
						|
 *
 | 
						|
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
						|
 *
 | 
						|
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * The Original Code is: all of this file.
 | 
						|
 *
 | 
						|
 * Contributor(s): none yet.
 | 
						|
 *
 | 
						|
 * ***** END GPL LICENSE BLOCK *****
 | 
						|
 */
 | 
						|
 | 
						|
/** \file gameengine/GameLogic/SCA_RandomActuator.cpp
 | 
						|
 *  \ingroup gamelogic
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
#include <stddef.h>
 | 
						|
 | 
						|
#include "BoolValue.h"
 | 
						|
#include "IntValue.h"
 | 
						|
#include "FloatValue.h"
 | 
						|
#include "SCA_IActuator.h"
 | 
						|
#include "SCA_RandomActuator.h"
 | 
						|
#include "math.h"
 | 
						|
#include "MT_Transform.h"
 | 
						|
 | 
						|
/* ------------------------------------------------------------------------- */
 | 
						|
/* Native functions                                                          */
 | 
						|
/* ------------------------------------------------------------------------- */
 | 
						|
 | 
						|
SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj, 
 | 
						|
									 long seed,
 | 
						|
									 SCA_RandomActuator::KX_RANDOMACT_MODE mode,
 | 
						|
									 float para1,
 | 
						|
									 float para2,
 | 
						|
									 const STR_String &propName)
 | 
						|
	: SCA_IActuator(gameobj, KX_ACT_RANDOM),
 | 
						|
	  m_propname(propName),
 | 
						|
	  m_parameter1(para1),
 | 
						|
	  m_parameter2(para2),
 | 
						|
	  m_distribution(mode)
 | 
						|
{
 | 
						|
	m_base = new SCA_RandomNumberGenerator(seed);
 | 
						|
	m_counter = 0;
 | 
						|
	enforceConstraints();
 | 
						|
} 
 | 
						|
 | 
						|
 | 
						|
 | 
						|
SCA_RandomActuator::~SCA_RandomActuator()
 | 
						|
{
 | 
						|
	m_base->Release();
 | 
						|
} 
 | 
						|
 | 
						|
 | 
						|
 | 
						|
CValue* SCA_RandomActuator::GetReplica()
 | 
						|
{
 | 
						|
	SCA_RandomActuator* replica = new SCA_RandomActuator(*this);
 | 
						|
	// replication just copy the m_base pointer => common random generator
 | 
						|
	replica->ProcessReplica();
 | 
						|
	return replica;
 | 
						|
}
 | 
						|
 | 
						|
void SCA_RandomActuator::ProcessReplica()
 | 
						|
{
 | 
						|
	SCA_IActuator::ProcessReplica();
 | 
						|
	// increment reference count so that we can release the generator at the end
 | 
						|
	m_base->AddRef();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
bool SCA_RandomActuator::Update()
 | 
						|
{
 | 
						|
	//bool result = false;	/*unused*/
 | 
						|
	bool bNegativeEvent = IsNegativeEvent();
 | 
						|
 | 
						|
	RemoveAllEvents();
 | 
						|
 | 
						|
 | 
						|
	CValue *tmpval = NULL;
 | 
						|
 | 
						|
	if (bNegativeEvent)
 | 
						|
		return false; // do nothing on negative events
 | 
						|
 | 
						|
	switch (m_distribution) {
 | 
						|
	case KX_RANDOMACT_BOOL_CONST: {
 | 
						|
		/* un petit peu filthy */
 | 
						|
		bool res = !(m_parameter1 < 0.5);
 | 
						|
		tmpval = new CBoolValue(res);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_BOOL_UNIFORM: {
 | 
						|
		/* flip a coin */
 | 
						|
		bool res; 
 | 
						|
		if (m_counter > 31) {
 | 
						|
			m_previous = m_base->Draw();
 | 
						|
			res = ((m_previous & 0x1) == 0);
 | 
						|
			m_counter = 1;
 | 
						|
		} else {
 | 
						|
			res = (((m_previous >> m_counter) & 0x1) == 0);
 | 
						|
			m_counter++;
 | 
						|
		}
 | 
						|
		tmpval = new CBoolValue(res);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_BOOL_BERNOUILLI: {
 | 
						|
		/* 'percentage' */
 | 
						|
		bool res;
 | 
						|
		res = (m_base->DrawFloat() < m_parameter1);
 | 
						|
		tmpval = new CBoolValue(res);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_INT_CONST: {
 | 
						|
		/* constant */
 | 
						|
		tmpval = new CIntValue((int) floor(m_parameter1));
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_INT_UNIFORM: {
 | 
						|
		/* uniform (toss a die) */
 | 
						|
		int res; 
 | 
						|
		/* The [0, 1] interval is projected onto the [min, max+1] domain,    */
 | 
						|
		/* and then rounded.                                                 */
 | 
						|
		res = (int) floor( ((m_parameter2 - m_parameter1 + 1) * m_base->DrawFloat())
 | 
						|
						   + m_parameter1);
 | 
						|
		tmpval = new CIntValue(res);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_INT_POISSON: {
 | 
						|
		/* poisson (queues) */
 | 
						|
		/* If x_1, x_2, ... is a sequence of random numbers with uniform     */
 | 
						|
		/* distribution between zero and one, k is the first integer for     */
 | 
						|
		/* which the product x_1*x_2*...*x_k < exp(-\lamba).                 */
 | 
						|
		float a, b;
 | 
						|
		int res = 0;
 | 
						|
		/* The - sign is important here! The number to test for, a, must be  */
 | 
						|
		/* between 0 and 1.                                                  */
 | 
						|
		a = exp(-m_parameter1);
 | 
						|
		/* a quickly reaches 0.... so we guard explicitly for that.          */
 | 
						|
		if (a < FLT_MIN) a = FLT_MIN;
 | 
						|
		b = m_base->DrawFloat();
 | 
						|
		while (b >= a) {
 | 
						|
			b = b * m_base->DrawFloat();
 | 
						|
			res++;
 | 
						|
		};	
 | 
						|
		tmpval = new CIntValue(res);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_FLOAT_CONST: {
 | 
						|
		/* constant */
 | 
						|
		tmpval = new CFloatValue(m_parameter1);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_FLOAT_UNIFORM: {
 | 
						|
		float res = ((m_parameter2 - m_parameter1) * m_base->DrawFloat())
 | 
						|
			+ m_parameter1;
 | 
						|
		tmpval = new CFloatValue(res);
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_FLOAT_NORMAL: {
 | 
						|
		/* normal (big numbers): para1 = mean, para2 = std dev               */
 | 
						|
 | 
						|
		/* 
 | 
						|
 | 
						|
		   070301 - nzc - Changed the termination condition. I think I 
 | 
						|
		   made a small mistake here, but it only affects distro's where
 | 
						|
		   the seed equals 0. In that case, the algorithm locks. Let's
 | 
						|
		   just guard that case separately.
 | 
						|
 | 
						|
		*/
 | 
						|
 | 
						|
		float x = 0.0, y = 0.0, s = 0.0, t = 0.0;
 | 
						|
		if (m_base->GetSeed() == 0) {
 | 
						|
			/*
 | 
						|
 | 
						|
			  070301 - nzc 
 | 
						|
			  Just taking the mean here seems reasonable.
 | 
						|
 | 
						|
			 */
 | 
						|
			tmpval = new CFloatValue(m_parameter1);
 | 
						|
		} else {
 | 
						|
			/*
 | 
						|
 | 
						|
			  070301 - nzc 
 | 
						|
			  Now, with seed != 0, we will most assuredly get some
 | 
						|
			  sensible values. The termination condition states two 
 | 
						|
			  things: 
 | 
						|
			  1. s >= 0 is not allowed: to prevent the distro from 
 | 
						|
				 getting a bias towards high values. This is a small
 | 
						|
				 correction, really, and might also be left out.
 | 
						|
			  2. s == 0 is not allowed: to prevent a division by zero
 | 
						|
				 when renormalising the drawn value to the desired
 | 
						|
				 distribution shape. As a side effect, the distro will
 | 
						|
				 never yield the exact mean. 
 | 
						|
			  I am not sure whether this is consistent, since the error 
 | 
						|
			  cause by #2 is of the same magnitude as the one 
 | 
						|
			  prevented by #1. The error introduced into the SD will be 
 | 
						|
			  improved, though. By how much? Hard to say... If you like
 | 
						|
			  the maths, feel free to analyse. Be aware that this is 
 | 
						|
			  one of the really old standard algorithms. I think the 
 | 
						|
			  original came in Fortran, was translated to Pascal, and 
 | 
						|
			  then someone came up with the C code. My guess it that
 | 
						|
			  this will be quite sufficient here.
 | 
						|
 | 
						|
			 */
 | 
						|
			do 
 | 
						|
			{
 | 
						|
				x = 2.0 * m_base->DrawFloat() - 1.0;
 | 
						|
				y = 2.0 * m_base->DrawFloat() - 1.0;
 | 
						|
				s = x*x + y*y;
 | 
						|
			} while ( (s >= 1.0) || (s == 0.0) );
 | 
						|
			t = x * sqrt( (-2.0 * log(s)) / s);
 | 
						|
			tmpval = new CFloatValue(m_parameter1 + m_parameter2 * t);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	case KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL: {
 | 
						|
		/* 1st order fall-off. I am very partial to using the half-life as    */
 | 
						|
		/* controlling parameter. Using the 'normal' exponent is not very     */
 | 
						|
		/* intuitive...                                                       */
 | 
						|
		/* tmpval = new CFloatValue( (1.0 / m_parameter1)                     */
 | 
						|
		tmpval = new CFloatValue( (m_parameter1) 
 | 
						|
								  * (-log(1.0 - m_base->DrawFloat())) );
 | 
						|
 | 
						|
	}
 | 
						|
	break;
 | 
						|
	default:
 | 
						|
	{
 | 
						|
		/* unknown distribution... */
 | 
						|
		static bool randomWarning = false;
 | 
						|
		if (!randomWarning) {
 | 
						|
			randomWarning = true;
 | 
						|
			std::cout << "RandomActuator '" << GetName() << "' has an unknown distribution." << std::endl;
 | 
						|
		}
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	}
 | 
						|
 | 
						|
	/* Round up: assign it */
 | 
						|
	CValue *prop = GetParent()->GetProperty(m_propname);
 | 
						|
	if (prop) {
 | 
						|
		prop->SetValue(tmpval);
 | 
						|
	}
 | 
						|
	tmpval->Release();
 | 
						|
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
void SCA_RandomActuator::enforceConstraints()
 | 
						|
{
 | 
						|
	/* The constraints that are checked here are the ones fundamental to     */
 | 
						|
	/* the various distributions. Limitations of the algorithms are checked  */
 | 
						|
	/* elsewhere (or they should be... ).                                    */
 | 
						|
	switch (m_distribution) {
 | 
						|
	case KX_RANDOMACT_BOOL_CONST:
 | 
						|
	case KX_RANDOMACT_BOOL_UNIFORM:
 | 
						|
	case KX_RANDOMACT_INT_CONST:
 | 
						|
	case KX_RANDOMACT_INT_UNIFORM:
 | 
						|
	case KX_RANDOMACT_FLOAT_UNIFORM:
 | 
						|
	case KX_RANDOMACT_FLOAT_CONST:
 | 
						|
		; /* Nothing to be done here. We allow uniform distro's to have      */
 | 
						|
		/* 'funny' domains, i.e. max < min. This does not give problems.     */
 | 
						|
		break;
 | 
						|
	case KX_RANDOMACT_BOOL_BERNOUILLI: 
 | 
						|
		/* clamp to [0, 1] */
 | 
						|
		if (m_parameter1 < 0.0) {
 | 
						|
			m_parameter1 = 0.0;
 | 
						|
		} else if (m_parameter1 > 1.0) {
 | 
						|
			m_parameter1 = 1.0;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case KX_RANDOMACT_INT_POISSON: 
 | 
						|
		/* non-negative */
 | 
						|
		if (m_parameter1 < 0.0) {
 | 
						|
			m_parameter1 = 0.0;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case KX_RANDOMACT_FLOAT_NORMAL: 
 | 
						|
		/* standard dev. is non-negative */
 | 
						|
		if (m_parameter2 < 0.0) {
 | 
						|
			m_parameter2 = 0.0;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL: 
 | 
						|
		/* halflife must be non-negative */
 | 
						|
		if (m_parameter1 < 0.0) {
 | 
						|
			m_parameter1 = 0.0;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		; /* unknown distribution... */
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#ifdef WITH_PYTHON
 | 
						|
 | 
						|
/* ------------------------------------------------------------------------- */
 | 
						|
/* Python functions                                                          */
 | 
						|
/* ------------------------------------------------------------------------- */
 | 
						|
 | 
						|
/* Integration hooks ------------------------------------------------------- */
 | 
						|
PyTypeObject SCA_RandomActuator::Type = {
 | 
						|
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
						|
	"SCA_RandomActuator",
 | 
						|
	sizeof(PyObjectPlus_Proxy),
 | 
						|
	0,
 | 
						|
	py_base_dealloc,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	py_base_repr,
 | 
						|
	0,0,0,0,0,0,0,0,0,
 | 
						|
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 | 
						|
	0,0,0,0,0,0,0,
 | 
						|
	Methods,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	&SCA_IActuator::Type,
 | 
						|
	0,0,0,0,0,0,
 | 
						|
	py_base_new
 | 
						|
};
 | 
						|
 | 
						|
PyMethodDef SCA_RandomActuator::Methods[] = {
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setBoolConst),
 | 
						|
	KX_PYMETHODTABLE_NOARGS(SCA_RandomActuator, setBoolUniform),
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setBoolBernouilli),
 | 
						|
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setIntConst),
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setIntUniform),
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setIntPoisson),
 | 
						|
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setFloatConst),
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setFloatUniform),
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setFloatNormal),
 | 
						|
	KX_PYMETHODTABLE(SCA_RandomActuator, setFloatNegativeExponential),
 | 
						|
	{NULL,NULL} //Sentinel
 | 
						|
};
 | 
						|
 | 
						|
PyAttributeDef SCA_RandomActuator::Attributes[] = {
 | 
						|
	KX_PYATTRIBUTE_FLOAT_RO("para1",SCA_RandomActuator,m_parameter1),
 | 
						|
	KX_PYATTRIBUTE_FLOAT_RO("para2",SCA_RandomActuator,m_parameter2),
 | 
						|
	KX_PYATTRIBUTE_ENUM_RO("distribution",SCA_RandomActuator,m_distribution),
 | 
						|
	KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_RandomActuator,m_propname,CheckProperty),
 | 
						|
	KX_PYATTRIBUTE_RW_FUNCTION("seed",SCA_RandomActuator,pyattr_get_seed,pyattr_set_seed),
 | 
						|
	{ NULL }	//Sentinel
 | 
						|
};	
 | 
						|
 | 
						|
PyObject* SCA_RandomActuator::pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
 | 
						|
{
 | 
						|
	SCA_RandomActuator* act = static_cast<SCA_RandomActuator*>(self);
 | 
						|
	return PyLong_FromSsize_t(act->m_base->GetSeed());
 | 
						|
}
 | 
						|
 | 
						|
int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 | 
						|
{
 | 
						|
	SCA_RandomActuator* act = static_cast<SCA_RandomActuator*>(self);
 | 
						|
	if (PyLong_Check(value))	{
 | 
						|
		int ival = PyLong_AsSsize_t(value);
 | 
						|
		act->m_base->SetSeed(ival);
 | 
						|
		return PY_SET_ATTR_SUCCESS;
 | 
						|
	} else {
 | 
						|
		PyErr_SetString(PyExc_TypeError, "actuator.seed = int: Random Actuator, expected an integer");
 | 
						|
		return PY_SET_ATTR_FAIL;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* 11. setBoolConst */
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setBoolConst,
 | 
						|
"setBoolConst(value)\n"
 | 
						|
"\t- value: 0 or 1\n"
 | 
						|
"\tSet this generator to produce a constant boolean value.\n") 
 | 
						|
{
 | 
						|
	int paraArg;
 | 
						|
	if(!PyArg_ParseTuple(args, "i:setBoolConst", ¶Arg)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_BOOL_CONST;
 | 
						|
	m_parameter1 = (paraArg) ? 1.0 : 0.0;
 | 
						|
	
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 12. setBoolUniform, */
 | 
						|
KX_PYMETHODDEF_DOC_NOARGS(SCA_RandomActuator, setBoolUniform,
 | 
						|
"setBoolUniform()\n"
 | 
						|
"\tSet this generator to produce true and false, each with 50%% chance of occuring\n") 
 | 
						|
{
 | 
						|
	/* no args */
 | 
						|
	m_distribution = KX_RANDOMACT_BOOL_UNIFORM;
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 13. setBoolBernouilli,  */
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setBoolBernouilli,
 | 
						|
"setBoolBernouilli(value)\n"
 | 
						|
"\t- value: a float between 0 and 1\n"
 | 
						|
"\tReturn false value * 100%% of the time.\n")
 | 
						|
{
 | 
						|
	float paraArg;
 | 
						|
	if(!PyArg_ParseTuple(args, "f:setBoolBernouilli", ¶Arg)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_BOOL_BERNOUILLI;
 | 
						|
	m_parameter1 = paraArg;	
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 14. setIntConst,*/
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setIntConst,
 | 
						|
"setIntConst(value)\n"
 | 
						|
"\t- value: integer\n"
 | 
						|
"\tAlways return value\n") 
 | 
						|
{
 | 
						|
	int paraArg;
 | 
						|
	if(!PyArg_ParseTuple(args, "i:setIntConst", ¶Arg)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_INT_CONST;
 | 
						|
	m_parameter1 = paraArg;
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 15. setIntUniform,*/
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setIntUniform,
 | 
						|
"setIntUniform(lower_bound, upper_bound)\n"
 | 
						|
"\t- lower_bound: integer\n"
 | 
						|
"\t- upper_bound: integer\n"
 | 
						|
"\tReturn a random integer between lower_bound and\n"
 | 
						|
"\tupper_bound. The boundaries are included.\n")
 | 
						|
{
 | 
						|
	int paraArg1, paraArg2;
 | 
						|
	if(!PyArg_ParseTuple(args, "ii:setIntUniform", ¶Arg1, ¶Arg2)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_INT_UNIFORM;
 | 
						|
	m_parameter1 = paraArg1;
 | 
						|
	m_parameter2 = paraArg2;
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 16. setIntPoisson,		*/
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setIntPoisson,
 | 
						|
"setIntPoisson(value)\n"
 | 
						|
"\t- value: float\n"
 | 
						|
"\tReturn a Poisson-distributed number. This performs a series\n"
 | 
						|
"\tof Bernouilli tests with parameter value. It returns the\n"
 | 
						|
"\tnumber of tries needed to achieve succes.\n")
 | 
						|
{
 | 
						|
	float paraArg;
 | 
						|
	if(!PyArg_ParseTuple(args, "f:setIntPoisson", ¶Arg)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_INT_POISSON;
 | 
						|
	m_parameter1 = paraArg;	
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 17. setFloatConst */
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setFloatConst,
 | 
						|
"setFloatConst(value)\n"
 | 
						|
"\t- value: float\n"
 | 
						|
"\tAlways return value\n")
 | 
						|
{
 | 
						|
	float paraArg;
 | 
						|
	if(!PyArg_ParseTuple(args, "f:setFloatConst", ¶Arg)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_FLOAT_CONST;
 | 
						|
	m_parameter1 = paraArg;	
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 18. setFloatUniform, */
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setFloatUniform,
 | 
						|
"setFloatUniform(lower_bound, upper_bound)\n"
 | 
						|
"\t- lower_bound: float\n"
 | 
						|
"\t- upper_bound: float\n"
 | 
						|
"\tReturn a random integer between lower_bound and\n"
 | 
						|
"\tupper_bound.\n")
 | 
						|
{
 | 
						|
	float paraArg1, paraArg2;
 | 
						|
	if(!PyArg_ParseTuple(args, "ff:setFloatUniform", ¶Arg1, ¶Arg2)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_FLOAT_UNIFORM;
 | 
						|
	m_parameter1 = paraArg1;
 | 
						|
	m_parameter2 = paraArg2;
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 19. setFloatNormal, */
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setFloatNormal,
 | 
						|
"setFloatNormal(mean, standard_deviation)\n"
 | 
						|
"\t- mean: float\n"
 | 
						|
"\t- standard_deviation: float\n"
 | 
						|
"\tReturn normal-distributed numbers. The average is mean, and the\n"
 | 
						|
"\tdeviation from the mean is characterized by standard_deviation.\n")
 | 
						|
{
 | 
						|
	float paraArg1, paraArg2;
 | 
						|
	if(!PyArg_ParseTuple(args, "ff:setFloatNormal", ¶Arg1, ¶Arg2)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_FLOAT_NORMAL;
 | 
						|
	m_parameter1 = paraArg1;
 | 
						|
	m_parameter2 = paraArg2;
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
/* 20. setFloatNegativeExponential, */
 | 
						|
KX_PYMETHODDEF_DOC_VARARGS(SCA_RandomActuator, setFloatNegativeExponential, 
 | 
						|
"setFloatNegativeExponential(half_life)\n"
 | 
						|
"\t- half_life: float\n"
 | 
						|
"\tReturn negative-exponentially distributed numbers. The half-life 'time'\n"
 | 
						|
"\tis characterized by half_life.\n")
 | 
						|
{
 | 
						|
	float paraArg;
 | 
						|
	if(!PyArg_ParseTuple(args, "f:setFloatNegativeExponential", ¶Arg)) {
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	m_distribution = KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
 | 
						|
	m_parameter1 = paraArg;	
 | 
						|
	enforceConstraints();
 | 
						|
	Py_RETURN_NONE;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
/* eof */
 |