<commit_before>module TicTacToe
  module AI

    class Minimax

      def initialize(my_mark, other_mark)
        @my_mark, @other_mark = my_mark, other_mark
      end

      def count_marks(marks)
        marks.each_with_object(Hash.new(0)) { |mark, counts| counts[mark] += 1 }
      end

      def has_my_marks(imarks:, count:)
        counts = count_marks(imarks.map { |imark| imark.mark })
        counts[@my_mark] == count && counts[" "] == 1
      end

      def i_can_win?(imarks)
        has_my_marks(imarks: imarks, count: 2)
      end

      def they_can_win?(imarks)
        has_my_marks(imarks: imarks, count: 0)
      end

      def score_node(node)
        winner = TicTacToe::Rules.who_won?(node)
        if winner == @my_mark
          1
        elsif winner == @other_mark
          -1
        elsif TicTacToe::Rules.draw?(node)
          0
        end
      end

      def negamax(marks, node, depth, alpha, beta, color)
        if depth == 0 or TicTacToe::Rules.finished?(node)
          return [-1, color * depth * score_node(node)]
        end

        node.empty_spaces.map do |index|
          next_child = node.speculative_move(marks[color], index)
          _, score = negamax(marks, next_child, depth - 1, -beta, -alpha, -color)
          val = -score # Invert the returned score as in regular negamax
          [index, val]
        end.max_by { |i, s| s }
      end

      def get_move(board)
        negamax({1 => @my_mark, -1 => @other_mark}, board, 10, -100, 100, 1).first
      end

    end

  end
end
<commit_msg>Switch to an each loop instead of mapping<commit_after>module TicTacToe
  module AI

    class Minimax

      def initialize(my_mark, other_mark)
        @my_mark, @other_mark = my_mark, other_mark
      end

      def count_marks(marks)
        marks.each_with_object(Hash.new(0)) { |mark, counts| counts[mark] += 1 }
      end

      def has_my_marks(imarks:, count:)
        counts = count_marks(imarks.map { |imark| imark.mark })
        counts[@my_mark] == count && counts[" "] == 1
      end

      def i_can_win?(imarks)
        has_my_marks(imarks: imarks, count: 2)
      end

      def they_can_win?(imarks)
        has_my_marks(imarks: imarks, count: 0)
      end

      def score_node(node)
        winner = TicTacToe::Rules.who_won?(node)
        if winner == @my_mark
          1
        elsif winner == @other_mark
          -1
        elsif TicTacToe::Rules.draw?(node)
          0
        end
      end

      def negamax(marks, node, depth, alpha, beta, color)
        if depth == 0 or TicTacToe::Rules.finished?(node)
          return [-1, color * depth * score_node(node)]
        end

        best = [-1, -100]
        node.empty_spaces.each do |index|
          next_child = node.speculative_move(marks[color], index)
          _, score = negamax(marks, next_child, depth - 1, -beta, -alpha, -color)
          val = -score # Invert the returned score as in regular negamax
          best = [best, [index, val]].max_by { |i, s| s }
        end

        return best
      end

      def get_move(board)
        negamax({1 => @my_mark, -1 => @other_mark}, board, 10, -100, 100, 1).first
      end

    end

  end
end

{'fraction_non_alphanumeric': 0.11191449229801949, 'fraction_numerical': 0.015089594467148696, 'mean_word_length': 2.0420650095602295, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '1528692', 'n_tokens_mistral': 1124, 'n_tokens_neox': 1082, 'n_words': 272}