Class: AcpcDealer::DealerRunner

Inherits:
Object
  • Object
show all
Defined in:
lib/acpc_dealer/dealer_runner.rb

Defined Under Namespace

Classes: Arguments

Constant Summary collapse

DEALER_COMMAND_FORMAT =

> array should correspond to those in the dealer_arguments of ::start.

> (see ::start)

Returns:

  • (Array<Symbol>)

    The format of the dealer command. The symbols in this

[
  # @note The name of the match to start.
  :match_name,
  # @note The path of the game definition to use.
  :game_def_file_name,
  # @note The number of hands to play.
  :hands,
  # @note The random seed to use.
  :random_seed,
  # @note The names of the players in the game. Should be specified as a space delimited string of names.
  :player_names,
  # @note Should be specified as an option string that the dealer will understand.
  :options
]

Class Method Summary collapse

Class Method Details

.command(dealer_arguments, port_numbers = nil) ⇒ String

> Defaults to the ACPC Dealer's default.

Parameters:

  • dealer_arguments (Array)

    Arguments to the new dealer instance.

  • port_numbers (Array) (defaults to: nil)

    The port numbers to which each player will connect.

Returns:

  • (String)

    The ACPC Dealer command that would be run


46
47
48
# File 'lib/acpc_dealer/dealer_runner.rb', line 46

def self.command(dealer_arguments, port_numbers=nil)
  command_components(dealer_arguments, port_numbers).join(' ')
end

.command_components(dealer_arguments, port_numbers = nil) ⇒ Array

> Defaults to the ACPC Dealer's default.

Parameters:

  • dealer_arguments (Array)

    Arguments to the new dealer instance.

  • port_numbers (Array) (defaults to: nil)

    The port numbers to which each player will connect.

Returns:

  • (Array)

    The components of the ACPC Dealer command that would be run (the executable, followed by arguments)


30
31
32
33
34
35
36
37
38
39
40
# File 'lib/acpc_dealer/dealer_runner.rb', line 30

def self.command_components(dealer_arguments, port_numbers=nil)
  dealer_start_command = DEALER_COMMAND_FORMAT.inject(
    [AcpcDealer::DEALER_PATH]
  ) do |command_, parameter|
    command_ += dealer_arguments[parameter].to_s.split
  end
  if port_numbers
    dealer_start_command << "-p" << "#{port_numbers.join(',')}"
  end
  dealer_start_command
end

.ports_for_players(number_of_players) ⇒ Array<Integer>

> Does NOT reserve the ports,

> so it's possible that the ports will come into use between calling

> this method and using them.

Returns:

  • (Array<Integer>)

    List of arbitrary open ports.


105
106
107
108
109
# File 'lib/acpc_dealer/dealer_runner.rb', line 105

def self.ports_for_players(number_of_players)
  number_of_players.times.map do
    TCPServer.open('localhost', 0) { |s| s.addr[1] }
  end
end

.start(dealer_arguments, log_directory = nil, port_numbers = nil, save_action_log = true, options = {}) ⇒ Object

> Defaults to <dealer_arguments>.logs.

> Defaults to the ACPC's default.

Parameters:

  • dealer_arguments (Array)

    Arguments to the new dealer instance.

  • log_directory (String) (defaults to: nil)

    The directory in which logs will be placed.

  • port_numbers (Array) (defaults to: nil)

    The port numbers to which each player will connect.

  • save_action_log (Boolean) (defaults to: true)
  • options (Hash) (defaults to: {})

    (see Process::spawn)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/acpc_dealer/dealer_runner.rb', line 60

def self.start(
  dealer_arguments,
  log_directory=nil,
  port_numbers=nil,
  save_action_log=true,
  options={}
)
  log_directory ||= File.expand_path(
    "../#{dealer_arguments[:match_name]}.logs",
    __FILE__
  )
  FileUtils.mkdir_p log_directory unless Dir.exist?(log_directory)

  options[:chdir] ||= log_directory

  IO.pipe do |read_io, write_io|
    options[:out] ||= write_io
    if save_action_log
      options[:err] = [
        File.join(
          log_directory,
          "#{dealer_arguments[:match_name]}.actions.log"
        ),
        File::CREAT|File::WRONLY
      ]
    end
    pid = Process.detach(
      Process.spawn(
        *command_components(dealer_arguments, port_numbers),
        options
      )
    ).pid

    {
      pid: pid,
      port_numbers: read_io.gets.split.map(&:to_i),
      log_directory: log_directory
    }
  end
end