<commit_before>class Round < Struct.new(:game)
  def hands
    @hands ||= calculate_hands
  end

  def deck
    @deck ||= calculate_deck
  end

  def pile
    return @pile if @pile.present?

    if game.started?
      @pile = Pile.new(calculate_shuffled_pile)
    else
      @pile = Pile.new([])
    end
  end

  private

  # FIXME 52 pickups is fine for the first shuffle
  # But subsequent pickups will trigger from running through the deck height
  # which will not be 52 the second time
  # If the deck is size 20 after the first shuffle
  # the second shuffle will be at 72 pickups!
  def calculate_shuffled_pile
    shuffle_count = game.pickups.count / Card::DECK.size

    # Just return played cards if we've not shuffled yet
    return game.plays.map(&:card) if shuffle_count.zero?

    # Find the card that triggered the shuffle
    @shuffle_trigger = game.pickups[ Card::DECK.size * shuffle_count - 1 ]

    # Pile will be previous pile's top card + played cards since then
    previous_top_card.concat played_since_shuffle
  end

  def previous_top_card
    [ plays_before_shuffle.last ]
  end

  def plays_before_shuffle
     game.plays.where("actions.id < ?", @shuffle_trigger.id).map(&:card)
  end

  def played_since_shuffle
    game.plays.where("actions.id > ?", @shuffle_trigger.id).map(&:card)
  end

  def cards_in_play
    pile + hands.values.flatten
  end

  def calculate_deck
    deck_cards = Card::DECK - cards_in_play
    Deck.new(deck_cards)
  end

  def calculate_hands
    hands = {}
    if game.started?
      game.players.each do |player|
        pickups = player.pickups.map(&:card)
        plays = player.plays.map(&:card)
        hands[player.nickname] = Hand.new(pickups - plays)<commit_msg>Refactor Round#pile, move logic into calculate_pile for simplicity<commit_after>class Round < Struct.new(:game)
  def hands
    @hands ||= calculate_hands
  end

  def deck
    @deck ||= calculate_deck
  end

  def pile
    @pile ||= calculate_shuffled_pile
  end

  private

  # FIXME 52 pickups is fine for the first shuffle
  # But subsequent pickups will trigger from running through the deck height
  # which will not be 52 the second time
  # If the deck is size 20 after the first shuffle
  # the second shuffle will be at 72 pickups!
  def calculate_shuffled_pile
    shuffle_count = game.pickups.count / Card::DECK.size

    if !game.started?
      pile_cards = []
    elsif shuffle_count.zero?
      # If we've not shuffled, just show all cards played
      pile_cards = game.plays.map(&:card)
    else
      # Find the card that triggered the shuffle
      @shuffle_trigger = game.pickups[ Card::DECK.size * shuffle_count - 1 ]

      # Pile will be previous pile's top card + played cards since then
      pile_cards = previous_top_card.concat played_since_shuffle
    end

    Pile.new(pile_cards)
  end

  def previous_top_card
    [ plays_before_shuffle.last ]
  end

  def plays_before_shuffle
     game.plays.where("actions.id < ?", @shuffle_trigger.id).map(&:card)
  end

  def played_since_shuffle
    game.plays.where("actions.id > ?", @shuffle_trigger.id).map(&:card)
  end

  def cards_in_play
    pile + hands.values.flatten
  end

  def calculate_deck
    deck_cards = Card::DECK - cards_in_play
    Deck.new(deck_cards)
  end

  def calculate_hands
    hands = {}
    if game.started?
      game.players.each do |player|
        pickups = player.pickups.map(&:card)
        plays = player.plays.map(&:card)
        hands[player.nickname] = Hand.new(pickups - plays)
{'fraction_non_alphanumeric': 0.08534850640113797, 'fraction_numerical': 0.005120910384068279, 'mean_word_length': 3.0367393800229623, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3358411', 'n_tokens_mistral': 1197, 'n_tokens_neox': 1106, 'n_words': 323}