为什么ruby哈希键不相等

时间:2012-08-17 23:19:02

标签: ruby

所以我遇到了哈希问题......我想:

我有两个哈希我正在比较。在我的代码中的某个时刻,我得到了一个响应,例如..

@moves = {:wm01 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "}

这对应于答案密钥哈希......

@anskey = {
    :wm01=>":c3",:wm02=>":c2",:wm03=>":c1",:wm04=>":b3",:wm05=>":b1",:wm06=>":a3",:wm07=>":a2",:wm08=>":a1",
    :wm09=>":a3",:wm10=>":c1",:wm11=>":a1",:wm12=>":c3",:wm13=>":c3",:wm14=>":c1",:wm15=>":c3",:wm16=>":a1",
    :wm17=>":b1",:wm18=>":b2",:wm19=>":b3",:wm20=>":a2",:wm21=>":b2",:wm22=>":b2",:wm23=>":c2",:wm24=>":b2"
  }

在这种情况下我需要迭代@anskey,其中@ moves.keys == @ anskey.keys

(看起来很简单,但似乎没有工作)

然后设置....

my_answer_is = @anskey.value

这样的事情???

@anskey.each do |key. value|
  if @moves.keys == key
     my_answer_is = @value
  end
end

下面的违规代码
class Player

  attr_reader :boardpiece

  def initialize(letter)
    @boardpiece = letter
  end

  def move_human(game)
    puts "human move..."
    @move = gets.chomp
  end

  def move_computer(game)
    puts "computer move..."

    # all possible third moves as 'O' (computer)
    @ai_winmoves = {
        :wm01 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm02 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm03 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm04 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm05 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm06 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
        :wm07 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
        :wm08 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
        #check those corners
        :wm09 => {:a1=>"O", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm10 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm11 => {:a1=>" ", :a2=>"O", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm12 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm13 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>"O"},
        :wm14 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>"O"},
        :wm15 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>"O", :c3=>" "},
        :wm16 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
        #check opposites
        :wm17 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
        :wm18 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
        :wm19 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
        :wm20 => {:a1=>"O", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm21 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
        :wm22 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
        :wm23 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>"O"},
        :wm24 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "}
      }
    # match current answers located in @thegrid with possible @anskey array, iterate for each item
    @anskey={
        :wm01=>":c3",:wm02=>":c2",:wm03=>":c1",:wm04=>":b3",:wm05=>":b1",:wm06=>":a3",:wm07=>":a2",:wm08=>":a1",
        :wm09=>":a3",:wm10=>":c1",:wm11=>":a1",:wm12=>":c3",:wm13=>":c3",:wm14=>":c1",:wm15=>":c3",:wm16=>":a1",
        :wm17=>":b1",:wm18=>":b2",:wm19=>":b3",:wm20=>":a2",:wm21=>":b2",:wm22=>":b2",:wm23=>":c2",:wm24=>":b2"
      }
    #
    # scan board for available move locations

    # select all values where value is X for thegrid and copy those into keys_with_x

    # compare result to ai_winmoves
    keys_with_o = $thegrid.select{ |k, v| v == "O" }.keys
    matching_moves = @ai_winmoves.select{ |k, v| v.select{ |k, v| v == "O" }.keys == keys_with_o }
    # if matching_moves.keys contains anything with wm print results
    test_str = matching_moves.keys.to_s
    win_key  = matching_moves.keys
    # str = [:wm21]
    puts "keys with o:"
    puts keys_with_o
    puts "matching:"
    puts win_key

THIS IS THE AREA THAT BOTHERS ME

    if test_str =~ /wm/ #match found then...
      puts "WIN DETECTED" #TODO - which player won?
      puts win_key
      puts test_str
      # which answer is it?
      @anskey.each do |key, value|
        if matching_moves.keys == key
          puts "answer:"
          @move = @anskey[value]
          puts @move
          exit
        else
          puts "error in if else loop"
        end
      end
    else

END AREA THAT BOTHERS ME

      # scan board for available moves... 
      available_moves = $thegrid.select{ |k, v| v == " " }.keys
      # then make a random move
      puts "availble:"
      puts available_moves
      @move = available_moves[rand(available_moves.length)]
      # @move = "b2"
    end
  end
end

2 个答案:

答案 0 :(得分:5)

字符串不是符号。

其中一个哈希值包含":c3"之类的字符串,不等于:c3 *

您可以使用.to_sym将字符串转换为符号,或使用.to_s将字符串转换为字符串。

正如马克斯所说,没有(好的)理由存储字符串而不是符号;如果您可以更改代码,请使用符号作为值和键,并完全跳过转换。这是首选,IMO。

*除非您使用Rails或使用等效的HashWithIndifferentAccess

答案 1 :(得分:0)

当您说@moves.keys时,您会在@moves中获得所有密钥的数组。

在第if @moves.keys == key行中,您试图将单元素数组[:wm01]与符号:wm01进行比较,但它们永远不会相等,因为它们是不同的类型。

如果您知道代码中的@moves代码只有一个密钥,那么您可以通过执行@moves.keys.first来获取密钥。然后使用该键索引到@anskey而不是循环遍历它:

@anskey[@moves.keys.first]

你不应该遍历哈希检查所有键是否相等。哈希的要点是hash[key]语法为key提供了值,而不需要任何循环。