-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtournament.rb
More file actions
131 lines (115 loc) · 2.37 KB
/
tournament.rb
File metadata and controls
131 lines (115 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
require './interpreter.rb'
require './compiler'
require './assembler.rb'
require './disassembler.rb'
require 'ostruct'
require 'rubygems'
require 'parallel'
$config=OpenStruct.new
$config.max_program_length=40
$config.max_cycles=2_000
$config.max_rounds=10
$config.arena_length=500
$config.threads=2
class Bot
attr_accessor :name,:code
end
#$DEBUG=true
allbots=[]
ARGV.each_index do |i|
if ARGV[i]=="-d"
$DEBUG=true
next
end
if ARGV[i]=="-p"
$PROFILE=true
next
end
bot=Bot.new
bot.name=ARGV[i]
lines=File.open(ARGV[i]).lines
cmds=Compiler.compile(Compiler.preprocess(lines))
if cmds.length>$config.max_program_length
puts "bot #{ARGV[i]} rejected because he is to long"
next
end
bot.code=cmds
puts cmds.map{|c| Disassembler.bin_to_code(c)}.inspect
allbots<<bot
end
if $PROFILE
require 'rubygems'
require 'ruby-prof'
RubyProf.start
end
class Array
def perm(n = size)
if size < n or n < 0
elsif n == 0
yield([])
else
self[1..-1].perm(n - 1) do |x|
(0...n).each do |i|
yield(x[0...i] + [first] + x[i..-1])
end
end
self[1..-1].perm(n) do |x|
yield(x)
end
end
end
end
permbots = []
allbots.perm(2) do |x|
permbots << x
end
permbots.each do |x|
bots = x
a=Parallel.in_processes($config.threads) do
wins=Array.new(bots.size){0}
ties=Array.new(bots.size){0}
($config.max_rounds/$config.threads).times do |round|
interpreter=Interpreter.new($config.arena_length)
players=[]
bots.each do |b|
p=Player.new
start=rand $config.arena_length
p.split(start)
b.code.each_index do |i|
interpreter.setCellNum(start+i,b.code[i].to_i(2),p)
end
players<<p
end
interpreter.run($config.max_cycles,*players)
if players.count{|p| p.threads.length>0} == 1
#one of them is a winner
players.each_index do |i|
wins[i] +=1 if players[i].threads.length>0
end
else
#game endet in a draw
players.each_index do |i|
ties[i] +=1 if players[i].threads.length>0
end
end
end
[wins,ties]
end.inject(){|result, element|
ws,ts=result
we,te=element
ws.each_index do |i|
ws[i]+=we[i]
ts[i]+=te[i]
end
[ws,ts]
}
bots.each_index do |i|
puts "bot #{bots[i].name} scored #{a[0][i]} wins and #{a[1][i]} ties"
end
end
if $PROFILE
result = RubyProf.stop
printer = RubyProf::GraphPrinter.new(result)
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT, 0)
end