swint 0.5

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 ADDED
@@ -0,0 +1,23 @@
1
+ 2008-01-17 v0.5 features
2
+
3
+ * -e und -c to require and use a ruby robot class
4
+ for debugging and profiling purposes
5
+
6
+ 2008-01-14 v0.4 features
7
+
8
+ * use -n <n> for more than one game
9
+ * use -i for timing statistics
10
+
11
+ 2008-01-07 v0.3 bug fixes
12
+
13
+ * map is rotated, turn this behavior off with option -t
14
+ * code now splited in several files
15
+ * walking on start is now possible
16
+
17
+ 2008-01-06 v0.2 lots of minor improvements
18
+
19
+ * less flickering
20
+ * use -s to see every step
21
+ * use -w to wait for input each step
22
+
23
+ 2008-01-02 v0.1 initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Philipp Hofmann <phil@s126.de>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,80 @@
1
+
2
+ ================================================================================
3
+ __ __ __
4
+ .-----.--.--.--.|__|.-----.| |_ .----.| |--.
5
+ |__ --| | | || || || _|__| _|| _ |
6
+ |_____|________||__||__|__||____|__|__| |_____|
7
+
8
+ (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
9
+ ================================================================================
10
+
11
+ swint.rb is an entirely in Ruby written client for the SwarmIntelligence
12
+ programming game originally created by Stefan Schwarzburg-Benz.
13
+
14
+ Usage:
15
+
16
+ ./swint.rb [options]
17
+
18
+
19
+ Options:
20
+
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
67
+
68
+ add a ruby robot class as player
69
+
70
+
71
+ Example:
72
+
73
+ For a quick match on example.map:
74
+
75
+ ./swint.rb -r http://localhost:8000/ -r http://localhost:8001/
76
+
77
+ For testing your bot:
78
+
79
+ ./swint.rb -r http://localhost:8000/ -s -t -w -m maps/example.map
80
+
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ require 'rubygems'
2
+ Gem::manage_gems
3
+ require 'rake/gempackagetask'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+
7
+ # REQUIRED
8
+
9
+ s.name = "swint"
10
+ s.version = "0.5"
11
+ s.summary = "a console client for the swarm intelligence programming game"
12
+
13
+ # REQUIRED AND SET BY DEFAULT
14
+
15
+ # s.platform = Gem::Platform::RUBY
16
+ # s.date = Time.now
17
+ # s.require_paths = ['lib']
18
+
19
+ # OPTIONAL
20
+
21
+ s.description = s.summary
22
+ #s.files = Dir.glob("**/*").delete_if { |item| /(.svn|~$|Rakefile|pkg)/.match(item) }
23
+ s.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
24
+ #s.authors = ['Philipp Hofmann']
25
+ s.author = 'Philipp Hofmann'
26
+ s.email = "phil @nospam@ branch14.org"
27
+ s.homepage = "http://branch14.org/swint/"
28
+ s.rubyforge_project = s.name
29
+ s.extra_rdoc_files = ['README', 'LICENSE', 'CHANGELOG']
30
+ s.executables = [s.name]
31
+ # s.default_executable = s.name
32
+
33
+ # OPTIONAL AND SET BY DEFAULT
34
+
35
+ # s.autorequire = nil
36
+ # s.bindir = 'bin'
37
+ # s.has_rdoc = false
38
+ # s.rdoc_options = []
39
+ # s.required_ruby_version = '> 0.0.0'
40
+ # s.requirements = []
41
+ # s.test_files = []
42
+ # s.dependencies = []
43
+ # s.add_dependency('log4r', '>= 1.0.5')
44
+ # s.extensions = []
45
+
46
+ # SET AUTOMATICALLY
47
+
48
+ # rubygems_version, specification_version
49
+
50
+ end
51
+
52
+ Rake::GemPackageTask.new(spec) do |pkg|
53
+ pkg.need_tar = true
54
+ end
55
+
56
+ task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
57
+ puts "generated latest version"
58
+ end
59
+
data/bin/swint ADDED
@@ -0,0 +1,75 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
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) }
51
+ 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
@@ -0,0 +1,30 @@
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
+ CHAR = {
9
+ :free => '_',
10
+ :object => 'o',
11
+ :start => 'S',
12
+ :goal => 'G',
13
+ :outside => '#',
14
+ :energy => '!'
15
+ }
16
+
17
+ DIRV = [
18
+ [-1, +1],
19
+ [-1, 0],
20
+ [ 0, -1],
21
+ [+1, -1],
22
+ [+1, 0],
23
+ [ 0, +1]
24
+ ]
25
+
26
+ def Swint.rotate_map!
27
+ DIRV.push DIRV.shift, DIRV.shift, DIRV.shift
28
+ end
29
+
30
+ end
@@ -0,0 +1,125 @@
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 AbstractRobot
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
@@ -0,0 +1,48 @@
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 ClassRobot < AbstractRobot
9
+
10
+ attr_accessor :pos
11
+
12
+ attr_reader :speed, :sight, :power, :energy, :weight, :energy_left, :uri, :name, :owner
13
+
14
+ def initialize(klass, pos)
15
+ @klass = klass
16
+ @instance = klass.new
17
+ # a = [:speed, :sight, :power, :energy, :weight, :name, :owner]
18
+ # a.each { |attr| send("self.#{attr}=", @instance.send(attr)) }
19
+ @speed = @instance.speed
20
+ @sight = @instance.sight
21
+ @power = @instance.power
22
+ @energy = @instance.energy
23
+ @weight = @instance.weight
24
+ @name = @instance.name
25
+ @owner = @instance.owner
26
+ @pos = pos
27
+ restore
28
+ end
29
+
30
+ def next(map)
31
+ check_action(@instance.next(calculate_view(map)).to_sym)
32
+ end
33
+
34
+ def move
35
+ check_direction(@instance.move)
36
+ end
37
+
38
+ def push
39
+ check_direction(@instance.push)
40
+ end
41
+
42
+ def end_game(msg)
43
+ @instance.end_game(msg)
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,27 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
3
+
4
+ # (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
5
+
6
+ # ------------------------------------------------------------
7
+
8
+ module Swint
9
+
10
+ class Field
11
+
12
+ attr_accessor :robot
13
+ attr_reader :pos
14
+
15
+ def initialize(s, pos)
16
+ @pos, @state = pos, s
17
+ @robot = false
18
+ end
19
+
20
+ def state
21
+ @robot ? :robot : @state
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
data/lib/swint/game.rb ADDED
@@ -0,0 +1,129 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
3
+
4
+ # (c) 2008-01-14 Philipp Hofmann <phil@s126.de>
5
+
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
93
+
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
110
+
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
120
+
121
+ def measure
122
+ t = Time.now.to_f
123
+ yield
124
+ Time.now.to_f - t
125
+ end
126
+
127
+ end
128
+
129
+ end
data/lib/swint/map.rb ADDED
@@ -0,0 +1,65 @@
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 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
41
+
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
58
+
59
+ def robotkey_at(robots, pos)
60
+ robots.each { |k, r| return k if r.pos==pos }
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,33 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
3
+
4
+ # (c) 2008-01-14 Philipp Hofmann <phil@s126.de>
5
+
6
+ module Swint
7
+
8
+ class Result
9
+
10
+ attr_accessor :winner, :rounds, :start, :end
11
+ attr_reader :data
12
+
13
+ def initialize(robots)
14
+ @data = Hash.new
15
+ @winner = '<no winner>'
16
+ robots.each do |k, r|
17
+ @data[k] = Hash.new
18
+ @data[k][:robot] = r
19
+ @data[k][:times] = []
20
+ end
21
+ end
22
+
23
+ def step(robot, time)
24
+ @data[robot][:times] << time
25
+ end
26
+
27
+ def time
28
+ @end.to_f - @start.to_f
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,125 @@
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
@@ -0,0 +1,47 @@
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 XmlrpcRobot < AbstractRobot
9
+
10
+ attr_accessor :pos
11
+
12
+ attr_reader :speed, :sight, :power, :energy, :weight, :energy_left, :uri, :name, :owner
13
+
14
+ def initialize(uri, pos)
15
+ @uri = uri
16
+ @server = XMLRPC::Client.new2(@uri)
17
+ @gameid = @server.call('start_game')
18
+ @speed = @server.call('get_speed', @gameid)
19
+ @sight = @server.call('get_sight', @gameid)
20
+ @power = @server.call('get_power', @gameid)
21
+ @energy = @server.call('get_energy', @gameid)
22
+ @weight = @server.call('get_weight', @gameid)
23
+ @name = @server.call('get_name', @gameid)
24
+ @owner = @server.call('get_owner', @gameid)
25
+ @pos = pos
26
+ restore
27
+ end
28
+
29
+ def next(map)
30
+ check_action(@server.call('next', @gameid, calculate_view(map)).to_sym)
31
+ end
32
+
33
+ def move
34
+ check_direction(@server.call('move', @gameid))
35
+ end
36
+
37
+ def push
38
+ check_direction(@server.call('push', @gameid))
39
+ end
40
+
41
+ def end_game(msg)
42
+ @server.call('end_game', @gameid, msg)
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,18 @@
1
+ #! /usr/bin/env ruby
2
+ #-*- coding: utf-8 -*-
3
+
4
+ # (c) 2008-01-07 Philipp Hofmann <phil@s126.de>
5
+
6
+ class Array
7
+
8
+ def add(a)
9
+ n = []
10
+ each_index { |i| n << (self[i] + a[i]) }
11
+ n
12
+ end
13
+
14
+ def add!(a)
15
+ replace(add(a))
16
+ end
17
+
18
+ end
@@ -0,0 +1,11 @@
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
+
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: swint
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.5"
5
+ platform: ""
6
+ authors:
7
+ - Philipp Hofmann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-20 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: a console client for the swarm intelligence programming game
17
+ email: phil @nospam@ branch14.org
18
+ executables:
19
+ - swint
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - LICENSE
25
+ - CHANGELOG
26
+ files:
27
+ - lib/swint/field.rb
28
+ - lib/swint/game.rb
29
+ - lib/swint/map.rb
30
+ - lib/swint/robot.rb
31
+ - lib/swint/result.rb
32
+ - lib/swint/xmlrpc_robot.rb
33
+ - 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
38
+ - bin/swint
39
+ - Rakefile
40
+ - CHANGELOG
41
+ - README
42
+ - LICENSE
43
+ has_rdoc: false
44
+ homepage: http://branch14.org/swint/
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project: swint
65
+ rubygems_version: 0.9.5
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: a console client for the swarm intelligence programming game
69
+ test_files: []
70
+