Wednesday, September 27, 2006

Robotic Pigeon v3.4

--Robert Knepher
--ROBOTIC PIGEONS LEAVE MESSES!
-- HANDLER
-- moveOK
-- DESCRIPTION
-- Returns TRUE / FALSE based on whether the indicated move is legal
-- INPUT VARIABLES
-- boardList, row, column
-- OUTPUT VARIABLES
-- TRUE / FALSE

on moveOK boardList, row, column

rowList = boardList[row]

thisItem = rowList[column]

if not (thisItem = ..EMPTY) then
return FALSE
end if

if (column > 1) then

-- Set startCol, check element to the left

startCol = column - 1

thisItem = rowList[startCol]

if not (thisItem = ..EMPTY) then
return TRUE
end if

else
startCol = column
end if

if (column < 8) then

-- Set endCol, check element to the right

endCol = column + 1

thisItem = rowList[endCol]

if not (thisItem = ..EMPTY) then
return TRUE
end if

else
endCol = column
end if


if (row > 1) then

-- Check upper row

rowList = boardList[row-1]

repeat with colIndex = startCol to endCol

thisItem = rowList[colIndex]

if not (thisItem = ..EMPTY) then
return TRUE
end if

end repeat

end if

if (row < 8) then

-- Check lower row

rowList = boardList[row+1]

repeat with colIndex = startCol to endCol

thisItem = rowList[colIndex]

if not (thisItem = ..EMPTY) then
return TRUE
end if

end repeat

end if

return FALSE

end


-- HANDLER
-- makeMove
-- DESCRIPTION
-- Returns a new board list based on the indicated move
-- INPUT VARIABLES
-- boardList, whoseTurn, row, column
-- OUTPUT VARIABLES
-- new board list

on makeMove boardList, whoseTurn, row, column

newList = duplicate (boardList)

rowList = newList[row]

rowList[column] = whoseTurn

-- Now traverse in 8 different directions to reverse any
-- needed values as a result of the move.

if (whoseTurn = ..cyborg) then

opponent = ..human

else

opponent = ..cyborg

end if

tweakMove (newList, ..UPPER_LEFT, whoseTurn, opponent, row, column)
tweakMove (newList, ..UP, whoseTurn, opponent, row, column)
tweakMove (newList, ..UPPER_RIGHT, whoseTurn, opponent, row, column)
tweakMove (newList, ..RIGHT, whoseTurn, opponent, row, column)
tweakMove (newList, ..LOWER_RIGHT, whoseTurn, opponent, row, column)
tweakMove (newList, ..DOWN, whoseTurn, opponent, row, column)
tweakMove (newList, ..LOWER_LEFT, whoseTurn, opponent, row, column)
tweakMove (newList, ..LEFT, whoseTurn, opponent, row, column)

return newList

end


on tweakMove boardList, direction, whoseTurn, opponent, row, column

-- Default values

rowIncrement = 1
colIncrement = 1

case direction of
..UPPER_LEFT,
..UP,
..UPPER_RIGHT:
rowIncrement = -1

..LEFT,
..RIGHT:
rowIncrement = 0

..LOWER_LEFT,
..DOWN,
..LOWER_RIGHT:
rowIncrement = 1

end case

case direction of
..UPPER_LEFT,
..LEFT,
..LOWER_LEFT:
colIncrement = -1

..UP,
..DOWN:
colIncrement = 0

..UPPER_RIGHT,
..RIGHT,
..LOWER_RIGHT:
colIncrement = 1

end case

rowIndex = row
colIndex = column

-- First check that there's a whoseTurn's token in the
-- direction we're searching

tokenFound = FALSE

repeat while TRUE

rowIndex = rowIndex + rowIncrement

if ((rowIndex < 1) or (rowIndex > 8)) then

exit repeat

end if

colIndex = colIndex + colIncrement

if ((colIndex < 1) or (colIndex > 8)) then

exit repeat

end if

rowList = boardList[rowIndex]

thisToken = rowList[colIndex]

if (thisToken = whoseTurn) then

