从哈希值中检索哈希值(在Ruby中)

时间:2013-12-15 05:40:43

标签: ruby sockets data-structures hash key

我正在尝试设置一个服务器来为一项任务进行战争游戏。我想我的插座和玩家都是哈希,其中键是我的插座而玩家是我的价值观。

现在一切都很好,我只为客户端类编写一个检索函数,因为它们只需要从服务器中提取,但我需要具体说明从哪个客户端获取输入,但我无法弄清楚如何从我的程序中的哈希值获取哈希键。

Mudasobwa,我试图通过的测试是

def test_server_capture_output_from_client

在底部。谢谢,这真让我烦恼。

#SERVER CLASS -- Server starts up a TCP, and starts up the game and players and deal the cards
#SERVER CLASS -- Server starts up a TCP, and starts up the game and players and deal the cards
require 'minitest/autorun'
require 'socket'
require_relative 'WarGame_Class.rb'
require_relative 'ModifiedPlayer_Class.rb'
require_relative 'DeckClass.rb'

class WarServer

    def initialize(host, port)  
        @socket_server = TCPServer.new(host, port)
        @players = [Player.new, Player.new]
        @deck = CardDeck.new
        @deck.deal_cards(@players[0].cards, @players[1].cards)
        game = WarGame.new
        @clients = {} # keys are sockets, values are players

    end

    def read_client_keys(keys)
        @clients.key[keys]
    end

    def close
        @socket_server.close
    end


    def capture_input(player)   ##input client to get what they wrote
        @input = @clients.keys[0].read_nonblock(1000) # arbitrary max number of bytes

    end

    def accept_client
        #Hash here to link client to player? (or game?)
        client = @socket_server.accept
        @clients[client] = @players[@clients.size]
    #   puts "clients key 0: #{@clients.keys[0]}"
        puts
    #   puts "clients values: #{@clients.values}"
        if @clients.size == 2
            start_game#####################!!!! Starts game if two clients  can put client messages in start game
        end
    end


    def start_game  ##############!!!
        @clients.keys[0].puts  "Welcome to War.  Please press enter to play your card"
        @clients.keys[1].puts  "Welcome to War.  Please press enter to play your card"

    end

end

class MockWarClient
    def initialize
        @socket = TCPSocket.new('localhost', 2012)
    end

    def output
        @output 
    end

    def capture_output  #need to add (socket)?  How else read from specific socket?
        @output = @socket.read_nonblock(1000) # arbitrary max number of bytes
    rescue
        @output = "capture_output error."
    end

    def capture_input

    end
end

class WarServerTest < MiniTest::Unit::TestCase


    def setup   #This would be like our INITIALIZE Function
        #anything is available through out all tests (i.e., instance vars)
        @war_server = WarServer.new('localhost', 2012)
    end


    def teardown
        @war_server.close
    end


    def test_have_1_port_listening


        socket_1 = TCPSocket.open('localhost', 2012)
        pass('connection in place')

        rescue Errno::ECONNREFUSED
        flunk('Port 1 error 1st test')


    end

    def test_connecting_two_clients 
            client_1 = MockWarClient.new
            @war_server.accept_client

            client_2 = MockWarClient.new
            @war_server.accept_client

            client_1.capture_output
            refute(client_1.output.empty?)

            #client2.capture_output
            #refute(client_2.output.empty?)
    end


    def test_server_capture_output_from_client
        client_1 = MockWarClient.new
        @war_server.accept_client

        client_2 = MockWarClient.new
        @war_server.accept_client

        #can output @war_server.read_client_keys, though, if I take out the argument to pass in.
        puts "Test_Server_output @client keys #{@war_server.read_client_keys(player)}" #cient_1?

        @warserver.capture_input
        refute(@war_server.input.empty)
    end    
end

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

通常,Hash#key method可以按值检索密钥:

h = {'a' => 1, 'b' => 2}
puts h.key(2)
# ⇒ 'b'

在你的情况下似乎就足够了。但是要知道不同键的值可能相同的情况:

h = {'a' => 1, 'b' => 2, 'c' => 1}
puts h.key(1)
# ⇒ 'c'

此处您获得了此值的 last 键。无论您是否怀疑不同键的值相同,您可能会使用Hash#keys methodHash#each迭代器并手动处理迭代。

例如,要将给定值的键检索为数组:

h = {'a' => 1, 'b' => 2, 'c' => 1}
puts h.select { |k,v| v == 1}.keys
# ⇒ ['a', 'c']