TrueskillThroughTime 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad443e0e1bc8fe648cf96398475a4d404a0e3e0340c9cb6b7a87427fa92bbe16
4
+ data.tar.gz: acebab4b1c744c37de1977d08c96aa9c8303afa3c13d0d87ae2e74a89d48c67c
5
+ SHA512:
6
+ metadata.gz: 9338de026ac8d0afcfd399d8969e6d92f7d8795a3be5713d8a4d7dfc51f8fe300e07bd43a8db5b5ab612a9a546056500cccea37374ce74ffbcd95a1927e433b4
7
+ data.tar.gz: 40594521eb51d88059cee576ac7b16952f69969ee8d72f6bb6e5a5e3f91a5e66616bdc04c8d8e6c55f86382533a0c93482586b40dff33494635f00432f4773f9
@@ -0,0 +1,72 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="ModuleRunConfigurationManager">
4
+ <shared />
5
+ </component>
6
+ <component name="NewModuleRootManager">
7
+ <content url="file://$MODULE_DIR$">
8
+ <sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
9
+ <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
10
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
11
+ </content>
12
+ <orderEntry type="jdk" jdkName="rbenv: 3.2.5" jdkType="RUBY_SDK" />
13
+ <orderEntry type="sourceFolder" forTests="false" />
14
+ <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, rbenv: 3.2.5) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v2.4.19, rbenv: 3.2.5) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="json (v2.6.3, rbenv: 3.2.5) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="language_server-protocol (v3.17.0.3, rbenv: 3.2.5) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.25.5, rbenv: 3.2.5) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="parallel (v1.23.0, rbenv: 3.2.5) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="parser (v3.2.2.3, rbenv: 3.2.5) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="racc (v1.8.1, rbenv: 3.2.5) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, rbenv: 3.2.5) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="rake (v13.3.0, rbenv: 3.2.5) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.8.1, rbenv: 3.2.5) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="rexml (v3.3.2, rbenv: 3.2.5) [gem]" level="application" />
26
+ <orderEntry type="library" scope="PROVIDED" name="rubocop (v1.56.3, rbenv: 3.2.5) [gem]" level="application" />
27
+ <orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.29.0, rbenv: 3.2.5) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.13.0, rbenv: 3.2.5) [gem]" level="application" />
29
+ <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.4.2, rbenv: 3.2.5) [gem]" level="application" />
30
+ </component>
31
+ <component name="RakeTasksCache-v2">
32
+ <option name="myRootTask">
33
+ <RakeTaskImpl id="rake">
34
+ <subtasks>
35
+ <RakeTaskImpl description="Build TrueskillThroughTime-0.1.0.gem into the pkg directory" fullCommand="build" id="build" />
36
+ <RakeTaskImpl id="build">
37
+ <subtasks>
38
+ <RakeTaskImpl description="Generate SHA512 checksum if TrueskillThroughTime-0.1.0.gem into the checksums directory" fullCommand="build:checksum" id="checksum" />
39
+ </subtasks>
40
+ </RakeTaskImpl>
41
+ <RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
42
+ <RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
43
+ <RakeTaskImpl description="Build and install TrueskillThroughTime-0.1.0.gem into system gems" fullCommand="install" id="install" />
44
+ <RakeTaskImpl id="install">
45
+ <subtasks>
46
+ <RakeTaskImpl description="Build and install TrueskillThroughTime-0.1.0.gem into system gems without network access" fullCommand="install:local" id="local" />
47
+ </subtasks>
48
+ </RakeTaskImpl>
49
+ <RakeTaskImpl description="Create tag v0.1.0 and build and push TrueskillThroughTime-0.1.0.gem to TODO: Set to your gem server 'https://example.com'" fullCommand="release[remote]" id="release[remote]" />
50
+ <RakeTaskImpl description="Run RuboCop" fullCommand="rubocop" id="rubocop" />
51
+ <RakeTaskImpl id="rubocop">
52
+ <subtasks>
53
+ <RakeTaskImpl description="Autocorrect RuboCop offenses (only when it's safe)" fullCommand="rubocop:autocorrect" id="autocorrect" />
54
+ <RakeTaskImpl description="Autocorrect RuboCop offenses (safe and unsafe)" fullCommand="rubocop:autocorrect_all" id="autocorrect_all" />
55
+ <RakeTaskImpl description="" fullCommand="rubocop:auto_correct" id="auto_correct" />
56
+ </subtasks>
57
+ </RakeTaskImpl>
58
+ <RakeTaskImpl description="Run tests" fullCommand="test" id="test" />
59
+ <RakeTaskImpl description="" fullCommand="default" id="default" />
60
+ <RakeTaskImpl description="" fullCommand="release" id="release" />
61
+ <RakeTaskImpl id="release">
62
+ <subtasks>
63
+ <RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
64
+ <RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
65
+ <RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
66
+ </subtasks>
67
+ </RakeTaskImpl>
68
+ </subtasks>
69
+ </RakeTaskImpl>
70
+ </option>
71
+ </component>
72
+ </module>
data/.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/TrueskillThroughTime.iml" filepath="$PROJECT_DIR$/.idea/TrueskillThroughTime.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,71 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="5cccfe11-d9d4-4261-b533-95d58b839d14" name="Changes" comment="">
8
+ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
9
+ </list>
10
+ <option name="SHOW_DIALOG" value="false" />
11
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
12
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
13
+ <option name="LAST_RESOLUTION" value="IGNORE" />
14
+ </component>
15
+ <component name="Git.Settings">
16
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
17
+ </component>
18
+ <component name="ProjectColorInfo"><![CDATA[{
19
+ "associatedIndex": 2
20
+ }]]></component>
21
+ <component name="ProjectId" id="3CQeG8eh43XRpG9r1qi8YrgDZY2" />
22
+ <component name="ProjectViewState">
23
+ <option name="autoscrollFromSource" value="true" />
24
+ <option name="autoscrollToSource" value="true" />
25
+ <option name="hideEmptyMiddlePackages" value="true" />
26
+ <option name="showLibraryContents" value="true" />
27
+ </component>
28
+ <component name="PropertiesComponent"><![CDATA[{
29
+ "keyToString": {
30
+ "Ruby.ttt.executor": "Run",
31
+ "RunOnceActivity.ShowReadmeOnStart": "true",
32
+ "RunOnceActivity.git.unshallow": "true",
33
+ "last_opened_file_path": "/home/sjb/RubymineProjects/TrueskillThroughTime/lib/example_data",
34
+ "node.js.detected.package.eslint": "true",
35
+ "node.js.detected.package.tslint": "true",
36
+ "node.js.selected.package.eslint": "(autodetect)",
37
+ "node.js.selected.package.tslint": "(autodetect)",
38
+ "nodejs_package_manager_path": "npm",
39
+ "ruby.structure.view.model.defaults.configured": "true",
40
+ "vue.rearranger.settings.migration": "true"
41
+ }
42
+ }]]></component>
43
+ <component name="RecentsManager">
44
+ <key name="CopyFile.RECENT_KEYS">
45
+ <recent name="$PROJECT_DIR$/lib/example_data" />
46
+ </key>
47
+ </component>
48
+ <component name="SharedIndexes">
49
+ <attachedChunks>
50
+ <set>
51
+ <option value="bundled-js-predefined-d6986cc7102b-e768b9ed790e-JavaScript-RM-243.21565.197" />
52
+ </set>
53
+ </attachedChunks>
54
+ </component>
55
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
56
+ <component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" RAKE_SPRING_PRE_LOADER_OPTION="true" RAILS_SPRING_PRE_LOADER_OPTION="true" />
57
+ <component name="TaskManager">
58
+ <task active="true" id="Default" summary="Default task">
59
+ <changelist id="5cccfe11-d9d4-4261-b533-95d58b839d14" name="Changes" comment="" />
60
+ <created>1776322123090</created>
61
+ <option name="number" value="Default" />
62
+ <option name="presentableId" value="Default" />
63
+ <updated>1776322123090</updated>
64
+ <workItem from="1776322124389" duration="4698000" />
65
+ </task>
66
+ <servers />
67
+ </component>
68
+ <component name="TypeScriptGeneratedFilesManager">
69
+ <option name="version" value="3" />
70
+ </component>
71
+ </project>
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.2
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2026-04-16
4
+
5
+ - Null release
6
+
7
+ ## [1.0.0] - 2026-04-16
8
+
9
+ - Initial release
data/LICENCE ADDED
@@ -0,0 +1,57 @@
1
+ Caution
2
+ =======
3
+
4
+ This TrueSkill project is opened under the BSD license but the
5
+ TrueSkill(TM) brand is not. Microsoft permits only Xbox Live games or
6
+ non-commercial projects to use TrueSkill(TM). If your project is
7
+ commercial, you should find another rating system.
8
+
9
+ Caution Redux
10
+ =======
11
+
12
+ The example data is from Liquipedia and is shared under the
13
+ CC-BY-SA 3.0 license "[(tl;dr)](https://liquipedia.net/commons/Liquipedia:Copyrights)"
14
+ If you use it or redistribute it, you need to attribute it and
15
+ license it likewise under CC-BY-SA 3.0.
16
+
17
+ References
18
+ ==========
19
+
20
+ The core ideas implemented in this project were developed in
21
+ "[TrueSkill Through Time: Revisiting the History of Chess](https://www.microsoft.com/en-us/research/publication/trueskill-through-time-revisiting-the-history-of-chess/)"
22
+
23
+ License
24
+ =======
25
+
26
+ The Clear BSD License
27
+
28
+ Copyright (c) 2026 by Solomon Birch
29
+ All rights reserved.
30
+
31
+ Redistribution and use in source and binary forms, with or without
32
+ modification, are permitted (subject to the limitations in the disclaimer
33
+ below) provided that the following conditions are met:
34
+
35
+ * Redistributions of source code must retain the above copyright notice,
36
+ this list of conditions and the following disclaimer.
37
+
38
+ * Redistributions in binary form must reproduce the above copyright
39
+ notice, this list of conditions and the following disclaimer in the
40
+ documentation and/or other materials provided with the distribution.
41
+
42
+ * Neither the name of the copyright holder nor the names of its
43
+ contributors may be used to endorse or promote products derived from this
44
+ software without specific prior written permission.
45
+
46
+ NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
47
+ THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
48
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
50
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
51
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
52
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
53
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
54
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
55
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57
+ POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # TrueskillThroughTime
2
+
3
+ This is a port of Trueskill Through Time (https://github.com/glandfried/TrueSkillThroughTime.py) to Ruby.
4
+
5
+ At present, v1.1.0 of TrueskillThroughTime.py is the ported version, corresponding to v1 of this gem.
6
+
7
+ In my test cases (large and complicated n vs n vs n etc FFA histories) it was approximately 1/4 to 1/3 faster than the target Python implementation, but I'm sure ymmv.
8
+
9
+ The gem was tested on Ruby 3.2.5 patch level 208, but there is no reason it shouldn't work on newer versions or older versions.
10
+
11
+ ## Installation
12
+
13
+ Install the gem and add to the application's Gemfile by executing:
14
+
15
+ $ bundle add Trueskill-Through-Time
16
+
17
+ ## Usage
18
+
19
+ Usage patterns have been kept identical to those of the source version, so their documentation should basically work. Their documentation is at: https://trueskillthroughtime.readthedocs.io/en/latest/
20
+
21
+ If you do not converge your results in a History instance, then your usage is equivalent to the original Trueskill implementation, license and patents. If you do converge results, then your usage will fall under the later Trueskill Through Time implementation, license and patent.
22
+
23
+ If you want to go poking around, any time a Tuple is used in the Python version, a two-element Array is used in Ruby.
24
+
25
+ Finally, example usage is contained as the methods `game_example` and `history_example`, which mirror the examples given in the Python documentation. An additional, more complicated example is given as `liquid_example` using data from the Liquipedia API (https://liquipedia.net) under the CC-BY-SA 3 license. If you use this example data, then your usage must also comply with that license.
26
+
27
+ Otherwise, a convenience method `evidence` is added to the history class to get the discrete evidence by event. I will add some more convenience methods when I update the gem and alter the interfaces.
28
+
29
+ ## Licensing
30
+ The original Trueskill and Trueskill Through Time are covered by the BSD license and separate Microsoft patents. One of these sets will apply to your usage, depending whether you converge your results. Notably, the only allowed uses either way are non-commercial products or XBox Live games.
31
+
32
+ The Liquipedia data used in the example is provided under CC-BY-SA 3.0, and if you use it then it will apply to your use.
33
+
34
+ Finally, this implementation is distributed under the Clear BSD License.
35
+
36
+ ## Contributing
37
+
38
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sjjbirch/TrueskillThroughTime. Probably hold off on PRs until it gets to v2, which I intend to be a less directly ported version with more convenience methods.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/test_*.rb"]
10
+ end
11
+
12
+ require "rubocop/rake_task"
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/TrueskillThroughTime/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "TrueskillThroughTime"
7
+ spec.version = TrueskillThroughTime::VERSION
8
+ spec.authors = ["Solomon Birch"]
9
+ spec.email = ["birch.jj@gmail.com"]
10
+
11
+ spec.summary = "A Ruby implementation of Trueskill Through Time."
12
+ spec.homepage = "https://github.com/sjjbirch/Trueskill-Through-Time"
13
+ spec.required_ruby_version = ">= 3.2"
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+ spec.metadata["source_code_uri"] = "https://github.com/sjjbirch/Trueskill-Through-Time"
17
+ spec.metadata["changelog_uri"] = "https://github.com/sjjbirch/Trueskill-Through-Time/blob/master/CHANGELOG.md"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (File.expand_path(f) == __FILE__) ||
24
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
25
+ end
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ # Uncomment to register a new dependency of your gem
32
+ # spec.add_dependency "example-gem", "~> 1.0"
33
+
34
+ # For more information and examples about making a new gem, check out our
35
+ # guide at: https://bundler.io/guides/creating_gem.html
36
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrueskillThroughTime
4
+ VERSION = "1.0.0"
5
+ end