View difference between Paste ID: dhPuYqkr and p3pDf2Zk
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 (nil, goal:int, held_cardsH::held_cardsT:card list, move_list:move list)=nil
100+
      let fun helper2 (nil, goal:int, held_cards:card list, move_list:move list)=nil
101-
	    |helper2(clH::clT:card list, goal:int, held_cardsH::held_cardsT:card list, move_list:move list)=
101+
	    |helper2(clH::clT:card list, goal:int, held_cards:card list, move_list:move list)=
102
(if score(held_cardsH::held_cardsT, goal)=0 (*orelse cl=[]*) then move_list
103
else
104-
    if score(clH::held_cardsH::held_cardsT, goal)< score(held_cardsH::held_cardsT, goal) andalso goal- sum_cards(held_cardsH::held_cardsT)>10
104+
    if score(clH::held_cards, goal)< score(held_cardsH, goal) andalso goal- sum_cards(held_cards)>10
105-
    then helper2(clT, goal,clH::held_cardsH::held_cardsT,Draw ::move_list)
105+
    then helper2(clT, goal,clH::held_cards,Draw ::move_list)
106-
    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+
    else if  score(clH::held_cards, goal)> score(held_cards, goal) andalso goal-sum_cards(held_cards)>0 
107-
         then helper2( cl,goal,held_cardsT, (Discard held_cardsH)::move_list)
107+
         then case held_cards as
108
	           nil => raise IllegalMove 
109
	         | h::t => helper2( cl,goal,t, (Discard h)::move_list)
110
         else move_list
111
 
112
    ) in 
113
	 rev(helper2(cl,goal,[],[]))
114
     end