!---------------------------------!
!        ***  CRIB  ***           !
!                                 !
!  Cribbage Program - version 0.0 !
!                                 !
!  By Thomas M. Niccum            !
!     21 MARCH 1982               !
!---------------------------------!


!---------------------------------!
! Maps                            !
!---------------------------------!

MAP1    hand(3,6)
       MAP2    shdc,b,1
       MAP2    value,b,1

MAP1    suit(4),s,8
MAP1    card(13),s,5
MAP1    deck'map(52),b,1
MAP1    crib'indicator(2),s,9
MAP1    play'stack(8)
       MAP2    play'suit,b,1
       MAP2    play'card,b,1
MAP1    run'list(8),b,1

MAP1    tuple(5,10,5),b,1

MAP1    hand'indicator(3),s,10

MAP1    pair'score(4),b,1

MAP1    true,b,1,1
MAP1    false,b,1,0

!-------------------------------------------------------------------------!
! Main Program
!-------------------------------------------------------------------------!

main'program:
       CALL initialize
       CALL play
END


!-------------------------------------------------------------------------!
! Level 1 Subroutines
!-------------------------------------------------------------------------!

initialize:
       ?TAB(-1,0);
       ?TAB(9,10); "+-----------------------------------+"
       ?TAB(10,10);"|      C  R  I  B  B  A  G  E       |"
       ?TAB(11,10);"|          version 1.0              |"
       ?TAB(12,10);"|         by Tom Niccum             |"
       ?TAB(13,10);"+-----------------------------------+"
       suit(1)="Spades"
       suit(2)="Hearts"
       suit(3)="Diamonds"
       suit(4)="Clubs"
       card(1)="Ace"
       card(2)="Two"
       card(3)="Three"
       card(4)="Four"
       card(5)="Five"
       card(6)="Six"
       card(7)="Seven"
       card(8)="Eight"
       card(9)="Nine"
       card(10)="Ten"
       card(11)="Jack"
       card(12)="Queen"
       card(13)="King"
       crib'indicator(1)=" My Crib "
       crib'indicator(2)="Your Crib"
       hand'indicator(1)="Computer"
       hand'indicator(2)="Human"
       hand'indicator(3)="Crib"
       pair'score(2)=2
       pair'score(3)=6
       pair'score(4)=12
       CALL tuple'initialize

       RANDOMIZE
       CALL cut'for'deal
RETURN



play:
       ?TAB(-1,0);TAB(1,35)"C R I B B A G E ";
       ?TAB(2,1);"My Hand is:";
       ?TAB(12,1);"Your Hand is:";
       ?TAB(6,60);"    SCOREBOARD";
       ?TAB(8,60);" The";TAB(8,70);"  The ";
       ?TAB(9,60);"Human";TAB(9,70);"Computer";
       ?TAB(10,60);"-----";TAB(10,70);"--------";
       ?TAB(22,1);"The Up-card is:";
       ?TAB(14,60);"------";crib'indicator(dealer);"------";
       CALL init'screen
       CALL score'board
       CALL deal'hand
       CALL display'hand
       CALL discard
       CALL up'card
       CALL play'hand
       CALL tally'points
       IF dealer=1 THEN dealer=2 ELSE dealer=1
GOTO play

!-------------------------------------------------------------------------!
! Level 2 Subroutines
!-------------------------------------------------------------------------!

tuple'initialize:
       FOR a=1 TO 5
               FOR b=1 TO 10
                       FOR c=1 TO 5
                                       tuple(a,b,c)=0
                       NEXT c
               NEXT b
       NEXT a

       tuple(1,1,1)=1
       tuple(1,2,1)=2
       tuple(1,3,1)=3
       tuple(1,4,1)=4
       tuple(1,5,1)=5

       tc=0
       FOR a=1 TO 4
               FOR b=a+1 TO 5
                       tc=tc+1
                       tuple(2,tc,1)=a
                       tuple(2,tc,2)=b
               NEXT b
       NEXT a

       tc=0
       FOR a=1 TO 3
               FOR b=a+1 TO 4
                       FOR c=b+1 TO 5
                               tc=tc+1
                               tuple(3,tc,1)=a
                               tuple(3,tc,2)=b
                               tuple(3,tc,3)=c
                       NEXT c
               NEXT b
       NEXT a

       tc=0
       FOR a=1 TO 2
               FOR b=a+1 TO 3
                       FOR c=b+1 TO 4
                               FOR d=c+1 TO 5
                                       tc=tc+1
                                       tuple(4,tc,1)=a
                                       tuple(4,tc,2)=b
                                       tuple(4,tc,3)=c
                                       tuple(4,tc,4)=d
                               NEXT d
                       NEXT c
               NEXT b
       NEXT a

       tuple(5,1,1)=1
       tuple(5,1,2)=2
       tuple(5,1,3)=3
       tuple(5,1,4)=4
       tuple(5,1,5)=5
RETURN


cut'for'deal:
       CALL init'deck'map
       ?TAB(20,10);:INPUT "Ready to cut for the Deal?" y$
       IF ucs(y$[1,1])#"Y" THEN GOTO cut'for'deal
       CALL deal'one'card
       ?TAB(22,15);"You cut up the ";card(c);" of ";suit(s);
       h=c
       CALL deal'one'card
       ?TAB(23,15);"  I got the ";card(c);" of ";suit(s);
       i=c
       IF i=h THEN ?tab(24,15);"** A Tie, lets do it again **"; : GOTO cut'for'deal
       IF h<i THEN dealer=2
       IF i<h THEN dealer=1
       IF dealer=2 THEN ?TAB(24,15);"Your Deal....Hit RETURN to start the game";
       IF dealer=1 THEN ?TAB(24,15);"My Deal......Hit RETURN to start the Game";
       INPUT x
RETURN

init'screen:
       FOR x=1 TO 6
               FOR y=1 TO 2
                       ?TAB((y-1)*10+3+x,1);SPACE(30);
               NEXT y
       NEXT x
       FOR x=1 TO 4
               ?TAB(15+x,60);SPACE(21);
       NEXT x
       ?TAB(23,6);SPACE(30);TAB(24,6);SPACE(30);
RETURN


score'board:
       ?TAB(11,60);points(2) using "####";TAB(11,70);points(1) using "#####";
       winner=0
       IF points(2)=>121 THEN winner=2 : loser=1
       IF points(1)=>121 THEN winner=1 : loser=2
       IF winner=0 THEN RETURN
       ?TAB(-1,0);
       ?TAB(10,20)"The Final Score:";
       ?TAB(12,30);"Computer:  ";points(1) USING "###";
       ?TAB(13,30);"Human:     ";points(2) USING "###";
       ?TAB(16,20);"The ";hand'indicator(winner);" beats ";
       IF points(loser)>90 THEN ?"the ";hand'indicator(loser);"!!!";
       IF points(loser)>90 THEN PRINT : GOTO end'it
       IF points(loser)<61 THEN d$=" double " ELSE d$=""
       ?" and ";d$;"skunks the ";hand'indicator(loser);"!!!"
end'it:
END

deal'hand:
       CALL init'deck'map
       IF dealer=1 THEN first=2 : second=1 : increment=-1
       IF dealer=2 THEN first=1 : second=2 : increment=1
       FOR pair=1 TO 6
               FOR player=first TO second step increment
                       CALL deal'one'card
                       shdc(player,pair)=s
                       value(player,pair)=c
               NEXT player
       NEXT pair
RETURN

display'hand:
       CALL sort'players'cards
       IF dealer=1 THEN first=2 : second=1 : increment=-1
       IF dealer=2 THEN first=1 : second=2 : increment=1
       FOR pair=1 TO 6
               FOR player=first TO second step increment
                       ?TAB((player-1)*10+3+pair,4);SPACE(30);
                       IF shdc(player,pair)=0 THEN GOTO skip'card
                       IF player=1 THEN ?TAB((player-1)*10+3+pair,4);pair;"-";"*****";" of ";"********"; &
                               ELSE ?TAB((player-1)*10+3+pair,4);pair;"-";card(value(player,pair));" of ";suit(shdc(player,pair));
               skip'card:
               NEXT player
       NEXT pair
RETURN

discard:
       CALL computer'discard
       CALL human'discard
RETURN

