2015-10-05 3 views
0
  • Я строю игру (вид покера) в Haskell, но я новичок в Haskell и вообще застревают, когда пытаются думать, как реализовать вещь в чисто функциональном языке. *

Игра состоит из 3-х игроков (просто чтобы было легко объяснить). Два игрока будут играть с настольных карточек, а один будет играть из стека. Оба игрока будут использовать одну карту и использовать ее, если это полезно (замените одну из ваших карт в руке) или просто свалите ее (если нет). Победа - это просто фулл-хаус или прямая.Haskell Переменная Updation

У двух из них есть understanding, что-то, с чем они договорились, прежде чем помогать друг другу. Например, если я взял K (скажем) из таблицы и следующей рукой я взял 4 из таблицы означает, что я собираюсь в полный дом, и, следовательно, вы должны помочь, если можете, любым возможным способом. Каждый из этих игроков должен помогать друг другу, чтобы один из них мог выиграть до того, как игрок сыграет со стопкой, но не ценой самого себя.

Таблица имеет всего 5 карт и так делает каждый игрок

Реализовать Понимание между двумя игроками:

я застрял, как отследить, что другой игрок уже взял со стола. Я пытаюсь это сделать, добавляя карты к моей руке (практически помню вещь), а в то время как вычисления донга моей руки (реальные) я собираюсь взять только первые пять карт и, выполняя расчет, чтобы помочь ему «Я собираюсь сбросить пять карт, а затем выполнить вычисления с этим. Есть ли какая-нибудь лучшая стратегия, чтобы сделать то же самое? Это может быть тривиально, но я любитель в мире haskell. Если вы хотите код, я могу его просто поднять.

базовый набор из моей игры:

data Card = Card { 
    c :: (Int, Char) 
    } deriving (Eq, Ord, Show) 

data Deck = Deck { 
    d :: [Card] 
} deriving (Show, Eq, Ord) 

data Game = Game { 
    bact1Hand :: [Card], 
    bact2Hand :: [Card], 
    orgHand :: [Card], 
    tableCards :: [Card], 
    deck :: Deck 
} deriving (Show, Eq, Ord) 

type GameState a = State Game a` 
+0

У нас нет переменных в Haskell! Используйте [рекурсия] (http://learnyouahaskell.com/recursion). – AJFarmar

+0

По крайней мере, я знаю. Но как вы собираетесь помнить? о последней руке или карте, которую игрок взял со стола? thanks – user2754673

+1

Дополнительные аргументы вашей функции. – Zeta

ответ

1

Если вы хотите сохранить его простым и не готовы для продвинутых Haskell вещей, вы можете использовать рекурсивные преобразования, как это было предложено в комментариях к вам вопрос.

Основная идея заключается в том, что вы создаете тип данных data Game, который полностью описывает состояние игры; а затем вы напишете функцию «Игрок А делает действие 1», что превращает игру (например, act:: Player -> Action -> Game -> Game). Такая функция преобразует полное состояние игры: сохраняет состояние от входа к выходу, но изменяет некоторые его части, связанные с игроком, и действие (например, добавление карты в руку). Последний шаг - привязать функцию к действиям IO: в простейшей настройке вы создаете основной цикл, в котором изменяется Game, ожидая ввода IO на каждой итерации (например, как и в основном цикле OpenGL). Или вы можете использовать Control.Concurrent.MVar для прохождения IO асинхронно.

Таким образом, в короткий код:

-- | State of the AI 
data Mind = Mind 
    { overallLogic :: ??? 
    , perPlayerLogic :: [(PlayerID, Understanding)] 
    } 

-- | Undersanding of one player by another player 
data Understanding = ??? 

newtype PlayerID = PlayerID Int 

-- | Full state of the player 
data Player = Player 
    { id :: PlayerID 
    , hand :: [Card] 
    , mind :: Mind 
    , ... 
    } 

-- | indication of the game state 
data Status = PlayersTurn PlayerID | PlayerWon PlayerID 

-- | Full state of the game 
data Game = Game 
    { status :: Status 
    , players :: [Player] -- or consider (Int)Map of player-id 
    , ... 
    } 

-- | Events in game are passed from IO: they indicate players' actions 
data Event = PlayersTurn PlayerID Action ... 
      | WhateverElseEvent 

-- | the function to transform Game's state 
react :: Event -> Game -> Game 
react ev game = game' 
    where game' = ... -- here is game logic 

И где-то вы положили основной цикл в отдельном потоке:

mainLoop :: MVar Event -> Game -> IO() 
mainLoop mevent game = do 
    event <- takeMVar mevent 
    let game' = react event game 
    if checkIfFinished game' 
     then return() 
     else mainLoop mevent game' 

Обратите внимание на хвост рекурсивный вызов - цикл идет до checkIfFinished возвращается True.checkIfFinished - ваша логика, чтобы решить, закончить игру или нет, на основе состояния Game. takeMVar ждет другой поток, чтобы что-то положить. В других потоках вы добавляете IO-действия, которые получают пользовательский ввод, делают из них данные Event и помещают его с помощью putMVar.

Обновление: Благодаря комментариям я поставил часть ответа на нижнюю часть в виде «дальнейшего чтения».

Если вы хотите, чтобы помнить состояния глобально, GHC предлагает два типа для вас: Data.STRef и Control.Concurrent.MVar. Однако это не «чисто функциональный» подход. Вы можете прочитать о состоянии полных вычислений и монаде читателя здесь http://learnyouahaskell.com/. Комментаторы предполагают, что государственная монада лучше, чем монада-читателя для текущих целей - спасибо, я признаю это. Во всяком случае, learnyouahaskell - отличный источник для этих видов информации :).

Наиболее чисто функциональным и полезным в применении подход будет использовать Functional Reactive Programming. Поведение Поведение представляет собой изменяющееся во времени значение. Некоторые люди скажут, что FRP - это избыток, и, вероятно, они будут правы. Но когда вы решите добавить графический интерфейс и другой ввод-вывод, используя приятные интерфейсы, предоставляемые, например, reactive-banana значительно упростит вашу жизнь.

+1

Что значит «читатель»? – dfeuer

+0

Пропускает состояние игры. Такая же рекурсия, но данные передаются неявно через среду monad. – artem

+0

редактирование лучше (но вы упомянете читатель-монаду, когда вы описываете государственную монаду), но все же очень сложно понять, как это относится к вопросу – Carsten

Смежные вопросы