Skat Engine und AI auf Haskell Basis
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

170 行
4.1KB

  1. module Card where
  2. import Data.List
  3. import Utils
  4. data Type = Seven
  5. | Eight
  6. | Nine
  7. | Queen
  8. | King
  9. | Ten
  10. | Ace
  11. | Jack
  12. deriving (Eq, Ord, Show, Enum)
  13. countType :: Type -> Int
  14. countType Ace = 11
  15. countType Ten = 10
  16. countType King = 4
  17. countType Queen = 3
  18. countType Jack = 2
  19. countType _ = 0
  20. data Colour = Diamonds
  21. | Hearts
  22. | Spades
  23. | Clubs
  24. deriving (Eq, Ord, Show, Enum, Read)
  25. data Card = Card Type Colour
  26. deriving (Eq, Show)
  27. countCard :: Card -> Int
  28. countCard (Card t _) = countType t
  29. count :: [Card] -> Int
  30. count = sum . map countCard
  31. data Team = Team | Single
  32. deriving (Show, Eq, Ord, Enum)
  33. data Space = Table | Hand1 | Hand2 | Hand3 | WonTeam | WonSingle | SkatP
  34. deriving (Show, Eq, Ord, Enum)
  35. teamPile :: Team -> Space
  36. teamPile Team = WonTeam
  37. teamPile Single = WonSingle
  38. playerHand :: Index -> Space
  39. playerHand One = Hand1
  40. playerHand Two = Hand2
  41. playerHand Three = Hand3
  42. playerOfHand :: Space -> Index
  43. playerOfHand Hand1 = One
  44. playerOfHand Hand2 = Two
  45. playerOfHand Hand3 = Three
  46. data CardS = CardS { getCard :: Card
  47. , getSpace :: Space
  48. , getOwner :: Space }
  49. deriving (Show, Eq)
  50. moveCard :: Card -> Space -> [CardS] -> [CardS]
  51. moveCard card sp cards = map f cards
  52. where f c = if card == getCard c then c { getSpace = sp } else c
  53. findCards :: Space -> [CardS] -> [Card]
  54. findCards sp cards = foldr f [] cards
  55. where f (CardS c s _) cs
  56. | s == sp = c : cs
  57. | otherwise = cs
  58. data Index = One | Two | Three
  59. deriving (Show, Ord, Eq, Enum)
  60. next :: Index -> Index
  61. next One = Two
  62. next Two = Three
  63. next Three = One
  64. prev :: Index -> Index
  65. prev One = Three
  66. prev Two = One
  67. prev Three = Two
  68. data Player = Player { team :: Team
  69. , index :: Index }
  70. deriving Show
  71. data Players = Players Player Player Player
  72. deriving Show
  73. player :: Players -> Index -> Player
  74. player (Players p _ _) One = p
  75. player (Players _ p _) Two = p
  76. player (Players _ _ p) Three = p
  77. type Hand = [Card]
  78. equals :: Colour -> Maybe Colour -> Bool
  79. equals col (Just x) = col == x
  80. equals col Nothing = True
  81. isTrump :: Colour -> Card -> Bool
  82. isTrump trumpCol (Card tp col)
  83. | tp == Jack = True
  84. | otherwise = col == trumpCol
  85. effectiveColour :: Colour -> Card -> Colour
  86. effectiveColour trumpCol card@(Card _ col) =
  87. if trump then trumpCol else col
  88. where trump = isTrump trumpCol card
  89. isAllowed :: Colour -> Maybe Colour -> Hand -> Card -> Bool
  90. isAllowed trumpCol turnCol cs card =
  91. if col `equals` turnCol
  92. then True
  93. else not $ any (\ca -> effectiveColour trumpCol ca `equals` turnCol && ca /= card) cs
  94. where col = effectiveColour trumpCol card
  95. putAt :: Space -> Card -> CardS
  96. putAt sp c = CardS c sp sp
  97. distribute :: [Card] -> [CardS]
  98. distribute cards = map (putAt Hand1) hand1
  99. ++ map (putAt Hand2) hand2
  100. ++ map (putAt Hand3) hand3
  101. ++ map (putAt SkatP) skt
  102. where round1 = chunksOf 3 (take 9 cards)
  103. skt = take 2 $ drop 9 cards
  104. round2 = chunksOf 4 (take 12 $ drop 11 cards)
  105. round3 = chunksOf 3 (take 9 $ drop 23 cards)
  106. hand1 = concatMap (!! 0) [round1, round2, round3]
  107. hand2 = concatMap (!! 1) [round1, round2, round3]
  108. hand3 = concatMap (!! 2) [round1, round2, round3]
  109. playersFromTable :: Players -> [CardS] -> [Player]
  110. playersFromTable ps = map (player ps . playerOfHand . getOwner)
  111. -- TESTING VARS
  112. c1 :: Card
  113. c1 = Card Jack Spades
  114. c2 :: Card
  115. c2 = Card Ace Diamonds
  116. c3 :: Card
  117. c3 = Card Queen Diamonds
  118. c4 :: Card
  119. c4 = Card Queen Hearts
  120. c5 :: Card
  121. c5 = Card Jack Clubs
  122. h1 :: Hand
  123. h1 = [c1,c2,c3,c4,c5]
  124. allCards :: [Card]
  125. allCards = [ Card t c | t <- tps, c <- cols ]
  126. where tps = [Seven .. Jack]
  127. cols = [Diamonds .. Clubs]
  128. distributePutSkat :: [Card] -> [CardS]
  129. distributePutSkat cards = foldr (\c m -> moveCard c WonSingle m) distributed skt
  130. where distributed = distribute cards
  131. skt = findCards SkatP distributed