up'card:
       CALL deal'one'card
       ?TAB(23,6);card(c);" of ";suit(s);
       up'card(1)=s : up'card(2)=c
       IF up'card(2)=11 THEN points(dealer)=points(dealer)+2 : &
               ?TAB((10*(dealer-1)+5),28);crib'indicator(dealer)[1,4];" Nobs, 2 points!!";
       CALL score'board
RETURN

play'hand:
       ?TAB(7,35);SPACE(20);TAB(17,35);SPACE(20);TAB(18,35);SPACE(20);
       ?TAB(12,25);"Play Total =>";
       player=dealer
       human'cards=4
       computer'cards=4
       stack'pointer=1
       computer'go=0 : human'go=0
       play'stack'total=0
       play=1

       next'play:
               IF player=1 THEN player=2 ELSE player=1
               IF human'go=1 THEN player=1
               IF computer'go=1 THEN player=2
               ON player CALL computer'plays,human'plays
               IF computer'go#0 AND human'go#0 THEN CALL go'score :&
                       computer'go=0 : human'go=0 : play'stack'total=0 : stack'pointer=0 :&
                       IF computer'cards=0 THEN computer'go=1 &
                       ELSE IF human'cards=0 THEN human'go=1
               stack'pointer=stack'pointer+1
               ?TAB(12,40);play'stack'total;
       IF play<=8 THEN GOTO next'play
       ?TAB(10,30);SPACE(15);TAB(23,30);SPACE(15);TAB(12,25);SPACE(25);
RETURN

tally'points:
       IF dealer=1 THEN non'dealer=2 ELSE non'dealer=1
       player=non'dealer
       CALL tally'a'hand
       IF points(player)=>121 THEN CALL score'board

       player=dealer
       CALL tally'a'hand
       IF points(player)=>121 THEN CALL score'board

       player=3 !CRIB!
       CALL tally'a'hand
       IF points(dealer)=>121 THEN CALL score'board
RETURN


!-------------------------------------------------------------------------!
! Level 3 Subroutines
!-------------------------------------------------------------------------!

init'deck'map:
       FOR x=1 TO 52
               deck'map(x)=0
       NEXT x
RETURN

deal'one'card:
       s=int(rnd(1)*4)+1
       c=int(rnd(1)*13)+1
       v=((s-1)*13)+c
       IF deck'map(v)#0 THEN GOTO deal'one'card
       deck'map(v)=1
RETURN


computer'discard:
       ?TAB(7,35);"I'm tossing two";
       CALL evaluate'hand
       discard'1=toss'1
       discard'2=toss'2
       player=1
       CALL show'discard
RETURN

human'discard:
       discard'1=0 : discard'2=0

       ?TAB(17,35);"Your first toss";
       INPUT discard'1
       IF discard'1=<0 OR discard'1>6 THEN GOTO human'discard
human'discard'2:
       ?TAB(18,35);"Your second toss";
       INPUT discard'2
       IF discard'2=<0 OR discard'2>6 OR discard'2=discard'1 THEN GOTO human'discard'2
       player=2
       CALL show'discard
RETURN

human'plays:
       IF human'cards=0 THEN RETURN
       ?TAB(23,30);"Play a card"; : INPUT x
       IF x<0 OR x>4 THEN GOTO human'plays
       ?TAB(5,28);SPACE(25)TAB(6,28);SPACE(25);;TAB(15,28);SPACE(25);TAB(16,28);SPACE(25);
       IF x=0 THEN human'go=1+computer'go : RETURN
       IF shdc(2,x)>10 THEN GOTO human'plays
       play'card=value(2,x)
       IF play'card>10 THEN play'card=10
       IF play'stack'total+play'card>31 THEN GOTO human'plays

       play'suit(stack'pointer)=shdc(2,x)
       play'card(stack'pointer)=value(2,x)
       shdc(2,x)=shdc(2,x)+10
       play'stack'total=play'stack'total+play'card
       ?TAB(13+x,1);SPACE(30);
       CALL play'stack'scoring
       play=play+1
       human'cards=human'cards-1
       IF human'cards=0 THEN human'go=1+computer'go
RETURN

