1 | require 'pty'
|
2 |
|
3 | class Agent
|
4 | def initialize(options={})
|
5 | @directory = options[:directory]
|
6 | @command = options[:command]
|
7 | @compile = options[:compile]
|
8 | end
|
9 |
|
10 | def cd
|
11 | "cd #{@directory}"
|
12 | end
|
13 |
|
14 | def compile!
|
15 | return unless @compile
|
16 | command = "#{cd} && #{@compile}"
|
17 | puts "compiling: #{command}"
|
18 | puts `#{command}`
|
19 | raise "Compile error" unless $?.to_i == 0
|
20 | end
|
21 |
|
22 | def command
|
23 | "#{cd} && #{@command}"
|
24 | end
|
25 | end
|
26 |
|
27 | desc "run ruby random agents"
|
28 | task :agents, :number, :langs, :game, :sleep do |t, args|
|
29 | args.with_defaults number: 4, sleep: 0.1, langs: "ruby:coffee", game: "hearts"
|
30 |
|
31 | agent_commands = {
|
32 | "hearts" => {
|
33 | "ruby" => Agent.new(directory: 'dist/hearts/ruby', command: 'ruby my_agent.rb'),
|
34 | "coffee" => Agent.new(directory: 'dist/hearts/nodejs', command: 'coffee myAgent.coffee'),
|
35 | "haskell" => Agent.new(directory: 'dist/hearts/haskell', compile: 'cabal configure && cabal build', command: 'dist/build/myAgent/myAgent'),
|
36 | "go" => Agent.new(directory: 'dist/hearts/go', compile: 'make', command: 'bin/my_agent')
|
37 | },
|
38 | "ttt" => {
|
39 | "ruby" => Agent.new(directory: 'dist/tic_tac_toe/ruby', command: 'ruby my_agent.rb'),
|
40 | }
|
41 | }
|
42 |
|
43 | agents = agent_commands[args.game].values_at(*args.langs.split(":")).shuffle
|
44 |
|
45 | agents.each(&:compile!)
|
46 |
|
47 | commands = agents.map(&:command).cycle
|
48 |
|
49 | pids = []
|
50 | args.number.to_i.times do |i|
|
51 | command = commands.next
|
52 | pids << fork do
|
53 | STDOUT.sync = true
|
54 |
|
55 | begin
|
56 | PTY.spawn(command) do |stdin, stdout, pid|
|
57 | begin
|
58 | stdin.each { |line| puts "[#{i}] #{line}" }
|
59 | rescue Errno::EIO
|
60 | puts "Errno:EIO error, but this probably just means that the process has finished giving output"
|
61 | end
|
62 | end
|
63 | rescue PTY::ChildExited
|
64 | puts "The child process exited!"
|
65 | end
|
66 | end
|
67 | sleep args.sleep.to_f
|
68 | end
|
69 |
|
70 | pids.each{|pid| Process.wait(pid)}
|
71 | end
|