Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- datatype suit = Clubs | Diamonds | Hearts | Spades
- datatype rank = Jack | Queen | King | Ace | Num of int
- type card = suit * rank
- datatype color = Red | Black
- datatype move = Discard of card | Draw
- exception IllegalMove
- (* put your solutions for problem 2 here *)
- fun card_color (c:suit * rank)=
- case c of
- ( Clubs,_) => Black
- |( Diamonds,_) => Red
- |( Hearts,_) => Red
- |( Spades,_) => Black
- fun card_value (c:card)=
- case c of
- (_,Ace) =>11
- |(_,Jack) =>10
- |(_,Queen)=>10
- |(_,King) =>10
- |(_,Num x) =>x
- fun remove_card ( cs:card list, c:card, e:exn)=
- (*val mytest = (remove_card([], (Clubs, Jack), IllegalMove); false) handle IllegalMove => true;*)
- case cs of
- []=> raise e (* IllegalMove*)
- |x::xs => if c=x then xs
- else if xs=[] then raise e
- else x::remove_card(xs,c,e)
- fun all_same_color ( cs:card list)=
- case cs of
- []=>true
- | x::xs=> case xs of
- []=>true
- |y::ys=> if card_color(x)= card_color(y) then all_same_color (xs)
- else false
- (* card_color(x)= card_color (all_same_color(xs)) then true
- else false*)
- fun sum_cards (cs:card list)=
- let fun aux( cs, acc)=
- case cs of
- []=>acc
- | x::xs=> aux( xs,card_value(x)+acc)
- in aux(cs,0)
- end
- fun score (cs: card list, goal: int)= (*int*)
- let fun prescore (cs: card list, num: int)=
- if all_same_color (cs) then num div 2
- else num
- in
- if goal< sum_cards(cs) then prescore(cs, 3*(sum_cards(cs)-goal))
- else prescore(cs, goal-sum_cards(cs))
- end
- fun officiate (cs:card list, moves : move list, goal : int)= (* -> int*)
- let fun helperf(cH::cT:card list, mH::mT :move list,held_cards:card list,goal:int)=
- if mH::mT=[] orelse sum_cards(held_cards) >goal then score(held_cards, goal)
- else case mH of
- Discard c=> helperf(cH::cT,mT,remove_card(held_cards,c,IllegalMove),goal)
- | Draw =>if cH::cT=[] then score(held_cards,goal)
- else helperf(cT,mT,cH::held_cards,goal)
- in helperf(cs,moves,[], goal)
- end
- fun count_of_Aces (cs:card list)=
- case cs of
- []=>0
- |x::xs=> case x of
- (_,Ace)=> 1+count_of_Aces(xs)
- |(_,_)=> count_of_Aces(xs)
- fun score_challenge (cs: card list, goal: int)=
- case cs of
- []=>0
- | x::xs=> case count_of_Aces(cs) of
- 0=>score(cs,goal)
- |_=> if sum_cards(cs)-goal>0 andalso (* Int.min( count_of_Aces(cs) ,( (sum_cards(cs)-goal) div 10 ) )+1>=0*)
- (* then if*) all_same_color(cs)
- then (goal-sum_cards(cs)+ 10*(count_of_Aces(cs)-(goal div 11))) div 2
- (* else (goal-sum_cards(cs)+ 10*(count_of_Aces(cs)-(goal div 11)))*)
- (* sum_cards(cs)- 10*Int.min(count_of_Aces(cs) ,((sum_cards(cs)-goal) div 10)+1)*)
- else score(cs,goal)
- fun officiate_challenge (cs:card list, moves : move list, goal : int)= (* -> int*)
- let fun helperf(cH::cT:card list, mH::mT :move list,held_cards:card list,goal:int)=
- if mH::mT=[] orelse sum_cards(held_cards) >goal then score_challenge(held_cards, goal)
- else case mH of
- Discard c=> helperf(cH::cT,mT,remove_card(held_cards,c,IllegalMove),goal)
- | Draw =>if cH::cT=[] then score_challenge(held_cards,goal)
- else helperf(cT,mT,cH::held_cards,goal)
- in helperf(cs,moves,[], goal)
- end
- fun rev (some_list:move list)=
- let fun aux(some_list:move list, acc:move list)=
- case some_list of
- []=>acc
- |x::xs=>aux(xs,x::acc)
- in aux(some_list,[])
- end
- fun careful_player (cl: card list, goal:int )= (*move list*)
- let fun helper2 (clH::clT:card list, goal:int, held_cardsH::held_cardsT:card list, move_list:move list)=
- if score(held_cardsH::held_cardsT, goal)=0 orelse cl=[] then move_list
- else
- if score(clH::held_cardsH::held_cardsT, goal)< score(held_cardsH::held_cardsT, goal) andalso goal- sum_cards(held_cardsH::held_cardsT)>10
- then helper2(clT, goal,clH::held_cardsH::held_cardsT,Draw ::move_list)
- else if score(clH::held_cardsH::held_cardsT, goal)> score(held_cardsH::held_cardsT, goal) andalso goal-sum_cards(held_cardsH::held_cardsT)>0
- then helper2( cl,goal,held_cardsT,(Discard held_cardsH)::move_list)
- else move_list
- in
- rev(helper2(cl,goal,[],[]))
- end
- (* fun helper1 (clH::clT:card list,goal:int,held_cards:card list,moves:move list)=
- if sum_cards(held_cards)-goal>=0 then []::held_cards
- else if goal- sum_card(held_cards)>10
- then if score(clH::held_cards, goal)=0
- then []::held_cards
- else helper( clT,goal,clH::held_cards)
- else remove_card (held_cardsH::held_cardsT,held_cardsH,IllegalMove)*)
Advertisement
Add Comment
Please, Sign In to add comment