computer'plays:
       IF computer'cards=0 THEN RETURN
       ?TAB(5,28);SPACE(25)TAB(6,28);SPACE(25);;TAB(15,28);SPACE(25);TAB(16,28);SPACE(25);
       ?TAB(10,30);SPACE(29);
       IF computer'cards>1 THEN CALL evaluate'play : GOTO skip'evaluate
       FOR y=1 TO 4
               IF shdc(1,y)<10 THEN x=y : y=5
       NEXT y
       play'card=value(1,x)
       IF play'card>10 THEN play'card=10
       IF play'stack'total+play'card>31 THEN x=0
skip'evaluate:
       IF x=0 THEN computer'go=1+human'go : ?TAB(10,30);"GO!"; : RETURN
       ?TAB(10,30);"I Play the ";card(value(1,x));" of ";suit(shdc(1,x));
       play'suit(stack'pointer)=shdc(1,x)
       play'card(stack'pointer)=value(1,x)
       shdc(1,x)=shdc(1,x)+10
       play'stack'total=play'stack'total+play'card
       ?TAB(3+x,1);SPACE(30);
       CALL play'stack'scoring
       play=play+1
       computer'cards=computer'cards-1
       IF computer'cards=0 THEN computer'go=1+human'go
RETURN

go'score:
       IF play'stack'total<31 THEN points(human'go)=points(human'go)+1 : &
       CALL score'board : ?TAB((10*(human'go-1)+6),28);"A GO for 1!";
RETURN

tally'a'hand:
       IF player#3 THEN ?TAB(-1,0);hand'indicator(player);"'s Hand Scoring"
       IF player=3 THEN ?TAB(-1,0);hand'indicator(dealer);"'s Crib scoring"
       ?
       ?"The hand shows:"
       FOR x=1 TO 4
               IF shdc(player,x)>10 THEN shdc(player,x)=shdc(player,x)-10
               play'suit(x)=shdc(player,x)
               play'card(x)=value(player,x)
               ?"The ";card(value(player,x));" of ";suit(shdc(player,x))
       NEXT x
       play'suit(5)=up'card(1)
       play'card(5)=up'card(2)
       ?"The ";card(up'card(2));" of ";suit(up'card(1));" (Up Card)"
       FOR x=6 TO 8
               play'suit(x)=0
               play'card(x)=0
       NEXT x
       CALL calculate'points
       IF fifteen'count>0 THEN ?fifteen'count;" Fifteens for ";fifteen'count*2
       IF pair'count>0 THEN ?pair'count;" Pairs for ";pair'count*2
       IF run'5'count>0 THEN ?run'5'count;" Runs of 5 for ";run'5'count*5
       IF run'4'count>0 THEN ?run'4'count;" Runs of 4 for ";run'4'count*4
       IF run'3'count>0 THEN ?run'3'count;" Runs of 3 for ";run'3'count*3
       IF flush'count>0 THEN ?" A flush of ";flush'count;" for ";flush'count
       IF nibs'count>0 THEN  ?" Nibs for ";nibs'count
       ?
       ?"Total Points for this hand is ";hand'points
       INPUT x
       IF player<3 THEN points(player)=points(player)+hand'points ELSE &
               points(dealer)=points(dealer)+hand'points
RETURN


!-------------------------------------------------------------------------!
! Level 4 Subroutines
!-------------------------------------------------------------------------!

evaluate'hand:
       optimal'score=0
       toss'1=1
       toss'2=2
       for eh1=1 to 5
               for eh2=eh1+1 to 6
                       y=1
                       for x=1 to 6
                               IF x#eh1 AND x#eh2 THEN &
                                       play'card(y)=value(1,x) : &
                                       play'suit(y)=shdc(1,x)  : y=y+1
                       next x
                       play'card(5)=-10 : play'suit(5)=-10
                       play'card(6)=-10 : play'suit(6)=-10
                       test'hand:
                               CALL calculate'points
                               CALL calculate'toss
                               IF dealer=1 THEN sign=1 ELSE sign=-1
                               toss'points=toss'points*sign
                               total'points=hand'points+toss'points
                               IF total'points<=optimal'score THEN GOTO next'try
                               optimal'score=total'points
                               toss'1=eh1
                               toss'2=eh2
               next'try:
               NEXT eh2
       NEXT eh1
RETURN


