@poprank/rankings
Advanced tools
Comparing version 1.1.1 to 1.1.2
/** | ||
* Given two players, their ratings, and their score (1 = win, 0 = loss), return their new ratings | ||
* Given two players, their ratings, and their score (1 = win, 0 = loss), return their new ratings. | ||
* @param rating1 | ||
* @param score1 | ||
* @param rating2 | ||
* @param score2 | ||
* @param roundsPlayed1 | ||
* @param roundsPlayed2 | ||
* @param useDecayingKFactor | ||
* @returns | ||
*/ | ||
export declare const getNewPlayerRatings: (rating1: number, score1: number, rating2: number, score2: number, roundsPlayed1: number, roundsPlayed2: number, useDecayingKFactor?: boolean) => [number, number]; |
@@ -5,4 +5,3 @@ "use strict"; | ||
// All elo ratings need a kFactor. A low kFactor could result in Ratings updating slowly, whereas | ||
// a high one will result in recent games impacting the rating a lot. From my reading, i saw talk of K | ||
// values around 30, one thing said 32, one 24 | ||
// a high one can result in volatility | ||
var exponentDenominator = 400; | ||
@@ -13,5 +12,12 @@ var exponentBase = 10; | ||
var kFactorDecayingVariableCoefficient = 40; | ||
// Article that explains the two main ELO functions | ||
// https://www.hackerearth.com/blog/developers/elo-rating-system-common-link-facemash-chess/#:~:text=That%20equation%20is%20called%20the%20Elo%20rating%20or,and%20American%20football.%20Elo%20believed%20in%20the%20following%3A | ||
var expectedOutcome = function (rating1, rating2) { | ||
/** | ||
* Calculate player1's expected outcome for a game between players of rating1 and rating2. | ||
* | ||
* Article that explains the two main ELO functions | ||
* https://www.hackerearth.com/blog/developers/elo-rating-system-common-link-facemash-chess/#:~:text=That%20equation%20is%20called%20the%20Elo%20rating%20or,and%20American%20football.%20Elo%20believed%20in%20the%20following%3A | ||
* @param rating1 | ||
* @param rating2 | ||
* @returns | ||
*/ | ||
var calculateExpectedOutcome = function (rating1, rating2) { | ||
return (1.0 / (1.0 + Math.pow(exponentBase, ((rating2 - rating1) / exponentDenominator)))); | ||
@@ -21,3 +27,3 @@ }; | ||
* Calculate the decaying K factor. When 0 rounds have been played, our k factor is static + variable. | ||
* As roundsPlayed goes to infinite, the variable component goes to 0 | ||
* As roundsPlayed goes to infinite, the variable component goes to 0. | ||
* @param roundsPlayed | ||
@@ -27,7 +33,6 @@ * @returns Decayed k factor | ||
var kFactorScaled = function (roundsPlayed) { | ||
// kFactor; | ||
// Math.max(10, (kFactor - 2 * roundsPlayed)); | ||
return (kFactorDecayingStatic + kFactorDecayingVariableCoefficient / Math.sqrt((roundsPlayed + 1))); | ||
}; | ||
/** | ||
* Get the new rating for a player. | ||
* @param actual actual outcome - for our win/lose game, it's 1/0, for other games that have scores it can be different | ||
@@ -39,3 +44,3 @@ * @param expected expected outcome - eg if someone has a 90% chance of winning, their expected outcome is 0.9 | ||
*/ | ||
var newRating = function (actual, expected, rating, roundsPlayed, useDecayingKFactor) { | ||
var calculateNewRating = function (actual, expected, rating, roundsPlayed, useDecayingKFactor) { | ||
var scaledRating = Math.round((rating + kFactorScaled(roundsPlayed) * (actual - expected))); | ||
@@ -46,2 +51,3 @@ var normRating = Math.round((rating + kFactorStatic * (actual - expected))); | ||
/** | ||
* Get the expected outcome for a game between 2 players. | ||
* @param rating1 Player 1 rating | ||
@@ -52,7 +58,15 @@ * @param rating2 Player 2 rating | ||
var getExpectedPlayerOutcomes = function (rating1, rating2) { | ||
var expectedP1Rating = expectedOutcome(rating1, rating2); | ||
var expectedP1Rating = calculateExpectedOutcome(rating1, rating2); | ||
return [expectedP1Rating, 1 - expectedP1Rating]; | ||
}; | ||
/** | ||
* Given two players, their ratings, and their score (1 = win, 0 = loss), return their new ratings | ||
* Given two players, their ratings, and their score (1 = win, 0 = loss), return their new ratings. | ||
* @param rating1 | ||
* @param score1 | ||
* @param rating2 | ||
* @param score2 | ||
* @param roundsPlayed1 | ||
* @param roundsPlayed2 | ||
* @param useDecayingKFactor | ||
* @returns | ||
*/ | ||
@@ -62,4 +76,4 @@ var getNewPlayerRatings = function (rating1, score1, rating2, score2, roundsPlayed1, roundsPlayed2, useDecayingKFactor) { | ||
var _a = getExpectedPlayerOutcomes(rating1, rating2), expectedP1Rating = _a[0], expectedP2Rating = _a[1]; | ||
var newP1Rating = newRating(score1, expectedP1Rating, rating1, roundsPlayed1, useDecayingKFactor); | ||
var newP2Rating = newRating(score2, expectedP2Rating, rating2, roundsPlayed2, useDecayingKFactor); | ||
var newP1Rating = calculateNewRating(score1, expectedP1Rating, rating1, roundsPlayed1, useDecayingKFactor); | ||
var newP2Rating = calculateNewRating(score2, expectedP2Rating, rating2, roundsPlayed2, useDecayingKFactor); | ||
return [newP1Rating, newP2Rating]; | ||
@@ -66,0 +80,0 @@ }; |
export * from './aesthetics'; | ||
export * from './rarity'; | ||
export * from './rarity.meta'; | ||
export * from './rarity/rarity'; | ||
export * from './rarity/rarity.meta'; | ||
export * from './types'; |
@@ -14,5 +14,5 @@ "use strict"; | ||
__exportStar(require("./aesthetics"), exports); | ||
__exportStar(require("./rarity"), exports); | ||
__exportStar(require("./rarity.meta"), exports); | ||
__exportStar(require("./rarity/rarity"), exports); | ||
__exportStar(require("./rarity/rarity.meta"), exports); | ||
__exportStar(require("./types"), exports); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@poprank/rankings", | ||
"version": "1.1.1", | ||
"description": "PopRank's NFT rarity and aesthetics ranking logic", | ||
"publishConfig": { | ||
"access": "public", | ||
"registry": "https://registry.npmjs.org/" | ||
}, | ||
"main": "lib/index.js", | ||
"files":[ "lib" ], | ||
"types": "lib/index.d.ts", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@typescript-eslint/eslint-plugin": "^5.13.0", | ||
"@typescript-eslint/parser": "^5.13.0", | ||
"eslint": "^8.10.0", | ||
"eslint-config-airbnb-typescript": "^16.1.0", | ||
"typescript": "~4.5.2" | ||
}, | ||
"scripts": { | ||
"build": "yarn tsc", | ||
"lint": "eslint . --ext .ts" | ||
}, | ||
"keywords": [], | ||
"author": { | ||
"email": "info@poprank.io", | ||
"name": "PopRank", | ||
"url": "https://poprank.io" | ||
} | ||
} | ||
"name": "@poprank/rankings", | ||
"version": "1.1.2", | ||
"description": "PopRank's NFT rarity and aesthetic ranking logic", | ||
"publishConfig": { | ||
"access": "public", | ||
"registry": "https://registry.npmjs.org/" | ||
}, | ||
"license": "MIT", | ||
"main": "lib/index.js", | ||
"files": [ | ||
"lib" | ||
], | ||
"types": "lib/index.d.ts", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@types/jest": "^27.4.1", | ||
"@typescript-eslint/eslint-plugin": "^5.13.0", | ||
"@typescript-eslint/parser": "^5.13.0", | ||
"eslint": "^8.10.0", | ||
"eslint-config-airbnb-typescript": "^16.1.0", | ||
"jest": "^27.5.1", | ||
"rimraf": "^3.0.2", | ||
"ts-jest": "^27.0.5", | ||
"ts-node": "^10.1.0", | ||
"typescript": "~4.5.2" | ||
}, | ||
"scripts": { | ||
"build": "yarn clean && yarn tsc", | ||
"ci": "yarn tsc", | ||
"clean": "rimraf ./lib", | ||
"example": "cd example && npx ts-node example.ts", | ||
"lint": "eslint . --ext .ts", | ||
"test": "jest" | ||
}, | ||
"keywords": [], | ||
"author": { | ||
"email": "info@poprank.io", | ||
"name": "PopRank", | ||
"url": "https://poprank.io" | ||
} | ||
} |
@@ -7,2 +7,14 @@ # Rankings | ||
Please join us in our [Discord](https://discord.com/invite/9R5RzdUbXb) too, we'd love to chat with you | ||
## Example | ||
In order to run the example, you need to have Node / NPM installed. To run a typescript file, we suggest installing `npx` such that you can run `npx ts-node <filename>.ts`. | ||
There are numerous how-to's online about this that can explain it better than we can. | ||
By default, our `example.ts` will use our saved collection we use for tests, in the rarity/ folder, which is an array of our `NftBase` type - NFTs with traits attached to them, but no rarity / trait counts calculated yet. | ||
The example will calculate the rarity for the collection, saving the final rankings both in its JSON form, and a simple HTML file that'll show you visually the top 100 ranked NFTs! | ||
You can make whatever edits you wish to our rarity algorithm and re-run the example.ts to see how it impacts the end result! We'd love to hear what you come up with :) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
39461
18
0
520
20
10
1