Question

Okay, so I'm building a server to play the game of war as an assignment. My server needs to get input from two different sockets, and that's where I'm stuck. I've stored my sockets as keys and my players as values in a hash, but I can't get the sockets in my main program.

I can puts the hash in my main program, but I can't just get ONE socket so that I can tell my program to read from it. Here's my classes and the test I'm running:

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
        @clients.key[0] #does not work
    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_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?
        puts "Test_Server_output @client keys #{@war_server.read_client_keys}" 
        # I NEED TO JUST BE ABLE TO GET *ONE* KEY SO I CAN READ FROM THE SOCKET
        @warserver.capture_input
        refute(@war_server.input.empty)
    end
end
Was it helpful?

Solution

You must use #keys[0] (or #keys.first) to select the first key of the Hash.

The function #key(val) does something different, returning the key corresponding to an occurrence of val in the hash.

http://www.ruby-doc.org/core-2.0.0/Hash.html#method-i-key-3F

def read_client_keys
  @clients.keys[0] # this should work
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top