evaluate'play:
       run'test:
               IF stack'pointer<3 THEN GOTO fifteen'test
               r1=play'card(stack'pointer-2)
               r2=play'card(stack'pointer-1)
               d=ABS(r1-r2)
               IF d=0 OR d>2 THEN GOTO fifteen'test
               IF r1>r2 THEN t=r2 : r2=r1 : r1=t
               IF d=1 THEN runner'1=r1-1 : runner'2=r2+1
               IF d=2 THEN runner'1=r1+1 : runner'2=0
               IF play'stack'total+runner'1>31 then runner'1=0
               IF play'stack'total+runner'2>31 THEN runner'2=0
               IF runner'1+runner'2
=0 THEN GOTO fifteen'test
               y=0 : z=0
               FOR x=1 TO 4
                       IF value(1,x)=runner'1 AND shdc(1,x)<10 THEN y=x
                       IF value(1,x)=runner'2 AND shdc(1,x)<10 THEN z=x
               NEXT x
               IF y+z=0 THEN GOTO fifteen'test
               IF y#0 AND z=0 THEN x=y : GOTO play'computer'card
               IF y=0 AND z#0 THEN x=z : GOTO play'computer'card
               t1=runner'1+play'stack'total
               t2=runner'2+play'stack'total
               IF t1=15 OR t1=31 THEN x=y ELSE x=z
       GOTO play'computer'card

       fifteen'test:
               x=0
               next'fifteen'test:
                       x=x+1
                       IF x>4 THEN x=0 : GOTO pair'test
                       IF shdc(1,x)>10 THEN GOTO next'fifteen'test
                       play'card=value(1,x)
                       IF play'card>10 THEN play'card=10
                       IF play'stack'total+play'card=15 THEN GOTO play'computer'card
                       IF play'stack'total+play'card=31 THEN GOTO play'computer'card
                       IF play'stack'total+play'card>31 THEN GOTO next'fifteen'test
               GOTO next'fifteen'test

       pair'test:
                       IF stack'pointer<2 THEN GOTO last'resort
                       x=x+1
                       IF x>4 THEN x=0 : GOTO last'resort
                       IF shdc(1,x)>10 THEN GOTO pair'test
                       play'card=value(1,x)
                       IF play'stack'total+play'card>31 THEN GOTO pair'test
                       IF value(1,x)=play'card(stack'pointer-1) THEN GOTO play'computer'card
       GOTO pair'test

       last'resort:
               x=0
               first'scan=true
               next'computer'card:
                       x=x+1
                       IF x>4 AND first'scan=false then x=1
                       IF x>4 THEN x=0 : GOTO play'computer'card
                       IF shdc(1,x)>10 THEN GOTO next'computer'card
                       play'card=value(1,x)
                       IF play'card>10 THEN play'card=10
                       IF play'stack'total+play'card>31 THEN GOTO next'computer'card
                       IF play'card=5 AND first'scan=true AND &
                               computer'cards>1 AND stack'pointer=1 AND &
                               x<4 THEN first'scan=false:GOTO next'computer'card
       play'computer'card:
       IF play'card>10 THEN play'card=10
RETURN