tokenFound = TRUE

exit repeat

else if (thisToken = ..empty) then

exit

end if

end repeat

if (tokenFound = FALSE) then
exit
end if

repeat while TRUE

rowIndex = rowIndex + rowIncrement

if ((rowIndex < 1) or (rowIndex > 8)) then

exit repeat

end if

colIndex = colIndex + colIncrement

if ((colIndex < 1) or (colIndex > 8)) then

exit repeat

end if

rowList = boardList[rowIndex]

if (rowList[colIndex] = opponent) then

rowList[colIndex] = whoseTurn

else

exit repeat

end if

end repeat

end


---------------------------------------------------------------------

property pRow
property pColumn
property pScore
property pBoardList


-- HANDLER
-- new
-- DESCRIPTION
-- Creates the object, initializes variables
-- INPUT VARIABLES
-- boardList
-- list of 8 lists, representing the board
-- whoseTurn
-- symbol. possible values: ..CYBORG, ..USER
-- levelsToGo
-- integer >= 0, indicating the search depth
-- OUTPUT VARIABLES
-- [HANDLER]
-- reference to the object

on new me, boardList, whoseTurn, levelsToGo

-- We'll generate a list of property lists, each property list
-- containing the necessary details of each possible move.
-- Each property list has the following properties:
-- ..boardList, ..row, ..column

templateList = [..boardList: [], ..row: 0, ..column: 0]

listOfPLists = []

repeat with rowIndex = 1 to 8

repeat with colIndex = 1 to 8

if ( moveOK(boardList, rowIndex, colIndex) ) then

newPList = duplicate(templateList)

newPList.boardList = makeMove(boardList, whoseTurn, rowIndex, colIndex)
newPList.row = rowIndex
newPList.column = colIndex

append listOfPLists, newPList
end if

end repeat

end repeat

-- We've generated a list of possible moves. If no deeper searching is required,
-- set variables and exit

if (whoseTurn = ..CYBORG) then
-- We'll set pScore to the highest score found. Initialize to low value

pScore = -10000

else
-- We'll set pScore to the lowest score found. Initialize to high value

pScore = 10000

end if

if (levelsToGo = 0) then

repeat with pList in listOfPLists

thisScore = computeScore (pList.boardList)

if (((whoseTurn = ..CYBORG) and (thisScore > pScore)) or
((whoseTurn = ..human) and (thisScore < pScore))) then

pScore = thisScore
pBoardList = pList.boardList
pRow = pList.row
pColumn = pList.column

end if

end repeat

return me

end if

-- Deeper searching is required (levelsToGo > 0)

newLevels = levelsToGo - 1

if (whoseTurn = ..CYBORG) then

newTurn = ..USER

else

newTurn = ..CYBORG

end if

repeat with pList in listOfPLists

newChildObject =
new(script "Recursive Analyze Object", pList.boardList, newTurn, newLevels)

thisScore = getScore (newChildObject)

if (((whoseTurn = ..CYBORG) and (thisScore > pScore)) or
((whoseTurn = ..human) and (thisScore < pScore))) then

pScore = thisScore
pBoardList = pList.boardList
pRow = pList.row
pColumn = pList.column

end if

end repeat

return me

end


on getScore me

return pScore

end


on getBoardList me

return pBoardList

end


on getRow me

return pRow

end


on getColumn me

return pColumn

end

-----------------------------------------------------------------------

global gBoardList
global gSpriteList

on startmovie

gBoardList=
[[..empty,..empty,..empty,..empty,..empty,..empty,..empty,..empty],
[..empty,..empty,..empty,..empty,..empty,..empty,..empty,..empty],
[..empty,..empty,..empty,..empty,..empty,..empty,..empty,..empty],
[..empty,..empty,..empty,..cyborg, ..human, ..empty,..empty,..empty],
[..empty,..empty,..empty,..human, ..cyborg, ..empty,..empty,..empty],
[..empty,..empty,..empty,..empty,..empty,..empty,..empty,..empty],
[..empty,..empty,..empty,..empty,..empty,..empty,..empty,..empty],
[..empty,..empty,..empty,..empty,..empty,..empty,..empty,..empty]]

