you mean a bit less random?
can be added more chances to the forward direction
and removed the ābackā direction.(as is in pacman original)
ok, now is a bit better 
import random
import bge
from mathutils import Vector, Matrix
"""pac-man ghost AI (iper - semplificated)
the face forward of the ghost object is +Y (green arrow)(to semplificate face_to())
the ghost obj is not a object physic (not influeced from collisions)
added patch for "no direction founded"
"""
TILE_SIZE = 2.0 # 2 meters
def face_to(own, pos): # align to position without interpolations
own.worldOrientation = (pos - own.worldPosition).to_track_quat("Y","Z")
def get_target(own):
vx, vy = own.worldOrientation.col[:2]
local_directions = [-vx, vx, vy, vy, vy] # more forward direction
start = own.worldPosition
targets_candidate = [start+vec*TILE_SIZE for vec in local_directions]
targets_free = []
for target in targets_candidate:
if not own.rayCast(target, start)[0]:
targets_free.append(target)
if not targets_free:
return None
target = random.choice(targets_free)
# chunkifyze.. should be already , but to be more sure ...
return Vector([round(v/TILE_SIZE)*TILE_SIZE for v in target])
def main():
cont = bge.logic.getCurrentController()
own = cont.owner
if not "init" in own:
own["target_xyz"] = None
own["init"] = True
own["speed"] = 0.1
if not own["target_xyz"]:
target = own["target_xyz"] = get_target(own)
if not target:
return
face_to(own, target)
#debug
bge.render.drawLine(own.worldPosition, own["target_xyz"], [1,0,0])
## move
speed = own["speed"]
dist = own.getDistanceTo(own["target_xyz"])
if dist > speed:
own.applyMovement((0,speed,0),1)
else:
own.worldPosition = own["target_xyz"]
own["target_xyz"] = None
try:
main()
except:
bge.logic.endGame()
raise