.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