swint 0.5 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,7 +1,25 @@
1
- 2008-01-17 v0.5 features
2
-
1
+ 2008-02-02 v0.6 features
2
+
3
+ * README rewritten
4
+ * swint executable now requires a subcommand, on of
5
+ 'race', 'asc2map'
6
+ * some refactorization
7
+ * -n flag removed
8
+ * 'push_object'-feature implemented
9
+ * 'shout'- and listen'-feature implemented, not tested though
10
+ * swint now is a rubyforge project, see
11
+ http://rubyforge.org/projects/swint
12
+ * swint now comes with a simple 'asc2map' converter
13
+ * -t also turns on the flags-feature for visual marks on the map
14
+ * -r http://localhost:1234/ may be abbreviated to -r 1234
15
+
16
+ 2008-01-17 v0.5 features and fixes
17
+
18
+ * swint now is a ruby gem
3
19
  * -e und -c to require and use a ruby robot class
4
- for debugging and profiling purposes
20
+ for debugging and profiling purposes
21
+ * map rotation fix
22
+ * -w fix
5
23
 
6
24
  2008-01-14 v0.4 features
7
25
 
@@ -16,7 +34,7 @@
16
34
 
17
35
  2008-01-06 v0.2 lots of minor improvements
18
36
 
19
- * less flickering
37
+ * less flickering (through ncurses binary tput)
20
38
  * use -s to see every step
21
39
  * use -w to wait for input each step
22
40
 
data/README CHANGED
@@ -1,80 +1,49 @@
1
-
1
+ (c) 2008-02-02 Philipp Hofmann <phil@s126.de>
2
2
  ================================================================================
