Pacman Ghost Random Moving Pattern...WTF?
Author |
Message |
Aziz
![](http://compsci.ca/v3/uploads/user_avatars/17740604804829f8242e90c.png)
|
Posted: Thu Dec 01, 2005 9:41 pm Post subject: Pacman Ghost Random Moving Pattern...WTF? |
|
|
Why does this guy go through walls? (btw, EMPTY is a constant with value 1, the empty spaces in the map
code: | var rChange, cChange : int
loop
rChange := Rand.Int (-1, 1)
cChange := Rand.Int (-1, 1)
exit when (rChange ~= 0 and cChange = 0) or (rChange = 0 and cChange ~= 0)
end loop
if Rand.Real > 0.9 and map (g.r + rChange, g.c + cChange) = EMPTY then
g.rChange := rChange
g.cChange := cChange
end if
if map (g.r + rChange, g.c + cChange) = EMPTY then
g.r += g.rChange
g.c += g.cChange
end if |
|
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
Jorbalax
![](http://usera.imagecave.com/Jorbalax/Signatures-Avatars/mrshroomyblue.png)
|
Posted: Fri Dec 02, 2005 12:07 am Post subject: (No subject) |
|
|
It's really hard to determine what the problem is with just that small line of coding. Perhaps you should post a bit more.
Also...
code: |
loop
rChange := Rand.Int (-1, 1)
cChange := Rand.Int (-1, 1)
exit when (rChange ~= 0 and cChange = 0) or (rChange = 0 and cChange ~= 0)
end loop
|
While this is an easy way of returning a random value within a certain set of numbers, I'm not sure if it's the safest way to do so. Making an exit when statement dependent on a random number means there is a possibility of your program staying in that loop for quite some time, especially if you choose to later increase those values. It also means that the time spent in the loop isn't always going to be relatively constant, which could be a problem.
My suggestion would be to first randomly select which variable is going to be 0 and then to randomly select an element from a predefined list of values in an arrayand the assign that value to your variable. Here's a comparison of the two methods.
code: |
var iNum1, iNum2, iPlaceHolder, TimeSince : int := 0
var iaSelectableValues : array 1..200 of int %array will hold selectable values
%initiates values between -100 and 100
iPlaceHolder := -100
for i:1..200
iaSelectableValues (i) := iPlaceHolder
iPlaceHolder +=1
end for
View.Set ("text")
loop
%method 1
TimeSince := Time.Elapsed
loop
iNum1 := Rand.Int (-100, 100)
iNum2 := Rand.Int (-100, 100)
exit when iNum1~=0 and iNum2 = 0
exit when iNum1=0 and iNum2 ~= 0
end loop
put "Time Elapsed (Method 1): ", (Time.Elapsed - TimeSince) / 1000
put iNum1, ", ", iNum2
Input.Pause
%method 2
TimeSince := Time.Elapsed
if Rand.Int (1 , 2) = 2 then %determine which value is going to be 0, and which is going to be a value from the array
iNum1 := 0
iNum2 := iaSelectableValues (Rand.Int (1, upper (iaSelectableValues))) %randomly select an element from the array and assign it
else
iNum2 := 0
iNum1 := iaSelectableValues (Rand.Int (1, upper (iaSelectableValues)))
end if
put "Time Elapsed (Method 2): ", (Time.Elapsed - TimeSince) / 1000
put iNum1, ", ", iNum2
Input.Pause
end loop
|
Run it through a couple times, and watch the time for method 1. Occasionally, it will be an odd number like 0.007 or something. Compare this to method 2, which stays relatively constant to two different times (0 and 0.001 for me). |
|
|
|
|
![](images/spacer.gif) |
Tony
![](http://wiki.compsci.ca/images/f/f4/OniTony.gif)
|
Posted: Fri Dec 02, 2005 9:41 am Post subject: (No subject) |
|
|
Jorbalax wrote: It's really hard to determine what the problem is with just that small line of coding.
Oh no, it's all there - look closer
code: | loop
rChange := Rand.Int (-1, 1)
cChange := Rand.Int (-1, 1)
exit when (rChange ~= 0 and cChange = 0) or (rChange = 0 and cChange ~= 0)
end loop
|
rChange and cChange are our random directions, pretty simple
code: |
if Rand.Real > 0.9 and map (g.r + rChange, g.c + cChange) = EMPTY then
g.rChange := rChange
g.cChange := cChange
end if
|
I don't quite understand this, but there's a 10% chance to assign g.rChange and g.cChange the random values we picked a step above, if we're allowed to move in that direction
code: |
if map (g.r + rChange, g.c + cChange) = EMPTY then
g.r += g.rChange
g.c += g.cChange
end if
|
We check once again if we can move in rChange/cChange direction, and is so, proceed to go in... g.rChange / g.cChange direction instead. Though there's only a 10% chance to actually have those values the same, so 90% of the time, if a random direction is valid, the ghost will continue to proceed straight through the wall
you need
code: |
if map (g.r + g.rChange, g.c + g.cChange) = EMPTY
|
basically look and go in the same direction. |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
![](images/spacer.gif) |
Aziz
![](http://compsci.ca/v3/uploads/user_avatars/17740604804829f8242e90c.png)
|
Posted: Sat Dec 03, 2005 2:12 pm Post subject: (No subject) |
|
|
Omg I knew I had worked on it straight for too long, yeah I seen the problem before the end of the post. Thank a bunch Tony! ![I am not worthy I am not worthy](images/smiles/honorhim.gif) |
|
|
|
|
![](images/spacer.gif) |
Aziz
![](http://compsci.ca/v3/uploads/user_avatars/17740604804829f8242e90c.png)
|
Posted: Tue Dec 06, 2005 8:16 am Post subject: (No subject) |
|
|
Jorbalax wrote: It's really hard to determine what the problem is with just that small line of coding. Perhaps you should post a bit more.
Also...
code: |
loop
rChange := Rand.Int (-1, 1)
cChange := Rand.Int (-1, 1)
exit when (rChange ~= 0 and cChange = 0) or (rChange = 0 and cChange ~= 0)
end loop
|
While this is an easy way of returning a random value within a certain set of numbers, I'm not sure if it's the safest way to do so. Making an exit when statement dependent on a random number means there is a possibility of your program staying in that loop for quite some time, especially if you choose to later increase those values. It also means that the time spent in the loop isn't always going to be relatively constant, which could be a problem.
My suggestion would be to first randomly select which variable is going to be 0 and then to randomly select an element from a predefined list of values in an arrayand the assign that value to your variable. Here's a comparison of the two methods.
code: |
var iNum1, iNum2, iPlaceHolder, TimeSince : int := 0
var iaSelectableValues : array 1..200 of int %array will hold selectable values
%initiates values between -100 and 100
iPlaceHolder := -100
for i:1..200
iaSelectableValues (i) := iPlaceHolder
iPlaceHolder +=1
end for
View.Set ("text")
loop
%method 1
TimeSince := Time.Elapsed
loop
iNum1 := Rand.Int (-100, 100)
iNum2 := Rand.Int (-100, 100)
exit when iNum1~=0 and iNum2 = 0
exit when iNum1=0 and iNum2 ~= 0
end loop
put "Time Elapsed (Method 1): ", (Time.Elapsed - TimeSince) / 1000
put iNum1, ", ", iNum2
Input.Pause
%method 2
TimeSince := Time.Elapsed
if Rand.Int (1 , 2) = 2 then %determine which value is going to be 0, and which is going to be a value from the array
iNum1 := 0
iNum2 := iaSelectableValues (Rand.Int (1, upper (iaSelectableValues))) %randomly select an element from the array and assign it
else
iNum2 := 0
iNum1 := iaSelectableValues (Rand.Int (1, upper (iaSelectableValues)))
end if
put "Time Elapsed (Method 2): ", (Time.Elapsed - TimeSince) / 1000
put iNum1, ", ", iNum2
Input.Pause
end loop
|
Run it through a couple times, and watch the time for method 1. Occasionally, it will be an odd number like 0.007 or something. Compare this to method 2, which stays relatively constant to two different times (0 and 0.001 for me).
You're absolutely right. That does make sense. But in that example, there was 200 different possibilities. I made it with only 2, and both methods were about the same. However, I am going to incorporate this into pacman and remember it for future use, as I have used this method (method #1 in the example) before and I think it is a lot better. Just pointing out that it didn't make much of i difference, but I do understand and you're wholly correct. (hahah....hole)
code: | var iNum1, iNum2, iPlaceHolder, TimeSince : int := 0
var iaSelectableValues : array 1 .. 2 of int %array will hold selectable values
iaSelectableValues (1) := -1
iaSelectableValues (2) := 1
View.Set ("text")
loop
%method 1
TimeSince := Time.Elapsed
loop
iNum1 := Rand.Int (-1, 1)
iNum2 := Rand.Int (-1, 1)
exit when iNum1 ~= 0 and iNum2 = 0 or iNum1 = 0 and iNum2 ~= 0
end loop
put "Time Elapsed (Method 1): ", (Time.Elapsed - TimeSince) / 1000
put iNum1, ", ", iNum2
Input.Pause
%method 2
TimeSince := Time.Elapsed
if Rand.Int (1, 2) = 2 then %determine which value is going to be 0, and which is going to be a value from the array
iNum1 := 0
iNum2 := iaSelectableValues (Rand.Int (1, upper (iaSelectableValues))) %randomly select an element from the array and assign it
else
iNum2 := 0
iNum1 := iaSelectableValues (Rand.Int (1, upper (iaSelectableValues)))
end if
put "Time Elapsed (Method 2): ", (Time.Elapsed - TimeSince) / 1000
put iNum1, ", ", iNum2
Input.Pause
end loop
|
|
|
|
|
|
![](images/spacer.gif) |
|
|