SHOW:
|
|
- or go back to the newest paste.
| 1 | datatype suit = Clubs | Diamonds | Hearts | Spades | |
| 2 | datatype rank = Jack | Queen | King | Ace | Num of int | |
| 3 | type card = suit * rank | |
| 4 | ||
| 5 | datatype color = Red | Black | |
| 6 | datatype move = Discard of card | Draw | |
| 7 | ||
| 8 | exception IllegalMove | |
| 9 | ||
| 10 | (* put your solutions for problem 2 here *) | |
| 11 | fun card_color (c:suit * rank)= | |
| 12 | case c of | |
| 13 | ( Clubs,_) => Black | |
| 14 | |( Diamonds,_) => Red | |
| 15 | |( Hearts,_) => Red | |
| 16 | |( Spades,_) => Black | |
| 17 | fun card_value (c:card)= | |
| 18 | case c of | |
| 19 | (_,Ace) =>11 | |
| 20 | |(_,Jack) =>10 | |
| 21 | |(_,Queen)=>10 | |
| 22 | |(_,King) =>10 | |
| 23 | |(_,Num x) =>x | |
| 24 | fun remove_card ( cs:card list, c:card, e:exn)= | |
| 25 | (*val mytest = (remove_card([], (Clubs, Jack), IllegalMove); false) handle IllegalMove => true;*) | |
| 26 | case cs of | |
| 27 | []=> raise e (* IllegalMove*) | |
| 28 | |x::xs => if c=x then xs | |
| 29 | else if xs=[] then raise e | |
| 30 | else x::remove_card(xs,c,e) | |
| 31 | fun all_same_color ( cs:card list)= | |
| 32 | case cs of | |
| 33 | []=>true | |
| 34 | | x::xs=> case xs of | |
| 35 | []=>true | |
| 36 | |y::ys=> if card_color(x)= card_color(y) then all_same_color (xs) | |
| 37 | else false | |
| 38 | (* card_color(x)= card_color (all_same_color(xs)) then true | |
| 39 | else false*) | |
| 40 | fun sum_cards (cs:card list)= | |
| 41 | let fun aux( cs, acc)= | |
| 42 | case cs of | |
| 43 | []=>acc | |
| 44 | | x::xs=> aux( xs,card_value(x)+acc) | |
| 45 | in aux(cs,0) | |
| 46 | end | |
| 47 | fun score (cs: card list, goal: int)= (*int*) | |
| 48 | let fun prescore (cs: card list, num: int)= | |
| 49 | if all_same_color (cs) then num div 2 | |
| 50 | else num | |
| 51 | in | |
| 52 | if goal< sum_cards(cs) then prescore(cs, 3*(sum_cards(cs)-goal)) | |
| 53 | else prescore(cs, goal-sum_cards(cs)) | |
| 54 | end | |
| 55 | fun officiate (cs:card list, moves : move list, goal : int)= (* -> int*) | |
| 56 | let fun helperf(cH::cT:card list, mH::mT :move list,held_cards:card list,goal:int)= | |
| 57 | if mH::mT=[] orelse sum_cards(held_cards) >goal then score(held_cards, goal) | |
| 58 | else case mH of | |
| 59 | Discard c=> helperf(cH::cT,mT,remove_card(held_cards,c,IllegalMove),goal) | |
| 60 | | Draw =>if cH::cT=[] then score(held_cards,goal) | |
| 61 | else helperf(cT,mT,cH::held_cards,goal) | |
| 62 | in helperf(cs,moves,[], goal) | |
| 63 | end | |
| 64 | fun count_of_Aces (cs:card list)= | |
| 65 | case cs of | |
| 66 | []=>0 | |
| 67 | |x::xs=> case x of | |
| 68 | (_,Ace)=> 1+count_of_Aces(xs) | |
| 69 | |(_,_)=> count_of_Aces(xs) | |
| 70 | fun score_challenge (cs: card list, goal: int)= | |
| 71 | case cs of | |
| 72 | []=>0 | |
| 73 | | x::xs=> case count_of_Aces(cs) of | |
| 74 | 0=>score(cs,goal) | |
| 75 | |_=> if sum_cards(cs)-goal>0 andalso (* Int.min( count_of_Aces(cs) ,( (sum_cards(cs)-goal) div 10 ) )+1>=0*) | |
| 76 | (* then if*) all_same_color(cs) | |
| 77 | then (goal-sum_cards(cs)+ 10*(count_of_Aces(cs)-(goal div 11))) div 2 | |
| 78 | (* else (goal-sum_cards(cs)+ 10*(count_of_Aces(cs)-(goal div 11)))*) | |
| 79 | (* sum_cards(cs)- 10*Int.min(count_of_Aces(cs) ,((sum_cards(cs)-goal) div 10)+1)*) | |
| 80 | else score(cs,goal) | |
| 81 | ||
| 82 | fun officiate_challenge (cs:card list, moves : move list, goal : int)= (* -> int*) | |
| 83 | let fun helperf(cH::cT:card list, mH::mT :move list,held_cards:card list,goal:int)= | |
| 84 | if mH::mT=[] orelse sum_cards(held_cards) >goal then score_challenge(held_cards, goal) | |
| 85 | else case mH of | |
| 86 | Discard c=> helperf(cH::cT,mT,remove_card(held_cards,c,IllegalMove),goal) | |
| 87 | | Draw =>if cH::cT=[] then score_challenge(held_cards,goal) | |
| 88 | else helperf(cT,mT,cH::held_cards,goal) | |
| 89 | in helperf(cs,moves,[], goal) | |
| 90 | end | |
| 91 | fun rev (some_list:move list)= | |
| 92 | let fun aux(some_list:move list, acc:move list)= | |
| 93 | case some_list of | |
| 94 | []=>acc | |
| 95 | |x::xs=>aux(xs,x::acc) | |
| 96 | in aux(some_list,[]) | |
| 97 | end | |
| 98 | ||
| 99 | fun careful_player (cl: card list, goal:int )= (*move list*) | |
| 100 | let fun helper2 (clH::clT:card list, goal:int, held_cardsH::held_cardsT:card list, move_list:move list)= | |
| 101 | if score(held_cardsH::held_cardsT, goal)=0 orelse cl=[] then move_list | |
| 102 | else | |
| 103 | if score(clH::held_cardsH::held_cardsT, goal)< score(held_cardsH::held_cardsT, goal) andalso goal- sum_cards(held_cardsH::held_cardsT)>10 | |
| 104 | then helper2(clT, goal,clH::held_cardsH::held_cardsT,Draw ::move_list) | |
| 105 | else if score(clH::held_cardsH::held_cardsT, goal)> score(held_cardsH::held_cardsT, goal) andalso goal-sum_cards(held_cardsH::held_cardsT)>0 | |
| 106 | then helper2( cl,goal,held_cardsT,(Discard held_cardsH)::move_list) | |
| 107 | else move_list | |
| 108 | ||
| 109 | in | |
| 110 | rev(helper2(cl,goal,[],[])) | |
| 111 | end | |
| 112 | ||
| 113 | (* fun helper1 (clH::clT:card list,goal:int,held_cards:card list,moves:move list)= | |
| 114 | if sum_cards(held_cards)-goal>=0 then []::held_cards | |
| 115 | else if goal- sum_card(held_cards)>10 | |
| 116 | then if score(clH::held_cards, goal)=0 | |
| 117 | then []::held_cards | |
| 118 | else helper( clT,goal,clH::held_cards) | |
| 119 | else remove_card (held_cardsH::held_cardsT,held_cardsH,IllegalMove)*) |