gSpriteList=
[[26, 27, 28, 29, 30, 31, 32, 33],
[35, 36, 37, 38, 39, 40, 41, 42],
[44, 45, 46, 47, 48, 49, 50, 51],
[53, 54, 55, 56, 57, 58, 59, 60],
[62, 63, 64, 65, 66, 67, 68, 69],
[71, 72, 73, 74, 75, 76, 77, 78],
[80, 81, 82, 83, 84, 85, 86, 87],
[89, 90, 91, 92, 93, 94, 95, 96]]


set the member of sprite 56 to "cyborg"
set the member of sprite 66 to "cyborg"
set the member of sprite 57 to "human"
set the member of sprite 65 to "human"
end


on updateSprites

repeat with rowIndex = 1 to 8

rowBoardList = gBoardList [rowIndex]
rowSpriteList = gSpriteList[rowIndex]

repeat with colIndex = 1 to 8

boardValue = rowBoardList [colIndex]
spriteNumber = rowSpriteList[colIndex]

case boardValue of
..empty:
sprite spriteNumber.member = member 2

..cyborg:
sprite spriteNumber.member = member "cyborg"

..human:
sprite spriteNumber.member = member "human"

end case

end repeat

end repeat

updateStage

end


---------------------------------------------------------------------------

global gBoardList
property pRow
property pColumn


-- HANDLER
-- getBehaviorDescription
-- DESCRIPTION
-- Provides a description that appears in the
-- bottom pane of the Behavior Inspector when the
-- behavior is selected.
-- INPUT VARIABLES
-- me
-- Sprite object that this behavior is attached to
-- OUTPUT VARIABLES
-- [HANDLER]
-- Behavior description string


on getBehaviorDescription me
return
"Riddle mouseDown behavior" & RETURN & RETURN &
"This behavior will attempt to make the user's move at the indicated " &
"square of the Riddle board. Human can choose the row and column." & RETURN & RETURN &
"PARAMETERS:" & RETURN &
"* Row (1 - 8)" & RETURN &
"* Column (1 - 8)"
end getBehaviorDescription


-- HANDLER
-- getBehaviorTooltip
-- DESCRIPTION
-- Provides a description that as a tooltip for the behavior
-- INPUT VARIABLES
-- me
-- Sprite object that this behavior is attached to
-- OUTPUT VARIABLES
-- [HANDLER]
-- Tooltip description string

on getBehaviorTooltip me
return
"Riddle mouseDown behavior. " &
"Performs processing when it's the user's turn to make a move."
end getBehaviorTooltip



-- HANDLER
-- getPropertyDescriptionList
-- DESCRIPTION
-- Provides a property list that is used by Director
-- to set the parameters of the behavior
-- INPUT VARIABLES
-- me
-- Sprite object that this behavior is attached to
-- OUTPUT VARIABLES
-- [HANDLER]
-- Property description list


on getPropertyDescriptionList me

return
[
..pRow:
[
..comment: "Row number",
..format: ..integer,
..range: [..min: 1, ..max: 8],
..default: 1
],
..pColumn:
[
..comment: "Column number",
..format: ..integer,
..range: [..min: 1, ..max: 8],
..default: 1
]
]
end getPropertyDescriptionList


-- HANDLER
-- mouseDown
-- DESCRIPTION
-- Performs processing when the user clicks on the sprite
-- INPUT VARIABLES
-- me
-- Sprite object that this behavior is attached to
-- OUTPUT VARIABLES

on mouseDown me

if not (moveOK (gBoardList, pRow, pColumn)) then

exit

end if

-- Do further processing

gBoardList = makeMove( gBoardList, ..human, pRow, pColumn )

newObject = new (script "Recursive Analyze Object", gBoardList, ..cyborg, 2)

gBoardList = getBoardList (newObject )

updateSprites

end

0 Comments:

Post a Comment

<< Home