rendered paste body.nolist
#include "ion.inc"
#include "ti83plus.inc"
.list
.org progstart-2
.db $BB,$6D
xor a ;should be "ret" if using Ion libs
jr nc,begin
.db "Title",0
begin:
b_call(_runindicoff)
b_call(_grbufclr)
set TextWrite,(IY+SgrFlags)
ld a,1
ld (penRow),a
ld a,42
ld (penCol),a
call puttext
.db "Wins:",0
ld a,8
ld (penRow),a
ld a,34
ld (penCol),a
call puttext
.db "Losses:",0
xor a
ld h,a
ld a,(wins)
ld l,a
b_call(_setxxxxop2)
b_call(_op2toop1)
ld a,1
ld (penRow),a
ld a,57
ld (penCol),a
b_call(_dispop1a)
xor a
ld h,a
ld a,(loss)
ld l,a
b_call(_setxxxxop2)
b_call(_op2toop1)
ld a,8
ld (penRow),a
ld a,57
ld (penCol),a
b_call(_dispop1a)
ld hl,ttt_gray2
ld de,ttt_temp2
ld bc,ttt_gray2-ttt_temp2
ldir
xor a
ld b,9
ld hl,board
svLoop:
ld (hl),a
inc hl
djnz svLoop
inc a
ld (cursorX),a
ld (cursorY),a
playerturn:
ld a,1
ld (turn2),a
ld hl,spr_x
ld (turn1),hl
call loadboard
call fastcopy
call checkwin
ptwait4Key:
ld b,2
pt3:
push bc
xor a
ld l,a
ld ix,ttt_temp2
ld c,4
ld b,32
call ilsprite
call getCurOff
ld c,2
ld b,10
ld ix,spr_cursor
call orsprite
call fastcopy
pop bc
djnz pt3
b_call(_getcsc)
or a
jr z,ptwait4key
cp skUp
jr z,up
cp skDown
jr z,down
cp skLeft
jr z,left
cp skRight
jr z,right
cp skClear
jr z,quit
cp sk2nd
call z,checkPlace
jr ptwait4key
eraseCursor:
call getCurOff
ld ix,spr_cursor
ld b,10
ld c,2
call ilsprite
ret
left:
call eraseCursor
ld a,(cursorX)
or a
ret z
dec a
ld (cursorX),a
jr ptwait4key
right:
call eraseCursor
ld a,(cursorX)
cp 2
ret z
inc a
ld (cursorX),a
jr ptwait4key
down:
call eraseCursor
ld a,(cursorY)
cp 2
ret z
inc a
ld (cursorY),a
jp ptwait4key
up:
call eraseCursor
ld a,(cursorY)
or a
ret z
dec a
ld (cursorY),a
jp ptwait4key
quit:
b_call(_homeup)
b_call(_runindicon)
b_call(_clrlcdfull)
b_call(_grbufclr)
ret
getCurOff:
ld a,(cursorY)
call mult11
ld l,a
ld a,(cursorX)
call mult11
ret
checkPlace:
ld a,(cursorY)
ld e,a
add a,a
add a,e
ld e,a
ld a,(cursorX)
add a,e
ld e,a
ld d,0
ld hl,board
add hl,de
ld a,(hl)
or a
ret nz
ld a,(turn2)
ld (hl),a
pop hl
call eraseGray
call loadboard
call getCurOff
inc a
inc l
ld ix,spr_eraseGray
call isprite
call getCurOff
inc a
inc l
ld ix,(turn1)
call isprite
ld a,(turn2)
cp 1
jp nz,playerTurn
AITurn:
call checkWin
ld a,2
ld (turn2),a
ld hl,spr_O
ld (turn1),hl
AIChkPlace:
ld b,8
ld hl,ttt_dat1
ld ix,ttt_dat2
AIchkLoop0:
ld a,(hl)
ld e,a
ld a,(ix)
push bc
push hl
push ix
call chkLine
pop ix
pop hl
inc hl
inc ix
pop bc
djnz AIchkLoop0
AIChk3: ;places piece in unnoccupied place
ld b,3
call random
ld (cursorX),a
ld b,3
call random
ld (cursorY),a
ld e,a
add a,a
add a,e
ld e,a
ld a,(cursorX)
ld hl,board
ld d,0
add hl,de
ld a,(hl)
or a
jr nz,AIChk3
pop hl
pop hl
pop hl
call checkPlace
;===========> Uses inputs to check for a win
;Inputs:
; a = increment
; e = offset
;Outputs:
; None -- places token for AI
AIChkLine:
ld d,0
ld hl,board
add hl,de
ld e,a
ld (temp),hl
ld b,3
xor a
AIChk1: ;checks if AI can win
ld a,(hl)
cp 1
call z,incA
add hl,de
djnz AIChk1
cp 2
jr z,AIPlacePiece
ld hl,(temp)
AIChk2: ;checks if player can win
ld a,(hl)
cp 2
call z,inca
add hl,de
djnz AIChk2
cp 2
ret nz
AIPlacePiece:
sub a
ld de,board
sbc hl,de
ld a,l
ld c,0
cp 3
jr c,AIgetX
inc c
inc c
inc c
sub 3
cp 3
jr c,AIgetX
inc c
inc c
inc c
sub 3
AIgetX:
ld (cursorX),a
ld c,a
ld (cursorY),a
pop hl
pop hl
pop hl
call checkPlace
incA:
inc a
ret
checkWin:
ld b,8
ld hl,ttt_dat1
ld ix,ttt_dat2
chkLoop4:
ld a,(hl)
ld e,a
ld a,(ix)
push bc
push hl
push ix
call chkLine
pop ix
pop hl
inc hl
inc ix
pop bc
or a
jr nz,chkWhoWon
djnz chkLoop4
ret
putText:
pop hl
b_call(_vputs)
jp (hl)
chkWhoWon:
ld a,57
ld (penRow),a
ld a,1
ld (penCol),a
pop hl
cp 1
jr z,playerWon
cp 2
jr z,AIWon
wait4Key:
xor a
ld l,a
ld ix,ttt_temp2
ld c,4
ld b,32
call ilsprite
call fastcopy
b_call(_getcsc)
or a
jr z,wait4Key
cp skClear
ret nz
pop hl
jp quit
catWon:
call puttext
.db "Catz Game!",0
call wait4key
jp begin
playerWon:
call puttext
.db "You Won!",0
call wait4key
ld hl,wins
inc (hl)
jp begin
AIWon:
call puttext
.db "You Lose!",0
call wait4key
ld hl,loss
inc (hl)
jp begin
;===========> Uses inputs to check for a win
;Inputs:
; a = increment
; e = offset
;Outputs:
; a = 1; Player won
; a = 2; AI won
; a = 0; no win
; a = 3; cat's game
ttt_dat1:
.db 0,3,6,0,1,2,0,2
ttt_dat2:
.db 1,1,1,3,3,3,4,2
temp: .dw 0
chkLine:
ld hl,board
ld d,0
add hl,de
ld (temp),hl
ld e,a
ld b,3
chkLoop1:
ld a,(hl)
cp 1
jr nz,chk2
add hl,de
djnz chkLoop1
ret
chk2:
ld hl,(temp)
ld b,3
chkLoop2:
ld a,(hl)
cp 2
jr nz,chk3
add hl,de
djnz chkLoop2
ret
chk3:
ld hl,(temp)
ld b,9
chkLoop3:
ld a,(hl)
or a
jr z,chkNoWin
add hl,de
djnz chkLoop3
ld a,3
ret
chkNoWin:
xor a
ret
loadBoard:
xor a
ld l,a
ld ix,ttt_temp1
ld c,4
ld b,32
call ilsprite
ret
eraseGray:
ld a,(cursorY)
ld l,a
ld h,0
ld d,h
ld e,l
add hl,hl
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,hl
ld de,ttt_temp2
add hl,de
ld a,(cursorX)
or a
jp z,egFirst
inc hl
cp 1
jp z,egSecond
inc hl
egThird:
ld b,2
eg3Loop1:
push bc
ld b,10
eg3Loop2:
ld a,(hl)
and %11111100
ld (hl),a
inc hl
ld a,(hl)
and %00000000
ld (hl),a
inc hl
inc hl
inc hl
djnz eg3Loop2
pop bc
ld de,88
add hl,de
djnz eg3Loop1
ret
egSecond:
ld b,2
eg2Loop1:
push bc
ld b,10
eg2Loop2:
ld a,(hl)
and %11100000
ld (hl),a
inc hl
ld a,(hl)
and %00000111
ld (hl),a
inc hl
inc hl
inc hl
djnz eg2Loop2
pop bc
ld de,88
add hl,de
djnz eg2Loop1
ret
egFirst:
ld b,2
eg1Loop1:
push bc
ld b,10
eg1Loop2:
ld a,(hl)
and %00000000
ld (hl),a
inc hl
ld a,(hl)
and %00111111
ld (hl),a
inc hl
inc hl
inc hl
djnz eg1Loop2
pop bc
ld de,88
add hl,de
djnz eg1Loop1
ret
mult11:
ld e,a
add a,a
add a,a
add a,e
add a,a
add a,e
ret
;================== Functions exactly like iputsprite ==================
isprite:
ld b,8
ld e,l
ld h,$00
ld d,h
add hl,de
add hl,de
add hl,hl
add hl,hl ;Find the Y displacement offset
ld e,a
and $07 ;Find the bit number
ld c,a
srl e
srl e
srl e
add hl,de ;Find the X displacement offset
ld de,plotsscreen
add hl,de
ispriteLoop1:
ld d,(ix) ;loads image byte into D
ld e,$00
ld a,c
or a
jr z,ispriteSkip1
ispriteLoop2:
srl d ;rotate to give out smooth moving
rr e
dec a
jr nz,ispriteLoop2
ispriteSkip1:
ld a,(hl)
xor d
ld (hl),a
inc hl
ld a,(hl)
xor e
ld (hl),a ;copy to buffer using XOR logic
ld de,$0B
add hl,de
inc ix ;Set for next byte of image
djnz ispriteLoop1
ret
fastCopy:
di
exx
ld a,$80 ; 7
out ($10),a ; 11
out ($20),a ; 11 Sets first two bits to zero to slow calc down if 83pse/84xx
ld hl,plotsscreen-12-(-(768)+1) ; 10
ld a,$20 ; 7
ld c,a ; 4
inc hl ; 6 waste
dec hl ; 6 waste
fastCopyAgain:
ld b,64 ; 7
inc c ; 4
ld de,-(12*64)+1 ; 10
out ($10),a ; 11
add hl,de ; 11
ld de,10 ; 10
fastCopyLoop:
add hl,de ; 11
inc hl ; 6 waste
inc hl ; 6 waste
inc de ; 6
ld a,(hl) ; 7
out ($11),a ; 11
dec de ; 6
djnz fastCopyLoop ; 13/8
ld a,c ; 4
cp $2B+1 ; 7
jr nz,fastCopyAgain ; 10/1
exx
ret
;-----------Ion Large Sprite-----------
;Input: ix->sprite
; a=x
; l=y
; b=height (in pixels)
; c=width (in bytes, e.g. 2 would be 16)
;Output: nothing
; All registers are destroyed except bc', de', hl'
ilsprite:
di
ex af,af'
ld a,c
push af
ex af,af'
ld e,l
ld h,$00
ld d,h
add hl,de
add hl,de
add hl,hl
add hl,hl
ld e,a
and $07
ld c,a
srl e
srl e
srl e
add hl,de
ld de,gbuf
add hl,de
ilspriteLoop1:
push hl
ilspriteLoop2:
ld d,(ix)
ld e,$00
ld a,c
or a
jr z,ilspriteSkip1
ilspriteLoop3:
srl d
rr e
dec a
jr nz,ilspriteLoop3
ilspriteSkip1:
ld a,(hl)
xor d
ld (hl),a
inc hl
ld a,(hl)
xor e
ld (hl),a
inc ix
ex af,af'
dec a
push af
ex af,af'
pop af
jr nz,ilspriteLoop2
pop hl
pop af
push af
ex af,af'
ld de,$0C
add hl,de
djnz ilspriteLoop1
pop af
ret
orsprite:
di
ex af,af'
ld a,c
push af
ex af,af'
ld e,l
ld h,$00
ld d,h
add hl,de
add hl,de
add hl,hl
add hl,hl
ld e,a
and $07
ld c,a
srl e
srl e
srl e
add hl,de
ld de,gbuf
add hl,de
orspriteLoop1:
push hl
orspriteLoop2:
ld d,(ix)
ld e,$00
ld a,c
or a
jr z,orspriteSkip1
orspriteLoop3:
srl d
rr e
dec a
jr nz,orspriteLoop3
orspriteSkip1:
ld a,(hl)
or d
ld (hl),a
inc hl
ld a,(hl)
or e
ld (hl),a
inc ix
ex af,af'
dec a
push af
ex af,af'
pop af
jr nz,orspriteLoop2
pop hl
pop af
push af
ex af,af'
ld de,$0C
add hl,de
djnz orspriteLoop1
pop af
ret
;-----> Generate a random number
; input b=upper bound
; ouput a=answer 0<=a<b
; all registers are preserved except: af and bc
random:
push hl
push de
ld hl,(Temp)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (Temp),hl
sbc hl,hl
ld e,a
ld d,h
randomLoop:
add hl,de
djnz randomLoop
ld a,h
pop de
pop hl
ret
turn1: .dw 0
turn2: .db 0
cursorX: .db 0
cursorY: .db 0
ttt_temp2:
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$00,$00,$00,$00,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$00,$00,$00,$00,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
ttt_temp1:
.db $00,$20,$04,$00,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$00,$20,$04,$00,$FF,$FF,$FF,$FF,$00,$20,$04,$00
.db $55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA
.db $55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA
.db $00,$20,$04,$00,$FF,$FF,$FF,$FF,$00,$20,$04,$00,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$00,$20,$04,$00
ttt_gray2:
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$00,$00,$00,$00,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$00,$00,$00,$00,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
.db $FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF,$FF,$DF,$FB,$FF
ttt_gray:
.db $00,$20,$04,$00,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$00,$20,$04,$00,$FF,$FF,$FF,$FF,$00,$20,$04,$00
.db $55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA
.db $55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA
.db $00,$20,$04,$00,$FF,$FF,$FF,$FF,$00,$20,$04,$00,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$55,$2A,$A5,$54
.db $2A,$A5,$54,$AA,$55,$2A,$A5,$54,$2A,$A5,$54,$AA,$00,$20,$04,$00
board:
.db 0,0,0
.db 0,0,0
.db 0,0,0
spr_X:
.db %10000001
.db %01000010
.db %00100100
.db %00011000
.db %00011000
.db %00100100
.db %01000010
.db %10000001
spr_O:
.db %00111100
.db %01000010
.db %10000001
.db %10000001
.db %10000001
.db %10000001
.db %01000010
.db %00111100
spr_cursor:
.db %11111111,%11000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %10000000,%01000000
.db %11111111,%11000000
spr_eraseGray:
.db %010101010
.db %101010101
.db %010101010
.db %101010101
.db %010101010
.db %101010101
.db %010101010
.db %101010101
wins: .db 0
loss: .db 0
.end
.end