Pacman AI - A*?
Author |
Message |
Aziz
|
Posted: Thu Dec 01, 2005 5:43 pm Post subject: Pacman AI - A*? |
|
|
ALright, I've read, read, and read for the past hour and a half. I've found virtually nothing as per a good Pacman AI. My ghosts are moving to match row, then column, but it's crap, and the ghosts just amalgamate :S. I read about the A* search algorithm, but nodda. Anyone have any source code? Any even pseudo-code? Or explainations other than "You need to get the to track pacman"? Help would be AMAZINGLY appreciated! |
|
|
|
|
|
Sponsor Sponsor
|
|
|
Aziz
|
Posted: Thu Dec 01, 2005 6:16 pm Post subject: (No subject) |
|
|
Mah bad... here's the source code:
Turing: | %PACMAN
%Anthony Aziz
%Number of rows and columns
const rows := 22
const cols := 19
%Set Screen
View.Set ("graphics:" + intstr (cols * 20) + ";" + intstr (rows * 20 + 40) + ",position:center;center,offscreenonly")
%Variables
%Keyboard movement variables
var row, col, dir : int
var key : string (1) := " "
%Player variables
var s : int := 1 %open/close mouth state
var score := 0 %score
var lives := 3 %lives
var running := true %running
%Ghost Record
type ghost :
record
r, c, d : int %Row, column, direction
rR, rC : int %Respawn row & column
t : int %Timer
clr : int %Colour
out : boolean %If ghost is out of pen
end record
%Ghost
var ghosts : array 1 .. 3 of ghost
%Map array
var map : array 1 .. rows, 1 .. cols of int
%Pellet array
var pellets : array 1 .. rows, 1 .. cols of boolean
%Key constants
const UP_ARROW := chr (200)
const LEFT_ARROW := chr (203)
const RIGHT_ARROW := chr (205)
const DOWN_ARROW := chr (208)
const ESC_KEY := chr (27)
%Direction constants
const UP := 90
const LEFT := 180
const RIGHT := 0
const DOWN := 270
%Map ID Constants
const WALL := 0
const EMPTY := 1
const BIGDOT := 2
const TELE_L := 3
const TELE_R := 4
const TELE_U := 5
const TELE_D := 6
const GHOST1 := 7
const GHOST2 := 8
const GHOST3 := 9
%Map colors
const mapClr : array 0 .. 9 of int := init (54, 7, 7, 7, 7, 7, 7, 7, 7, 7) %Everything is black except walls
%Counts timers
process ghostTimer (g : int)
loop
exit when ~running
if ghosts (g ).t > 0 then %~ghosts (g).out then
ghosts (g ).t - = 1
delay (1000)
else
ghosts (g ).t := 10
delay (1000)
end if
end loop
end ghostTimer
%Return x value of col (bottom left of square)
fcn gridX (col : int) : int
result (col - 1) * 20
end gridX
%Return y value of row (bottom left of square)
fcn gridY (row : int) : int
result (row - 1) * 20
end gridY
%Draw the map
proc drawMap
for i : 1 .. cols
for j : 1 .. rows
var x, y : int
x := gridX (i )
y := gridY (j )
drawfillbox (x, maxy - y, x + 20, maxy - y - 20, mapClr (map (j, i )))
%Draw pellets
if pellets (j, i ) then
drawfilloval (x + 10, maxy - y - 10, 2, 2, 13)
end if
end for
end for
end drawMap
%Draw pacman character at (x,y) either open or closed
proc drawPacman (row, col, state, dir : int)
%Variables
var a1, a2 : int %Arc angles
var clr : int %Color
if state = 1 then
%Open pacman
a1 := 30
a2 := 330
clr := 14
elsif state = - 1 then
%Close pacman
a1 := 0
a2 := 360
clr := 14
elsif state = 0 then
%Dead pacman
a1 := 30
a2 := 330
clr := 12
else
%Error if wrong state
Error.Halt ("State must be 1, -1, or 0!")
end if
%Calculate x and y values of grid coordinates
var x, y : int
x := gridX (col ) + 10
y := maxy - gridY (row ) - 10
%Draw pacman
drawfillarc (x, y, 8, 8, a1 + dir, a2 + dir, clr )
end drawPacman
%Read map
fcn readMap (mapname : string) : array 1 .. rows, 1 .. cols of int
%Variables
var f : int %file id
var grid : array 1 .. rows, 1 .. cols of int %2d grid array
%Open map file
open : f, "maps\\" + mapname + ".pacmap", get
for i : 1 .. rows
%Read temporary line
var temp : string
get : f, temp
for j : 1 .. cols
%Read all values of the line into array (base 16, can store up to 16 IDs
grid (i, j ) := strint (temp (j ), 16)
end for
end for
%Close files
close : f
%Result the grid
result grid
end readMap
%Draw ghosts
proc drawGhost (g : ghost )
%Calculate x and y values of grid coordinates
var x, y : int
x := gridX (g.c ) + 10
y := maxy - gridY (g.r ) - 10
%head
drawfilloval (x, y, 8, 8, g.clr )
%body
drawfillbox (x - 8, y - 8, x + 8, y, g.clr )
%eyes
drawfilloval (x - 3, y, 2, 2, 0) %left
drawfilloval (x + 3, y, 2, 2, 0) %right
%pupils
drawfilloval (x - 2, y, 1, 1, 7) %left
drawfilloval (x + 2, y, 1, 1, 7) %right
end drawGhost
%Move ghosts
proc moveGhost (var g : ghost )
%Row and column difference in order to reach pacman
var rDiff := 0
var cDiff := 0
if row ~ = g.r then
rDiff := (row - g.r ) div abs (row - g.r )
end if
if col ~ = g.c then
cDiff := (col - g.c ) div abs (col - g.c )
end if
if map (g.r, g.c + cDiff ) >= EMPTY and cDiff ~ = 0 then
g.c + = cDiff
elsif map (g.r + rDiff, g.c ) >= EMPTY then
g.r + = rDiff
end if
end moveGhost
%Set colours
color (0)
colorback (7)
%Read map
map := readMap ("test")
%Find ghost starting place
for i : 1 .. cols
for j : 1 .. rows
%Ghost respawn points
if map (j, i ) >= GHOST1 & map (i, j ) <= GHOST3 then
ghosts (map (j, i ) - 6).rR := j
ghosts (map (j, i ) - 6).rC := i
end if
end for
end for
%Initialize all pellets
for i : 1 .. cols
for j : 1 .. rows
if map (j, i ) = EMPTY then
pellets (j, i ) := true
else
pellets (j, i ) := false
end if
end for
end for
%Start ghosts
for i : 1 .. 3
%Colors
var clrs : array 1 .. 3 of int := init (9, 10, 12)
ghosts (i ).r := ghosts (i ).rR
ghosts (i ).c := ghosts (i ).rC
ghosts (i ).t := Rand.Int (1, 8)
ghosts (i ).clr := clrs (i )
ghosts (i ).out := false
fork ghostTimer (i )
end for
%Draw and erase packman at top left facing right
row := 2
col := 2
dir := RIGHT
drawPacman (row, col, 1, dir )
View.Update
%Draw map
drawMap
loop
%Bottom panel
drawfillbox (0, 0, maxx, 40, 7)
%Draw lives
for i : 1 .. lives
drawfillarc (i * 20, 20, 8, 8, 30, 330, 14)
end for
locate (maxrow - 1, maxcol - 16)
put "SCORE ", score : 10
%Get keypress
loop
if hasch then
getch (key )
else
%Set key to nothing
key := " "
end if
exit when not hasch
end loop
%Exit if user pressed ESC
exit when key = ESC_KEY
%Choose direction
if col > 1 & col < cols & row > 1 & row < rows then %prevents user trying to move off map in teleporters
if key = UP_ARROW & map (row - 1, col ) >= EMPTY then
dir := UP
elsif key = LEFT_ARROW & map (row, col - 1) >= EMPTY then
dir := LEFT
elsif key = RIGHT_ARROW & map (row, col + 1) >= EMPTY then
dir := RIGHT
elsif key = DOWN_ARROW & map (row + 1, col ) >= EMPTY then
dir := DOWN
end if
end if
%Move
if dir = UP & map (row - 1, col ) >= EMPTY then
if map (row - 1, col ) = TELE_U then
row := rows
else
row - = 1
end if
elsif dir = LEFT & map (row, col - 1) >= EMPTY then
if map (row, col - 1) = TELE_L then
col := cols
else
col - = 1
end if
elsif dir = RIGHT & map (row, col + 1) >= EMPTY then
if map (row, col + 1) = TELE_R then
col := 1
else
col + = 1
end if
elsif dir = DOWN & map (row + 1, col ) >= EMPTY then
if map (row + 1, col ) = TELE_D then
row := 1
else
row + = 1
end if
end if
%Move ghosts
for i : 1 .. 3
if ghosts (i ).t = 0 & ghosts (i ).r = ghosts (i ).rR & ghosts (i ).c = ghosts (i ).rC then
ghosts (i ).r - = 1
delay (150)
ghosts (i ).r - = 1
%ghosts (i).out := true
elsif ghosts (i ).r ~ = ghosts (i ).rR| ghosts (i ).c ~ = ghosts (i ).rC then %ghosts (i).t = 10 then
moveGhost (ghosts (i ))
end if
end for
%Compare grid values
if pellets (row, col ) then
pellets (row, col ) := false
score + = 10
end if
%Draw ghosts
for i : 1 .. 3
drawGhost (ghosts (i ))
end for
%Draw and uppdate pacman
drawPacman (row, col, s, dir )
View.Update
delay (150)
%Change state of pacman's mouth
s := -s
%Draw the map
drawMap
delay (50)
end loop
running := false
Window.Hide (defWinID ) |
And the map file should be saved under a folder "maps" as "test.pacmap"
code: | 0500000050500000050
3111111110111111114
0100100010100010010
0100100010100010010
0111111111111111110
0000101000001010000
3111101110111011114
0100100010100010010
0100101111111010010
0100101000001010010
3111111078901111114
0100101000001010010
0100101111111010010
0100101000001010010
3111111110111111114
0100100010100010010
0110111111111110110
0010101000001010100
0111101110111011110
0100000010100000010
3111111110111111114
0600000060600000060
0 = Wall
1 = Empty
2 = Big Dot
3 = Teleporter left
4 = Teleporter right
5 = Teleporter up
6 = Teleporter down
7 = Ghost 1
8 = Ghost 2
9 = Ghost 3[/quote][/quote] |
|
|
|
|
|
|
MysticVegeta
|
|
|
|
|
Mr. T
|
Posted: Fri Dec 02, 2005 8:18 pm Post subject: Alex's Opinion |
|
|
I tried saving the map file in both turing and notepad, but it doesn't work. |
|
|
|
|
|
|
|