zxGammon

play.asm

The title and menu, games and matches, the player's and Gnubby's turns, the doubling cube, the scores. Download · All the source

; ----------------------------------------------------------------- play; The games: the title and menu, a match or money session, and each; game's turns, the cube, and the scores.start:  di        ld sp,0        xor a        out ($fe),a        call init        ld hl,1        ld (SEED),hl        ; the loading screen a while longer, or until a key        xor a                   ; K_ANY        ld (KSET),a        inc a        ld (KWAIT),a        ld b,200.hold:  push bc        call scan        pop bc        or a        jr nz,title        push bc        ld b,1        call pause        pop bc        djnz .hold; The title, and a choice of game.title:  ld sp,0        xor a        ld (KWAIT),a        ld (SAID),a        ld (UP),a               ; the board to be set up again        call cls        ld a,$42        ld (TATTR),a        ld hl,S_TITLE        ld bc,2*256+8        call bigtext        ld a,1        ld (MOOD),a        ld bc,6*256+14        call mascot        ld a,$45        ld (TATTR),a        ld hl,S_WITH        ld bc,11*256+9        call print        ld a,$46        ld (TATTR),a        ld hl,S_MENU        ld bc,13*256+8        call print        ld a,$05        ld (TATTR),a        ld hl,S_FOOT        ld bc,23*256+4        call print.k:     ld a,K_TITLE        ; M for money, else the match's length        call getk        ld b,0        cp 'M'        jr z,.len        sub '0'        ld b,a        cp 8        jr nc,.k        and 1                   ; 1, 3, 5 or 7        jr z,.k.len:   ld a,b        ld (MLEN),a        ld hl,0        ld (SCH),hl        ld (SCC),hl        xor a        ld (CRAW),a; A game.newgame:        ld sp,0        call lgame        ld hl,START        ld de,GB        call copy64        ld a,1        ld (CUBE),a        xor a        ld (OWNER),a        ld (SHOWN),a        ld (MOOD),a        ld (PLAYED),a        ld (U1),a        ld (U2),a        ld (NDONE),a        ld a,25        ld (CURS),a        ld hl,S_HELLO        call say        call drawall        call getkey        ; the opening roll: one die each, the higher starts with both.open:  ld a,3        ld (SHOWN),a        call roll        call tsay        ld hl,S_YOUROLL        call tstr        ld a,(DIE1)        call tdig        ld hl,S_IROLL        call tstr        ld a,(DIE2)        call tdig        ld a,(DIE1)        ld b,a        ld a,(DIE2)        cp b        jr nz,.go        ld hl,S_TIE        call tstr        call tdone        call getkey        jr .open.go:    ld hl,S_YOUSTART        jr c,.h        ld hl,S_ISTART.h:     push af        call tstr        call tdone        call getkey        pop af        ld a,1        jr c,.hum        inc a.hum:   ld (SHOWN),a        dec a        ld (TURN),a        jp nz,cturn1        jp hturn1; The player's turn: first the cube, then the dice.hturn:  xor a        ld (SHOWN),a        ld (U1),a        ld (U2),a        ld (NDONE),a        ld a,25        ld (CURS),a        xor a        ld (TURN),a        call candbl        ld hl,S_ROLL        jr nc,.nd        ld hl,S_ROLLDBL.nd:    call sayplay        ld a,0        ld (MOOD),a        call drawall.k:     call candbl         ; D only if the player may double        ld a,K_ROLL        jr nc,.kr        ld a,K_ROLLD.kr:    call getk        cp 'R'        jr z,.roll        cp ' '        jr z,.roll        cp 13        jr z,.roll        cp 'D'        jr nz,.k        call candbl        jr nc,.k        call hdouble        ret c                   ; Gnubby passed: the game is over.roll:  ld a,1        ld (SHOWN),a        call rollhturn1: call hmove        ld hl,GB        call total        or a        jr nz,cturn        ; the player bore off the last checker        ld a,1        jp won; Gnubby's turn.cturn:  xor a        ld (U1),a        ld (U2),a        ld (NDONE),a        ld (SHOWN),a        ld a,25        ld (CURS),a        ld a,1        ld (TURN),a        call drawall            ; the player's cursor gone        call cdouble        ret c                   ; the player passed        ld a,2        ld (SHOWN),a        call rollcturn1: ld a,25        ld (CURS),a        call cmove        ld hl,GB+32        call total        or a        jp nz,hturn        ld a,2        jp won; won: A = 1 if the player won, 2 Gnubby: its points, and the next game.won:    ld (WINNER),a        ; 1 point, 2 for a gammon (the loser has none off), 3 for a        ; backgammon (and a checker on the bar or in the winner's home)        ld hl,GB+32        cp 1        jr z,.l        ld hl,GB.l:     push hl        call total        pop hl        ld c,1        cp 15        jr nz,.pts        inc c        ld de,18        add hl,de        ld b,7        xor a.bg:    or (hl)        inc hl        djnz .bg        jr z,.pts        inc c.pts:   ld a,c        ld (GAMMON),a        ld a,(CUBE)        ld b,a        xor a.m:     add a,c        djnz .m        jp score; score: A points to WINNER; the score, and a new game, or the match's end.score:  ld (POINTS),a        call lwin        ld a,(POINTS)        ld e,a        ld d,0        ld a,(WINNER)        dec a        ld hl,SCH        jr z,.h        ld hl,SCC.h:     ld a,(hl)        add a,e        ld (hl),a        inc hl        ld a,(hl)        adc a,d        ld (hl),a    ; the Crawford game is the one after a player first needs one point        ld a,(MLEN)        or a        jr z,.said        ld a,(CRAW)        cp 1        jr nz,.nc        inc a        ld (CRAW),a        jr .said.nc:    or a        jr nz,.said        ld a,(MLEN)        dec a        ld hl,SCH        cp (hl)        jr z,.cr        ld hl,SCC        cp (hl)        jr nz,.said.cr:    ld a,1        ld (CRAW),a.said:  call tsay        ld a,(WINNER)        dec a        ld hl,S_YOUWIN        jr z,.w        ld hl,S_IWIN.w:     call tstr        ld a,(POINTS)        call tnum        ld hl,S_POINT        call tstr        ld a,(POINTS)        dec a        jr z,.one        ld a,'S'        call tchr.one:   ld a,(GAMMON)        dec a        jr z,.plain        ld hl,S_GAMMON        dec a        jr z,.g        ld hl,S_BACKG.g:     call tstr.plain: ld a,(WINNER)        dec a        ld hl,S_YAY        ld a,2                  ; Gnubby sad, but a good sport        jr z,.m        ld hl,S_HEHE        ld a,1.m:     ld (MOOD),a        push hl                 ; the second line, unless the match is over        ; the match over?        ld a,(MLEN)        or a        jr z,.money        ld e,a        ld d,0        ld hl,(SCH)        or a        sbc hl,de        ld hl,S_MATCHYOU        jr nc,.over        ld hl,(SCC)        or a        sbc hl,de        ld hl,S_MATCHME        jr nc,.over        pop hl        call tstr        call tdone        call drawall        call cheer        call getkey        jp newgame.over:  pop de        push hl        ld hl,S_NL        call tstr        pop hl        call tstr        call tdone        call drawall        call cheer        call getkey        jp title.money: pop hl        call tstr        ld hl,S_AGAIN        call tstr        call tdone        call drawall        call cheer        ld a,K_AGAIN        call yesno        jp c,newgame        jp title; cheer: a tune for the winner.cheer:  ld a,(WINNER)        dec a        ld hl,T_WIN        jr z,.t        ld hl,T_LOSE.t:     jp tune; ----------------------------------------------------------------- cube; candbl: carry if the side on roll (TURN) may double: the cube theirs or; in the middle, not the Crawford game, and more points in it than they; need, in a match.candbl: ld a,(OWNER)        ld hl,TURN        or a        jr z,.mine        dec a        cp (hl)        jr nz,.no.mine:  ld a,(MLEN)        or a        jr z,.yes        ld a,(CRAW)        dec a        jr z,.no        call need        ld hl,CUBE        cp (hl)        jr c,.no        jr z,.no.yes:   scf        ret.no:    or a        ret; need: A = the points the side on roll needs to win the match.need:   ld a,(TURN)        or a        ld hl,(SCH)        jr z,.h        ld hl,(SCC).h:     ld a,(MLEN)        sub l        ret; hdouble: the player doubles: Gnubby takes (carry clear) or passes (the; game over, carry set).hdouble:        xor a                   ; the player        call ldbl        ld hl,S_DBLYOU        call say        ld a,3        ld (MOOD),a        call drawall        ; take if passing loses the match        ld a,(MLEN)        or a        jr z,.eq        ld hl,CUBE        ld a,(SCH)        add a,(hl)        ld hl,MLEN        cp (hl)        jr nc,.take        ; else if the player's equity is under the take threshold.eq:    ld hl,GB        ld de,ROOT        call copy64        ld a,1        ld (TAKEQ),a        xor a        ld (OWNED),a        call cubeq        ld de,(CT1)        call scmp        jr c,.take.pass:  ld a,$41                ; Gnubby passes        call lone        ld hl,S_IPASS        call say        ld a,2        ld (MOOD),a        call drawall        call getkey        ld a,1        ld (WINNER),a        ld (GAMMON),a        ld a,(CUBE)        call score        scf        ret.take:  ld a,$31                ; Gnubby takes        call lone        ld hl,CUBE        sla (hl)        ld a,2        ld (OWNER),a        ld hl,S_ITAKE        call say        xor a        ld (MOOD),a        call drawall        ld hl,T_DBL        call tune        call getkey        or a        ret; cdouble: Gnubby's turn: it may double; the player takes (carry clear) or; passes (the game over, carry set).cdouble:        call candbl        ret nc        ; after the Crawford game, double at once when the player needs        ; a point and Gnubby more        ld a,(CRAW)        cp 2        jr nz,.eq        ld a,(MLEN)        dec a        ld hl,SCH        cp (hl)        jr z,.dbl.eq:    ld hl,GB        ld de,ROOT        call turn        xor a        ld (TAKEQ),a        ld a,(OWNER)        cp 2        ld a,0        jr nz,.o        inc a.o:     ld (OWNED),a        ld a,1        call cubeq        ; from the lower threshold, and short of too good        push hl        ld de,(CT1)        call scmp        pop hl        jr c,.no        ld de,(CT2)        call scmp        jr c,.dbl.no:    or a        ret.dbl:   ld a,1                  ; Gnubby doubles        call ldbl        ld hl,T_DBL        call tune        call tsay        ld hl,S_IDOUBLE        call tstr        ld a,(CUBE)        add a,a        call tnum        ld hl,S_TAKEQ        call tstr        call tdone        ld a,1        ld (MOOD),a        call drawall        ld a,K_TAKE        call yesno        jr nc,.pass        ld a,$30                ; the player takes        call lone        ld hl,CUBE        sla (hl)        ld a,1        ld (OWNER),a        ld hl,S_YOUTAKE        call say        xor a        ld (MOOD),a        call drawall        ld b,40        call pause        or a        ret.pass:  ld a,$40                ; the player passes        call lone        ld a,2        ld (WINNER),a        ld a,1        ld (GAMMON),a        ld a,(CUBE)        call score        scf        ret; ------------------------------------------------------- the cube's rules; Gnubby judges the cube by an equity for the doubler against three; thresholds: double from, too good from, and take below. In a match they; come from a table (METTAB) made from gnubg's cubeful match equity at the; score and cube, taking the equity for chances with a fixed share of; gammons; in money play (MONEYREC) they follow gnubg's money-play cube; decisions. Each is by who owns the cube and by race or contact. The; equity is the nets' (0-ply); within C_W of a threshold, a ply deeper; (the engine's ply1, up to 6 s); and within C_W2, a ply deeper with; Gnubby's plays chosen by the contact net instead (ply1c, about 14 s).; All in the nets' units, 8192 a point.C_W     equ 2458                ; a ply deeper within 0.3 of a thresholdC_W2    equ 1229                ; with the plays chosen better within 0.15; cubeq: ROOT = a board, the doubler (A: 0 the player, 1 Gnubby) on roll,; OWNED whether they own the cube, TAKEQ whether it is a take -> HL = the; doubler's equity, and the thresholds: CT1 (double from, or take below); and CT2 (too good from).cubeq:  call crec        ld hl,ROOT        call equity        call contact        sbc a,a        and 2        ld (CFLAG),a            ; 0 race, 2 contact        ld hl,(RECP)        ld a,(TAKEQ)        or a        jr z,.dbl        ld a,(CFLAG)        rrca        add a,8        call thr        ld (CT1),hl        ld hl,16383        ld (CT2),hl        jr .e.dbl:   ld a,(OWNED)        add a,a        add a,a        ld b,a        ld a,(CFLAG)        add a,b        push af        call thr        ld (CT1),hl        pop af        inc a        ld hl,(RECP)        call thr        ld (CT2),hl.e:     call res16        ld bc,C_W2        call close        ld de,ply1c             ; very close: the plays chosen better        jr c,.deep        ld bc,C_W        call close        ret nc        ld de,ply1.deep:  push de        ld a,3                  ; thinking        ld (MOOD),a        call drawmasc        ld a,(TAKEQ)            ; his own double: he says he is thinking        or a                    ; (a take follows "YOU DOUBLE? HMM")        ld hl,S_CUBEQ        call z,say        pop hl        call jphl        jp res16jphl:   jp (hl); close: carry if HL is within BC of a threshold: CT1, or for a double; CT2 too. Keeps HL.close:  ld de,(CT1)        call near        ret c        ld a,(TAKEQ)        or a        ret nz        ld de,(CT2)        jr near; near: carry if HL is within BC of DE. Keeps HL, BC.near:   push hl        or a        sbc hl,de        jp p,.pos        xor a        sub l        ld l,a        sbc a,a        sub h        ld h,a.pos:   or a        sbc hl,bc        pop hl        ret; thr: HL -> a record, A = an entry -> HL = its threshold: 80 x the byte,; less 8192; 0 for always, 255 for never.thr:    add a,l        ld l,a        jr nc,.n        inc h.n:     ld a,(hl)        cp 255        ld hl,16383        ret z        or a        ld hl,-16384        ret z        ld l,a        ld h,0        add hl,hl        add hl,hl        add hl,hl        add hl,hl        ld d,h        ld e,l        add hl,hl        add hl,hl        add hl,de               ; 80 x        ld de,-8192        add hl,de        ret; crec: A = the doubler (0 the player, 1 Gnubby) -> RECP = the record for; the game, score and cube: money's, or METTAB's for the doubler 2 to 7; away, the other 1 to 7, and the cube 1, 2 or 4.crec:   ld b,a        ld hl,MONEYREC        ld (RECP),hl        ld a,(MLEN)        or a        ret z        ld c,a        ld a,(SCH)        ld d,a        ld a,(SCC)        ld e,a        ld a,b        or a        jr z,.p        ld a,d        ld d,e        ld e,a.p:     ld a,c        sub d        ld d,a                  ; the doubler's away        ld a,c        sub e        ld e,a                  ; the other's        ld a,(CUBE)        ld b,-1.k:     inc b        rra        jr nc,.k                ; B = log2 of the cube        ld a,b        cp 3        jr c,.kk        ld b,2.kk:    ld a,d        sub 2        ld l,a        add a,a        add a,a        add a,a        sub l                   ; 7 (a - 2)        add a,e        dec a        ld l,a        add a,a        add a,l        add a,b                 ; 3 (7 (a - 2) + b - 1) + k        ld l,a        ld h,0        add hl,hl        ld d,h        ld e,l        add hl,hl        add hl,hl        add hl,de               ; 10 bytes a record        ld de,METTAB        add hl,de        ld (RECP),hl        ret; res16: HL = RES, within -16384 to 16383 (two points).res16:  ld hl,(RES)        ld a,(RES+2)        ld de,16383        or a        jp m,.neg        jr nz,.hi        ld a,h        cp $40        ret c.hi:    ex de,hl        ret.neg:   inc a        jr nz,.lo        ld a,h        cp $c0        ret nc.lo:    ld hl,-16384        ret; scmp: carry if HL < DE, signed. Loses HL.scmp:   ld a,h        xor d        jp m,.diff        or a        sbc hl,de        ret.diff:  ld a,h        rla        ret; equity: HL -> a board -> RES = the side on roll's equity, by the; contact or race net (8192 a point).equity: ld de,PA        call copy64        jp s_last; ----------------------------------------------------------- the player; hmove: the player plays DIE1, DIE2 (DHI, DLO), a checker at a time.hmove:  ld hl,GB        ld de,TB0        call copy64        xor a        ld (NDONE),a        ld (U1),a        ld (U2),a        ld hl,GB        call mx        ld (NMAX),a        or a        jr nz,.can        ld hl,S_NOMOVE        call say        ld a,2        ld (MOOD),a        call drawall        ld hl,0                 ; the player's turn, no play        xor a        call lmove        jp getkey.can:   call first.loop:  xor a        ld (MOOD),a        ld a,(NDONE)        ld hl,NMAX        cp (hl)        jr nz,.more        ld hl,S_DONE        call say        call drawall.dk:    ld a,K_DONE        call getk        cp 13        jr z,.fin        cp ' '        jr z,.fin        cp 'U'        jr nz,.dk        call undo        jr .loop.fin:   ld hl,TSTEPS            ; the player's turn, as played        xor a        jp lmove.more:  ld hl,S_MOVE        call say        call drawall.k:     ld a,K_MOVE        call getk        cp 'D'        jr z,.swap        cp 'Q'                  ; up, towards 24        jr z,.up        cp '7'                  ; (the cursor keys' up)        jr z,.up        cp 'A'                  ; down, towards 1        jr z,.down        cp '6'        jr z,.down        cp 'U'        jr z,.undo        cp 'H'        jr z,.hint        cp '1'        ld hl,DIE1        jr z,.die        cp '2'        ld hl,DIE2        jr z,.die        cp 13        jr z,.any        cp ' '        jr nz,.k.any:   ; the current die, the left unless it is played        ld a,(U1)        or a        jr nz,.rt        ld a,(DIE1)        call tryd        jp nc,.loop        ; it cannot be: the right, if it can, swapped to the left        ld a,(U2)        or a        jr nz,.no        call swapd        ld a,(DIE1)        call tryd        jp nc,.loop        call swapd        jr .no.rt:    ld a,(DIE2).try:   call tryd        jp nc,.loop.no:    ld hl,T_LOSE+4        call tune        jp .k.die:   ld a,(hl)        jr .try.swap:  call swapd        call drawall        jp .k.up:    ld e,1        jr .mv.down:  ld e,-1.mv:    call cursor        call drawall        jp .k.undo:  call undo        jp .loop.hint:  ld hl,S_HINT        call say        ld a,3        ld (MOOD),a        ld a,25                 ; no cursor while he thinks        ld (CURS),a        call drawall        ld hl,TB0        ld de,ROOT        call copy64        call think        ; its steps, for the log: the play generated again, as Gnubby's        ld hl,match        ld (USERFN),hl        ld hl,ROOT        call gen        ld hl,CSTEPS        ld de,TSTEPS        ld bc,8        ldir        ld hl,RESULT        ld de,GB        call copy64        ld a,(NMAX)        ld (NDONE),a        ld a,1        ld (U1),a        ld (U2),a        ld a,25        ld (CURS),a        jp .loop; swapd: the dice (and whether each is played) the other way round.swapd:  ld hl,(DIE1)        ld a,l        ld l,h        ld h,a        ld (DIE1),hl        ld hl,(U1)        ld a,l        ld l,h        ld h,a        ld (U1),hl        ret; undo: the turn's start again.undo:   ld hl,TB0        ld de,GB        call copy64        xor a        ld (NDONE),a        ld (U1),a        ld (U2),a; first: the cursor on the bar, or the highest point with a checker.first:  ld a,$ff                ; no steps yet this turn        ld (TSTEPS),a        ld a,26        ld (CURS),a        ld e,0; cursor: to the next point in direction E (1 up, -1 down) with one of the; player's checkers, or (E = 0) kept if it has one; on the bar while; there are checkers there; none (25) when all are borne off.cursor: ld hl,GB        call total        or a        jr nz,.some        ld a,25        ld (CURS),a        ret.some:  ld a,(GB+24)        or a        ld a,24        jr nz,.set        ld a,e        or a        jr nz,.go        dec e        ld a,(CURS)        cp 24        jr c,.chk        ld a,23        jr .chk.go:    ld a,(CURS)        cp 24        jr c,.l        ld a,24.l:     add a,e        cp 24        jr c,.chk        ld a,e        or a        ld a,23        jp m,.chk        xor a.chk:   push af        ld hl,GB        call index        or a        pop bc        ld a,b        jr z,.l.set:   ld (CURS),a        ret; tryd: A = a die: its step from the cursor, if legal and the rest of the; roll can still be played as it must; carry if not.tryd:   ld e,a        ; the die unplayed?        ld a,(DIE1)        ld b,a        ld a,(DIE2)        cp b        jr z,.ok        ld a,e        cp b        jr nz,.d2        ld a,(U1)        or a        jr z,.ok.d2:    ld a,(DIE2)        cp e        scf        ret nz        ld a,(U2)        or a        scf        ret nz.ok:    ; with only one die to play, the larger if it can be        ld a,(NMAX)        dec a        jr nz,.st        ld a,(MUSTHI)        or a        jr z,.st        ld a,(DHI)        cp e        scf        ret nz.st:    push de        ld hl,GB        ld de,W        call copy64        pop de        ld a,(CURS)        ld b,a        push de        call step        pop de        ret c        ; the rest: as many dice as the roll must play        ld hl,W        push de        ld de,ANIM        call copy64        pop de        ld a,(NDONE)        ld b,a        ld a,(NMAX)        sub b        dec a        jr z,.yes        ld (NEED),a        ld hl,GDIE        ld (hl),e        ld a,(DIE1)        ld b,a        ld a,(DIE2)        cp b        jr z,.dbl        cp e        jr nz,.oth        ld a,b.oth:   ld (hl),a.dbl:   inc l        ld (hl),e        inc l        ld (hl),e        inc l        ld (hl),e        ld (GDOUBLE),a        ld hl,ANIM        ld (GROOT),hl        xor a        ld (GKEYED),a        ld (GPRUNE),a        push de        ld a,(NEED)        call measure        pop de        ld hl,NEED        cp (hl)        ret c.yes:   call lstep        ld hl,ANIM        push de        ld de,GB        call copy64        pop de        ld hl,NDONE        inc (hl)        ; which die        ld a,(DIE1)        cp e        jr nz,.u2        ld hl,U1        ld a,(hl)        or a        jr z,.set.u2:    ld hl,U2.set:   ld (hl),1        ld e,0        call cursor        ld bc,$0430        call tone        or a        ret; mx: HL -> a board, DHI/DLO the dice -> A = how many can be played, and; MUSTHI: only one can, and the larger can.mx:     ld (GROOT),hl        ld de,W        call copy64        xor a        ld (GKEYED),a        ld (GPRUNE),a        ld (MUSTHI),a        ld a,(DHI)        ld b,a        ld a,(DLO)        cp b        jr nz,.nd        ld hl,GDIE        ld (hl),a        inc l        ld (hl),a        inc l        ld (hl),a        inc l        ld (hl),a        ld (GDOUBLE),a        ld a,4        jp measure.nd:    xor a        ld (GDOUBLE),a        call order_a        call measure2        ld (MXA),a        cp 2        ret z        call order_b        call measure2        ld b,a        ld a,(MXA)        cp b        jr nc,.a        ld a,b        ret.a:     or a        ret z        ld (MUSTHI),a        ret; ---------------------------------------------------------------- Gnubby; cmove: Gnubby plays DHI, DLO, shown a checker at a time.cmove:  ld hl,S_THINK        call say        ld a,3        ld (MOOD),a        call drawall        ld hl,GB        ld de,ROOT        call turn        call think        or a        jr nz,.can        ld hl,0                 ; Gnubby's turn, no play        ld a,1        call lmove        call tsay        ld hl,S_ICANT        call tstr        call tdone        ld a,1        ld (PLAYED),a        ld a,2        ld (MOOD),a        call drawall        ld b,100        jp pause.can:   ; its steps: the play generated again, the one giving RESULT        ld hl,match        ld (USERFN),hl        ld hl,ROOT        call gen        ld hl,CSTEPS            ; Gnubby's turn, as played        ld a,1        call lmove        ld hl,ROOT        ld de,ANIM        call copy64        call tsay        ld hl,S_IPLAY        call tstr        ld a,4        ld (CNT),a        ld hl,CSTEPS.s:     ld a,(hl)        cp $ff        jr z,.done        push hl        ld b,a        ld de,4        add hl,de        ld e,(hl)        push de        push bc        ; its notation: from/to, * for a hit        ld a,b        cp 24        jr nz,.pt        ld hl,S_BAR        call tstr        jr .to.pt:    inc a        call tnum.to:    ld a,'/'        call tchr        pop bc        pop de        push bc        push de        ld hl,ANIM        ld de,W        call copy64        pop de        pop bc        call step        push af        ld a,b        sub e        jr nc,.on        ld hl,S_OFF        call tstr        jr .hit.on:    inc a        call tnum.hit:   pop af        or a        jr z,.nh        ld a,'*'        call tchr.nh:    ld a,' '        call tchr        ld hl,W        ld de,ANIM        call copy64        ld hl,ANIM        ld de,GB        call turn        call drawall        ld bc,$0440        call tone        ld b,25        call pause        pop hl        inc hl        ld a,(CNT)        dec a        ld (CNT),a        jr nz,.s.done:  call tdone        ld a,1        ld (PLAYED),a        ld (MOOD),a        call drawall        ld b,50        jp pause; sayplay: says HL, after Gnubby's play if he has just played (without; its "I PLAY" if it would not fit on a line).sayplay:        ld a,(PLAYED)        or a        jp z,say        xor a        ld (PLAYED),a        push hl        ld hl,TXT        xor a        ld bc,0        cpir        ld a,c        add a,33                ; the length with its 0 is -C: carry if        ld hl,TXT               ; 32 or less        jr c,.fit        ld hl,TXT+7.fit:   ld de,TXT2.c:     ld a,(hl)        ld (de),a        inc hl        inc de        or a        jr nz,.c        call tsay        ld hl,TXT2        call tstr        ld a,'|'        call tchr        pop hl        call tstr        jp tdone; think: decide, keeping the dice (it leaves DHI, DLO at the last reply; it looked at).think:  call decide        push af        call setdice        pop af        ret; match: a generated play: its steps kept if it is the chosen one.match:  ld hl,W        ld de,RESULT        ld b,64.c:     ld a,(de)        cp (hl)        ret nz        inc hl        inc de        djnz .c        call mksteps        ld hl,NEWSTEPS        ld de,CSTEPS        ld bc,8        ldir        ret; ----------------------------------------------------------------- text; Building what Gnubby says: tsay starts, tstr/tnum/tdig/tchr add, tdone; says it.tsay:   ld hl,TXT        ld (TXP),hl        rettstr:   ld de,(TXP).l:     ld a,(hl)        or a        jr z,.e        ld (de),a        inc hl        inc de        jr .l.e:     ld (TXP),de        rettdig:   add a,'0'tchr:   ld hl,(TXP)        ld (hl),a        inc hl        ld (TXP),hl        rettnum:   ld l,a        ld h,0        ld de,(TXP)        call utoa        ld (TXP),de        rettdone:  xor a        call tchr        ld hl,TXT        jp say