kayabot 0.1.0 → 0.1.1
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/README.markdown +7 -3
- data/bin/kayabot +5 -3
- data/kayabot.gemspec +1 -1
- data/lib/gg.rb +31 -6
- data/lib/kayabot.rb +14 -9
- metadata +5 -5
data/README.markdown
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
This is the official Gem to run a bot in Kaya.
|
2
2
|
|
3
|
-
Right now only gnubot is default and has to be installed.
|
4
3
|
|
5
4
|
Feel free to expand the gem to allow other bots with GTP interface, should work plug-play easily.
|
6
5
|
|
6
|
+
Requirements:
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
gnugo
|
9
|
+
ruby 1.9.2
|
10
|
+
rubygems
|
10
11
|
|
11
12
|
To install :
|
13
|
+
|
12
14
|
gem install kayabot
|
15
|
+
|
13
16
|
To run:
|
17
|
+
|
14
18
|
kayabot my_configuration.yaml
|
15
19
|
|
16
20
|
The configuration yaml must look like this:
|
data/bin/kayabot
CHANGED
@@ -17,11 +17,13 @@ if ARGV.length > 0
|
|
17
17
|
config_file = ARGV.first
|
18
18
|
if File.exists?(config_file)
|
19
19
|
config = YAML.load_file(config_file)
|
20
|
-
if config["url"] && config["user"] && config["pass"]
|
21
|
-
|
20
|
+
if config["url"] && config["user"] && config["pass"] && config["title"] && config["size"]
|
21
|
+
sz = config["size"].to_i
|
22
|
+
raise "Invalid size!. only 9,13,19 are supported" unless sz == 9 || sz == 13 || sz == 19
|
23
|
+
k = KayaBot.new(config)
|
22
24
|
k.listener_loop
|
23
25
|
else
|
24
|
-
puts "Invalid config file."
|
26
|
+
puts "Invalid config file. url,user, pass, title, size required."
|
25
27
|
end
|
26
28
|
else
|
27
29
|
puts "File does not exist."
|
data/kayabot.gemspec
CHANGED
data/lib/gg.rb
CHANGED
@@ -40,8 +40,22 @@ class GTP
|
|
40
40
|
|
41
41
|
def list_stones(color)
|
42
42
|
@io.puts [:list_stones, color].join(" ")
|
43
|
-
|
44
|
-
|
43
|
+
return self.clean_gtp_response
|
44
|
+
end
|
45
|
+
|
46
|
+
def final_score()
|
47
|
+
@io.puts [:final_score]
|
48
|
+
return self.clean_gtp_response
|
49
|
+
end
|
50
|
+
|
51
|
+
def list_dead_stones()
|
52
|
+
@io.puts [:final_status_list, "dead"].join(" ")
|
53
|
+
return self.clean_gtp_response
|
54
|
+
end
|
55
|
+
|
56
|
+
def clean_gtp_response()
|
57
|
+
response = @io.take_while { |line| line != "\n" }.join(" ")
|
58
|
+
return response.sub(/^=\s+/, "")
|
45
59
|
end
|
46
60
|
|
47
61
|
def send_command(command, *arguments)
|
@@ -72,9 +86,16 @@ def score_game(game_id, game_sgf)
|
|
72
86
|
IO.popen("gnugo --score aftermath #{filepath}") do |f|
|
73
87
|
re = f.read
|
74
88
|
end
|
89
|
+
dead_stones = ""
|
90
|
+
GTP.run("gnugo") do |gtp|
|
91
|
+
gtp.loadsgf filepath
|
92
|
+
dead_stones = gtp.list_dead_stones
|
93
|
+
end
|
94
|
+
|
95
|
+
p dead_stones
|
75
96
|
|
76
97
|
File.delete(filepath)
|
77
|
-
return re
|
98
|
+
return {:score => re, :dead_stones => dead_stones}
|
78
99
|
end
|
79
100
|
|
80
101
|
# return a move coordinates, such as "c17", or "PASS", or "resign"
|
@@ -93,25 +114,29 @@ def ai_move(game_id, game_sgf, color)
|
|
93
114
|
if color == 'black' || color == 'white'
|
94
115
|
game_bot = 'gnugo'
|
95
116
|
end
|
117
|
+
size = 19
|
96
118
|
GTP.run(game_bot) do |gtp|
|
97
119
|
gtp.loadsgf filepath
|
120
|
+
size = gtp.send_command(:query_boardsize)
|
98
121
|
re = gtp.genmove color
|
99
122
|
end
|
100
123
|
p re
|
101
|
-
|
124
|
+
p size
|
125
|
+
move = convert_move(re,size)
|
102
126
|
|
103
127
|
File.delete(filepath)
|
104
128
|
return move
|
105
129
|
end
|
106
130
|
|
107
131
|
#switches GTP move into sgf-like coordinate
|
108
|
-
def convert_move(move)
|
132
|
+
def convert_move(move, size=19)
|
109
133
|
if move == "PASS"
|
110
134
|
return 'pass'
|
111
135
|
elsif move == "resign"
|
112
136
|
return 'resign'
|
113
137
|
else
|
114
|
-
alphabet = "ABCDEFGHIJKLMNOPQRS"
|
138
|
+
alphabet = "ABCDEFGHIJKLMNOPQRS"[0..size.to_i - 1]
|
139
|
+
sgf_alphabet = "ABCDEFGHJKLMNOPQRST"[0..size.to_i - 1]
|
115
140
|
return alphabet["ABCDEFGHJKLMNOPQRST".index(move[0])].downcase + alphabet.reverse[(move[1].to_s + move[2].to_s).to_i - 1].downcase
|
116
141
|
end
|
117
142
|
end
|
data/lib/kayabot.rb
CHANGED
@@ -11,31 +11,36 @@ class KayaBot
|
|
11
11
|
OPEN_GAME_URL = "/bot/open_game"
|
12
12
|
RESIGN_URL = "/bot/resign"
|
13
13
|
SCORE_URL = "/bot/score"
|
14
|
+
VERSION = "0.1.1"#Gem::Specification.find_by_name("kayabot").version.to_s
|
14
15
|
|
15
16
|
attr_accessor :challenger, :status, :move
|
16
17
|
|
17
|
-
def initialize(
|
18
|
-
|
19
|
-
@
|
20
|
-
@
|
18
|
+
def initialize(config)
|
19
|
+
p config
|
20
|
+
@server_url = config["url"]
|
21
|
+
@user = config["user"]
|
22
|
+
@pass = config["pass"]
|
23
|
+
@size = config["size"]
|
24
|
+
@title = config["title"]
|
21
25
|
@agent = Mechanize.new
|
22
26
|
@status
|
23
27
|
@sgf
|
24
28
|
end
|
25
29
|
|
26
30
|
def game_configuration
|
27
|
-
{:title => "Come at me bro"}
|
31
|
+
{:title => @title || "Come at me bro", :size => @size || 19}
|
28
32
|
end
|
29
33
|
|
30
34
|
def connect
|
35
|
+
return if @agent.cookies.last && @agent.cookies.last.name == "rack.session"
|
31
36
|
page = @agent.post(@server_url+ "/session/create", {:id => @user, :password => @pass})
|
32
37
|
end
|
33
38
|
|
34
39
|
TIME_LAPSE = 4
|
35
40
|
|
36
41
|
def listener_loop
|
37
|
-
connect
|
38
42
|
while (true) do
|
43
|
+
connect
|
39
44
|
fetch_and_parse_data
|
40
45
|
open_game if @status=="connected" || @status=="finished"
|
41
46
|
post_score if @status=="scoring"
|
@@ -45,7 +50,7 @@ class KayaBot
|
|
45
50
|
end
|
46
51
|
|
47
52
|
def fetch_and_parse_data
|
48
|
-
page = @agent.get(@server_url + "/bot/status")
|
53
|
+
page = @agent.get(@server_url + "/bot/status", {:version => VERSION })
|
49
54
|
json = JSON.parse(page.body)
|
50
55
|
p json
|
51
56
|
@status = json["status"]
|
@@ -76,12 +81,12 @@ class KayaBot
|
|
76
81
|
def resign
|
77
82
|
@agent.post(@server_url+ RESIGN_URL, {:result => "resign"})
|
78
83
|
end
|
84
|
+
|
79
85
|
def post_score
|
80
86
|
result = score_game("temp", sgf_content)
|
81
87
|
p result
|
82
|
-
@agent.post(@server_url+ SCORE_URL, {:score => parse_result_from_bot(result)})
|
88
|
+
@agent.post(@server_url+ SCORE_URL, {:score => parse_result_from_bot(result[:score]), :dead_stones => result[:dead_stones]})
|
83
89
|
end
|
84
|
-
|
85
90
|
#Black wins by 61.5 points
|
86
91
|
def parse_result_from_bot(result)
|
87
92
|
color = result[0]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kayabot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mechanize
|
@@ -54,10 +54,10 @@ files:
|
|
54
54
|
- README.markdown
|
55
55
|
- LICENSE
|
56
56
|
- Rakefile
|
57
|
-
- lib/kayabot.rb
|
58
57
|
- lib/node.rb
|
59
|
-
- lib/sgf.rb
|
60
58
|
- lib/gg.rb
|
59
|
+
- lib/sgf.rb
|
60
|
+
- lib/kayabot.rb
|
61
61
|
- kayabot.gemspec
|
62
62
|
- bin/kayabot
|
63
63
|
homepage: http://github.com/conanbatt/OpenKaya
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.8.
|
83
|
+
rubygems_version: 1.8.24
|
84
84
|
signing_key:
|
85
85
|
specification_version: 3
|
86
86
|
summary: Interface to run Go Bots on Kaya
|