繁体   English   中英

不同意的规则类型

[英]Types of Rules Don't Agree

我正在尝试用 SML 编写一个程序来解决以下问题:

使用卡片列表和目标进行游戏。 玩家有一个持有牌的列表,最初是空的。 玩家通过抽牌来移动,这意味着从卡片列表中移除卡片列表中的第一张卡片并将其添加到持有的卡片中,或者通过丢弃,这意味着选择一张持有的卡片来移除。 当玩家选择不再移动或持有的卡片值的总和大于目标时,游戏结束。 编写一个函数 officiate,“运行游戏”。 它需要一个卡片列表(卡片列表)、一个移动列表(玩家在每个点“做什么”)和一个 int(目标),并在处理完游戏结束时返回得分(部分或全部) 移动列表中的移动顺序。 使用本地定义的递归辅助函数,该函数接受多个参数,这些参数共同表示游戏的当前状态。 如上所述:

  • 游戏以持有的牌为空列表开始。
  • 如果没有更多动作,则游戏结束。 (玩家选择停止,因为移动列表为空。)
  • 如果玩家丢弃了一些牌 c,则游戏继续(即,进行递归调用),持有的牌没有 c,牌列表不变。 如果 c 不在持有的牌中,则引发 IllegalMove 异常。
  • 如果玩家抽牌并且卡片列表(已经)为空,则游戏结束。 否则,如果抽牌导致所持牌的总和超过目标,则游戏结束(抽牌后)。 其他游戏继续使用更大的手牌和更小的牌表。

这是我的解决方案:

datatype suit = Clubs | Diamonds | Hearts | Spades
datatype rank = Jack | Queen | King | Ace | Num of int 
type card = suit * rank

datatype move = Discard of card | Draw 

exception IllegalMove

fun remove_card (cs, c, e) =
    let
       fun delete_it (cs, c, e, count, acs) =
           case cs of
           [] => if count = 0 then raise e else acs
         | cp::cs' => if cp = c andalso count = 0
                      then delete_it (cs', c, e, count + 1, acs)
                      else
                          if cp = c then delete_it (cs', c, e, count + 1, [cp] @ acs) else delete_it (cs', c, e, count, [cp] @ acs)                
    in
       delete_it (cs, c, e, 0, [])
    end 

fun sum_cards (loc) =
    let
        fun sum_it (loc, sum) =
           case loc of
           [] => sum
         | c::loc' => sum_it (loc', sum + card_value (c))
    in
        sum_it (loc, 0)
    end 

fun score (loc, goal) =
    let
        val sum = sum_cards (loc)
        val all_same = all_same_color (loc)         
    in
        let
           fun prem_score (sum, goal) =
               if sum > goal
               then 3 * (sum - goal)
               else goal - sum     
        in
           let 
              val pre_score = prem_score (sum, goal)
              fun final_score (all, pre) =
                  if all
                  then pre div 2
                  else pre
        in
           final_score (all_same, pre_score)
        end         
    end
    end

fun officiate (loc, lom, goal) =
    let
    fun get_score (lcards, lohc, lmoves, goal, e) =
        case lmoves of
        [] => score (lcards, goal)
          | Draw::lmoves' => case lcards of
                   [] => score (lcards, goal)
                 | c::loc' => if sum_cards (c) > goal
                          then score (lcards, goal)
                          else get_score (loc', c::lohc, lmoves', goal, e)
          | d::lmoves' => case d of
                 Discard c => get_score (loc, remove_card (lohc, c, e), lmoves', goal, e)        
    in
    get_score (loc, [], lom, goal, IllegalMove)
    end                    

函数sum_cards返回给定卡片列表的值总和。 score函数返回游戏的分数,而remove_card返回一个卡片列表减去提供的卡片。 所有这些功能都运行良好,但问题出在officiate功能上,因为我尝试使用另外两个辅助功能但没有运气。 这是错误日志:

hw2.sml:196.17-196.60 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (suit * rank) list * (suit * rank) list list * 'Z * int * 
                   'Y
  operand:         (suit * rank) list list * (suit * rank) list list * 
                   move list * int * 'Y
  in expression:
    get_score (loc',c :: lohc,lmoves',goal,e)
hw2.sml:198.29-198.78 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (suit * rank) list list * (suit * rank) list * exn
  operand:         (suit * rank) list list * card * 'Z
  in expression:
    remove_card (lohc,c,e)
hw2.sml:192.27-198.78 Error: types of rules don't agree [tycon mismatch]
  earlier rule(s): (suit * rank) list list -> int
  this rule: move list -> 'Z
  in rule:
    :: (d,lmoves') =>
      (case d
        of Discard c => get_score (<exp>,<exp>,<exp>,<exp>,<exp>))
hw2.sml:192.27-198.78 Error: case object and rules don't agree [tycon mismatch]
  rule domain: (suit * rank) list list
  object: (suit * rank) list
  in expression:
    (case lcards
      of nil => score (lcards,goal)
       | :: (c,loc') =>
           if sum_cards <exp> > goal
           then score (<exp>,<exp>)
           else get_score (<exp>,<exp>,<exp>,<exp>,<exp>)
       | :: (d,lmoves') =>
           (case d
             of Discard <pat> => get_score <exp>))
val it = () : unit

我认为这是因为我使用了多个 case 表达式。 任何帮助将不胜感激!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM