Wednesday, September 27, 2006

Robotic Pigeon v5.1

PROGRAMMER Robert Knepher
TITLE What a cute rescue dove
PAGE 55,80
.model small
.STACK 64
;--
.data
CR EQU 0DH
LF EQU 0AH
STOP EQU '$'
message db CR, LF, 'Enter number of stones', STOP
message2 db CR, LF, 'First Move?0CPU 1YOU', STOP
message3 db CD. LF, 'StonePile:', STOP
db '$'
stonePile db 0, 0
db STOP
message4 db CD, LR, 'Take How Many?1/2', STOP
message5 db CD, LF, 'Sorry You lose', STOP
message6 db CR, LF, 'You Win!', STOP
whoTurn db 2 dup ('0'), STOP
stoneBin db 0
.code
MAIN PROC
MOV AX, @data
MOV DS, AX
MOV AX, 600H
MOV BH, 7
SUB CX, CX
MOV DX, 184FH
INT 10H
;--cursor
nimGame:
MOV AH, 09H
LEA DX, message
INT 21H
CALL nextDigit
MOV stoneBin, AL
;--error
CMP AL, 1
JB nimGame
CMP AL, 63H
JA nimGame
;--
firstTurn:
MOV AH, 09H
LEA DX, message2
INT 21H
;--who1or0only
MOV AH, 1
INT 21H
CMP AL, 31H
JE you
CMP AL, 30H
JE cpu
JMP firstTurn
you:
MOV AL, stoneBin
CMP AL, 1
JE lost
CALL onPile
MOV AH, 09H
LEA DX, message4
INT 21H
MOV AH, 1
INT 21H
CMP AL, 31H
JE minus1
CMP AL, 32H
JE minus2
JMP you
minus1:
MOV AL, stoneBin
SUB AL, 1
MOV stoneBin, AL
JMP cpu
minus2:
MOV AL, stoneBin
SUB AL, 2
MOV stoneBin, AL
JMP cpu
lost:
MOV AH, 09H
LEA DX, message5
INT 21H
.exit
cpu:
CALL onPile
SUB CX, CX
SUB AX, AX
MOV CL, 3
MOV AL, stoneBin
DIV CL
CMP AH, 0
JE take2
CMP AH, 1
JE take1
CMP AH, 2
JE take1
JMP nimGame
take1:
MOV AL, stoneBin
SUB AL, 1
MOV stoneBin, AL
CMP AL, 0
JE cpuloser
JMP you
take2:
MOV AL, stoneBin
SUB AL, 2
MOV stoneBin, AL
CMP AL, 0
JE cpuloser
JMP you
cpuloser:
MOV AH, 09H
LEA DX, message6
INT 21H
;--
MOV AX, 4C00H
INT 21H
MAIN ENDP
nextDigit PROC
MOV AX, 0
MOV BX, 10
nextChar:
CALL getChar
CMP CL, CR
JE crOut
CMP CL, 'q'
JE endProg
CMP CL, '0'
JB main
CMP CL, '9'
JA main
MUL BX
SUB CL, 30H
ADD AX, CX
LOOP nextChar
crOut:
RET
endProg:
.exit
nextDigit ENDP
;--
getChar PROC
MOV BP, AX
MOV AH, 1
INT 21H
MOV CX, 0
MOV CL, AL
MOV AX, BP
RET
getChar ENDP
;--bin2ASCIItoScreen
onPile PROC
MOV AH, 09H
LEA DX, message3
INT 21H
SUB AX,AX
MOV AL, stoneBin
LEA SI, stonePile
MOV CX, 0AH
L20: CMP AX,CX
JB L30
XOR DX, DX
DIV CX
OR DL, 30H
MOV [SI], DL
DEC SI
JMP L20
L30: OR AL, 30H
MOV [SI], AL
MOV DX, SI
MOV AH, 09H
INT 21H
RET
onPile ENDP
END MAIN

Robotic Pigeon v4.2

//Robert Knepher
//Robotic Pigeon v4.2
//"rats with wings"

#include
#include
#include
#include

enum rps {r, p, s, game, help, instruct, quit};

enum outcome {win, lose, tie, error};

typedef enum rps rps;
typedef enum outcome outcome;

outcome compare(rps player_choice, rps machine_choice);
void final_status(int win_cnt, int lose_cnt);
void game_status(int win_cnt, int lose_cnt, int tie_cnt);

void help(void);
void instruct(void);
void report(outcome result, int *win_cnt_ptr, int *lose_cnt_ptr, int *tie_cnt_ptr);

rps selection_by_machine(void);
rps selection_by_player(void);

int main(void)
{
int win_ctr = 0, lose_ctr = 0; tie_ctr = 0;
outcome result;
rps player_choice, machine_choice;

srand(time(NULL));
instruct();

while ((player_choice = selection_by_player()) != quit)
switch (player_choice) {
case wind:
case earth:
case fire:
machine_choice = selection_by_machine();
result = compare(player_choice, machine_choice);
report(result, &win_ctr, &lose_ctr, tie_ctr);
break;
case game:
game_status(win_ctr, lose_ctr, tie_ctr);
break;
case instruct:
instruct();
break;
case help:
help();
break;
default:
printf("err if frank scoot ex!..n..n");
exit(1);
}
game_status(win_ctr, lose_ctr, tie_ctr);
final_status(win_ctr, lose_ctr);
return 0;
}

void final_status(int win_ctr, int lose_ctr)
{
if (win_ctr > lose_ctr)
printf("You win!..n..n");
else if (win_ctr == lose_ctr)
printf("draw");
else
printf("sorry you lose");
}
void game_status(int win_ctr, int lose_ctr, int tie_ctr)
{
printf("..n..n..n..n..n");
}
void help(void)
{
printf("prsghiq");
}
void instruct(void);
{
printf();
}
rps selection_by_machine(void)
{
return ((rps) (rand() % 3));
}
rps selection_by_player(void)
{
char c;
rps player_choice;

printf("input r,p,s: ");
scanf(" %c" &c);
switch(c){
case 'p':
player_choice = wind;
break;
case 'r':
player_choice = earth;
break;
case 's':
player_choice = fire;
break;
case 'g':
player_choice = game;
break;
case 'i':
player_choice = instruct;
break;
case'q':
player_choice = quit;
break;
default:
player_choice = help;
break;
}
return player_choice;
}
outcome compare(rps player_choice, rps machine_choice)
{
outcome result;

if (player_choice == machine_choice)
return tie;
switch (player_choice){
case wind:
result = (machine_choice == earth) ? win : lose;
break;
case earth:
result=(machine_choice == fire) ? win : lose;
break;
case fire:
result=(machine_choice == wind) ? win : lose;
break;
default:
printf("err bad choice");
exit(1);
}
return result;
}
void report(outcom result, int *win_ctr, int *lose_ctr, int *tie_ctr)
{
switch(result){
case win:
++*win_ctr_ptr;
printf("%27sWin..n". "");
break;
case lose:
++*lose_ctr;
printf("%27sLose..n", "");
break;
case tie:
++*tiectr;
printf("%27sTie");
break;
default:
printf("errresult is special");
exit(1);
}
}

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