show'discard:
       shdc(3,((player-1)*2)+1)=shdc(player,discard'1)
       value(3,((player-1)*2)+1)=value(player,discard'1)
       shdc(3,((player-1)*2)+2)=shdc(player,discard'2)
       value(3,((player-1)*2)+2)=value(player,discard'2)
       shdc(player,discard'1)=0
       shdc(player,discard'2)=0
       value(player,discard'1)=0
       value(player,discard'1)=0

       x=0
compress:
       x=x+1 : IF x=5 THEN GOTO show'crib
compress'2:
       IF shdc(player,x)#0 THEN GOTO compress
       FOR y=x TO 5
               shdc(player,y)=shdc(player,y+1) : value(player,y)=value(player,y+1)
       NEXT y
       shdc(player,6)=0 : value(player,6)=0
GOTO compress'2

show'crib:
       FOR pair=1 TO 6
               ?TAB((player-1)*10+3+pair,4);SPACE(30);
               IF pair>4 THEN GOTO skip'discard
               IF player=1 THEN ?TAB((player-1)*10+3+pair,4);pair;"-";"*****";" of ";"********"; &
                       ELSE ?TAB((player-1)*10+3+pair,4);pair;"-";card(value(player,pair));" of ";suit(shdc(player,pair));
       skip'discard:
       NEXT pair

       FOR x=1 TO ((player-1)*2)+2
               ?TAB(15+x,60);x;"-";"*****";" ** ";"********"
       NEXT x
RETURN

play'stack'scoring:
       ?TAB(12,40);play'stack'total;
       IF play'stack'total=15 THEN points(player)=points(player)+2:&
               CALL score'board : ?TAB((10*(player-1)+5),28);"Fifteen for 2!";
       IF play'stack'total=31 THEN points(player)=points(player)+2:&
               human'go=1 : computer'go=1 :&
               CALL score'board : ?TAB((10*(player-1)+5),28);"Thiry One for 2!";
       IF stack'pointer<4 THEN GOTO skip'4'of'kind
       IF play'card(stack'pointer)=play'card(stack'pointer-1) AND &
          play'card(stack'pointer-1)=play'card(stack'pointer-2) AND &
          play'card(stack'pointer-2)=play'card(stack'pointer-3) THEN &
               points(player)=points(player)+12 : &
               CALL score'board : ?TAB((10*(player-1)+5),28);"Four of a Kind for 12!";&
               : GOTO skip'2'of'kind

skip'4'of'kind:
       IF stack'pointer<3 THEN GOTO skip'3'of'kind
       IF play'card(stack'pointer)=play'card(stack'pointer-1) AND &
          play'card(stack'pointer-1)=play'card(stack'pointer-2) THEN &
               points(player)=points(player)+6 : &
               CALL score'board : ?TAB((10*(player-1)+5),28);"Three of a Kind for 6!";&
               : GOTO skip'2'of'kind

skip'3'of'kind:
       IF stack'pointer<2 THEN GOTO skip'2'of'kind
       IF play'card(stack'pointer)=play'card(stack'pointer-1) THEN &
               points(player)=points(player)+2 : &
               CALL score'board : ?TAB((10*(player-1)+5),28);"Two of a Kind for 2!";

skip'2'of'kind:
       IF stack'pointer<3 THEN GOTO stack'score'exit
!*** check for run of 5 ***
       IF stack'pointer<5 THEN GOTO check'run'of'4
       FOR r=stack'pointer-4 TO stack'pointer
               run'list(r)=play'card(r)
       NEXT r
       r=5
       CALL check'for'run
       IF run'points=5 THEN GOTO stack'score'exit
check'run'of'4:
       IF stack'pointer<4 THEN GOTO check'run'of'3
       FOR r=stack'pointer-3 TO stack'pointer
               run'list(r)=play'card(r)
       NEXT r
       r=4
       CALL check'for'run
       IF run'points=4 THEN GOTO stack'score'exit
check'run'of'3:
       IF stack'pointer<3 THEN GOTO stack'score'exit
       FOR r=stack'pointer-2 TO stack'pointer
               run'list(r)=play'card(r)
       NEXT r
       r=3
       CALL check'for'run

stack'score'exit:
RETURN


calculate'points:
               hand'points=0
               CALL fifteens
               hand'points=hand'points+points
               CALL runs
               hand'points=hand'points+points
               CALL flushes
               hand'points=hand'points+points
               CALL pairs'and'better
               hand'points=hand'points+points
               CALL nibs
               hand'points=hand'points+points
RETURN

calculate'toss:
       toss'points=0
       v1=value(1,eh1)
       s1=shdc(1,eh1)
       v2=value(1,eh2)
       s2=shdc(1,eh2)
       IF v1=5 THEN toss'points=toss'points+2
       IF v2=5 THEN toss'points=toss'points+2
       IF v1=v2 THEN toss'points=toss'points+2
       IF v1+v2=15 THEN toss'points=toss'points+2
       IF v1=11 AND dealer=2 THEN toss'points=toss'points+.25
       IF v2=11 AND dealer=2 THEN toss'points=toss'points+.25
       IF s1=s2 THEN toss'points=toss'points+.25
       IF ABS(v1-v2)=1 THEN toss'points=toss'points+1
       IF ABS(v1-v2)=2 THEN toss'points=toss'points+.5
RETURN



!-------------------------------------------------------------------------!
! Level 5 Subroutines
!-------------------------------------------------------------------------!

