ficsr 0.0.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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.markdown +4 -0
- data/Rakefile +2 -0
- data/autotest/discover.rb +4 -0
- data/ficsr.gemspec +26 -0
- data/lib/ficsr.rb +4 -0
- data/lib/ficsr/game.rb +74 -0
- data/lib/ficsr/session.rb +84 -0
- data/lib/ficsr/version.rb +3 -0
- data/spec-integration/ficsr_spec.rb +44 -0
- data/spec/game_spec.rb +108 -0
- metadata +111 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
data/Rakefile
ADDED
data/ficsr.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ficsr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ficsr"
|
7
|
+
s.version = Ficsr::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Thilko Richter"]
|
10
|
+
s.email = [""]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Ruby library for the free internet chess server}
|
13
|
+
s.description = %q{Administration of games any other various thing are possible}
|
14
|
+
|
15
|
+
s.rubyforge_project = "ficsr"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency('rspec', "~> 2.6.0")
|
23
|
+
s.add_development_dependency('autotest', "~> 4.4.6")
|
24
|
+
s.add_development_dependency('autotest-growl', "~> 0.2.9")
|
25
|
+
s.add_development_dependency('autotest-fsevent', "~> 0.2.5")
|
26
|
+
end
|
data/lib/ficsr.rb
ADDED
data/lib/ficsr/game.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Ficsr
|
2
|
+
|
3
|
+
CATEGORIES = { :b => :blitz, :s => :standard, :B => :Bughouse, :l => :lightning,
|
4
|
+
:w => :wild, :L => :losers, :u => :untimed, :x => :atomic,
|
5
|
+
:S => :Suicide, :e => :examined_game, :z => :crazyhouse
|
6
|
+
}
|
7
|
+
class Game
|
8
|
+
def initialize(game_def)
|
9
|
+
game_regexp = %r{
|
10
|
+
(?<number>^\d*){0}
|
11
|
+
(?<white_rating>\S*){0}
|
12
|
+
(?<white_handle>\S*){0}
|
13
|
+
(?<black_rating>\S*){0}
|
14
|
+
(?<black_handle>\S*){0}
|
15
|
+
(?<private>p?){0}
|
16
|
+
(?<category>\w?){0}
|
17
|
+
(?<rated>\w?){0}
|
18
|
+
(?<start_minutes>\d*){0}
|
19
|
+
(?<increment_seconds>\d*){0}
|
20
|
+
(?<time_white>\d*:\d*:?\d*){0}
|
21
|
+
(?<time_black>\d*:\d*:?\d*){0}
|
22
|
+
(?<strength_white>\d*){0}
|
23
|
+
(?<strength_black>\d*){0}
|
24
|
+
(?<turn>[WB]){0}
|
25
|
+
(?<move_number>\d*){0}
|
26
|
+
|
27
|
+
\g<number>\s*\g<white_rating>\s*\g<white_handle>\s*\g<black_rating>\s*\g<black_handle>\s*\[\g<private>\s*
|
28
|
+
\g<category>\s*\g<rated>\s*\g<start_minutes>\s*\g<increment_seconds>\]\s*\g<time_white>\s*-\s*
|
29
|
+
\g<time_black>\s*\(\s*\g<strength_white>\s*-\s*\g<strength_black>\)\s\g<turn>:\s*\g<move_number>$
|
30
|
+
|
31
|
+
}x
|
32
|
+
|
33
|
+
match_data = game_def.match(game_regexp)
|
34
|
+
if match_data
|
35
|
+
self.number = match_data[:number].to_i
|
36
|
+
self.white_rating = match_data[:white_rating]
|
37
|
+
self.white_handle = match_data[:white_handle]
|
38
|
+
self.black_rating = match_data[:black_rating]
|
39
|
+
self.black_handle = match_data[:black_handle]
|
40
|
+
self.private = !match_data[:private].empty?
|
41
|
+
self.category_id = match_data[:category].to_sym
|
42
|
+
self.rated = match_data[:rated]
|
43
|
+
self.start_minutes = match_data[:start_minutes].to_i
|
44
|
+
self.increment_seconds = match_data[:increment_seconds].to_i
|
45
|
+
self.time_white = match_data[:time_white]
|
46
|
+
self.time_black = match_data[:time_black]
|
47
|
+
self.strength_white = match_data[:strength_white].to_i
|
48
|
+
self.strength_black = match_data[:strength_black].to_i
|
49
|
+
self.turn = match_data[:turn]
|
50
|
+
self.move_number = match_data[:move_number].to_i
|
51
|
+
else
|
52
|
+
p "ignoring game '#{game_def}'"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_accessor :number, :white_rating, :white_handle, :black_rating, :black_handle, :private, :category_id, :rated, :start_minutes, :increment_seconds, :time_white, :time_black, :strength_white, :strength_black, :turn, :move_number
|
57
|
+
|
58
|
+
def private?
|
59
|
+
self.private
|
60
|
+
end
|
61
|
+
|
62
|
+
def category
|
63
|
+
CATEGORIES[self.category_id]
|
64
|
+
end
|
65
|
+
|
66
|
+
def rated?
|
67
|
+
self.rated == "r"
|
68
|
+
end
|
69
|
+
|
70
|
+
def whites_turn?
|
71
|
+
self.turn == "W"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Ficsr
|
2
|
+
class Session
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def login(username, password="")
|
6
|
+
new(username, password)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :username, :password
|
11
|
+
|
12
|
+
def initialize(username, password)
|
13
|
+
@username = username
|
14
|
+
@password = password
|
15
|
+
|
16
|
+
send username, /password|is not a registered name/
|
17
|
+
|
18
|
+
if registered?
|
19
|
+
send password, /fics|login/
|
20
|
+
else
|
21
|
+
send "\n", /#{username}/
|
22
|
+
end
|
23
|
+
raise "Unable to login with username #{username} " unless logged_in?
|
24
|
+
end
|
25
|
+
|
26
|
+
def games
|
27
|
+
send "games", /fics/
|
28
|
+
last_result.split("\n\r").select { |line| line =~ /^\d{3}\s\w{1,4}.*$/ }.collect do |game|
|
29
|
+
Ficsr::Game.new game
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def observe(game_number, &action)
|
34
|
+
t = Thread.new do
|
35
|
+
send "observe #{game_number}", /fics/
|
36
|
+
last_result.each_line("\n\r") do |line|
|
37
|
+
action.call(line) if line =~/^<12>/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
t.join
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def connection
|
47
|
+
@connection ||= Net::Telnet.new "Host" => host, "Port" => port, "Prompt" => default_prompt
|
48
|
+
end
|
49
|
+
|
50
|
+
def logged_in?
|
51
|
+
last_result.include?("Starting FICS session as #{username}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def send(cmd, match="", opts={}, &actions)
|
55
|
+
all_opts = {"String" => cmd, "Match" => match}.merge opts
|
56
|
+
|
57
|
+
if block_given?
|
58
|
+
@last_result = connection.cmd(all_opts, &actions)
|
59
|
+
else
|
60
|
+
@last_result = connection.cmd(all_opts)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def last_result
|
65
|
+
@last_result
|
66
|
+
end
|
67
|
+
|
68
|
+
def registered?
|
69
|
+
last_result =~ /is a registered name/
|
70
|
+
end
|
71
|
+
|
72
|
+
def host
|
73
|
+
"freechess.org"
|
74
|
+
end
|
75
|
+
|
76
|
+
def port
|
77
|
+
5000
|
78
|
+
end
|
79
|
+
|
80
|
+
def default_prompt
|
81
|
+
/fics/
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "ficsr"
|
2
|
+
|
3
|
+
describe Ficsr::Session do
|
4
|
+
describe ".login" do
|
5
|
+
context "with valid credentials" do
|
6
|
+
it "performs a successful login" do
|
7
|
+
@session = Ficsr::Session.login ENV["ficsr_username"], ENV["ficsr_password"]
|
8
|
+
@session.should_not be_nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "with invalid credentials" do
|
13
|
+
it "does not login" do
|
14
|
+
expect { Ficsr::Session.login "blackhacker", "xxx" }.to
|
15
|
+
raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with an anonymous user" do
|
20
|
+
it "does a login" do
|
21
|
+
@session = Ficsr::Session.login "someanonymous"
|
22
|
+
@session.should_not be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:session) { Ficsr::Session.login ENV["ficsr_username"], ENV["ficsr_password"] }
|
28
|
+
|
29
|
+
describe "#games" do
|
30
|
+
it "returns a list of games" do
|
31
|
+
session.games.each { |game| game.should be_a Ficsr::Game }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#observe" do
|
36
|
+
let(:game_number) { session.games.first.number }
|
37
|
+
it "starts observing the game" do
|
38
|
+
session.observe game_number do |move|
|
39
|
+
p "MOVE: #{move}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/spec/game_spec.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require "ficsr"
|
2
|
+
|
3
|
+
GAME = "302 1221 vinayakghol ++++ Bhuvi [psr 15 20] 16:38 - 15:08 (37-39) W: 13"
|
4
|
+
|
5
|
+
describe Ficsr::Game do
|
6
|
+
describe ".new" do
|
7
|
+
it "creates a new game object from the given string" do
|
8
|
+
Ficsr::Game.new(GAME).should be_a Ficsr::Game
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:game) { Ficsr::Game.new GAME }
|
13
|
+
|
14
|
+
describe "#number" do
|
15
|
+
it "returns the number of the game " do
|
16
|
+
game.number.should == 302
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#white_handle" do
|
21
|
+
it "returns the handle of the white player " do
|
22
|
+
game.white_handle.should == "vinayakghol"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#white_rating" do
|
27
|
+
it "returns the rating of the white player " do
|
28
|
+
game.white_rating.should == "1221"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
describe "#black_handle" do
|
32
|
+
it "returns the handle of the black player " do
|
33
|
+
game.black_handle.should == "Bhuvi"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#black_rating" do
|
38
|
+
it "returns the rating of the white player " do
|
39
|
+
game.black_rating.should == "++++"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#private?" do
|
44
|
+
it "returns true if the game is private" do
|
45
|
+
game.should be_private
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#category" do
|
50
|
+
it "returns the category" do
|
51
|
+
game.category.should == :standard
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#rated?" do
|
56
|
+
it "returns true for a rated game" do
|
57
|
+
game.should be_rated
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#start_minutes" do
|
62
|
+
it "returns the minuted each player get at the beginning" do
|
63
|
+
game.start_minutes.should == 15
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#increment_seconds" do
|
68
|
+
it "returns true for a rated game" do
|
69
|
+
game.increment_seconds.should == 20
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#time_white" do
|
74
|
+
it "returns the remaining time of white" do
|
75
|
+
game.time_white.should == "16:38"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#time_black" do
|
80
|
+
it "returns the remaining time of black" do
|
81
|
+
game.time_black.should == "15:08"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#strength_white" do
|
86
|
+
it "returns the strength of white" do
|
87
|
+
game.strength_white.should == 37
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#strength_black" do
|
92
|
+
it "returns the strength of black" do
|
93
|
+
game.strength_black.should == 39
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#whites_turn?" do
|
98
|
+
it "return true if it is whites turn" do
|
99
|
+
game.should be_whites_turn
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#move_number" do
|
104
|
+
it "return the current move number of white/black" do
|
105
|
+
game.move_number == 13
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ficsr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Thilko Richter
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-09-22 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.6.0
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: autotest
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 4.4.6
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: autotest-growl
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.2.9
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: autotest-fsevent
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.2.5
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
description: Administration of games any other various thing are possible
|
61
|
+
email:
|
62
|
+
- ""
|
63
|
+
executables: []
|
64
|
+
|
65
|
+
extensions: []
|
66
|
+
|
67
|
+
extra_rdoc_files: []
|
68
|
+
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- README.markdown
|
73
|
+
- Rakefile
|
74
|
+
- autotest/discover.rb
|
75
|
+
- ficsr.gemspec
|
76
|
+
- lib/ficsr.rb
|
77
|
+
- lib/ficsr/game.rb
|
78
|
+
- lib/ficsr/session.rb
|
79
|
+
- lib/ficsr/version.rb
|
80
|
+
- spec-integration/ficsr_spec.rb
|
81
|
+
- spec/game_spec.rb
|
82
|
+
has_rdoc: true
|
83
|
+
homepage: ""
|
84
|
+
licenses: []
|
85
|
+
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: ficsr
|
106
|
+
rubygems_version: 1.5.2
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Ruby library for the free internet chess server
|
110
|
+
test_files:
|
111
|
+
- spec/game_spec.rb
|