implement grand and null mechanics, fix some online player issues
This commit is contained in:
+8
-7
@@ -12,6 +12,7 @@ import Skat.Card
|
|||||||
import Skat.Operations
|
import Skat.Operations
|
||||||
import Skat.Player
|
import Skat.Player
|
||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
|
import Skat.Bidding
|
||||||
|
|
||||||
import Skat.AI.Stupid
|
import Skat.AI.Stupid
|
||||||
import Skat.AI.Online
|
import Skat.AI.Online
|
||||||
@@ -37,7 +38,7 @@ runAI = do
|
|||||||
env <- shuffledEnv
|
env <- shuffledEnv
|
||||||
let ps = piles env
|
let ps = piles env
|
||||||
cs = handCards Hand3 ps
|
cs = handCards Hand3 ps
|
||||||
trs = filter (isTrump Spades) cs
|
trs = filter (isTrump $ TrumpColour Spades) cs
|
||||||
if length trs >= 5 && any ((==32) . getID) cs
|
if length trs >= 5 && any ((==32) . getID) cs
|
||||||
then do
|
then do
|
||||||
pts <- fst <$> evalStateT turn env
|
pts <- fst <$> evalStateT turn env
|
||||||
@@ -46,11 +47,11 @@ runAI = do
|
|||||||
else runAI
|
else runAI
|
||||||
|
|
||||||
env :: SkatEnv
|
env :: SkatEnv
|
||||||
env = SkatEnv piles Nothing Spades playersExamp Hand1
|
env = SkatEnv piles Nothing (Colour Spades Einfach) playersExamp Hand1
|
||||||
where piles = distribute allCards
|
where piles = distribute allCards
|
||||||
|
|
||||||
envStupid :: SkatEnv
|
envStupid :: SkatEnv
|
||||||
envStupid = SkatEnv piles Nothing Spades pls2 Hand1
|
envStupid = SkatEnv piles Nothing (Colour Spades Einfach) pls2 Hand1
|
||||||
where piles = distribute allCards
|
where piles = distribute allCards
|
||||||
|
|
||||||
playersExamp :: Players
|
playersExamp :: Players
|
||||||
@@ -68,22 +69,22 @@ pls2 = Players
|
|||||||
shuffledEnv :: IO SkatEnv
|
shuffledEnv :: IO SkatEnv
|
||||||
shuffledEnv = do
|
shuffledEnv = do
|
||||||
cards <- shuffleCards
|
cards <- shuffleCards
|
||||||
return $ SkatEnv (distribute cards) Nothing Spades playersExamp Hand1
|
return $ SkatEnv (distribute cards) Nothing (Colour Spades Einfach) playersExamp Hand1
|
||||||
|
|
||||||
shuffledEnv2 :: IO SkatEnv
|
shuffledEnv2 :: IO SkatEnv
|
||||||
shuffledEnv2 = do
|
shuffledEnv2 = do
|
||||||
cards <- shuffleCards
|
cards <- shuffleCards
|
||||||
return $ SkatEnv (distribute cards) Nothing Spades pls2 Hand1
|
return $ SkatEnv (distribute cards) Nothing (Colour Spades Einfach) pls2 Hand1
|
||||||
|
|
||||||
env2 :: SkatEnv
|
env2 :: SkatEnv
|
||||||
env2 = SkatEnv piles Nothing Hearts playersExamp Hand2
|
env2 = SkatEnv piles Nothing (Colour Hearts Einfach) playersExamp Hand2
|
||||||
where hand1 = [Card Eight Hearts, Card Queen Hearts, Card Ace Clubs, Card Queen Diamonds]
|
where hand1 = [Card Eight Hearts, Card Queen Hearts, Card Ace Clubs, Card Queen Diamonds]
|
||||||
hand2 = [Card Seven Hearts, Card King Hearts, Card Ten Hearts, Card Queen Spades]
|
hand2 = [Card Seven Hearts, Card King Hearts, Card Ten Hearts, Card Queen Spades]
|
||||||
hand3 = [Card Seven Spades, Card King Spades, Card Ace Spades, Card Queen Clubs]
|
hand3 = [Card Seven Spades, Card King Spades, Card Ace Spades, Card Queen Clubs]
|
||||||
piles = emptyPiles hand1 hand2 hand3 []
|
piles = emptyPiles hand1 hand2 hand3 []
|
||||||
|
|
||||||
env3 :: SkatEnv
|
env3 :: SkatEnv
|
||||||
env3 = SkatEnv piles Nothing Diamonds pls2 Hand3
|
env3 = SkatEnv piles Nothing (Colour Diamonds Einfach) pls2 Hand3
|
||||||
where hand1 = [ Card Jack Diamonds, Card Jack Clubs, Card Nine Spades, Card King Spades
|
where hand1 = [ Card Jack Diamonds, Card Jack Clubs, Card Nine Spades, Card King Spades
|
||||||
, Card Seven Diamonds, Card Nine Diamonds, Card Seven Clubs, Card Eight Clubs
|
, Card Seven Diamonds, Card Nine Diamonds, Card Seven Clubs, Card Eight Clubs
|
||||||
, Card Ten Clubs, Card Eight Hearts ]
|
, Card Ten Clubs, Card Eight Hearts ]
|
||||||
|
|||||||
+3
-2
@@ -5,6 +5,7 @@ import Skat.Card
|
|||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
import Skat.Player
|
import Skat.Player
|
||||||
import Skat.AI.Stupid
|
import Skat.AI.Stupid
|
||||||
|
import Skat.Bidding
|
||||||
|
|
||||||
pls2 :: Players
|
pls2 :: Players
|
||||||
pls2 = Players
|
pls2 = Players
|
||||||
@@ -13,7 +14,7 @@ pls2 = Players
|
|||||||
(PL $ Stupid Single Hand3)
|
(PL $ Stupid Single Hand3)
|
||||||
|
|
||||||
env3 :: SkatEnv
|
env3 :: SkatEnv
|
||||||
env3 = SkatEnv piles Nothing Diamonds pls2 Hand3
|
env3 = SkatEnv piles Nothing (Colour Diamonds Einfach) pls2 Hand3
|
||||||
where hand1 = [ Card Jack Diamonds, Card Jack Clubs, Card Nine Spades, Card King Spades
|
where hand1 = [ Card Jack Diamonds, Card Jack Clubs, Card Nine Spades, Card King Spades
|
||||||
, Card Seven Diamonds, Card Nine Diamonds, Card Seven Clubs, Card Eight Clubs
|
, Card Seven Diamonds, Card Nine Diamonds, Card Seven Clubs, Card Eight Clubs
|
||||||
, Card Ten Clubs, Card Eight Hearts ]
|
, Card Ten Clubs, Card Eight Hearts ]
|
||||||
@@ -28,4 +29,4 @@ env3 = SkatEnv piles Nothing Diamonds pls2 Hand3
|
|||||||
shuffledEnv2 :: IO SkatEnv
|
shuffledEnv2 :: IO SkatEnv
|
||||||
shuffledEnv2 = do
|
shuffledEnv2 = do
|
||||||
cards <- shuffleCards
|
cards <- shuffleCards
|
||||||
return $ SkatEnv (distribute cards) Nothing Spades pls2 Hand1
|
return $ SkatEnv (distribute cards) Nothing (Colour Spades Einfach) pls2 Hand1
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name: skat
|
name: skat
|
||||||
version: 0.1.0.5
|
version: 0.1.0.7
|
||||||
github: "githubuser/skat"
|
github: "githubuser/skat"
|
||||||
license: BSD3
|
license: BSD3
|
||||||
author: "flavis"
|
author: "flavis"
|
||||||
|
|||||||
+2
-2
@@ -4,10 +4,10 @@ cabal-version: 1.12
|
|||||||
--
|
--
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
--
|
--
|
||||||
-- hash: 625d9f93a3dec23993347bdccc3746fdf28ac4b67c85ec04a99f505ff61a171f
|
-- hash: 9c412ae20820c69f342fb431118c3d2be6a5461e1b5a521d92c1546f163ee94a
|
||||||
|
|
||||||
name: skat
|
name: skat
|
||||||
version: 0.1.0.5
|
version: 0.1.0.7
|
||||||
description: Please see the README on Gitea at <https://git.flavigny.de/christian/skat>
|
description: Please see the README on Gitea at <https://git.flavigny.de/christian/skat>
|
||||||
homepage: https://github.com/githubuser/skat#readme
|
homepage: https://github.com/githubuser/skat#readme
|
||||||
bug-reports: https://github.com/githubuser/skat/issues
|
bug-reports: https://github.com/githubuser/skat/issues
|
||||||
|
|||||||
+8
-7
@@ -10,13 +10,14 @@ import Data.List
|
|||||||
import Data.Vector (Vector)
|
import Data.Vector (Vector)
|
||||||
|
|
||||||
import Skat.Card
|
import Skat.Card
|
||||||
|
import Skat.Bidding
|
||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
import Skat.Player (Players)
|
import Skat.Player (Players)
|
||||||
import qualified Skat.Player as P
|
import qualified Skat.Player as P
|
||||||
|
|
||||||
data SkatEnv = SkatEnv { piles :: Piles
|
data SkatEnv = SkatEnv { piles :: Piles
|
||||||
, turnColour :: Maybe Colour
|
, turnColour :: Maybe TurnColour
|
||||||
, trumpColour :: Colour
|
, game :: Game
|
||||||
, players :: Players
|
, players :: Players
|
||||||
, currentHand :: Hand }
|
, currentHand :: Hand }
|
||||||
deriving Show
|
deriving Show
|
||||||
@@ -24,7 +25,7 @@ data SkatEnv = SkatEnv { piles :: Piles
|
|||||||
type Skat = StateT SkatEnv IO
|
type Skat = StateT SkatEnv IO
|
||||||
|
|
||||||
instance P.MonadPlayer Skat where
|
instance P.MonadPlayer Skat where
|
||||||
trumpColour = gets trumpColour
|
trump = gets $ getTrump . game
|
||||||
turnColour = gets turnColour
|
turnColour = gets turnColour
|
||||||
showSkat p = case P.team p of
|
showSkat p = case P.team p of
|
||||||
Single -> fmap (Just . skatCards) $ gets piles
|
Single -> fmap (Just . skatCards) $ gets piles
|
||||||
@@ -44,19 +45,19 @@ modifyPlayers :: (Players -> Players) -> Skat ()
|
|||||||
modifyPlayers f = modify g
|
modifyPlayers f = modify g
|
||||||
where g env@(SkatEnv {players}) = env { players = f players }
|
where g env@(SkatEnv {players}) = env { players = f players }
|
||||||
|
|
||||||
setTurnColour :: Maybe Colour -> SkatEnv -> SkatEnv
|
setTurnColour :: Maybe TurnColour -> SkatEnv -> SkatEnv
|
||||||
setTurnColour col sk = sk { turnColour = col }
|
setTurnColour col sk = sk { turnColour = col }
|
||||||
|
|
||||||
setCurrentHand :: Hand -> SkatEnv -> SkatEnv
|
setCurrentHand :: Hand -> SkatEnv -> SkatEnv
|
||||||
setCurrentHand hand sk = sk { currentHand = hand }
|
setCurrentHand hand sk = sk { currentHand = hand }
|
||||||
|
|
||||||
mkSkatEnv :: Piles -> Maybe Colour -> Colour -> Players -> Hand -> SkatEnv
|
mkSkatEnv :: Piles -> Maybe TurnColour -> Game -> Players -> Hand -> SkatEnv
|
||||||
mkSkatEnv = SkatEnv
|
mkSkatEnv = SkatEnv
|
||||||
|
|
||||||
allowedCards :: Skat [CardS Owner]
|
allowedCards :: Skat [CardS Owner]
|
||||||
allowedCards = do
|
allowedCards = do
|
||||||
curHand <- gets currentHand
|
curHand <- gets currentHand
|
||||||
pls <- gets players
|
pls <- gets players
|
||||||
turnCol <- gets turnColour
|
turnCol <- P.turnColour
|
||||||
trumpCol <- gets trumpColour
|
trumpCol <- P.trump
|
||||||
getp $ allowed curHand trumpCol turnCol
|
getp $ allowed curHand trumpCol turnCol
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ instance Player Human where
|
|||||||
team = getTeam
|
team = getTeam
|
||||||
hand = getHand
|
hand = getHand
|
||||||
chooseCard p table _ hand = do
|
chooseCard p table _ hand = do
|
||||||
trumpCol <- trumpColour
|
trumpCol <- trump
|
||||||
turnCol <- turnColour
|
turnCol <- turnColour
|
||||||
let possible = filter (isAllowed trumpCol turnCol hand) hand
|
let possible = filter (isAllowed trumpCol turnCol hand) hand
|
||||||
c <- liftIO $ askIO (map getCard table) (map toCard possible) (map toCard hand)
|
c <- liftIO $ askIO (map getCard table) (map toCard possible) (map toCard hand)
|
||||||
|
|||||||
+17
-23
@@ -6,7 +6,7 @@ module Skat.AI.Online where
|
|||||||
|
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Concurrent.Chan
|
import Control.Concurrent.Chan
|
||||||
import Data.Aeson
|
import Data.Aeson hiding (Result)
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import qualified Data.ByteString.Lazy.Char8 as BS
|
import qualified Data.ByteString.Lazy.Char8 as BS
|
||||||
|
|
||||||
@@ -49,8 +49,6 @@ instance Communicator c => Player (OnlineEnv c) where
|
|||||||
hand = getHand
|
hand = getHand
|
||||||
chooseCard p table _ hand = runReaderT (choose table hand) p >>= \c -> return (c, p)
|
chooseCard p table _ hand = runReaderT (choose table hand) p >>= \c -> return (c, p)
|
||||||
onCardPlayed p c = runReaderT (cardPlayed c) p >> return p
|
onCardPlayed p c = runReaderT (cardPlayed c) p >> return p
|
||||||
onGameResults p res = runReaderT (onResults res) p
|
|
||||||
onGameStart p singlePlayer = runReaderT (onStartOnline singlePlayer) p
|
|
||||||
|
|
||||||
instance Communicator c => Bidder (PrepOnline c) where
|
instance Communicator c => Bidder (PrepOnline c) where
|
||||||
hand = prepHand
|
hand = prepHand
|
||||||
@@ -87,8 +85,12 @@ instance Communicator c => Bidder (PrepOnline c) where
|
|||||||
Nothing -> askSkat p bid cards
|
Nothing -> askSkat p bid cards
|
||||||
toPlayer p tm = PL $ OnlineEnv tm (prepHand p) (prepConnection p)
|
toPlayer p tm = PL $ OnlineEnv tm (prepHand p) (prepConnection p)
|
||||||
onStart p = do
|
onStart p = do
|
||||||
let cards = prepCards p
|
let cards = sortRender Jacks $ prepCards p
|
||||||
liftIO $ send (prepConnection p) (BS.unpack $ encode $ CardsQuery cards)
|
liftIO $ send (prepConnection p) (BS.unpack $ encode $ CardsQuery cards)
|
||||||
|
onResult p res =
|
||||||
|
liftIO $ send (prepConnection p) (BS.unpack $ encode $ GameResultsQuery res)
|
||||||
|
onGame p game sglPlayer = do
|
||||||
|
liftIO $ send (prepConnection p) (BS.unpack $ encode $ GameStartQuery game sglPlayer)
|
||||||
|
|
||||||
type Online a m = ReaderT (OnlineEnv a) m
|
type Online a m = ReaderT (OnlineEnv a) m
|
||||||
|
|
||||||
@@ -101,13 +103,13 @@ instance (Communicator c, MonadIO m) => MonadClient (Online c m) where
|
|||||||
liftIO $ receive conn
|
liftIO $ receive conn
|
||||||
|
|
||||||
instance MonadPlayer m => MonadPlayer (Online a m) where
|
instance MonadPlayer m => MonadPlayer (Online a m) where
|
||||||
trumpColour = lift $ trumpColour
|
trump = lift $ trump
|
||||||
turnColour = lift $ turnColour
|
turnColour = lift $ turnColour
|
||||||
showSkat = lift . showSkat
|
showSkat = lift . showSkat
|
||||||
|
|
||||||
choose :: HasCard a => (Communicator c, MonadPlayer m) => [CardS Played] -> [a] -> Online c m Card
|
choose :: HasCard a => (Communicator c, MonadPlayer m) => [CardS Played] -> [a] -> Online c m Card
|
||||||
choose table hand' = do
|
choose table hand' = do
|
||||||
let hand = map toCard hand'
|
let hand = sortRender Jacks $ map toCard hand'
|
||||||
query (BS.unpack $ encode $ ChooseQuery hand table)
|
query (BS.unpack $ encode $ ChooseQuery hand table)
|
||||||
r <- response
|
r <- response
|
||||||
case decode (BS.pack r) of
|
case decode (BS.pack r) of
|
||||||
@@ -119,21 +121,12 @@ choose table hand' = do
|
|||||||
cardPlayed :: (Communicator c, MonadPlayer m) => CardS Played -> Online c m ()
|
cardPlayed :: (Communicator c, MonadPlayer m) => CardS Played -> Online c m ()
|
||||||
cardPlayed card = query (BS.unpack $ encode $ CardPlayedQuery card)
|
cardPlayed card = query (BS.unpack $ encode $ CardPlayedQuery card)
|
||||||
|
|
||||||
onResults :: (Communicator c, MonadIO m) => (Int, Int) -> Online c m ()
|
|
||||||
onResults (sgl, tm) = query (BS.unpack $ encode $ GameResultsQuery sgl tm)
|
|
||||||
|
|
||||||
onStartOnline :: (Communicator c, MonadPlayer m) => Hand -> Online c m ()
|
|
||||||
onStartOnline singlePlayer = do
|
|
||||||
trCol <- trumpColour
|
|
||||||
ownHand <- asks getHand
|
|
||||||
query (BS.unpack $ encode $ GameStartQuery trCol ownHand singlePlayer)
|
|
||||||
|
|
||||||
-- | QUERIES AND RESPONSES
|
-- | QUERIES AND RESPONSES
|
||||||
|
|
||||||
data Query = ChooseQuery [Card] [CardS Played]
|
data Query = ChooseQuery [Card] [CardS Played]
|
||||||
| CardPlayedQuery (CardS Played)
|
| CardPlayedQuery (CardS Played)
|
||||||
| GameResultsQuery Int Int
|
| GameResultsQuery Result
|
||||||
| GameStartQuery Colour Hand Hand
|
| GameStartQuery Game Hand
|
||||||
| BidQuery Hand Bid
|
| BidQuery Hand Bid
|
||||||
| BidResponseQuery Hand Bid
|
| BidResponseQuery Hand Bid
|
||||||
| AskGameQuery Bid
|
| AskGameQuery Bid
|
||||||
@@ -153,15 +146,16 @@ instance ToJSON Query where
|
|||||||
object ["query" .= ("choose_card" :: String), "hand" .= hand, "table" .= table]
|
object ["query" .= ("choose_card" :: String), "hand" .= hand, "table" .= table]
|
||||||
toJSON (CardPlayedQuery card) =
|
toJSON (CardPlayedQuery card) =
|
||||||
object ["query" .= ("card_played" :: String), "card" .= card]
|
object ["query" .= ("card_played" :: String), "card" .= card]
|
||||||
toJSON (GameResultsQuery sgl tm) =
|
toJSON (GameResultsQuery result) =
|
||||||
object ["query" .= ("results" :: String), "single" .= sgl, "team" .= tm]
|
object ["query" .= ("results" :: String), "result" .= result]
|
||||||
toJSON (GameStartQuery trumps handNo sglPlayer) =
|
toJSON (GameStartQuery game sglPlayer) =
|
||||||
object ["query" .= ("start_game" :: String), "trumps" .= show trumps,
|
object [ "query" .= ("start_game" :: String)
|
||||||
"hand" .= toInt handNo, "single" .= toInt sglPlayer ]
|
, "game" .= game
|
||||||
|
, "single" .= toInt sglPlayer ]
|
||||||
toJSON (BidQuery hand bid) =
|
toJSON (BidQuery hand bid) =
|
||||||
object ["query" .= ("bid" :: String), "whom" .= show hand, "current" .= bid]
|
object ["query" .= ("bid" :: String), "whom" .= show hand, "current" .= bid]
|
||||||
toJSON (BidResponseQuery hand bid) =
|
toJSON (BidResponseQuery hand bid) =
|
||||||
object ["query" .= ("bid_response" :: String), "from" .= show hand ]
|
object ["query" .= ("bid_response" :: String), "from" .= show hand, "bid" .= bid ]
|
||||||
toJSON (AskHandQuery) =
|
toJSON (AskHandQuery) =
|
||||||
object ["query" .= ("play_hand" :: String)]
|
object ["query" .= ("play_hand" :: String)]
|
||||||
toJSON (AskSkatQuery cards bid) =
|
toJSON (AskSkatQuery cards bid) =
|
||||||
|
|||||||
+19
-16
@@ -26,6 +26,7 @@ import Skat (Skat, modifyp, mkSkatEnv)
|
|||||||
import Skat.Operations
|
import Skat.Operations
|
||||||
import qualified Skat.AI.Minmax as Minmax
|
import qualified Skat.AI.Minmax as Minmax
|
||||||
import qualified Skat.AI.Stupid as Stupid (Stupid(..))
|
import qualified Skat.AI.Stupid as Stupid (Stupid(..))
|
||||||
|
import Skat.Bidding
|
||||||
|
|
||||||
data AIEnv = AIEnv { getTeam :: Team
|
data AIEnv = AIEnv { getTeam :: Team
|
||||||
, getHand :: Hand
|
, getHand :: Hand
|
||||||
@@ -55,8 +56,8 @@ modifyg f = modify g
|
|||||||
type AI m = StateT AIEnv m
|
type AI m = StateT AIEnv m
|
||||||
|
|
||||||
instance MonadPlayer m => MonadPlayer (AI m) where
|
instance MonadPlayer m => MonadPlayer (AI m) where
|
||||||
trumpColour = lift $ trumpColour
|
trump = lift trump
|
||||||
turnColour = lift $ turnColour
|
turnColour = lift turnColour
|
||||||
showSkat = lift . showSkat
|
showSkat = lift . showSkat
|
||||||
|
|
||||||
instance MonadPlayerOpen m => MonadPlayerOpen (AI m) where
|
instance MonadPlayerOpen m => MonadPlayerOpen (AI m) where
|
||||||
@@ -65,7 +66,7 @@ instance MonadPlayerOpen m => MonadPlayerOpen (AI m) where
|
|||||||
type Simulator m = ReaderT Piles (AI m)
|
type Simulator m = ReaderT Piles (AI m)
|
||||||
|
|
||||||
instance MonadPlayer m => MonadPlayer (Simulator m) where
|
instance MonadPlayer m => MonadPlayer (Simulator m) where
|
||||||
trumpColour = lift $ trumpColour
|
trump = lift trump
|
||||||
turnColour = lift $ turnColour
|
turnColour = lift $ turnColour
|
||||||
showSkat = lift . showSkat
|
showSkat = lift . showSkat
|
||||||
|
|
||||||
@@ -112,15 +113,15 @@ has hand cs = M.mapWithKey f
|
|||||||
| card `elem` cs = [H hand]
|
| card `elem` cs = [H hand]
|
||||||
| otherwise = hands
|
| otherwise = hands
|
||||||
|
|
||||||
hasNoLonger :: MonadPlayer m => Hand -> Colour -> AI m ()
|
hasNoLonger :: MonadPlayer m => Hand -> TurnColour -> AI m ()
|
||||||
hasNoLonger hand colour = do
|
hasNoLonger hand colour = do
|
||||||
trCol <- trumpColour
|
trCol <- trump
|
||||||
modifyg $ hasNoLonger_ trCol hand colour
|
modifyg $ hasNoLonger_ trCol hand colour
|
||||||
|
|
||||||
hasNoLonger_ :: Colour -> Hand -> Colour -> Guess -> Guess
|
hasNoLonger_ :: Trump -> Hand -> TurnColour -> Guess -> Guess
|
||||||
hasNoLonger_ trColour hand effCol = M.mapWithKey f
|
hasNoLonger_ trump hand effCol = M.mapWithKey f
|
||||||
where f card hands
|
where f card hands
|
||||||
| effectiveColour trColour card == effCol && (H hand) `elem` hands = filter (/=H hand) hands
|
| effectiveColour trump card == effCol && (H hand) `elem` hands = filter (/=H hand) hands
|
||||||
| otherwise = hands
|
| otherwise = hands
|
||||||
|
|
||||||
isSkat :: [Card] -> Guess -> Guess
|
isSkat :: [Card] -> Guess -> Guess
|
||||||
@@ -136,7 +137,7 @@ analyzeTurn (c1, c2, c3) = do
|
|||||||
modifyg (getCard c1 `hasBeenPlayed`)
|
modifyg (getCard c1 `hasBeenPlayed`)
|
||||||
modifyg (getCard c2 `hasBeenPlayed`)
|
modifyg (getCard c2 `hasBeenPlayed`)
|
||||||
modifyg (getCard c3 `hasBeenPlayed`)
|
modifyg (getCard c3 `hasBeenPlayed`)
|
||||||
trCol <- trumpColour
|
trCol <- trump
|
||||||
let turnCol = getColour $ getCard c1
|
let turnCol = getColour $ getCard c1
|
||||||
demanded = effectiveColour trCol (getCard c1)
|
demanded = effectiveColour trCol (getCard c1)
|
||||||
col2 = effectiveColour trCol (getCard c2)
|
col2 = effectiveColour trCol (getCard c2)
|
||||||
@@ -218,7 +219,7 @@ onPlayed :: MonadPlayer m => CardS Played -> AI m ()
|
|||||||
onPlayed c = do
|
onPlayed c = do
|
||||||
liftIO $ print c
|
liftIO $ print c
|
||||||
modifyg (getCard c `hasBeenPlayed`)
|
modifyg (getCard c `hasBeenPlayed`)
|
||||||
trCol <- trumpColour
|
trCol <- trump
|
||||||
turnCol <- turnColour
|
turnCol <- turnColour
|
||||||
let col = effectiveColour trCol (getCard c)
|
let col = effectiveColour trCol (getCard c)
|
||||||
case turnCol of
|
case turnCol of
|
||||||
@@ -308,13 +309,14 @@ chooseSimulating :: (MonadState AIEnv m, MonadPlayerOpen m)
|
|||||||
chooseSimulating = do
|
chooseSimulating = do
|
||||||
piles <- showPiles
|
piles <- showPiles
|
||||||
turnCol <- turnColour
|
turnCol <- turnColour
|
||||||
trumpCol <- trumpColour
|
trumpCol <- trump
|
||||||
myHand <- gets getHand
|
myHand <- gets getHand
|
||||||
depth <- gets simulationDepth
|
depth <- gets simulationDepth
|
||||||
let ps = Players (PL $ Stupid.Stupid Team Hand1)
|
let ps = Players (PL $ Stupid.Stupid Team Hand1)
|
||||||
(PL $ Stupid.Stupid Team Hand2)
|
(PL $ Stupid.Stupid Team Hand2)
|
||||||
(PL $ Stupid.Stupid Single Hand3)
|
(PL $ Stupid.Stupid Single Hand3)
|
||||||
env = mkSkatEnv piles turnCol trumpCol ps myHand
|
-- TODO: fix
|
||||||
|
env = mkSkatEnv piles turnCol undefined ps myHand
|
||||||
liftIO $ evalStateT (toCard <$> (Minmax.choose depth :: Skat (CardS Owner))) env
|
liftIO $ evalStateT (toCard <$> (Minmax.choose depth :: Skat (CardS Owner))) env
|
||||||
|
|
||||||
simulate :: (MonadState AIEnv m, MonadPlayerOpen m)
|
simulate :: (MonadState AIEnv m, MonadPlayerOpen m)
|
||||||
@@ -323,7 +325,7 @@ simulate card = do
|
|||||||
-- retrieve all relevant info
|
-- retrieve all relevant info
|
||||||
piles <- showPiles
|
piles <- showPiles
|
||||||
turnCol <- turnColour
|
turnCol <- turnColour
|
||||||
trumpCol <- trumpColour
|
trumpCol <- trump
|
||||||
myTeam <- gets getTeam
|
myTeam <- gets getTeam
|
||||||
myHand <- gets getHand
|
myHand <- gets getHand
|
||||||
depth <- gets simulationDepth
|
depth <- gets simulationDepth
|
||||||
@@ -334,7 +336,8 @@ simulate card = do
|
|||||||
(PL $ mkAIEnv Team Hand1 newDepth)
|
(PL $ mkAIEnv Team Hand1 newDepth)
|
||||||
(PL $ mkAIEnv Team Hand2 newDepth)
|
(PL $ mkAIEnv Team Hand2 newDepth)
|
||||||
(PL $ mkAIEnv Single Hand3 newDepth)
|
(PL $ mkAIEnv Single Hand3 newDepth)
|
||||||
env = mkSkatEnv piles turnCol trumpCol ps (next myHand)
|
-- TODO: fix
|
||||||
|
env = mkSkatEnv piles turnCol undefined ps (next myHand)
|
||||||
-- simulate the game after playing the given card
|
-- simulate the game after playing the given card
|
||||||
(sgl, tm) <- liftIO $ evalStateT (do
|
(sgl, tm) <- liftIO $ evalStateT (do
|
||||||
modifyp $ playCard myHand card
|
modifyp $ playCard myHand card
|
||||||
@@ -357,7 +360,7 @@ predictValue (own, others) = do
|
|||||||
potential :: (MonadState AIEnv m, MonadPlayerOpen m, HasCard c)
|
potential :: (MonadState AIEnv m, MonadPlayerOpen m, HasCard c)
|
||||||
=> [c] -> m Int
|
=> [c] -> m Int
|
||||||
potential cs = do
|
potential cs = do
|
||||||
tr <- trumpColour
|
tr <- trump
|
||||||
let trs = filter (isTrump tr) cs
|
let trs = filter (isTrump tr) cs
|
||||||
value = count . map toCard $ cs
|
value = count . map toCard $ cs
|
||||||
positions <- filter (==0) <$> mapM (position . toCard) cs
|
positions <- filter (==0) <$> mapM (position . toCard) cs
|
||||||
@@ -366,7 +369,7 @@ potential cs = do
|
|||||||
position :: (MonadState AIEnv m, MonadPlayer m)
|
position :: (MonadState AIEnv m, MonadPlayer m)
|
||||||
=> Card -> m Int
|
=> Card -> m Int
|
||||||
position card = do
|
position card = do
|
||||||
tr <- trumpColour
|
tr <- trump
|
||||||
guess <- gets guess
|
guess <- gets guess
|
||||||
let effCol = effectiveColour tr card
|
let effCol = effectiveColour tr card
|
||||||
l = M.toList guess
|
l = M.toList guess
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Skat.Player
|
|||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
import Skat.Card
|
import Skat.Card
|
||||||
import Skat.Preperation
|
import Skat.Preperation
|
||||||
|
import Skat.Bidding
|
||||||
|
|
||||||
data Stupid = Stupid { getTeam :: Team
|
data Stupid = Stupid { getTeam :: Team
|
||||||
, getHand :: Hand }
|
, getHand :: Hand }
|
||||||
@@ -13,7 +14,7 @@ instance Player Stupid where
|
|||||||
team = getTeam
|
team = getTeam
|
||||||
hand = getHand
|
hand = getHand
|
||||||
chooseCard p _ _ hand = do
|
chooseCard p _ _ hand = do
|
||||||
trumpCol <- trumpColour
|
trumpCol <- trump
|
||||||
turnCol <- turnColour
|
turnCol <- turnColour
|
||||||
let possible = filter (isAllowed trumpCol turnCol hand) hand
|
let possible = filter (isAllowed trumpCol turnCol hand) hand
|
||||||
return (toCard $ head possible, p)
|
return (toCard $ head possible, p)
|
||||||
@@ -24,10 +25,10 @@ newtype NoBidder = NoBidder Hand
|
|||||||
-- | no bidding from that player
|
-- | no bidding from that player
|
||||||
instance Bidder NoBidder where
|
instance Bidder NoBidder where
|
||||||
hand (NoBidder h) = h
|
hand (NoBidder h) = h
|
||||||
askBid _ _ _ = return Nothing
|
askBid _ _ bid = return $ Just 20
|
||||||
askResponse _ _ _ = return False
|
askResponse _ _ bid = if bid < 24 then return True else return False
|
||||||
askGame _ _ = undefined -- never called
|
askGame _ _ = return $ Grand Hand
|
||||||
askHand _ _ = return False -- never called
|
askHand _ _ = return True
|
||||||
askSkat _ _ _ = undefined -- never called
|
askSkat _ _ _ = undefined -- never called
|
||||||
toPlayer (NoBidder h) team = PL $ Stupid team h
|
toPlayer (NoBidder h) team = PL $ Stupid team h
|
||||||
onStart _ = return ()
|
onStart _ = return ()
|
||||||
|
|||||||
+75
-4
@@ -1,15 +1,17 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
module Skat.Bidding (
|
module Skat.Bidding (
|
||||||
biddingScore, Game(..), Modifier(..), isHand
|
biddingScore, Game(..), Modifier(..), isHand, getTrump, Result(..),
|
||||||
|
getResults
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Aeson hiding (Null)
|
import Data.Aeson hiding (Null, Result)
|
||||||
|
|
||||||
import Skat.Card
|
import Skat.Card
|
||||||
import Data.List (sortOn)
|
import Data.List (sortOn)
|
||||||
import Data.Ord (Down(..))
|
import Data.Ord (Down(..))
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Skat.Pile
|
||||||
|
|
||||||
-- | different game types
|
-- | different game types
|
||||||
data Game = Colour Colour Modifier
|
data Game = Colour Colour Modifier
|
||||||
@@ -20,6 +22,16 @@ data Game = Colour Colour Modifier
|
|||||||
| NullOuvertHand
|
| NullOuvertHand
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
instance ToJSON Game where
|
||||||
|
toJSON (Grand mod) =
|
||||||
|
object ["game" .= ("grand" :: String), "modifier" .= show mod]
|
||||||
|
toJSON (Colour col mod) =
|
||||||
|
object ["game" .= ("colour" :: String), "modifier" .= show mod, "colour" .= show col]
|
||||||
|
toJSON Null = object ["game" .= ("null" :: String)]
|
||||||
|
toJSON NullHand = object ["game" .= ("nullhand" :: String)]
|
||||||
|
toJSON NullOuvert = object ["game" .= ("nullouvert" :: String)]
|
||||||
|
toJSON NullOuvertHand = object ["game" .= ("nullouverthand" :: String)]
|
||||||
|
|
||||||
instance FromJSON Game where
|
instance FromJSON Game where
|
||||||
parseJSON = withObject "Game" $ \v -> do
|
parseJSON = withObject "Game" $ \v -> do
|
||||||
gamekind <- v .: "game"
|
gamekind <- v .: "game"
|
||||||
@@ -118,6 +130,65 @@ spitzen game cards
|
|||||||
|
|
||||||
-- | get all trumps for a given game out of a hand of cards
|
-- | get all trumps for a given game out of a hand of cards
|
||||||
getTrumps :: HasCard c => Game -> [c] -> [Card]
|
getTrumps :: HasCard c => Game -> [c] -> [Card]
|
||||||
getTrumps (Grand _) cards = sortOn Down $ filter ((==Jack) . getType) $ map toCard cards
|
getTrumps (Grand _) cards = sortOn Down $ filter (isTrump Jacks) $ map toCard cards
|
||||||
getTrumps (Colour col _) cards = sortOn Down $ filter (isTrump col) $ map toCard cards
|
getTrumps (Colour col _) cards = sortOn Down $ filter (isTrump $ TrumpColour col) $ map toCard cards
|
||||||
getTrumps _ _ = []
|
getTrumps _ _ = []
|
||||||
|
|
||||||
|
-- | get trump for a given game
|
||||||
|
getTrump :: Game -> Trump
|
||||||
|
getTrump (Colour col _) = TrumpColour col
|
||||||
|
getTrump (Grand _) = Jacks
|
||||||
|
getTrump _ = None
|
||||||
|
|
||||||
|
data Result = Result Game Int Int Int
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
instance ToJSON Result where
|
||||||
|
toJSON (Result game points sgl tm) =
|
||||||
|
object ["game" .= game, "points" .= points, "single" .= sgl, "team" .= tm]
|
||||||
|
|
||||||
|
isSchwarz :: Team -> Piles -> Bool
|
||||||
|
isSchwarz tm = null . wonCards tm
|
||||||
|
|
||||||
|
hasWon :: Game -> Piles -> (Bool, Game)
|
||||||
|
hasWon Null ps = (Single `isSchwarz` ps, Null)
|
||||||
|
hasWon NullHand ps = (Single `isSchwarz` ps, NullHand)
|
||||||
|
hasWon NullOuvert ps = (Single `isSchwarz` ps, NullOuvert)
|
||||||
|
hasWon NullOuvertHand ps = (Single `isSchwarz` ps, NullOuvertHand)
|
||||||
|
hasWon (Colour col mod) ps = let (b, mod') = meetsCall mod ps
|
||||||
|
in (b, Colour col mod')
|
||||||
|
hasWon (Grand mod) ps = let (b, mod') = meetsCall mod ps
|
||||||
|
in (b, Grand mod')
|
||||||
|
|
||||||
|
meetsCall :: Modifier -> Piles -> (Bool, Modifier)
|
||||||
|
meetsCall Hand ps = case wonByPoints ps of
|
||||||
|
(b, Schneider) -> (b, HandSchneider)
|
||||||
|
(b, Schwarz) -> (b, HandSchneiderSchwarz)
|
||||||
|
(b, Einfach) -> (b, Hand)
|
||||||
|
meetsCall HandSchneiderAngesagt ps = case wonByPoints ps of
|
||||||
|
(b, Schneider) -> (b, HandSchneiderAngesagt)
|
||||||
|
(b, Schwarz) -> (b, HandSchneiderAngesagtSchwarz)
|
||||||
|
(b, Einfach) -> (False, HandSchneiderAngesagt)
|
||||||
|
meetsCall HandSchwarzAngesagt ps = case wonByPoints ps of
|
||||||
|
(b, Schneider) -> (False, HandSchwarzAngesagt)
|
||||||
|
(b, Schwarz) -> (b, HandSchwarzAngesagt)
|
||||||
|
(b, Einfach) -> (False, HandSchwarzAngesagt)
|
||||||
|
meetsCall _ ps = wonByPoints ps
|
||||||
|
|
||||||
|
wonByPoints :: Piles -> (Bool, Modifier)
|
||||||
|
wonByPoints ps
|
||||||
|
| Team `isSchwarz` ps = (True, Schwarz)
|
||||||
|
| sgl >= 90 = (True, Schneider)
|
||||||
|
| Single `isSchwarz` ps = (False, Schwarz)
|
||||||
|
| sgl <= 30 = (False, Schneider)
|
||||||
|
| otherwise = (sgl > 60, Einfach)
|
||||||
|
where (sgl, _) = count ps :: (Int, Int)
|
||||||
|
|
||||||
|
-- | get result of game
|
||||||
|
getResults :: Game -> Hand -> Piles -> Piles -> Result
|
||||||
|
getResults game sglPlayer before after = Result afterGame score sglPoints teamPoints
|
||||||
|
where (won, afterGame) = hasWon game after
|
||||||
|
hand = skatCards before ++ (map toCard $ handCards sglPlayer before)
|
||||||
|
(sglPoints, teamPoints) = count after
|
||||||
|
gameScore = biddingScore afterGame hand
|
||||||
|
score = if won then gameScore else (-2) * gameScore
|
||||||
|
|||||||
+79
-25
@@ -31,6 +31,16 @@ data Type = Seven
|
|||||||
| Jack
|
| Jack
|
||||||
deriving (Eq, Ord, Show, Enum, Read)
|
deriving (Eq, Ord, Show, Enum, Read)
|
||||||
|
|
||||||
|
data NullType = NSeven
|
||||||
|
| NEight
|
||||||
|
| NNine
|
||||||
|
| NTen
|
||||||
|
| NJack
|
||||||
|
| NQueen
|
||||||
|
| NKing
|
||||||
|
| NAce
|
||||||
|
deriving (Eq, Ord, Show, Enum, Read)
|
||||||
|
|
||||||
instance Countable Type Int where
|
instance Countable Type Int where
|
||||||
count Ace = 11
|
count Ace = 11
|
||||||
count Ten = 10
|
count Ten = 10
|
||||||
@@ -45,6 +55,15 @@ data Colour = Diamonds
|
|||||||
| Clubs
|
| Clubs
|
||||||
deriving (Eq, Ord, Show, Enum, Read)
|
deriving (Eq, Ord, Show, Enum, Read)
|
||||||
|
|
||||||
|
data Trump = TrumpColour Colour
|
||||||
|
| Jacks
|
||||||
|
| None
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data TurnColour = TurnColour Colour
|
||||||
|
| Trump
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
data Card = Card Type Colour
|
data Card = Card Type Colour
|
||||||
deriving (Eq, Show, Ord, Read)
|
deriving (Eq, Show, Ord, Read)
|
||||||
|
|
||||||
@@ -98,50 +117,85 @@ instance Countable (S.Set Card) Int where
|
|||||||
instance NFData Card where
|
instance NFData Card where
|
||||||
rnf (Card t c) = t `seq` c `seq` ()
|
rnf (Card t c) = t `seq` c `seq` ()
|
||||||
|
|
||||||
equals :: Colour -> Maybe Colour -> Bool
|
equals :: TurnColour -> Maybe TurnColour -> Bool
|
||||||
equals col (Just x) = col == x
|
equals col (Just x) = col == x
|
||||||
equals col Nothing = True
|
equals col Nothing = True
|
||||||
|
|
||||||
isTrump :: HasCard c => Colour -> c -> Bool
|
isTrump :: HasCard c => Trump -> c -> Bool
|
||||||
isTrump trumpCol crd
|
isTrump None crd = False
|
||||||
|
isTrump Jacks crd = getType (toCard crd) == Jack
|
||||||
|
isTrump (TrumpColour trumpCol) crd
|
||||||
| getType (toCard crd) == Jack = True
|
| getType (toCard crd) == Jack = True
|
||||||
| otherwise = getColour (toCard crd) == trumpCol
|
| otherwise = getColour (toCard crd) == trumpCol
|
||||||
|
|
||||||
effectiveColour :: HasCard c => Colour -> c -> Colour
|
effectiveColour :: HasCard c => Trump -> c -> TurnColour
|
||||||
effectiveColour trumpCol crd = if trump then trumpCol else getColour (toCard crd)
|
effectiveColour trump card
|
||||||
where trump = isTrump trumpCol crd
|
| isTrump trump card = Trump
|
||||||
|
| otherwise = TurnColour $ getColour (toCard card)
|
||||||
|
|
||||||
isAllowed :: (Foldable t, HasCard c1, HasCard c2) => Colour -> Maybe Colour -> t c1 -> c2 -> Bool
|
isAllowed :: (Foldable t, HasCard c1, HasCard c2) => Trump -> Maybe TurnColour -> t c1 -> c2 -> Bool
|
||||||
isAllowed trumpCol turnCol cs crd =
|
isAllowed trump turnCol cs crd =
|
||||||
if col `equals` turnCol
|
if col `equals` turnCol
|
||||||
then True
|
then True
|
||||||
else not $ F.any (\ca -> effectiveColour trumpCol ca `equals` turnCol && toCard ca /= toCard crd) cs
|
else not $ F.any (\ca -> effectiveColour trump ca `equals` turnCol && toCard ca /= toCard crd) cs
|
||||||
where col = effectiveColour trumpCol (toCard crd)
|
where col = effectiveColour trump (toCard crd)
|
||||||
|
|
||||||
compareCards :: Colour
|
compareCards :: Trump
|
||||||
-> Maybe Colour
|
-> Maybe TurnColour
|
||||||
-> Card
|
-> Card
|
||||||
-> Card
|
-> Card
|
||||||
-> Ordering
|
-> Ordering
|
||||||
compareCards _ _ (Card Jack col1) (Card Jack col2) = compare col1 col2
|
compareCards _ _ (Card Jack col1) (Card Jack col2) = compare col1 col2
|
||||||
compareCards trumpCol turnCol c1@(Card tp1 col1) c2@(Card tp2 col2) =
|
compareCards trump turnCol c1@(Card tp1 col1) c2@(Card tp2 col2) =
|
||||||
case (trp1, trp2) of
|
case (trp1, trp2) of
|
||||||
(True, True) -> compare tp1 tp2
|
(True, True) -> compare tp1 tp2
|
||||||
(False, False) -> case compare (col1 `equals` turnCol)
|
(False, False) -> case ( effectiveColour trump c1 `equals` turnCol
|
||||||
(col2 `equals` turnCol) of
|
, effectiveColour trump c2 `equals` turnCol ) of
|
||||||
EQ -> compare tp1 tp2
|
(True, True) -> compareTypes trump tp1 tp2
|
||||||
v -> v
|
(True, False) -> GT
|
||||||
|
(False, True) -> LT
|
||||||
|
_ -> EQ
|
||||||
_ -> compare trp1 trp2
|
_ -> compare trp1 trp2
|
||||||
where trp1 = isTrump trumpCol c1
|
where trp1 = isTrump trump c1
|
||||||
trp2 = isTrump trumpCol c2
|
trp2 = isTrump trump c2
|
||||||
|
|
||||||
sortCards :: HasCard c => Colour -> Maybe Colour -> [c] -> [c]
|
compareRender :: Trump -> Card -> Card -> Ordering
|
||||||
sortCards trumpCol turnCol cs = sortBy f cs
|
compareRender trump c1@(Card tp1 col1) c2@(Card tp2 col2) =
|
||||||
where f c1 c2 = compareCards trumpCol turnCol (toCard c1) (toCard c2)
|
case (trp1, trp2) of
|
||||||
|
(True, True) -> compare tp1 tp2
|
||||||
|
(False, False) -> case compare col1 col2 of
|
||||||
|
EQ -> compare tp1 tp2
|
||||||
|
v -> v
|
||||||
|
_ -> compare trp1 trp2
|
||||||
|
where trp1 = isTrump trump c1
|
||||||
|
trp2 = isTrump trump c2
|
||||||
|
|
||||||
highestCard :: HasCard c => Colour -> Maybe Colour -> [c] -> c
|
compareTypes :: Trump
|
||||||
highestCard trumpCol turnCol cs = maximumBy f cs
|
-> Type
|
||||||
where f c1 c2 = compareCards trumpCol turnCol (toCard c1) (toCard c2)
|
-> Type
|
||||||
|
-> Ordering
|
||||||
|
compareTypes None tp1 tp2 = compare (toNullType tp1) (toNullType tp2)
|
||||||
|
where toNullType Seven = NSeven
|
||||||
|
toNullType Eight = NEight
|
||||||
|
toNullType Nine = NNine
|
||||||
|
toNullType Ten = NTen
|
||||||
|
toNullType Jack = NJack
|
||||||
|
toNullType Queen = NQueen
|
||||||
|
toNullType King = NKing
|
||||||
|
toNullType Ace = NAce
|
||||||
|
compareTypes _ tp1 tp2 = compare tp1 tp2
|
||||||
|
|
||||||
|
sortCards :: HasCard c => Trump -> Maybe TurnColour -> [c] -> [c]
|
||||||
|
sortCards trump turnCol cs = sortBy f cs
|
||||||
|
where f c1 c2 = compareCards trump turnCol (toCard c1) (toCard c2)
|
||||||
|
|
||||||
|
sortRender :: HasCard c => Trump -> [c] -> [c]
|
||||||
|
sortRender trump cs = sortBy f cs
|
||||||
|
where f c1 c2 = compareRender trump (toCard c2) (toCard c1)
|
||||||
|
|
||||||
|
highestCard :: HasCard c => Trump -> Maybe TurnColour -> [c] -> c
|
||||||
|
highestCard trump turnCol cs = maximumBy f cs
|
||||||
|
where f c1 c2 = compareCards trump turnCol (toCard c1) (toCard c2)
|
||||||
|
|
||||||
shuffleCards :: IO [Card]
|
shuffleCards :: IO [Card]
|
||||||
shuffleCards = do
|
shuffleCards = do
|
||||||
|
|||||||
+20
-23
@@ -1,5 +1,5 @@
|
|||||||
module Skat.Matches (
|
module Skat.Matches (
|
||||||
singleVsBots, pvp, pvpWithBidding, singleWithBidding
|
singleVsBots, pvp, singleWithBidding
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
@@ -12,11 +12,26 @@ import Skat.Player
|
|||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
import Skat.Card
|
import Skat.Card
|
||||||
import Skat.Preperation
|
import Skat.Preperation
|
||||||
|
import Skat.Bidding
|
||||||
|
|
||||||
import Skat.AI.Rulebased
|
import Skat.AI.Rulebased
|
||||||
import Skat.AI.Online
|
import Skat.AI.Online
|
||||||
import Skat.AI.Stupid
|
import Skat.AI.Stupid
|
||||||
|
|
||||||
|
match :: PrepEnv -> IO ()
|
||||||
|
match prepEnv = do
|
||||||
|
maySkatEnv <- runReaderT runPreperation prepEnv
|
||||||
|
case maySkatEnv of
|
||||||
|
Just (sglPlayer, skatEnv) -> do
|
||||||
|
finished <- execStateT turn skatEnv
|
||||||
|
let res = getResults
|
||||||
|
(game skatEnv)
|
||||||
|
sglPlayer
|
||||||
|
(Skat.piles skatEnv)
|
||||||
|
(Skat.piles finished)
|
||||||
|
publishGameResults res (bidders prepEnv)
|
||||||
|
Nothing -> putStrLn "no one wanted to play"
|
||||||
|
|
||||||
-- | predefined card distribution for testing purposes
|
-- | predefined card distribution for testing purposes
|
||||||
cardDistr :: Piles
|
cardDistr :: Piles
|
||||||
cardDistr = emptyPiles hand1 hand2 hand3 skt
|
cardDistr = emptyPiles hand1 hand2 hand3 skt
|
||||||
@@ -38,8 +53,8 @@ singleVsBots comm = do
|
|||||||
(PL $ OnlineEnv Team Hand1 comm)
|
(PL $ OnlineEnv Team Hand1 comm)
|
||||||
(PL $ Stupid Team Hand2)
|
(PL $ Stupid Team Hand2)
|
||||||
(PL $ mkAIEnv Single Hand3 10)
|
(PL $ mkAIEnv Single Hand3 10)
|
||||||
env = SkatEnv (distribute cards) Nothing Spades ps Hand1
|
env = SkatEnv (distribute cards) Nothing (Colour Spades Einfach) ps Hand1
|
||||||
liftIO $ evalStateT (publishGameStart >> turn >>= publishGameResults) env
|
void $ evalStateT turn env
|
||||||
|
|
||||||
singleWithBidding :: Communicator c => c -> IO ()
|
singleWithBidding :: Communicator c => c -> IO ()
|
||||||
singleWithBidding comm = do
|
singleWithBidding comm = do
|
||||||
@@ -51,24 +66,10 @@ singleWithBidding comm = do
|
|||||||
(BD $ NoBidder Hand2)
|
(BD $ NoBidder Hand2)
|
||||||
(BD $ NoBidder Hand3)
|
(BD $ NoBidder Hand3)
|
||||||
env = PrepEnv ps bs
|
env = PrepEnv ps bs
|
||||||
maySkatEnv <- liftIO $ runReaderT runPreperation env
|
match env
|
||||||
case maySkatEnv of
|
|
||||||
Just skatEnv ->
|
|
||||||
liftIO $ evalStateT (publishGameStart >> turn >>= publishGameResults) skatEnv
|
|
||||||
Nothing -> putStrLn "No one wanted to play."
|
|
||||||
|
|
||||||
pvp :: Communicator c => c -> c -> c -> IO ()
|
pvp :: Communicator c => c -> c -> c -> IO ()
|
||||||
pvp comm1 comm2 comm3 = do
|
pvp comm1 comm2 comm3 = do
|
||||||
cards <- shuffleCards
|
|
||||||
let ps = Players
|
|
||||||
(PL $ OnlineEnv Team Hand1 comm1)
|
|
||||||
(PL $ OnlineEnv Team Hand2 comm2)
|
|
||||||
(PL $ OnlineEnv Team Hand3 comm3)
|
|
||||||
env = SkatEnv (distribute cards) Nothing Spades ps Hand1
|
|
||||||
liftIO $ evalStateT (publishGameStart >> turn >>= publishGameResults) env
|
|
||||||
|
|
||||||
pvpWithBidding :: Communicator c => c -> c -> c -> IO ()
|
|
||||||
pvpWithBidding comm1 comm2 comm3 = do
|
|
||||||
cards <- shuffleCards
|
cards <- shuffleCards
|
||||||
let ps = distribute cards
|
let ps = distribute cards
|
||||||
h1 = map toCard $ handCards Hand1 ps
|
h1 = map toCard $ handCards Hand1 ps
|
||||||
@@ -79,8 +80,4 @@ pvpWithBidding comm1 comm2 comm3 = do
|
|||||||
(BD $ PrepOnline Hand2 comm2 $ h2)
|
(BD $ PrepOnline Hand2 comm2 $ h2)
|
||||||
(BD $ PrepOnline Hand3 comm3 $ h3)
|
(BD $ PrepOnline Hand3 comm3 $ h3)
|
||||||
env = PrepEnv ps bs
|
env = PrepEnv ps bs
|
||||||
maySkatEnv <- liftIO $ runReaderT runPreperation env
|
match env
|
||||||
case maySkatEnv of
|
|
||||||
Just skatEnv ->
|
|
||||||
liftIO $ evalStateT (publishGameStart >> turn >>= publishGameResults) skatEnv
|
|
||||||
Nothing -> putStrLn "No one wanted to play."
|
|
||||||
|
|||||||
+8
-27
@@ -1,6 +1,6 @@
|
|||||||
module Skat.Operations (
|
module Skat.Operations (
|
||||||
turn, turnGeneric, play, playOpen, publishGameResults,
|
turn, turnGeneric, play, playOpen,
|
||||||
publishGameStart, play_, sortRender, undo_
|
play_, sortRender, undo_
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
@@ -13,21 +13,13 @@ import Skat
|
|||||||
import Skat.Card
|
import Skat.Card
|
||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
import Skat.Player (chooseCard, Players(..), Player(..), PL(..),
|
import Skat.Player (chooseCard, Players(..), Player(..), PL(..),
|
||||||
updatePlayer, playersToList, player, MonadPlayer, getSinglePlayer)
|
updatePlayer, playersToList, player, MonadPlayer, getSinglePlayer, trump)
|
||||||
import Skat.Utils (shuffle)
|
import Skat.Utils (shuffle)
|
||||||
|
|
||||||
compareRender :: Card -> Card -> Ordering
|
|
||||||
compareRender (Card t1 c1) (Card t2 c2) = case compare c1 c2 of
|
|
||||||
EQ -> compare t1 t2
|
|
||||||
v -> v
|
|
||||||
|
|
||||||
sortRender :: [Card] -> [Card]
|
|
||||||
sortRender = sortBy compareRender
|
|
||||||
|
|
||||||
play_ :: HasCard c => c -> Skat ()
|
play_ :: HasCard c => c -> Skat ()
|
||||||
play_ card = do
|
play_ card = do
|
||||||
hand <- gets currentHand
|
hand <- gets currentHand
|
||||||
trCol <- gets trumpColour
|
trCol <- trump
|
||||||
modifyp $ playCard hand card
|
modifyp $ playCard hand card
|
||||||
table <- getp tableCards
|
table <- getp tableCards
|
||||||
case length table of
|
case length table of
|
||||||
@@ -36,7 +28,7 @@ play_ card = do
|
|||||||
3 -> evaluateTable >>= modify . setCurrentHand
|
3 -> evaluateTable >>= modify . setCurrentHand
|
||||||
_ -> modify (setCurrentHand $ next hand)
|
_ -> modify (setCurrentHand $ next hand)
|
||||||
|
|
||||||
undo_ :: HasCard c => c -> Hand -> Maybe Colour -> Team -> Skat ()
|
undo_ :: HasCard c => c -> Hand -> Maybe TurnColour -> Team -> Skat ()
|
||||||
undo_ card oldCurrent oldTurnCol oldWinner = do
|
undo_ card oldCurrent oldTurnCol oldWinner = do
|
||||||
modify $ setCurrentHand oldCurrent
|
modify $ setCurrentHand oldCurrent
|
||||||
modify $ setTurnColour oldTurnCol
|
modify $ setTurnColour oldTurnCol
|
||||||
@@ -51,7 +43,7 @@ turnGeneric playFunc depth = do
|
|||||||
ps <- gets players
|
ps <- gets players
|
||||||
let p = player ps n
|
let p = player ps n
|
||||||
over <- getp $ handEmpty n
|
over <- getp $ handEmpty n
|
||||||
trCol <- gets trumpColour
|
trCol <- trump
|
||||||
case length table of
|
case length table of
|
||||||
0 -> playFunc p >> modify (setCurrentHand $ next n) >> turnGeneric playFunc depth
|
0 -> playFunc p >> modify (setCurrentHand $ next n) >> turnGeneric playFunc depth
|
||||||
1 -> do
|
1 -> do
|
||||||
@@ -72,7 +64,7 @@ turn = turnGeneric play 10
|
|||||||
|
|
||||||
evaluateTable :: Skat Hand
|
evaluateTable :: Skat Hand
|
||||||
evaluateTable = do
|
evaluateTable = do
|
||||||
trumpCol <- gets trumpColour
|
trumpCol <- trump
|
||||||
turnCol <- gets turnColour
|
turnCol <- gets turnColour
|
||||||
table <- getp tableCards
|
table <- getp tableCards
|
||||||
ps <- gets players
|
ps <- gets players
|
||||||
@@ -89,7 +81,7 @@ play :: (Show p, Player p) => p -> Skat Card
|
|||||||
play p = do
|
play p = do
|
||||||
table <- getp tableCards
|
table <- getp tableCards
|
||||||
turnCol <- gets turnColour
|
turnCol <- gets turnColour
|
||||||
trump <- gets trumpColour
|
trump <- trump
|
||||||
cards <- getp $ handCards (hand p)
|
cards <- getp $ handCards (hand p)
|
||||||
fallen <- getp played
|
fallen <- getp played
|
||||||
(card, p') <- chooseCard p table fallen cards
|
(card, p') <- chooseCard p table fallen cards
|
||||||
@@ -107,14 +99,3 @@ playOpen p = do
|
|||||||
card <- chooseCardOpen p
|
card <- chooseCardOpen p
|
||||||
modifyp $ playCard (hand p) card
|
modifyp $ playCard (hand p) card
|
||||||
return card
|
return card
|
||||||
|
|
||||||
publishGameResults :: (Int, Int) -> Skat ()
|
|
||||||
publishGameResults res = do
|
|
||||||
pls <- gets players
|
|
||||||
mapM_ (\p -> onGameResults p res) (playersToList pls)
|
|
||||||
|
|
||||||
publishGameStart :: Skat ()
|
|
||||||
publishGameStart = do
|
|
||||||
pls <- gets players
|
|
||||||
let sglPlayer = getSinglePlayer pls
|
|
||||||
mapM_ (\p -> onGameStart p sglPlayer) (playersToList pls)
|
|
||||||
|
|||||||
+3
-3
@@ -153,12 +153,12 @@ handCards Hand1 = _hand1
|
|||||||
handCards Hand2 = _hand2
|
handCards Hand2 = _hand2
|
||||||
handCards Hand3 = _hand3
|
handCards Hand3 = _hand3
|
||||||
|
|
||||||
allowed :: Hand -> Colour -> Maybe Colour -> Piles -> [CardS Owner]
|
allowed :: Hand -> Trump -> Maybe TurnColour -> Piles -> [CardS Owner]
|
||||||
allowed hand trCol turnCol ps
|
allowed hand trump turnCol ps
|
||||||
| null sameColour = cards
|
| null sameColour = cards
|
||||||
| otherwise = sameColour
|
| otherwise = sameColour
|
||||||
where cards = handCards hand ps
|
where cards = handCards hand ps
|
||||||
sameColour = filter (\ca -> effectiveColour trCol ca `equals` turnCol) cards
|
sameColour = filter (\ca -> effectiveColour trump ca `equals` turnCol) cards
|
||||||
|
|
||||||
skatCards :: Piles -> [Card]
|
skatCards :: Piles -> [Card]
|
||||||
skatCards = map getCard . _skat
|
skatCards = map getCard . _skat
|
||||||
|
|||||||
+2
-14
@@ -8,8 +8,8 @@ import Skat.Card
|
|||||||
import Skat.Pile
|
import Skat.Pile
|
||||||
|
|
||||||
class (Monad m, MonadIO m) => MonadPlayer m where
|
class (Monad m, MonadIO m) => MonadPlayer m where
|
||||||
trumpColour :: m Colour
|
trump :: m Trump
|
||||||
turnColour :: m (Maybe Colour)
|
turnColour :: m (Maybe TurnColour)
|
||||||
showSkat :: Player p => p -> m (Maybe [Card])
|
showSkat :: Player p => p -> m (Maybe [Card])
|
||||||
|
|
||||||
class (Monad m, MonadIO m, MonadPlayer m) => MonadPlayerOpen m where
|
class (Monad m, MonadIO m, MonadPlayer m) => MonadPlayerOpen m where
|
||||||
@@ -38,16 +38,6 @@ class Player p where
|
|||||||
fallen = played piles
|
fallen = played piles
|
||||||
myCards = handCards (hand p) piles
|
myCards = handCards (hand p) piles
|
||||||
fst <$> chooseCard p table fallen myCards
|
fst <$> chooseCard p table fallen myCards
|
||||||
onGameResults :: MonadIO m
|
|
||||||
=> p
|
|
||||||
-> (Int, Int)
|
|
||||||
-> m ()
|
|
||||||
onGameResults _ _ = return ()
|
|
||||||
onGameStart :: MonadPlayer m
|
|
||||||
=> p
|
|
||||||
-> Hand
|
|
||||||
-> m ()
|
|
||||||
onGameStart _ _ = return ()
|
|
||||||
|
|
||||||
data PL = forall p. (Show p, Player p) => PL p
|
data PL = forall p. (Show p, Player p) => PL p
|
||||||
|
|
||||||
@@ -64,8 +54,6 @@ instance Player PL where
|
|||||||
v <- onCardPlayed p card
|
v <- onCardPlayed p card
|
||||||
return $ PL v
|
return $ PL v
|
||||||
chooseCardOpen (PL p) = chooseCardOpen p
|
chooseCardOpen (PL p) = chooseCardOpen p
|
||||||
onGameResults (PL p) res = onGameResults p res
|
|
||||||
onGameStart (PL p) singlePlayer = onGameStart p singlePlayer
|
|
||||||
|
|
||||||
data Players = Players PL PL PL
|
data Players = Players PL PL PL
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import Skat.Card (Card, HasCard(..))
|
|||||||
|
|
||||||
isAllowed :: (HasCard c, MonadPlayer m) => [c] -> c -> m Bool
|
isAllowed :: (HasCard c, MonadPlayer m) => [c] -> c -> m Bool
|
||||||
isAllowed hand card = do
|
isAllowed hand card = do
|
||||||
trCol <- trumpColour
|
tr <- trump
|
||||||
turnCol <- turnColour
|
turnCol <- turnColour
|
||||||
return $ C.isAllowed trCol turnCol hand card
|
return $ C.isAllowed tr turnCol hand card
|
||||||
|
|
||||||
isTrump :: MonadPlayer m => Card -> m Bool
|
isTrump :: MonadPlayer m => Card -> m Bool
|
||||||
isTrump card = do
|
isTrump card = do
|
||||||
trCol <- trumpColour
|
tr <- trump
|
||||||
return $ C.isTrump trCol card
|
return $ C.isTrump tr card
|
||||||
|
|||||||
+35
-10
@@ -1,7 +1,9 @@
|
|||||||
{-# LANGUAGE ExistentialQuantification #-}
|
{-# LANGUAGE ExistentialQuantification #-}
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
|
|
||||||
module Skat.Preperation (
|
module Skat.Preperation (
|
||||||
Bidder(..), Bid, BD(..), Bidders(..), PrepEnv(..), runPreperation
|
Bidder(..), Bid, BD(..), Bidders(..), PrepEnv(..), runPreperation,
|
||||||
|
publishGameResults
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
@@ -30,6 +32,10 @@ class Bidder a where
|
|||||||
askHand :: MonadIO m => a -> Bid -> m Bool
|
askHand :: MonadIO m => a -> Bid -> m Bool
|
||||||
askSkat :: MonadIO m => a -> Bid -> [Card] -> m [Card]
|
askSkat :: MonadIO m => a -> Bid -> [Card] -> m [Card]
|
||||||
toPlayer :: a -> Team -> PL
|
toPlayer :: a -> Team -> PL
|
||||||
|
onGame :: MonadIO m => a -> Game -> Hand -> m ()
|
||||||
|
onGame _ _ _ = return ()
|
||||||
|
onResult :: MonadIO m => a -> Result -> m ()
|
||||||
|
onResult _ _ = return ()
|
||||||
|
|
||||||
-- | trick to allow heterogenous bidder list
|
-- | trick to allow heterogenous bidder list
|
||||||
data BD = forall b. (Show b, Bidder b) => BD b
|
data BD = forall b. (Show b, Bidder b) => BD b
|
||||||
@@ -46,6 +52,8 @@ instance Bidder BD where
|
|||||||
askResponse (BD b) = askResponse b
|
askResponse (BD b) = askResponse b
|
||||||
toPlayer (BD b) = toPlayer b
|
toPlayer (BD b) = toPlayer b
|
||||||
onStart (BD b) = onStart b
|
onStart (BD b) = onStart b
|
||||||
|
onGame (BD b) = onGame b
|
||||||
|
onResult (BD b) = onResult b
|
||||||
|
|
||||||
data Bidders = Bidders BD BD BD
|
data Bidders = Bidders BD BD BD
|
||||||
deriving Show
|
deriving Show
|
||||||
@@ -61,29 +69,31 @@ toPlayers single (Bidders b1 b2 b3) =
|
|||||||
(toPlayer b2 $ if single == Hand2 then Single else Team)
|
(toPlayer b2 $ if single == Hand2 then Single else Team)
|
||||||
(toPlayer b3 $ if single == Hand3 then Single else Team)
|
(toPlayer b3 $ if single == Hand3 then Single else Team)
|
||||||
|
|
||||||
runPreperation :: Preperation (Maybe SkatEnv)
|
runPreperation :: Preperation (Maybe (Hand, SkatEnv))
|
||||||
runPreperation = do
|
runPreperation = do
|
||||||
bds <- asks bidders
|
bds <- asks bidders
|
||||||
onStart (bidder bds Hand1)
|
onStart (bidder bds Hand1)
|
||||||
onStart (bidder bds Hand2)
|
onStart (bidder bds Hand2)
|
||||||
onStart (bidder bds Hand3)
|
onStart (bidder bds Hand3)
|
||||||
(winner, bid) <- runBidding 0 (bidder bds Hand2) (bidder bds Hand1)
|
(winner, bid) <- runBidding 0 (bidder bds Hand2) (bidder bds Hand1)
|
||||||
(finalWinner, finalBid) <- runBidding 0 (bidder bds Hand3) (bidder bds winner)
|
(finalWinner, finalBid) <- runBidding bid (bidder bds Hand3) (bidder bds winner)
|
||||||
if finalBid == 0 then do
|
if finalBid == 0 then do
|
||||||
bid <- askBid (bidder bds finalWinner) finalWinner 0
|
bid <- askBid (bidder bds finalWinner) finalWinner 0
|
||||||
case bid of
|
case bid of
|
||||||
Just val -> Just <$> initGame finalWinner val
|
Just val -> (Just . (finalWinner,)) <$> initGame finalWinner val
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
else Just <$> initGame finalWinner finalBid
|
else (Just . (finalWinner,)) <$> initGame finalWinner finalBid
|
||||||
|
|
||||||
runBidding :: Bid -> BD -> BD -> Preperation (Hand, Bid)
|
runBidding :: Bid -> BD -> BD -> Preperation (Hand, Bid)
|
||||||
runBidding startingBid reizer gereizter = do
|
runBidding startingBid reizer gereizter = do
|
||||||
first <- askBid reizer (hand gereizter) startingBid
|
first <- askBid reizer (hand gereizter) startingBid
|
||||||
case first of
|
case first of
|
||||||
Just val -> do
|
Just val
|
||||||
response <- askResponse gereizter (hand reizer) val
|
| val > startingBid -> do
|
||||||
if response then runBidding val reizer gereizter
|
response <- askResponse gereizter (hand reizer) val
|
||||||
else return (hand reizer, val)
|
if response then runBidding val reizer gereizter
|
||||||
|
else return (hand reizer, val)
|
||||||
|
| otherwise -> return (hand gereizter, startingBid)
|
||||||
Nothing -> return (hand gereizter, startingBid)
|
Nothing -> return (hand gereizter, startingBid)
|
||||||
|
|
||||||
initGame :: Hand -> Bid -> Preperation SkatEnv
|
initGame :: Hand -> Bid -> Preperation SkatEnv
|
||||||
@@ -96,8 +106,10 @@ initGame single bid = do
|
|||||||
ps' <- if noSkat then return ps else handleSkat (bidder bds single) bid ps
|
ps' <- if noSkat then return ps else handleSkat (bidder bds single) bid ps
|
||||||
-- ask for game kind
|
-- ask for game kind
|
||||||
game <- handleGame (bidder bds single) bid noSkat
|
game <- handleGame (bidder bds single) bid noSkat
|
||||||
|
-- publish game start
|
||||||
|
publishGameStart game single
|
||||||
-- construct skat env
|
-- construct skat env
|
||||||
return $ mkSkatEnv ps' Nothing Spades (toPlayers single bds) Hand1
|
return $ mkSkatEnv ps' Nothing game (toPlayers single bds) Hand1
|
||||||
|
|
||||||
handleGame :: BD -> Bid -> Bool -> Preperation Game
|
handleGame :: BD -> Bid -> Bool -> Preperation Game
|
||||||
handleGame bd bid noSkat = do
|
handleGame bd bid noSkat = do
|
||||||
@@ -119,3 +131,16 @@ handleSkat bd bid ps = do
|
|||||||
case moveToSkat (hand bd) skat' ps of
|
case moveToSkat (hand bd) skat' ps of
|
||||||
Just correct -> return correct
|
Just correct -> return correct
|
||||||
Nothing -> handleSkat bd bid ps
|
Nothing -> handleSkat bd bid ps
|
||||||
|
|
||||||
|
publishGameResults :: MonadIO m => Result -> Bidders -> m ()
|
||||||
|
publishGameResults res bidders = do
|
||||||
|
onResult (bidder bidders Hand1) res
|
||||||
|
onResult (bidder bidders Hand2) res
|
||||||
|
onResult (bidder bidders Hand3) res
|
||||||
|
|
||||||
|
publishGameStart :: Game -> Hand -> Preperation ()
|
||||||
|
publishGameStart game sglPlayer = do
|
||||||
|
bds <- asks bidders
|
||||||
|
onGame (bidder bds Hand1) game sglPlayer
|
||||||
|
onGame (bidder bds Hand2) game sglPlayer
|
||||||
|
onGame (bidder bds Hand3) game sglPlayer
|
||||||
|
|||||||
Reference in New Issue
Block a user