Python Runtime Error

I have a game that runs perfectly fine in the blend file, and also works as a runtime on a computer with python installed. But when played on another computer, I get an error: “no module named random.” I thought the purpose of a runtime was to play it on a computer without having to install Blender or Python. What am I missing?

(I posted this in the discussion forum, but this seems more appropriate. My apologies.)

The random library is one of the standard libraries of Python. It is available only after installing Python. If this is the only library needed from outside, you can certainly find some other way to go around. Either you can code your own random algorithm, or maybe you’ll find a sufficient random routine from Blenders Noise library, for example the function Noise.random(): http://www.blender.org/documentation/242PythonDoc/Noise-module.html#random

It seems easiest to go with the Noise library, but a few quick questions:

  1. I’ve used the Blender module in a game before to move objects, but it always glitched, showing edit mode for just a moment. Would this happen if I got a random number using the Blender module?

  2. Say I wanted to just copy the code that python uses for random numbers, where could I find it?

  3. How advanced is making my own algorithm? I have no idea of how I would start, but it seems like a fascinating project. :smiley:

thanks!

Basically the code is in the source files, but it is all written in C, so it may be not that useful. This is quite the common method, the Python layer appears just as a wrapper around the compiled C-code. If I remember right, the original Python random module uses the so called Mersenne twister -algorithm, which is described here: http://en.wikipedia.org/wiki/Mersenne_twister

For me this seems too complicated for own game projects, so with a little imagination you could construct a much simpler random generator. What kind of random numbers would you need, are they integers, reals, do they need to fill some kind of statistical criteria, are they from a predefined range?

I only need a random number from 1-10 to draw from a deck of cards. :smiley:

Here is one algorithm suggested by Wikipedia (don’t ask how it works):

def random_uint(m_z,m_w):
  m_z = 36969 * (m_z & 65535) + (m_z >> 16)
  m_w = 18000 * (m_w & 65535) + (m_w >> 16)
  return (m_z << 16) + (m_w & 65535)

It needs two seeds m_z and m_w. I guess it is ok to take the seeds from time() function:

#import Blender
#t1=int(100*Blender.sys.time())
import time
t1=int(100*time.time())
t2=t1//2

The time module again is a standard Python module, so it may not be available in game engine, so in that case use the Blender.sys.time() function commented out in previous code. Now if you call random_uint(t1,t2) you get big random number. Next time use the previous m_z and m_w as seeds.

You may want to take the modulo from this r=random_uint(), in your case r%10, and maybe shuffle the card deck [1,2,3,4,5,6,7,8,9,10] accordingly.

I don’t think I followed much of any of that… :confused:

I think this is above my head right now… :spin:

I think this will do the job:

import Blender
t1=int(100*Blender.sys.time())
t2=t1//2
m_z=None
m_w=None
def random_uint():
  global m_z,m_w
  m_z = 36969 * (m_z & 65535) + (m_z >> 16)
  m_w = 18000 * (m_w & 65535) + (m_w >> 16)
  return (m_z << 16) + (m_w & 65535)
def random_randint(a):
  global m_z,m_w
  if not m_z: m_z=t1; m_w=t2
  return random_uint()%a
deck=[1,2,3,4,5,6,7,8,9,10]
for i in range(25):
  r=deck[random_randint(len(deck))]
  print r

This just takes a new card, and puts it back, and takes again 25 times. If you need to take the card away, you’ll need to manipulate the deck. Or basically you could replace the whole for loop with a single random_randint(10) call.

That’s a pretty nifty piece of code.

Would you mind explaining how it works, or even better, commenting on each section?

I implemented the code as needed, and it works great!

…only problem is that now I get an error “no module named Blender” during the runtime. All I want is to have a game choose some random cards, and be able to save the runtime to a disk to play on computers without python installed. What modules can I use to do this? If neither random nor Blender work, would the noise module work?

Sorry about that. I’m trying to answer based on my basic Python knowledge, so all the Game Engine spesific areas are a bit dimmy for me.

What I found in the Game Engine API, there exists a random float function there too:

Mathutils.Rand(low=0.0, high=1.0)

The simple solution for getting an integer between [1…10] would be:

import Mathutils
r=int(Mathutils.Rand(low=1.0, high=10.99))
print r

Mathutils library should be usable inside Game Engine.

Thanks so much!

That random generator looked pretty interesting, would you mind still giving a word or two on how it works? I mainly can’t follow :

  m_z = 36969 * (m_z & 65535) + (m_z >> 16)
  m_w = 18000 * (m_w & 65535) + (m_w >> 16)
  return (m_z << 16) + (m_w & 65535)

What’s the significance of the Mersenne primes?

I just stumbled up GameLogic.getRandomFloat(), but (Mathutils.Rand(1,10)) works a bit better. :smiley: