Skat Engine und AI auf Haskell Basis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.7KB

  1. module Skat.Operations (
  2. turn, turnGeneric, play, playOpen, publishGameResults,
  3. publishGameStart, play_, sortRender, undo_
  4. ) where
  5. import Control.Monad.State
  6. import System.Random (newStdGen, randoms)
  7. import Data.List
  8. import Data.Ord
  9. import qualified Data.Set as S
  10. import Skat
  11. import Skat.Card
  12. import Skat.Pile
  13. import Skat.Player (chooseCard, Players(..), Player(..), PL(..),
  14. updatePlayer, playersToList, player, MonadPlayer)
  15. import Skat.Utils (shuffle)
  16. compareRender :: Card -> Card -> Ordering
  17. compareRender (Card t1 c1) (Card t2 c2) = case compare c1 c2 of
  18. EQ -> compare t1 t2
  19. v -> v
  20. sortRender :: [Card] -> [Card]
  21. sortRender = sortBy compareRender
  22. play_ :: HasCard c => c -> Skat ()
  23. play_ card = do
  24. hand <- gets currentHand
  25. trCol <- gets trumpColour
  26. modifyp $ playCard hand card
  27. table <- getp tableCards
  28. case length table of
  29. 1 -> do modify (setCurrentHand $ next hand)
  30. modify $ setTurnColour (Just $ effectiveColour trCol $ head table)
  31. 3 -> evaluateTable >>= modify . setCurrentHand
  32. _ -> modify (setCurrentHand $ next hand)
  33. undo_ :: HasCard c => c -> Hand -> Maybe Colour -> Team -> Skat ()
  34. undo_ card oldCurrent oldTurnCol oldWinner = do
  35. modify $ setCurrentHand oldCurrent
  36. modify $ setTurnColour oldTurnCol
  37. modifyp $ unplayCard oldCurrent (toCard card) oldWinner
  38. turnGeneric :: (PL -> Skat Card)
  39. -> Int
  40. -> Skat (Int, Int)
  41. turnGeneric playFunc depth = do
  42. n <- gets currentHand
  43. table <- getp tableCards
  44. ps <- gets players
  45. let p = player ps n
  46. over <- getp $ handEmpty n
  47. trCol <- gets trumpColour
  48. case length table of
  49. 0 -> playFunc p >> modify (setCurrentHand $ next n) >> turnGeneric playFunc depth
  50. 1 -> do
  51. modify $ setTurnColour
  52. (Just $ effectiveColour trCol $ head table)
  53. playFunc p
  54. modify (setCurrentHand $ next n)
  55. turnGeneric playFunc depth
  56. 2 -> playFunc p >> modify (setCurrentHand $ next n) >> turnGeneric playFunc depth
  57. 3 -> do
  58. w <- evaluateTable
  59. if depth <= 1 || over
  60. then countGame
  61. else modify (setCurrentHand w) >> turnGeneric playFunc (depth - 1)
  62. turn :: Skat (Int, Int)
  63. turn = turnGeneric play 10
  64. evaluateTable :: Skat Hand
  65. evaluateTable = do
  66. trumpCol <- gets trumpColour
  67. turnCol <- gets turnColour
  68. table <- getp tableCards
  69. ps <- gets players
  70. let winnerHand = uorigin $ getPile $ highestCard trumpCol turnCol table
  71. winner = player ps winnerHand
  72. modifyp $ cleanTable (team winner)
  73. modify $ setTurnColour Nothing
  74. return $ hand winner
  75. countGame :: Skat (Int, Int)
  76. countGame = getp count
  77. play :: (Show p, Player p) => p -> Skat Card
  78. play p = do
  79. table <- getp tableCards
  80. turnCol <- gets turnColour
  81. trump <- gets trumpColour
  82. cards <- getp $ handCards (hand p)
  83. fallen <- getp played
  84. (card, p') <- chooseCard p table fallen cards
  85. modifyPlayers $ updatePlayer p'
  86. modifyp $ playCard (hand p) card
  87. ps <- fmap playersToList $ gets players
  88. table' <- getp tableCards
  89. ps' <- mapM (\p -> onCardPlayed p (head table')) ps
  90. mapM_ (modifyPlayers . updatePlayer) ps'
  91. return (toCard card)
  92. playOpen :: (Show p, Player p) => p -> Skat Card
  93. playOpen p = do
  94. --liftIO $ putStrLn $ show (hand p) ++ " playing open"
  95. card <- chooseCardOpen p
  96. modifyp $ playCard (hand p) card
  97. return card
  98. publishGameResults :: (Int, Int) -> Skat ()
  99. publishGameResults res = do
  100. pls <- gets players
  101. mapM_ (\p -> onGameResults p res) (playersToList pls)
  102. publishGameStart :: Hand -> Skat ()
  103. publishGameStart sglPlayer = do
  104. pls <- gets players
  105. mapM_ (\p -> onGameStart p sglPlayer) (playersToList pls)