swint 0.5

Sign up to get free protection for your applications and to get access to all the features.
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
+