Это код idiomati c? Есть ли лучший или более сжатый способ написать это? - PullRequest
2 голосов
/ 13 июля 2020

Я пытаюсь смоделировать игру в покер.

Состояние моей игры отображается на карте, в этом вопросе меня интересуют только игроки.

{:players {:1 {:money 200} :2 {money 400}}}

Каждая функция принимает состояние игры и некоторые другие параметры и возвращает новое состояние игры, например:

(defn update-player-money
  "Returns new game state where player has added amount to his money"
  [game-state player amount]
  (assoc-in game-state [:players player :money]
            (+ (-> game-state :players player :money)
               amount)))

Теперь мне нужна функция, которая удаляет определенную сумму денег из каждого игрок при передаче нового игрового состояния. Чтобы прояснить, что-то, что подойдет для двух игроков:

(update-player-money (update-player-money game-state :1 (- 20)) :2 (-20))

Вот что я придумал:

(defn phase-1-blind
  "Removes blind from all players."
  [game-state blind-amount]
  (letfn [(blind-helper [game-state player-list amount]
            (if (seq player-list)
              (blind-helper (update-player-money game-state
                                                 (first player-list)
                                                 (- amount))
                            (rest player-list)
                            amount)
              game-state))]
  (blind-helper game-state (keys (:players game-state)) blind-amount)))

Это работает, но мне было интересно, есть ли еще idiomati c или краткий способ достижения того же эффекта.

1 Ответ

2 голосов
/ 13 июля 2020

Если вы хотите реализовать phase-1-blind, используя update-player-money, здесь может быть полезен reduce:

(defn update-player-money
  "Returns new game state where player has added amount to his money"
  [game player-id amt]
  (update-in game [:players player-id :money] (fnil + 0) amt))

(defn phase-1-blind
  "Removes blind from all players."
  [game blind]
  (reduce #(update-player-money % %2 blind)
          game
          (keys (:players game))))

In update-player-money, fnil следит за тем, чтобы все не сломалось, даже если у игрока нет ключа :money.

...