Project init, returns a shuffled pile (deck) of cards

This commit is contained in:
Github Readme Stats Bot 2026-01-16 21:14:50 -07:00
commit 59a0995c29
11 changed files with 264 additions and 0 deletions

34
.gitignore vendored Normal file
View file

@ -0,0 +1,34 @@
# dependencies (bun install)
node_modules
# output
out
dist
*.tgz
# code coverage
coverage
*.lcov
# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# caches
.eslintcache
.cache
*.tsbuildinfo
# IntelliJ based IDEs
.idea
# Finder (MacOS) folder config
.DS_Store

15
README.md Normal file
View file

@ -0,0 +1,15 @@
# cards
To install dependencies:
```bash
bun install
```
To run:
```bash
bun run index.ts
```
This project was created using `bun init` in bun v1.3.6. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.

26
bun.lock Normal file
View file

@ -0,0 +1,26 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "cards",
"devDependencies": {
"@types/bun": "latest",
},
"peerDependencies": {
"typescript": "^5",
},
},
},
"packages": {
"@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
"@types/node": ["@types/node@25.0.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="],
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
}
}

72
card.ts Normal file
View file

@ -0,0 +1,72 @@
export enum Index {
Joker,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King,
Ace
}
export enum Suit {
Diamond,
Club,
Heart,
Spade
}
export default class Card {
index: Index
suit: Suit
constructor(index: Index, suit: Suit) {
this.index = index
this.suit = suit
}
get decimalIndex() {
const base = 2
return this.index.toString(base)
}
get decimalSuit() {
const base = 2
return this.suit.toString(base)
}
get pretty() {
return `${this.prettyIndex} of ${this.prettySuit}`
}
get prettyIndex() {
return [
'Joker',
'One',
'Two',
'Three',
'Four',
'Five',
'Six',
'Seven',
'Eight',
'Nine',
'Ten',
'Jack',
'Queen',
'King',
'Ace'
][this.index]
}
get prettySuit() {
return ['♦', '♣', '♥', '♠'][this.suit]
}
}

34
decks/standard52.ts Normal file
View file

@ -0,0 +1,34 @@
import Card from '../card'
import { Index, Suit } from '../card'
import Pile from '../pile'
import { arrayOfLength } from '../utils'
export default () => {
const indexes = [
Index.One,
Index.Two,
Index.Three,
Index.Four,
Index.Five,
Index.Six,
Index.Seven,
Index.Eight,
Index.Nine,
Index.Ten,
Index.Jack,
Index.Queen,
Index.King,
Index.Ace
]
const suits = [Suit.Diamond, Suit.Club, Suit.Heart, Suit.Spade]
const baseIndexCards = 1
const baseIndexSuits = 0
return new Pile(
arrayOfLength(indexes.length).map(index => {
return arrayOfLength(suits.length).map(suit => {
return (new Card(index + baseIndexCards, suit + baseIndexSuits))
})
}).flat()
)
}

5
index.ts Normal file
View file

@ -0,0 +1,5 @@
import standard52 from './decks/standard52'
const deck = standard52()
deck.shuffle(5)
console.log(deck.pretty)

2
mise.toml Normal file
View file

@ -0,0 +1,2 @@
[tools]
bun = "latest"

11
package.json Normal file
View file

@ -0,0 +1,11 @@
{
"name": "cards",
"module": "index.ts",
"type": "module",
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}

24
pile.ts Normal file
View file

@ -0,0 +1,24 @@
import { arrayShuffle } from './utils'
import type Card from './card'
export default class Pile {
cards: Card[]
constructor(cards: Card[]) {
this.cards = cards
}
get pretty() {
return this.cards.map(card => card.pretty).join('\n')
}
shuffle(times = 1) {
let cards = this.cards
for (let index = 0; index < times; index++) {
cards = arrayShuffle(cards)
}
this.cards = cards
return this.cards
}
}

29
tsconfig.json Normal file
View file

@ -0,0 +1,29 @@
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}

12
utils.ts Normal file
View file

@ -0,0 +1,12 @@
export const arrayOfLength = (length: number): number[] => {
return [...Array(length).keys()]
}
export function arrayShuffle(array: any[]) {
const copy = [...array]; // Create a shallow copy
for (let i = copy.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[copy[i], copy[j]] = [copy[j], copy[i]];
}
return copy;
}