swint 0.5 → 0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
-