Help with unexpected behavior in falling sand game

I’m working on a falling sand game in python and I’ve noticed two very strange glitches, the first is that the materials that shift left or right randomly, like gas or water, seem to prefer to move on one side and seem to behave differently and spread out more to the left, this is despite the fact that I used the random choice function to determine the direction. The second is, for some reason the gas when it is allowed to move more than one space to the left or right at a time can go beyond the bounds of the screen despite such things being accounted for. If anyone has experience with these types of games and knows what’s going on, it would be greatly appreciated.

Repl link:

def xshift(arr,m,npos,ystep,x,y):
  
  randmove = random.choice([m.spread,-m.spread])
  if randmove >= 0: xstep = 1
  else: xstep = -1
  
  if xstep+x < 0 or xstep+x >= len(arr[0]):
    randmove = -randmove
    xstep = -xstep
  
  elif arr[y][xstep+x] != "":
    if arr[y][xstep+x].dense > m.dense:
      randmove = -randmove
      xstep = -xstep
          
  for xmove in range(abs(randmove)):
    if npos[1]+xstep < len(arr[0]) and npos[1]+xstep >= 0:
      
      if arr[y][npos[1]+xstep] == "":
        
        if type(m) == Dust:
          if (arr[npos[0]][npos[1]+xstep] == "") or (arr[npos[0]][npos[1]+xstep]).dense < m.dense:
            npos[1] += xstep
            npos[0] += ystep

        else:
          npos[1] += xstep
          
      elif (arr[y][npos[1]+xstep]).dense < m.dense:
        
        if type(m) == Dust:
          if (arr[y+ystep][x+xmove+xstep] == "") or (arr[y+ystep][x+xmove+xstep]).dense < m.dense:
            npos[1] += xstep
            npos[0] += ystep

        else:
          npos[1] += xstep

  return npos

About the material moving to one side I can give some hints, but I have no clue about the other one.

From looking your code, you’re reversing the randmove and xstep variables if a collision or a boundary is detected, and then you set a random choice, which is ok, but if a collision happens, you reverse both randmove and xstep, that can create a bias to one side.

I think it’s better if you re-randomize the direction of the movement if a boundary or a denser material is detected instead of reversing it.

The gas moving beyond the screen I got no clue.

1 Like

Actually I think I got it. When I’m iterating through the array via a for loop it goes from one side to the other, preventing the particles from moving on one side but not on the other. I’ll have to find a way to iterate through the list that goes from the sides to the middle