fifteens:
       points=0
       fifteen'count=0
       FOR x=5 TO 2 STEP -1
               FOR y=1 TO 10
                       fifteen=0
                       FOR z=1 TO x
                               IF tuple(x,y,z)=0 THEN GOTO tuple'done
                               play'card=play'card(tuple(x,y,z))
                               IF play'card>10 AND play'card<=13 THEN play'card=10
                               fifteen=fifteen+play'card
                       tuple'done:
                       NEXT z
                       IF fifteen=15 THEN fifteen'count=fifteen'count+1
               NEXT y
       NEXT x
       points=fifteen'count*2
RETURN

pairs'and'better:
       points=0
       pair'count=0
       FOR y=1 TO 10
               pair'found=true
               FOR z=1 TO 2
                       IF pair'found=false THEN GOTO pair'tuple'done
                       IF tuple(2,y,z)=0 THEN pair'found=false : &
                               GOTO pair'tuple'done
                       IF z=1 THEN prior=play'card(tuple(2,y,z)) :&
                               GOTO pair'tuple'done
                       IF play'card(tuple(2,y,z))#prior THEN pair'found=false
               pair'tuple'done:
               NEXT z
               IF pair'found=true THEN points=points+2 : pair'count=pair'count+1
       NEXT y
RETURN

runs:
       run'5'count=0
       run'4'count=0
       run'3'count=0
       points=0
       run'points=0
       runs'of'four=false
       FOR a=1 TO 5
               run'list(a)=play'card(a)
       NEXT a
       r=5
       CALL sort'run
       CALL check'run
       IF run'points=5 THEN run'5'count=1 : points=points+5 : GOTO runs'exit
       FOR a=1 TO 5
               FOR b=1 TO 4
                       run'list(b)=play'card(tuple(4,a,b))
               NEXT b
               r=4
               CALL sort'run
               CALL check'run
               IF run'points=4 THEN run'4'count=run'4'count+1 : points=points+4 : &
                       runs'of'four=true
       NEXT a
       IF runs'of'four=true THEN GOTO runs'exit

       FOR a=1 TO 10
               FOR b=1 TO 3
                       run'list(b)=play'card(tuple(3,a,b))
               NEXT b
               r=3
               CALL sort'run
               CALL check'run
               IF run'points=3 THEN run'3'count=run'3'count+1 : points=points+run'points
       NEXT a

       runs'exit:
RETURN

flushes:
       flush'count=0
       points=0
       IF play'suit(1)=play'suit(2) AND play'suit(2)=play'suit(3) AND &
               play'suit(3)=play'suit(4) THEN points=4 ELSE RETURN
       IF play'suit(5)=play'suit(4) THEN points=5
       IF player=3 AND points=4 THEN points=0
       flush'count=points
RETURN

nibs:
       nibs'count=0
       points=0
       FOR x=1 TO 4
               IF play'card(x)=11 AND play'suit(x)=play'suit(5) &
                       THEN points=1
       NEXT x
       nibs'count=points
RETURN

check'for'run:
       CALL sort'run
       CALL check'run
       IF run'points=0 THEN RETURN
       points(player)=points(player)+run'points
       CALL score'board
       ?TAB((10*(player-1)+5),28);"Run of ";run'points;" for ";run'points;
RETURN


!-------------------------------------------------------------------------!
! Level 6 Subroutines
!-------------------------------------------------------------------------!

sort'run:
       FOR y=1 TO r-1
               FOR z=r TO 2 STEP -1
                       IF run'list(z)<run'list(z-1) THEN tmp=run'list(z-1):run'list(z-1)=run'list(z):run'list(z)=tmp
               NEXT z
       NEXT y
RETURN

check'run:
       run'points=0
       FOR q=1 TO r-1
               IF run'list(q)+1=run'list(q+1) THEN run'points=q+1 ELSE q=r
       NEXT q
       IF run'points#r THEN run'points=0
RETURN

sort'players'cards:
       FOR y=1 TO 5
               FOR z=6 TO 2 STEP -1
                       IF value(2,z)>=value(2,z-1) THEN GOTO next'bubble
                       tmp=value(2,z-1):value(2,z-1)=value(2,z):value(2,z)=tmp
                       tmp=shdc(2,z-1):shdc(2,z-1)=shdc(2,z):shdc(2,z)=tmp
               next'bubble:
               NEXT z
       NEXT y
RETURN