{"id":26215326,"url":"https://github.com/rocambille/elo","last_synced_at":"2025-04-15T19:05:36.712Z","repository":{"id":46648994,"uuid":"398567551","full_name":"rocambille/elo","owner":"rocambille","description":"Enrich your objects with Elo rating.","archived":false,"fork":false,"pushed_at":"2024-10-05T08:01:49.000Z","size":327,"stargazers_count":8,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T23:51:17.951Z","etag":null,"topics":["chess","elo","elo-rating","game","go","hacktoberfest","ranking","rating"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@rocambille/elo","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rocambille.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-21T13:40:21.000Z","updated_at":"2024-10-05T08:01:19.000Z","dependencies_parsed_at":"2023-02-02T15:02:17.622Z","dependency_job_id":null,"html_url":"https://github.com/rocambille/elo","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocambille%2Felo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocambille%2Felo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocambille%2Felo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rocambille%2Felo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rocambille","download_url":"https://codeload.github.com/rocambille/elo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248744208,"owners_count":21154821,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chess","elo","elo-rating","game","go","hacktoberfest","ranking","rating"],"created_at":"2025-03-12T10:27:39.537Z","updated_at":"2025-04-15T19:05:36.686Z","avatar_url":"https://github.com/rocambille.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elo\n\n![npm (scoped)](https://img.shields.io/npm/v/@rocambille/elo)\n![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/@rocambille/elo)\n\nEnrich your objects with [Elo rating](https://en.wikipedia.org/wiki/Elo_rating_system).\n\n## Installation\n\n```bash\nnpm i @rocambille/elo\n```\n\n## Basic usage\n\n```js\nimport elo from \"@rocambille/elo\";\n// or const elo = require(\"@rocambille/elo\");\n\nconst player = elo();\n\nlet foo = { a: 42 };\nlet bar = { z: 43 };\n\nconst odds = player(foo).oddsAgainst(bar);\n\nconsole.log(`foo has a ${odds * 100}% chance of winning against bar`);\n\n[foo, bar] = player(foo).wins(bar);\n// or [foo, bar] = player(foo).loses(bar);\n// or [foo, bar] = player(foo).ties(bar);\n\nconsole.log(foo, bar);\n```\n\nShould print something like this:\n\n```bash\nfoo has a 50% chance of winning against bar\n{\n  a: 42,\n  elo: {\n    rating: 1516,\n    matchCount: 1,\n    lastDelta: 16,\n    lastPlayedAt: 1629554837908\n  }\n} {\n  z: 43,\n  elo: {\n    rating: 1484,\n    matchCount: 1,\n    lastDelta: -16,\n    lastPlayedAt: 1629554837908\n  }\n}\n```\n\nNote that the elo module keeps `foo.a` and `bar.z` untouched.\nIt enriches the objects with Elo stuff (rating, match count, last delta and last play timestamp).\nThis is useful if you want to add elo rating on top of existing data, e.g. coming from an API.\n\n## The Pool object\n\nYou can manage a whole collection using the `Pool` object as follows:\n\n```js\nimport { Pool } from \"@rocambille/elo\";\n// or const { Pool } = require(\"@rocambille/elo\");\n\nlet pool = Pool.from([{ a: 42 }, { z: 43 }, { x: 44 }]);\n\nconst odds = pool.player(0).oddsAgainst(1);\n\nconsole.log(`player 0 has a ${odds * 100}% chance of winning against player 1`);\n\npool = pool.player(0).wins(1);\n// or pool = pool.player(0).loses(1);\n// or pool = pool.player(0).ties(1);\n\nconsole.log(pool);\n```\n\nShould print something like this:\n\n```bash\nplayer 0 has a 50% chance of winning against player 1\n[\n  {\n    a: 42,\n    elo: {\n      rating: 1516,\n      matchCount: 1,\n      lastDelta: 16,\n      lastPlayedAt: 1629554837908\n    }\n  },\n  {\n    z: 43,\n    elo: {\n      rating: 1484,\n      matchCount: 1,\n      lastDelta: -16,\n      lastPlayedAt: 1629554837908\n    }\n  },\n  {\n    x: 44,\n    elo: {\n      rating: 1500,\n      matchCount: 0,\n      lastDelta: NaN,\n      lastPlayedAt: NaN\n    }\n  }\n]\n```\n\nThe `Pool` provides a useful method to `pick` player indices using multiple options:\n\n```js\nimport { Pool } from \"@rocambille/elo\";\n// or const { Pool } = require(\"@rocambille/elo\");\n\nlet pool = Pool.from([{ a: 42 }, { z: 43 }, { x: 44 }]);\n\n// use one of the following lines to pick players\n\nconst [i, j] = pool.pick(\"random\"); // randomly pick\nconst [i, j] = pool.pick(\"matchCount\"); // pick players with a low match count\nconst [i, j] = pool.pick(\"lastPlayedAt\"); // pick players who have last played in the longest time\nconst [i, j] = pool.pick(); // pick players by randomly choosing one the above method (recommended)\n\n// then you can use i and j to trigger a match\n\npool = pool.player(i).wins(j);\n```\n\n## Configuration\n\nYou can pass a configuration object as parameter to the `elo` function.\nHere is an example with the default values:\n\n```js\nimport elo from \"elo\";\n// or const elo = require(\"@rocambille/elo\");\n\nconst player = elo({\n  initialRating: 1500,\n  DMax: 400,\n  kGenerator: (eloData) =\u003e {\n    if (eloData.matchCount \u003c 30) {\n      return 32;\n    }\n\n    return 24;\n  },\n  propsKey: \"elo\",\n});\n```\n\nSame works with the `Pool` object, using the `Pool.config` method:\n\n```js\nimport { Pool } from \"elo\";\n// or const { Pool } = require(\"@rocambille/elo\");\n\nconst pool = Pool.config({\n  initialRating: 1500,\n  DMax: 400,\n  kGenerator: (eloData) =\u003e {\n    if (eloData.matchCount \u003c 30) {\n      return 32;\n    }\n\n    return 24;\n  },\n  propsKey: \"elo\",\n}).from(...);\n```\n\nThe module will use `initialRating` for players with an _undefined_ rating.\nSee details of [Elo rating system](https://en.wikipedia.org/wiki/Elo_rating_system) for the `DMax` and `k` factors.\n\n## License\n\nelo is open source software [licensed as MIT](https://github.com/rocambille/elo/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frocambille%2Felo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frocambille%2Felo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frocambille%2Felo/lists"}