Help in two areas

I need some help in two areas.

Fisrt, I have three different models which I want to place in my scene. I want to randomize the models to be placed, but I want them to be placed in particular positions. Let me try to simplify what I am saying.
I have three tiles that has its own characteristics. I want to place the tiles beginning at one point of the scene and ending at another point (in a straight line).
When a tile is placed it would be any of the three at random. I tried a method for this, but somehow it is not randomizing. Here is the method I used:

# Variable to choose tile type
self.tileModel = random()*3

Then during a running task, I try to randamize the tile to be placed (which isn’t working).

# Choose tile type
if self.tileCounter == 0:
    self.tileModel = random()*3
    taskMgr.doMethodLater(1, self.tilePosition, "tilePos") # To place the tile
    self.tileCounter = 1
            
if self.tileCounter == 2:
    self.tileModel = random()*3
    taskMgr.doMethodLater(1, self.tilePosition, "tilePos")
    self.tileCounter = 3
            
if self.tileCounter == 4:
    self.tileModel = random()*3
    taskMgr.doMethodLater(1, self.tilePosition, "tilePos")
    self.tileCounter = 5


# Place the tile
def tilePosition(self, task):
    # 01
    if self.tileModel == 0 or self.tileModel == 1 and self.tileCounter == 1:
        self.tileModel001 = loader.loadModel("Models/tile01")
        self.tileModel001.setPos(-200,195,0.75)
        self.tileModel001.reparentTo(render)
        self.tileCounter = 2
    elif self.tileModel == 2 and self.tileCounter == 1:
        self.tileModel001 = loader.loadModel("Models/tile02")
        self.tileModel001.setPos(-200,195,0.75)
        self.tileModel001.reparentTo(render)
        self.tileCounter = 2
    elif self.tileModel == 3 and self.tileCounter == 1:
        self.tileModel001 = loader.loadModel("Models/tile03")
        self.tileModel001.setPos(-200,195,0.75)
        self.tileModel001.reparentTo(render)
        self.tileCounter = 2
    # 02
    if self.tileModel == 0 or self.tileModel == 1 and self.tileCounter == 3:
        self.tileModel002 = loader.loadModel("Models/tile01")
        self.tileModel002.setPos(-200,196,0.75)
        self.tileModel002.reparentTo(render)
        self.tileCounter = 4
    elif self.tileModel == 2 and self.tileCounter == 3:
        self.tileModel002 = loader.loadModel("Models/tile02")
        self.tileModel002.setPos(-200,196,0.75)
        self.tileModel002.reparentTo(render)
        self.tileCounter = 4
    elif self.tileModel == 3 and self.tileCounter == 3:
        self.tileModel002 = loader.loadModel("Models/tile03")
        self.tileModel002.setPos(-200,196,0.75)
        self.tileModel002.reparentTo(render)
        self.tileCounter = 4
    # 03
    if self.tileModel == 0 or self.tileModel == 1 and self.tileCounter == 5:
        self.tileModel003 = loader.loadModel("Models/tile01")
        self.tileModel003.setPos(-200,197,0.75)
        self.tileModel003.reparentTo(render)
        self.tileCounter = 6
    elif self.tileModel == 2 and self.tileCounter == 5:
        self.tileModel003 = loader.loadModel("Models/tile02")
        self.tileModel003.setPos(-200,197,0.75)
        self.tileModel003.reparentTo(render)
        self.tileCounter = 6
    elif self.tileModel == 3 and self.tileCounter == 5:
        self.tileModel003 = loader.loadModel("Models/tile03")
        self.tileModel003.setPos(-200,197,0.75)
        self.tileModel003.reparentTo(render)
        self.tileCounter = 6

I know there is a simpler way to do this. If I can get the randomization to work them I will use the method:

for i in range():

I hope this is understandable. I want to get my tile randomization working. Can anyone help?

Second, after I get that working, I want to have an event occur when my character lands on the tile (for example, change color etc.). I want to accomplish this through collisions.

This is the method used in Roaming Ralph

# make a traverser and make it the default traverser
self.cTrav = CollisionTraverser()
base.cTrav = self.cTrav

