View difference between Paste ID: ctcqhqzf and 3S0Hv3cs
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)*)