3
- __ __ __
4
- .-----.--.--.--.|__|.-----.| |_ .----.| |--.
5
- |__ --| | | || || || _|__| _|| _ |
6
- |_____|________||__||__|__||____|__|__| |_____|
7
-
8
- (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
3
+ __ __
4
+ .-----.--.--.--.|__|.-----.| |_
5
+ |__ --| | | || || || _|
6
+ |_____|________||__||__|__||____|
7
+
9
8
  ================================================================================
10
9
 
11
- swint.rb is an entirely in Ruby written client for the SwarmIntelligence
12
- programming game originally created by Stefan Schwarzburg-Benz.
10
+ _swint_ is an entirely in Ruby written client for the Swarm Intelligence
11
+ programming game originally created by Stefan Schwarzburg.
12
+
13
13
 
14
14
  Usage:
15
15
 
16
- ./swint.rb [options]
16
+ swint race [options]
17
+ swint asc2map <filename>
17
18
 
18
19
 
19
20
  Options:
20
21
 
21
- -r|--robot <uri>
22
-
23
- supply a URL to your robot's XMLRPC interface here, may be used repeatedly
24
-
25
-
26
- -m|--map <filename>
27
-
28
- supply a filename to the XML map of the game
29
-
30
-
31
- -s|--step
32
-
33
- visualize each step, not only each turn
34
-
35
-
36
- -w|--wait
37
-
38
- wait for input before each step
39
-
40
-
41
- -v|--no-visual
42
-
43
- turn off visuals
44
-
45
-
46
- -t|--test
47
-
48
- turn off the initial rotation of map (better for testing)
49
-
50
-
51
- -n|--n-times <times>
52
-
53
- play more than one game
54
-
55
-
56
- -i|--statistics
57
-
58
- display statistics
59
-
60
-
61
- -e|--require <file>
62
-
63
- require a ruby file
64
-
65
-
66
- -c|--class
22
+ -r|--robot <uri> supply a URL to your robot's XMLRPC
23
+ interface here, may be used repeatedly
24
+ -m|--map <filename> supply a filename to the XML map of the game
25
+ -s|--step visualize each step, not only each turn
26
+ -w|--wait wait for input before each step
27
+ -v|--no-visual turn off visuals
28
+ -t|--test turn off the initial rotation of map
29
+ (better for testing)
30
+ -i|--statistics display timing statistics
31
+ -e|--require <file> require a ruby file
32
+ -c|--class add a ruby robot class as player
67
33
 
68
- add a ruby robot class as player
69
34
 
35
+ Examples:
70
36
 
71
- Example:
37
+ A quick race on example.map
38
+ $ swint race -r 8000 -r 8001 -i
72
39
 
73
- For a quick match on example.map:
40
+ Testing your bot
41
+ $ swint race -r 8000 -s -t -m another.map
74
42
 
75
- ./swint.rb -r http://localhost:8000/ -r http://localhost:8001/
43
+ Converting an ascii-map to xml-map
44
+ $ swint asc2map ascii.map > xml.map
76
45
 
77
- For testing your bot:
78
46
 
79
- ./swint.rb -r http://localhost:8000/ -s -t -w -m maps/example.map
47
+ See Also:
80
48
 
49
+ Project Hompage: http://branch14.org/swint
data/Rakefile CHANGED
@@ -1,5 +1,19 @@
1
1
  require 'rubygems'
2
2
  Gem::manage_gems
3
+
4
+ ################################################################################
5
+
6
+ require 'spec/rake/spectask'
7
+
8
+ desc "Run all examples with RCov"
9
+ Spec::Rake::SpecTask.new('examples_with_rcov') do |t|
10
+ t.spec_files = FileList['examples/**/*.rb']
11
+ t.rcov = true
12
+ t.rcov_opts = ['--exclude', 'examples']
13
+ end
14
+
15
+ ################################################################################
16
+
3
17
  require 'rake/gempackagetask'
4
18
 
5
19
  spec = Gem::Specification.new do |s|
@@ -7,7 +21,7 @@ spec = Gem::Specification.new do |s|
7
21
  # REQUIRED
8
22
 
9
23
  s.name = "swint"
10
- s.version = "0.5"
24
+ s.version = "0.6"
11
25
  s.summary = "a console client for the swarm intelligence programming game"
12
26
 
13
27
  # REQUIRED AND SET BY DEFAULT
@@ -37,7 +51,8 @@ spec = Gem::Specification.new do |s|
37
51
  # s.has_rdoc = false
38
52
  # s.rdoc_options = []
39
53
  # s.required_ruby_version = '> 0.0.0'
40
- # s.requirements = []
54
+ s.requirements << 'tput binary from ncurses'
55
+ s.requirements << "swarm intelligence maps, see #{s.homepage}"
41
56
  # s.test_files = []
42
57
  # s.dependencies = []
43
58
  # s.add_dependency('log4r', '>= 1.0.5')
@@ -56,4 +71,3 @@ end
56
71
  task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
57
72
  puts "generated latest version"
58
73
  end
59
-
data/bin/swint CHANGED
@@ -1,75 +1,19 @@
1
1
  #! /usr/bin/env ruby
2
2
  #-*- coding: utf-8 -*-
3
3
 
4
- # (c) 2008-01-17 Philipp Hofmann <phil@s126.de>
5
-
6
- ##############################
7
-
8
- require 'optparse'
9
- require 'ostruct'
10
- require 'xmlrpc/client'
11
- require 'rexml/document'
12
-
13
- ##############################
14
-
15
- # $:.unshift(File.dirname(__FILE__))
16
-
17
- require 'swint_basics/array'
18
- require 'swint_basics/hash'
19
-
20
- require 'swint/_constants'
21
- require 'swint/game'
22
- require 'swint/map'
23
- require 'swint/field'
24
- require 'swint/result'
25
- require 'swint/abstract_robot'
26
- require 'swint/xmlrpc_robot'
27
- require 'swint/class_robot'
28
-
29
- ##############################
30
-
31
- config = OpenStruct.new
32
- config.step = false
33
- config.wait = false
34
- config.visual = true
35
- config.map = 'example.map'
36
- config.robots = []
37
- config.ntimes = 1
38
- config.statistics = false
39
-
40
- opts = OptionParser.new do |o|
41
- o.on('-r', '--robot URI', 'URI of robot') { |r| config.robots << r }
42
- o.on('-m', '--map URI', 'URI of map') { |m| config.map = m }
43
- o.on('-s', '--step', 'Show each step') { config.step = true }
44
- o.on('-w', '--wait', 'Wait for return after visual') { config.wait = true }
45
- o.on('-v', '--no-visual', 'No visual at all') { config.visual = false }
46
- o.on('-t', '--test', 'Do not rotate map') { config.test = true }
47
- o.on('-n', '--n-times TIMES', 'Run n games') { |n| config.ntimes = n.to_i }
48
- o.on('-i', '--statistics', 'Display statistics') { config.statistics = true }
49
- o.on('-e', '--require FILENAME', 'Provide a file to require') { |e| require(e) }
50
- o.on('-c', '--class CLASS', 'Provide a Ruby Robot Class') { |c| config.robots << Kernel.const_get(c) }
4
+ # (c) 2008-02-02 Philipp Hofmann <phil@s126.de>
5
+
6
+ args = ARGV
7
+ case args.shift.to_sym
8
+ when :race
9
+ require 'swint_exec/race'
10
+ SwintExec::Race::start(args)
11
+ when :tournament
12
+ require 'swint_exec/tournament'
13
+ SwintExec::Tournament::start(args)
14
+ when :asc2map
15
+ require 'swint_exec/ascii_to_map'
16
+ SwintExec::AsciiToMap::start(args)
17
+ else
18
+ puts 'unkown command (valid commands: race, tournament, asc2map)'
51
19
  end
52
-
53
- opts.parse!(ARGV)
54
-
55
- Swint.rotate_map! unless config.test
56
-
57
- unless File.exist?(config.map)
58
- puts "mapfile #{config.map} not found"
59
- exit
60
- end
61
-
62
- config.ntimes.times do
63
- game = Swint::Game.new(config)
64
- result = game.run
65
- puts "winner after % 3s rounds robot %s" % [result.rounds, result.winner]
66
- if config.statistics
67
- puts "\ntiming statistics\n-----------------"
68
- puts "game took %5.2f seconds" % result.time
69
- result.data.each do |r, d|
70
- time = 0
71
- d[:times].each { |t| time += t }
72
- puts "% 5.2f seconds %s (%s)" % [time, d[:robot].name, d[:robot].owner]
73
- end
74
- end
75
- end
@@ -15,4 +15,12 @@ class Array
15
15
  replace(add(a))
16
16
  end
17
17
 
18
+ def shuffle
19
+ # method 1, sorting is always slower
20
+ sort_by { rand }
21
+ # method 2, maybe faster
22
+ # a = self.clone
23
+ # a.collect { a.slice!(rand(a.size)) }
24
+ end
25
+
18
26
  end
@@ -33,6 +33,15 @@ module Swint
33
33
  def end_game(msg)
34
34
  end
35
35
 
36
+ def flags
37
+ end
38
+
39
+ def listen
40
+ end
41
+
42
+ def shout
43
+ end
44
+
36
45
  # --------------------------------------------------------------------------------
37
46
 
38
47
  def is_valid?
@@ -43,6 +43,18 @@ module Swint
43
43
  @instance.end_game(msg)
44
44
  end
45
45
 
46
+ def listen(msg)
47
+ @instance.listen(msg)
48
+ end
49
+
50
+ def shout
51
+ @instance.shout
52
+ end
53
+
54
+ def flags
55
+ @instance.flags
56
+ end
57
+
46
58
  end
47
59
 
48
60
  end
@@ -9,16 +9,16 @@ module Swint
9
9
 
10
10
  class Field
11
11
 
12
- attr_accessor :robot
12
+ attr_accessor :robot, :weight
13
13
  attr_reader :pos
14
14
 
15
- def initialize(s, pos)
16
- @pos, @state = pos, s
15
+ def initialize(s, pos, weight=nil)
16
+ @pos, @state, @weight = pos, s, weight
17
17
  @robot = false
18
18
  end
19
19
 
20
20
  def state
21
- @robot ? :robot : @state
21
+ @robot ? :robot : (@weight ? :object : @state)
22
22
  end
23
23
 
24
24
  end
@@ -1,129 +1,158 @@
1
1
  #! /usr/bin/env ruby
2
- #-*- coding: utf-8 -*-
2
+ #-*- coding:utf-8 -*-
3
3
 
4
4
  # (c) 2008-01-14 Philipp Hofmann <phil@s126.de>
5
5
 
6
6
  module Swint
7
-
8
- class Game
9
-
10
- def initialize(config)
11
- @config = config
12
- @robots = Hash.new
13
- @map = Swint::Map.new.load_from_xml(File.new(config.map).read)
14
- config.robots.each do |r|
15
- puts "connecting to robot: #{r}" if config.visual
16
- @robots[@robots.size+1] = Swint::XmlrpcRobot.new(r, @map.start) if r.is_a?(String)
17
- @robots[@robots.size+1] = Swint::ClassRobot.new(r, @map.start) if r.is_a?(Class)
18
- end
19
- @result = Result.new(@robots)
20
- @game_end = false
21
- end
22
-
23
- def run
24
- system "clear" if @config.visual
25
- @robots.shuffle!
26
- counter = 0
27
- @result.start = Time.now
28
- until @game_end
29
- counter += 1
30
- no_robot_left = true
31
- @robots.each do |k, r|
32
- r.speed.times do |step|
33
- if !@game_end
34
- answer = :do_nothing
35
- dt = measure { answer = r.next(@map) } if r.has_energy?
36
- case answer
37
-
38
- when :move_to
39
- no_robot_left = false
40
- if r.use_energy?
41
- dir = nil
42
- dt += measure { dir = r.move }
43
- npos = r.pos.add(DIRV[dir])
44
- nstate = @map.state_of_field(npos)
45
- if nstate==:goal
46
- @robots.each { |key, b| b.end_game( (b==r) ? 'winner' : 'looser' ) }
47
- @result.winner = k
48
- @game_end = true
49
- end
50
- if [:free, :energy, :start].include?(nstate)
51
- f, p = @map.fields[npos], @map.fields[r.pos]
52
- r.restore if f.state==:energy
53
- p.robot = false
54
- f.robot = true
55
- r.pos = npos
56
- end
57
- end
58
-
59
- when :push_object
60
- no_robot_left = false
61
- if r.use_energy?
62
- dir = nil
63
- dt += measure { dir = r.push }
64
- opos = r.pos.add(DIRV[dir])
65
- ppos = opos.add(DIRV[dir])
66
- ostate = @map.state_of_field(opos)
67
- pstate = @map.state_of_field(ppos)
68
-
69
- if pstate==:free
70
- if ostate==:object
71
- # ...
72
- end
73
- if ostate==:robot
74
- # ...
75
- end
76
- end
77
-
78
- end
79
-
80
- end
81
-
82
- @result.step(k, dt || 0)
83
- # end of step
84
- visualize(counter, step) if @config.visual && @config.step
85
-
86
- end
87
-
88
- end
89
-
90
- # end of robot
91
-
92
- end
7
+
8
+ class Game
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ @robots = Hash.new
13
+ @map = Swint::Map.new.load_from_xml(File.new(config.map).read)
14
+ config.robots.each do |r|
15
+ puts "connecting to robot: #{r}" if config.visual
16
+ @robots[@robots.size+1] = Swint::XmlrpcRobot.new(r, @map.start) if r.is_a?(String)
17
+ @robots[@robots.size+1] = Swint::ClassRobot.new(r, @map.start) if r.is_a?(Class)
18
+ end
19
+ @result = Result.new(@robots)
20
+ @game_end = false
21
+ end
93
22
 
94
- # end of turn
95
- visualize(counter) if @config.visual && !@config.step
96
-
97
- if no_robot_left
98
- @robots.each { |k, b| b.end_game('looser') }
99
- @game_end = true
100
- end
101
-
102
- end
103
-
104
- # end of game
105
- @result.rounds = counter
106
- @result.end = Time.now
107
- @result
108
-
109
- end
23
+ def run
24
+ system "clear" if @config.visual
25
+ counter = 0
26
+ @result.start = Time.now
27
+ until @game_end
28
+ counter += 1
29
+ no_robot_left = true
30
+ @robots.to_a.shuffle.each do |robot|
31
+ k, r = robot
32
+ r.speed.times do |step|
33
+ if !@game_end
34
+ answer = :do_nothing
35
+ dt = measure { answer = r.next(@map) } if r.has_energy?
36
+ case answer
37
+
38
+ when :move_to
39
+ no_robot_left = false
40
+ if r.use_energy?
41
+ dir = nil
42
+ dt += measure { dir = r.move }
43
+ npos = r.pos.add(DIRV[dir])
44
+ nstate = @map.state_of_field(npos)
45
+ if nstate==:goal
46
+ @robots.each { |key, b| b.end_game( (b==r) ? 'winner' : 'looser' ) }
47
+ @result.winner = k
48
+ @game_end = true
49
+ end
50
+ if [:free, :energy, :start].include?(nstate)
51
+ f, p = @map.fields[npos], @map.fields[r.pos]
52
+ r.restore if f.state==:energy
53
+ p.robot = false
54
+ f.robot = true
55
+ r.pos = npos
56
+ end
57
+ end
58
+
59
+ when :push_object
60
+ no_robot_left = false
61
+ if r.use_energy?
62
+ dir = nil
63
+ dt += measure { dir = r.push }
64
+ opos = r.pos.add(DIRV[dir])
65
+ ppos = opos.add(DIRV[dir])
66
+ ostate = @map.state_of_field(opos)
67
+ pstate = @map.state_of_field(ppos)
68
+
69
+ if pstate==:free || pstate==:energy
70
+ if ostate==:object
71
+ if r.power >= @map.fields[opos].weight
72
+ @map.fields[ppos].weight = @map.fields[opos].weight
73
+ @map.fields[opos].weight = 0
74
+ end
75
+ end
76
+ if ostate==:robot
77
+ rob = @robots.values.select { |ro| ro.pos==opos }.first
78
+ if r.power >= rob.weight
79
+ rob.pos = ppos
80
+ rob.restore if pstate==:energy
81
+ @map.fields[opos].robot = false
82
+ @map.fields[ppos].robot = true
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ when :shout
90
+ no_robot_left = false
91
+ dt += measure { msg = r.shout }
92
+ @robots.each do |rid, rob|
93
+ next if rid==k
94
+ rob.listen(msg) if hex_distance(r.pos, rob.pos) <= r.voice * 10
95
+ end
96
+
97
+ end
98
+
99
+ @result.step(k, dt || 0)
100
+ # end of step
101
+ visualize(counter, step) if @config.visual && @config.step
102
+
103
+ end
104
+
105
+ end
106
+
107
+ # end of robot
108
+
109
+ end
110
+
111
+ # end of turn
112
+ visualize(counter) if @config.visual && !@config.step
113
+
114
+ if no_robot_left
115
+ @robots.each { |k, b| b.end_game('looser') }
116
+ @game_end = true
117
+ end
118
+
119
+ end
120
+
121
+ # end of game
122
+ @result.rounds = counter
123
+ @result.end = Time.now
124
+ @result
125
+
126
+ end
110
127
 
111
- def visualize(round, step=nil)
112
- system "tput cup 0 0"
113
- print "ROUND: #{round}"
114
- print " | STEP: #{step}" if step
115
- puts
116
- @robots.each { |k, r| puts "%s. [% 2s/% 2s] %s" % [k, r.energy_left, r.energy, r] }
117
- @map.print_map(@robots)
118
- gets if @config.wait
119
- end
128
+ def visualize(round, step=nil)
129
+ system "tput cup 0 0"
130
+ print "ROUND: #{round}"
131
+ print " | STEP: #{step}" if step
132
+ puts
133
+ flags = {}
134
+ @robots.each do |k, r|
135
+ puts "%s. [% 2s/% 2s] %s" % [k, r.energy_left, r.energy, r]
136
+ flags.merge!(r.flags) if !@game_end && @config.test
137
+ end
138
+ @map.print_map(@robots, flags)
139
+ gets if @config.wait
140
+ end
120
141
 
121
- def measure
122
- t = Time.now.to_f
123
- yield
124
- Time.now.to_f - t
125
- end
126
-
127
- end
142
+ def measure
143
+ t = Time.now.to_f
144
+ yield
145
+ Time.now.to_f - t
146
+ end
128
147
 
129
- end
148
+ def hex_distance(pos1, pos2) # might fail when map is rotated
149
+ x, y = pos2.add(pos1.collect { |e| -e })
150
+ a = 0
151
+ a = (x==y) ? 2 : 1 if ((x < 0) && (y < 0)) || ((x > 0) && (y > 0))
152
+ [x.abs, y.abs].max + a
153
+ end
154
+
155
+ end
156
+
157
+ end
158
+
@@ -4,62 +4,75 @@
4
4
  # (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
5
5
 
6
6
  module Swint
7
-
8
- class Map
9
-
10
- attr_reader :start, :fields
11
-
12
- def initialize
13
- @min, @max = [0, 0], [0, 0] # THIS IS AN ASUMPTION!
14
- @fields = Hash.new(:outside)
15
- end
16
-
17
- def load_from_xml(xml)
18
- doc = REXML::Document.new(xml)
19
- doc.elements.each('map/field') do |e|
20
- v = e.attribute('v').value.to_i
21
- u = e.attribute('u').value.to_i
22
- s = e.attribute('state').value.to_sym
23
- f = Swint::Field.new(s, [u, v])
24
- @fields[f.pos] = f
25
- @min[0] = u if u < @min[0]
26
- @min[1] = v if v < @min[1]
27
- @max[0] = u if u > @max[0]
28
- @max[1] = v if v > @max[1]
29
- if s==:start
30
- @start = [u, v]
31
- # f.robot = true # HACK!
32
- end
33
- end
34
- self
35
- end
36
-
37
- def state_of_field(pos)
38
- v = @fields[pos]
39
- v.is_a?(Symbol) ? v : v.state
40
- end
7
+
8
+ class Map
41
9
 
42
- def print_map(robots)
43
- w = ((@max[0]-@min[0])*2+(@max[1]-@min[1]))
44
- border = '='*(w+6)
45
- puts border
46
- for y in @min[1]..@max[1]
47
- line = ''
48
- line += ' '*(y)
49
- for x in @min[0]..@max[0]
50
- s = state_of_field([x, y])
51
- c = s!=:robot ? CHAR[state_of_field([x, y])] : robotkey_at(robots, [x, y]).to_s
52
- line += c+' '
53
- end
54
- puts line
55
- end
56
- puts border
57
- end
10
+ attr_reader :start, :fields
58
11
 
59
- def robotkey_at(robots, pos)
60
- robots.each { |k, r| return k if r.pos==pos }
61
- end
12
+ def initialize
13
+ @min, @max = [0, 0], [0, 0] # THIS IS AN ASUMPTION!
14
+ @fields = Hash.new(:outside)
15
+ end
62
16
 
63
- end
17
+ def load_from_xml(xml)
18
+ doc = REXML::Document.new(xml)
19
+ doc.elements.each('map/field') do |e|
20
+ v = e.attribute('v').value.to_i
21
+ u = e.attribute('u').value.to_i
22
+ s = e.attribute('state').value.to_sym
23
+ w = nil
24
+ if s==:object
25
+ w = e.attribute('weight').value.to_i
26
+ s = :free
27
+ end
28
+ f = Swint::Field.new(s, [u, v], w)
29
+ @fields[f.pos] = f
30
+ @min[0] = u if u < @min[0]
31
+ @min[1] = v if v < @min[1]
32
+ @max[0] = u if u > @max[0]
33
+ @max[1] = v if v > @max[1]
34
+ if s==:start
35
+ @start = [u, v]
36
+ # f.robot = true # HACK!
37
+ end
38
+ end
39
+ self
40
+ end
41
+
42
+ def state_of_field(pos)
43
+ v = @fields[pos]
44
+ v.is_a?(Symbol) ? v : v.state
45
+ end
46
+
47
+ def print_map(robots, flags)
48
+ w = ((@max[0]-@min[0])*2+(@max[1]-@min[1]))
49
+ border = '='*(w+6)
50
+ puts border
51
+ print draw_map(robots, flags)
52
+ puts border
53
+ end
64
54
 
55
+ def draw_map(robots, flags)
56
+ output = []
57
+ for y in @min[1]..@max[1]
58
+ line = ''
59
+ line += ' '*(y)
60
+ for x in @min[0]..@max[0]
61
+ s = state_of_field([x, y])
62
+ c = s!=:robot ? CHAR[state_of_field([x, y])] : robotkey_at(robots, [x, y]).to_s
63
+ pstr = [x, y].add(@start.collect { |s| -s })*'x'
64
+ c = flags[pstr] if flags[pstr]
65
+ line += c+' '
66
+ end
67
+ output << line
68
+ end
69
+ output.join("\n")+"\n"
70
+ end
71
+
72
+ def robotkey_at(robots, pos)
73
+ robots.each { |k, r| return k if r.pos==pos }
74
+ end
75
+
76
+ end
77
+
65
78
  end
@@ -42,6 +42,18 @@ module Swint
42
42
  @server.call('end_game', @gameid, msg)
43
43
  end
44
44
 
45
+ def listen(msg)
46
+ @server.call('listen', @gameid, msg)
47
+ end
48
+
49
+ def shout
50
+ @server.call('shout', @gameid)
51
+ end
52
+
53
+ def flags
54
+ @server.call('flags', @gameid)
55
+ end
56
+
45
57
  end
46
58
 
47
59
  end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # (c) 2008-01-22 Philipp Hofmann <phil@s126.de>
4
+
5
+ require 'rexml/document'
6
+
7
+ module SwintExec
8
+
9
+ module AsciiToMap
10
+
11
+ STATE = {
12
+ 'S' => 'start',
13
+ 'G' => 'goal',
14
+ '_' => 'free',
15
+ 'o' => 'object',
16
+ '#' => 'outside',
17
+ '!' => 'energy'
18
+ }
19
+
20
+ def AsciiToMap.start(args)
21
+
22
+ filename = args.first
23
+ lines = File.open(filename).read.split("\n")
24
+ xmldoc = REXML::Document.new
25
+ map = xmldoc.add_element('map')
26
+
27
+ lines.size.times do |i|
28
+ line = lines[i].strip.split(' ')
29
+ line.size.times do |j|
30
+ map.add_element('field', {'state'=>STATE[line[j]], 'u'=>j, 'v'=>i })
31
+ end
32
+ end
33
+
34
+ puts xmldoc
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,74 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
3
+
4
+ # (c) 2008-01-17 Philipp Hofmann <phil@s126.de>
5
+
6
+ require 'optparse'
7
+ require 'ostruct'
8
+ require 'xmlrpc/client'
9
+ require 'rexml/document'
10
+
11
+ require 'array'
12
+
13
+ require 'swint/_constants'
14
+ require 'swint/game'
15
+ require 'swint/map'
16
+ require 'swint/field'
17
+ require 'swint/result'
18
+ require 'swint/abstract_robot'
19
+ require 'swint/xmlrpc_robot'
20
+ require 'swint/class_robot'
21
+
22
+ module SwintExec
23
+
24
+ module Race
25
+
26
+ def Race.start(args)
27
+
28
+ config = OpenStruct.new
29
+ config.step = false
30
+ config.wait = false
31
+ config.visual = true
32
+ config.map = 'example.map'
33
+ config.robots = []
34
+ config.statistics = false
35
+
36
+ opts = OptionParser.new do |o|
37
+ o.on('-r', '--robot URI', 'URI of robot') do |r|
38
+ r = "http://localhost:#{r}/" if /[0-9]+/.match(r)
39
+ config.robots << r
40
+ end
41
+ o.on('-m', '--map URI', 'URI of map') { |m| config.map = m }
42
+ o.on('-s', '--step', 'Show each step') { config.step = true }
43
+ o.on('-w', '--wait', 'Wait for return after visual') { config.wait = true }
44
+ o.on('-v', '--no-visual', 'No visual at all') { config.visual = false }
45
+ o.on('-t', '--test', 'Do not rotate map') { config.test = true }
46
+ o.on('-i', '--statistics', 'Display statistics') { config.statistics = true }
47
+ o.on('-e', '--require FILENAME', 'Provide a file to require') { |e| require(e) }
48
+ o.on('-c', '--class CLASS', 'Provide a Ruby Robot Class') { |c| config.robots << Kernel.const_get(c) }
49
+ end
50
+
51
+ opts.parse!(args)
52
+
53
+ Swint.rotate_map! unless config.test
54
+
55
+ unless File.exist?(config.map)
56
+ puts "mapfile #{config.map} not found"
57
+ exit
58
+ end
59
+
60
+ result = Swint::Game.new(config).run
61
+ puts "winner after % 3s rounds robot %s" % [result.rounds, result.winner]
62
+ if config.statistics
63
+ puts "\ntiming statistics\n-----------------"
64
+ puts "game took %5.2f seconds" % result.time
65
+ result.data.each do |r, d|
66
+ time = 0
67
+ d[:times].each { |t| time += t }
68
+ puts "% 5.2f seconds %s (%s)" % [time, d[:robot].name, d[:robot].owner]
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,78 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
3
+
4
+ # (c) 2008-02-02 Philipp Hofmann <phil@s126.de>
5
+
6
+ require 'optparse'
7
+ require 'ostruct'
8
+ require 'xmlrpc/client'
9
+ require 'rexml/document'
10
+
11
+ require 'array'
12
+
13
+ require 'swint/_constants'
14
+ require 'swint/game'
15
+ require 'swint/map'
16
+ require 'swint/field'
17
+ require 'swint/result'
18
+ require 'swint/abstract_robot'
19
+ require 'swint/xmlrpc_robot'
20
+ require 'swint/class_robot'
21
+
22
+ module SwintExec
23
+
24
+ module Tournament
25
+
26
+ def Tournament.start(args)
27
+
28
+ puts 'sorry, not implemented yet'
29
+ exit
30
+
31
+ ### config = OpenStruct.new
32
+ ### config.step = false
33
+ ### config.wait = false
34
+ ### config.visual = true
35
+ ### config.map = 'example.map'
36
+ ### config.robots = []
37
+ ### config.statistics = false
38
+ ###
39
+ ### opts = OptionParser.new do |o|
40
+ ### o.on('-r', '--robot URI', 'URI of robot') do |r|
41
+ ### r = "http://localhost:#{r}/" if /[0-9]+/.match(r)
42
+ ### config.robots << r
43
+ ### end
44
+ ### o.on('-m', '--map URI', 'URI of map') { |m| config.map = m }
45
+ ### o.on('-s', '--step', 'Show each step') { config.step = true }
46
+ ### o.on('-w', '--wait', 'Wait for return after visual') { config.wait = true }
47
+ ### o.on('-v', '--no-visual', 'No visual at all') { config.visual = false }
48
+ ### o.on('-t', '--test', 'Do not rotate map') { config.test = true }
49
+ ### o.on('-i', '--statistics', 'Display statistics') { config.statistics = true }
50
+ ### o.on('-e', '--require FILENAME', 'Provide a file to require') { |e| require(e) }
51
+ ### o.on('-c', '--class CLASS', 'Provide a Ruby Robot Class') { |c| config.robots << Kernel.const_get(c) }
52
+ ### end
53
+ ###
54
+ ### opts.parse!(args)
55
+ ###
56
+ ### Swint.rotate_map! unless config.test
57
+ ###
58
+ ### unless File.exist?(config.map)
59
+ ### puts "mapfile #{config.map} not found"
60
+ ### exit
61
+ ### end
62
+ ###
63
+ ### game = Swint::Game.new(config)
64
+ ### result = game.run
65
+ ### puts "winner after % 3s rounds robot %s" % [result.rounds, result.winner]
66
+ ### if config.statistics
67
+ ### puts "\ntiming statistics\n-----------------"
68
+ ### puts "game took %5.2f seconds" % result.time
69
+ ### result.data.each do |r, d|
70
+ ### time = 0
71
+ ### d[:times].each { |t| time += t }
72
+ ### puts "% 5.2f seconds %s (%s)" % [time, d[:robot].name, d[:robot].owner]
73
+ ### end
74
+ ### end
75
+
76
+ end
77
+ end
78
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swint
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.5"
4
+ version: "0.6"
5
5
  platform: ""
6
6
  authors:
7
7
  - Philipp Hofmann
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-20 00:00:00 +01:00
12
+ date: 2008-02-02 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -24,22 +24,23 @@ extra_rdoc_files:
24
24
  - LICENSE
25
25
  - CHANGELOG
26
26
  files:
27
- - lib/swint/field.rb
28
- - lib/swint/game.rb
27
+ - lib/array.rb
29
28
  - lib/swint/map.rb
30
- - lib/swint/robot.rb
31
29
  - lib/swint/result.rb
30
+ - lib/swint/field.rb
31
+ - lib/swint/abstract_robot.rb
32
+ - lib/swint/game.rb
33
+ - lib/swint/class_robot.rb
32
34
  - lib/swint/xmlrpc_robot.rb
33
35
  - lib/swint/_constants.rb
34
- - lib/swint/class_robot.rb
35
- - lib/swint/abstract_robot.rb
36
- - lib/swint_basics/array.rb
37
- - lib/swint_basics/hash.rb
36
+ - lib/swint_exec/tournament.rb
37
+ - lib/swint_exec/ascii_to_map.rb
38
+ - lib/swint_exec/race.rb
38
39
  - bin/swint
40
+ - LICENSE
39
41
  - Rakefile
40
42
  - CHANGELOG
41
43
  - README
42
- - LICENSE
43
44
  has_rdoc: false
44
45
  homepage: http://branch14.org/swint/
45
46
  post_install_message:
@@ -59,8 +60,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
60
  - !ruby/object:Gem::Version
60
61
  version: "0"
61
62
  version:
62
- requirements: []
63
-
63
+ requirements:
64
+ - tput binary from ncurses
65
+ - swarm intelligence maps, see http://branch14.org/swint/
64
66
  rubyforge_project: swint
65
67
  rubygems_version: 0.9.5
66
68
  signing_key:
@@ -1,125 +0,0 @@
1
- #! /usr/bin/env ruby
2
- #-*- coding: utf-8 -*-
3
-
4
- # (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
5
-
6
- module Swint
7
-
8
- class Robot
9
-
10
- attr_accessor :pos
11
-
12
- attr_reader :speed, :sight, :power, :energy, :weight, :energy_left, :uri, :name, :owner
13
-
14
- # --------------------------------------------------------------------------------
15
- # --- stub
16
-
17
- def initialize(uri, pos)
18
- @uri = uri
19
- @pos = pos
20
- restore
21
- end
22
-
23
- def next(map)
24
- end
25
-
26
- def move
27
- # check_direction(...)
28
- end
29
-
30
- def push
31
- end
32
-
33
- def end_game(msg)
34
- end
35
-
36
- # --------------------------------------------------------------------------------
37
-
38
- def is_valid?
39
- (@speed + @sight + @power + @energy + @weight) == 22
40
- end
41
-
42
- def check_direction(d)
43
- unless (0..5).include?(d)
44
- puts "#{@name}, what is this? '#{d}' is not a drection."
45
- exit
46
- end
47
- d
48
- end
49
-
50
- def check_action(a)
51
- unless [:do_nothing, :move_to, :push_object, :shout].include?(a)
52
- puts "#{@name}, what is this? '#{a}' is not an action."
53
- exit
54
- end
55
- a
56
- end
57
-
58
- def to_s
59
- a = ["#{@name} (#{@owner})", @speed, @sight, @power, @weight, @energy]
60
- "%-30s [sp: % 2s, si: % 2s, po: % 2s, we: % 2s, en: % 2s]" % a
61
- end
62
-
63
- def use_energy?
64
- return false unless has_energy?
65
- @energy_left -= 1
66
- true
67
- end
68
-
69
- def has_energy?
70
- @energy_left>0
71
- end
72
-
73
- def restore
74
- @energy_left = @energy
75
- end
76
-
77
- def calculate_view(map)
78
-
79
- # A centered hexagonal number, or hex number, is a centered figurate
80
- # number that represents a hexagon with a dot in the center and all
81
- # other dots surrounding the center dot in a hexagonal lattice.
82
- # 1, 7, 19, 37, 61, 91, 127, 169, 217, 271, 331, 397, 469, 547, 631, 721, 817, 919
83
-
84
- # relative directions
85
- reld = [2, 3, 4, 5, 0, 1]
86
-
87
- data = []
88
- cpos = pos.clone # that was tough!
89
-
90
- ### stef's version
91
-
92
- sight.times do |depth|
93
- cpos.add!(DIRV[0])
94
- data << map.state_of_field(cpos)
95
- 5.times do |dir|
96
- (depth+1).times do |i|
97
- cpos.add!(DIRV[reld[dir]])
98
- data << map.state_of_field(cpos)
99
- end
100
- end
101
- depth.times do |i|
102
- cpos.add!(DIRV[reld[5]])
103
- data << map.state_of_field(cpos)
104
- end
105
- cpos.add!(DIRV[1])
106
- end
107
-
108
- ### sight.times do |depth|
109
- ### cpos.add!(DIRV[0])
110
- ### data << map.state_of_field(cpos)
111
- ### 6.times do |dir|
112
- ### (depth+1).times do |i|
113
- ### cpos.add!(DIRV[reld[dir]])
114
- ### data << map.state_of_field(cpos)
115
- ### end
116
- ### end
117
- ### end
118
-
119
- data
120
-
121
- end
122
-
123
- end
124
-
125
- end
@@ -1,11 +0,0 @@
1
- #! /usr/bin/env ruby
2
- #-*- coding: utf-8 -*-
3
-
4
- # (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
5
-
6
- class Hash
7
- def shuffle!
8
- replace(self) # HACK!
9
- end
10
- end
11
-