# player
self.Mod1TileRay = CollisionRay()
self.Mod1TileRay.setOrigin(0,0,1000)
self.Mod1TileRay.setDirection(0,0,-1)
self.Mod1TileCol = CollisionNode('ralphRay')
self.Mod1TileCol.addSolid(self.Mod1TileRay)
self.Mod1TileCol.setFromCollideMask(BitMask32.bit(0))
self.Mod1TileCol.setIntoCollideMask(BitMask32.allOff())
self.Mod1TileColNp = self.Mod1.attachNewNode(self.Mod1TileCol)
self.Mod1TileHandler = CollisionHandlerQueue()
self.cTrav.addCollider(self.Mod1TileColNp, self.Mod1TileHandler)


def move(self, task):

    elapsed = task.time - self.prevtime

    # Now check for collisions.
    self.cTrav.traverse(render)
    
    # Adjust model's Z coordinate.  If model's ray hit terrain,
    # update his Z. If it hit anything else, or didn't hit anything, put
    # him back where he was last frame.
    entries = []
    for i in range(self.Mod1TileHandler.getNumEntries()):
        entry = self.Mod1TileHandler.getEntry(i)
        entries.append(entry)
    entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                x.getSurfacePoint(render).getZ()))
    if (len(entries)>0) and (entries[0].getIntoNode().getName() == "tile01"):
        # I WANT TO PERFORM AN EVENT ON THE TILE COLLIDED WITH HERE
self.Mod1.setZ(entries[0].getSurfacePoint(render).getZ())
    else:
        self.Mod1.setPos(startpos)

What code can I use to perform an event on collision?

OK. I got through the collision part sorted out by using this example:

import direct.directbase.DirectStart
from direct.showbase import DirectObject
from pandac.PandaModules import *


class World( DirectObject.DirectObject ):
    def __init__( self ):
        #initialize traverser
        base.cTrav = CollisionTraverser()
        
        #initialize handler
        self.collHandEvent=CollisionHandlerEvent()
        self.collHandEvent.addInPattern('into-%in')
        self.collHandEvent.addOutPattern('outof-%in')
        
        #initialize collision count (for unique collision strings)
        self.collCount=0
        
        
        self.loadObj1()
        self.loadObj2()
    
    
    def loadObj1(self):
        #load a model. reparent it to the camera so we can move it.
        s = loader.loadModel('smiley') 
        s.reparentTo(camera)
        s.setPos(0, 25,0)
        
        #setup a collision solid for this model
        sColl=self.initCollisionSphere(s, True)
        
        #set up bitmasks
        #this object can only collide into things
        sColl[0].node().setIntoCollideMask( BitMask32.allOff() )
        #this object will only collide with objects with this bitmask
        sColl[0].node().setFromCollideMask( BitMask32.bit( 1 ) )
        
        #add this object to the traverser
        base.cTrav .addCollider(sColl[0] , self.collHandEvent)
    
    
    def loadObj2(self):
        #load a model. 
        t = loader.loadModel('smiley') 
        t.reparentTo(render)
        t.setPos(5, 25,0)
        
        #setup a collision solid for this model
        tColl=self.initCollisionSphere(t, True)
        
        #set up bitmasks
        #this object can only be collided into and will collide with the other object
        tColl[0].node().setIntoCollideMask( BitMask32.bit( 1 ))
        tColl[0].node().setFromCollideMask( BitMask32.allOff())
        
        #add this object to the traverser
        base.cTrav .addCollider(tColl[0], self.collHandEvent)
        
        #accept the events sent by the collisions
        self.accept( 'into-' + tColl[1], self.collide)
        self.accept( 'outof-' + tColl[1], self.collide2)
    
    
    def collide(self, collEntry):
        print "WERT: object has collided into another object"
    
    def collide2(self, collEntry):
        print "WERT: object is no longer colliding with another object"
    
    def initCollisionSphere( self, obj, show=False):
        #get the size of the object for the collision sphere
        bounds = obj.getChild(0).getBounds()
        center = bounds.getCenter()
        radius = bounds.getRadius()*1.1
        
        #create a collision sphere and name it something understandable
        collSphereStr = 'CollisionHull' +obj.getName()
        cNode=CollisionNode(collSphereStr)
        cNode.addSolid(CollisionSphere(center, radius ) )
        cNodepath=obj.attachNewNode(cNode)
        if show:
            cNodepath.show()
        
        # return a tuple with the collision node and its corrsponding string
        # return the collison node so that the bitmask can be set
        return (cNodepath,collSphereStr )



#run the world. move around with the mouse to create collisions
w = World()
run()

I am still having problems with this code though.

self.tileModel = random()*3 

Am I using the right method?