{"id":16327142,"url":"https://github.com/danguilherme/uno","last_synced_at":"2025-06-23T09:05:03.408Z","repository":{"id":6254748,"uuid":"55201120","full_name":"danguilherme/uno","owner":"danguilherme","description":":game_die: Uno game logic implemented in JavaScript","archived":false,"fork":false,"pushed_at":"2024-06-16T09:57:39.000Z","size":2101,"stargazers_count":102,"open_issues_count":6,"forks_count":28,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-06-18T19:51:19.967Z","etag":null,"topics":["card","card-game","game","uno","uno-game"],"latest_commit_sha":null,"homepage":"","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/danguilherme.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-01T03:30:15.000Z","updated_at":"2025-06-13T16:07:43.000Z","dependencies_parsed_at":"2024-04-30T11:05:15.276Z","dependency_job_id":"8249460d-345c-4c0e-b89a-38cf33ae9e2d","html_url":"https://github.com/danguilherme/uno","commit_stats":{"total_commits":119,"total_committers":6,"mean_commits":"19.833333333333332","dds":0.4117647058823529,"last_synced_commit":"f6accdc9e2d9a92de8e74aad034e42eda04d37ac"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/danguilherme/uno","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danguilherme%2Funo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danguilherme%2Funo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danguilherme%2Funo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danguilherme%2Funo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danguilherme","download_url":"https://codeload.github.com/danguilherme/uno/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danguilherme%2Funo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260834731,"owners_count":23070130,"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":["card","card-game","game","uno","uno-game"],"created_at":"2024-10-10T23:10:30.949Z","updated_at":"2025-06-23T09:04:58.396Z","avatar_url":"https://github.com/danguilherme.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UNO\n\nUno game implemented in JavaScript.\n\n[![npm package](https://img.shields.io/npm/v/uno-engine.svg?label=uno-engine)](https://www.npmjs.com/package/uno-engine)\n[![Build Status](https://img.shields.io/travis/danguilherme/uno/master.svg)](https://travis-ci.org/danguilherme/uno)\n[![License](https://img.shields.io/github/license/danguilherme/uno.svg)](LICENSE)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n\n\n## Installation\n```bash\n$ npm install uno-engine\n```\n\n## Usage\n\n### Import\n**JavaScript**\n```js\nconst { Game } = require('uno-engine');\n```\n\n**TypeScript**\n```ts\nimport { Game } from 'uno-engine';\n```\n\n### New Game\n```ts\nconst players = ['Player 1', 'Player 2', 'etc.']; // maximum 10 players with unique names\nconst customRules = [CumulativeDrawTwo];          // you can add your own rules (see https://github.com/danguilherme/uno/tree/v0.1.0-alpha/src/house-rules)\nconst game = new Game(players, customRules);      // initialize the game\n```\nAfter starting a new game, the first card will be randomly chosen, hands of 7 dealt, and a player will be randomly chosen to go first.\n\n### Player Properties\n```ts\nconst player = game.currentPlayer;          // player whose turn it is\nconst hand = player.hand;                   // array of `Card` objects\nconst p = game.getPlayer(\"Player 1\");       // get player by name\nconst card = player.getCardByValue(value);  // get the exact card in the player's hand\n```\n\n### Card Properties\n```ts\nimport { Color, Value } from 'uno-engine';\n\nconst card = game.discardedCard;  // current card in-play\nconst cardColor = card.color;     // get the index of the card color: 0 to 3\n                                  // (WILD and WILD DRAW FOUR will not have this property set)\nColor[cardColor];                 // get the name of the color: RED, BLUE, GREEN, or YELLOW\n\n// Card value\nconst cardValue = card.value; // get the index of the card value: 0 to 14\nValue[cardValue];             // get the name of the card:\n                              // 0-9, SKIP, REVERSE, DRAW_TWO, WILD, or WILD_DRAW_TWO\n\n// Get card from value/color strings\nconst value = Value.SIX;\nconst color = Color.BLUE;\nconst card = new Card(value, color);\n\n// Set WILD or WD4 color\nconst [color, value] = ['GREEN', 'WILD'];   // get args from player input\nconst card = player.getCardByValue(value);  // get exact WILD/WD4 in player's hand\ncard.color = Color[color];                  // set color of WILD/WD4 in hand\n\n// Get Card from args function\nconst getCard = ([color, value], player) =\u003e {\n  let card = new Card(Value[value], Color[color]);\n  if (value === 'WILD' || value === 'WILD_DRAW_FOUR') {\n    card = player.getCardByValue(Value[value]);\n    card.color = Color[color];\n  }\n  return card;\n};\n```\n\n### Game Loop\n```ts\ntry {\n  game.play(card); // play a card from the hand of the current player\n} catch (e) {\n  // throws error if player tries to play a card they don't have\n  // throws error if player tries to play a card that can't be played (doesn't match discardedCard)\n  // throws error if card doesn't have a color property (wild, wd4)\n  // see `Card Properties` for setting wild and wd4 color\n}\n\ngame.draw(); // draw a card for the current player\n\ntry {\n  game.pass(); // current player pass after drawing\n} catch (e) {\n  // throws error if player hasn't drawn yet\n}\n\n// Yelling UNO!\ngame.uno();           // game.currentPlayer is yelling UNO!\ngame.uno(\"Player 1\"); // Other than current player yells UNO\n                      // - If the yelling player is the current player,\n                      //   and they have 2 or less cards, he is just marked as \"yelled\"\n                      // - If the yelling player has more than 2 cards,\n                      //   the game searches for someone with 1 card that did not yell \"UNO!\",\n                      //   and make him draw 2 cards. If there's no one,\n                      //   the yelling player draws instead.\n```\n\n### Game Events\n\n- [Game Events](https://github.com/danguilherme/uno/blob/feature/typescript/src/events/game-events.ts)\n\n```ts\ngame.on('beforedraw', ({ data: { player, quantity } }) =\u003e {\n  // Fired when a player requests cards from the draw pile.\n});\n\ngame.on('draw', ({ data: { player, cards } }) =\u003e {\n  // Fired after player's drawn cards are added to his hands.\n});\n\ngame.on('beforepass', ({ data: { player } }) =\u003e {\n  // Fired when a player can pass and requests to pass its turn.\n});\n\ngame.on('beforecardplay', ({ data: { card, player } }) =\u003e {\n  // Fired before player discards a card in the discard pile.\n});\n\ngame.on('cardplay', ({ data: { card, player } }) =\u003e {\n  // Fired after player's card is thrown in the discard pile.\n});\n\ngame.on('nextplayer', ({ data: { player } ) =\u003e {\n  // Fired when `game.currentPlayer` changes.\n});\n\ngame.on('end', ({ data: { winner, score } }) =\u003e {\n  // emitted when any player has 0 cards left\n  // ----------\n  // the winner gets score based on the cards the other players have remaining at the end:\n  // - number cards are worth their own value\n  // - WILD and WD4 are worth 50\n  // - DRAW TWO, SKIP, and REVERSE are worth 20\n});\n```\n\n## Game Rules\n\nCheck all the [official game rules](RULES.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanguilherme%2Funo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanguilherme%2Funo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanguilherme%2Funo/lists"}