DND character

This commit is contained in:
2022-11-04 15:13:10 +01:00
parent 419e22e008
commit 6ec5cf99ca
13 changed files with 16398 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
!.meta
# Protected or generated
.git
.vscode
# When using npm
node_modules/*
# Configuration files
.eslintrc.cjs
babel.config.cjs
jest.config.cjs

View File

@@ -0,0 +1,44 @@
module.exports = {
root: true,
parserOptions: {
tsconfigRootDir: __dirname,
project: ["./tsconfig.json"],
},
overrides: [
// Student provided files
{
files: ["*.ts"],
excludedFiles: [".meta/proof.ci.ts", ".meta/exemplar.ts", "*.test.ts"],
extends: "@exercism/eslint-config-typescript",
rules: {
"@typescript-eslint/semi": 0,
},
},
// Exercism given tests
{
files: ["*.test.ts"],
excludedFiles: ["custom.test.ts"],
env: {
jest: true,
},
extends: "@exercism/eslint-config-typescript/maintainers",
rules: {
"@typescript-eslint/semi": 0,
},
},
// Student provided tests
{
files: ["custom.test.ts"],
env: {
jest: true,
},
extends: "@exercism/eslint-config-typescript",
},
// Exercism provided files
{
files: [".meta/proof.ci.ts", ".meta/exemplar.ts", "*.test.ts"],
excludedFiles: ["custom.test.ts"],
extends: "@exercism/eslint-config-typescript/maintainers",
},
],
};

View File

@@ -0,0 +1,12 @@
{
"blurb": "Randomly generate Dungeons & Dragons characters.",
"authors": ["JoshiRaez", "SleeplessByte"],
"contributors": [],
"files": {
"solution": ["dnd-character.ts"],
"test": ["dnd-character.test.ts"],
"example": [".meta/proof.ci.ts"]
},
"source": "Simon Shine, Erik Schierboom",
"source_url": "https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945"
}

View File

@@ -0,0 +1 @@
{"track":"typescript","exercise":"dnd-character","id":"3024ea9475214598a55ba78480591f66","url":"https://exercism.org/tracks/typescript/exercises/dnd-character","handle":"briemens","is_requester":true,"auto_approve":false}

View File

@@ -0,0 +1,44 @@
# Help
## Running the tests
Execute the tests with:
```bash
$ yarn test
```
## Skipped tests
In the test suites all tests but the first have been skipped.
Once you get a test passing, you can enable the next one by changing `xit` to
`it`.
## Submitting your solution
You can submit your solution using the `exercism submit dnd-character.ts` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [TypeScript track's documentation](https://exercism.org/docs/tracks/typescript)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [TypeScript QuickStart](https://www.typescriptlang.org/docs/handbook/release-notes/overview.html)
- [ECMAScript 2015 Language Specification](https://www.ecma-international.org/wp-content/uploads/ECMA-262_6th_edition_june_2015.pdf) (pdf)
- [Mozilla JavaScript Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference)
- [/r/typescript](https://www.reddit.com/r/typescript) is the TypeScript subreddit.
- [StackOverflow](https://stackoverflow.com/questions/tagged/typescript) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

View File

@@ -0,0 +1,49 @@
# D&D Character
Welcome to D&D Character on Exercism's TypeScript Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
For a game of [Dungeons & Dragons][dnd], each player starts by generating a
character they can play with. This character has, among other things, six
abilities; strength, dexterity, constitution, intelligence, wisdom and
charisma. These six abilities have scores that are determined randomly. You
do this by rolling four 6-sided dice and record the sum of the largest three
dice. You do this six times, once for each ability.
Your character's initial hitpoints are 10 + your character's constitution
modifier. You find your character's constitution modifier by subtracting 10
from your character's constitution, divide by 2 and round down.
Write a random character generator that follows the rules above.
For example, the six throws of four dice may look like:
- 5, 3, 1, 6: You discard the 1 and sum 5 + 3 + 6 = 14, which you assign to strength.
- 3, 2, 5, 3: You discard the 2 and sum 3 + 5 + 3 = 11, which you assign to dexterity.
- 1, 1, 1, 1: You discard the 1 and sum 1 + 1 + 1 = 3, which you assign to constitution.
- 2, 1, 6, 6: You discard the 1 and sum 2 + 6 + 6 = 14, which you assign to intelligence.
- 3, 5, 3, 4: You discard the 3 and sum 5 + 3 + 4 = 12, which you assign to wisdom.
- 6, 6, 6, 6: You discard the 6 and sum 6 + 6 + 6 = 18, which you assign to charisma.
Because constitution is 3, the constitution modifier is -4 and the hitpoints are 6.
## Notes
Most programming languages feature (pseudo-)random generators, but few
programming languages are designed to roll dice. One such language is [Troll].
[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons
[troll]: http://hjemmesider.diku.dk/~torbenm/Troll/
## Source
### Created by
- @JoshiRaez
- @SleeplessByte
### Based on
Simon Shine, Erik Schierboom - https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945

View File

@@ -0,0 +1,4 @@
module.exports = {
presets: ['@exercism/babel-preset-typescript'],
plugins: [],
}

View File

@@ -0,0 +1,110 @@
/* eslint-disable @typescript-eslint/semi */
import { DnDCharacter } from "./dnd-character";
describe("Ability modifier", () => {
it("Ability modifier for score 3 is -4", () => {
expect(DnDCharacter.getModifierFor(3)).toEqual(-4);
});
it("Ability modifier for score 4 is -3", () => {
expect(DnDCharacter.getModifierFor(4)).toEqual(-3);
});
it("Ability modifier for score 5 is -3", () => {
expect(DnDCharacter.getModifierFor(5)).toEqual(-3);
});
it("Ability modifier for score 6 is -2", () => {
expect(DnDCharacter.getModifierFor(6)).toEqual(-2);
});
it("Ability modifier for score 7 is -2", () => {
expect(DnDCharacter.getModifierFor(7)).toEqual(-2);
});
it("Ability modifier for score 8 is -1", () => {
expect(DnDCharacter.getModifierFor(8)).toEqual(-1);
});
it("Ability modifier for score 9 is -1", () => {
expect(DnDCharacter.getModifierFor(9)).toEqual(-1);
});
it("Ability modifier for score 10 is 0", () => {
expect(DnDCharacter.getModifierFor(10)).toEqual(0);
});
it("Ability modifier for score 11 is 0", () => {
expect(DnDCharacter.getModifierFor(11)).toEqual(0);
});
it("Ability modifier for score 12 is 1", () => {
expect(DnDCharacter.getModifierFor(12)).toEqual(1);
});
it("Ability modifier for score 13 is 1", () => {
expect(DnDCharacter.getModifierFor(13)).toEqual(1);
});
it("Ability modifier for score 14 is 2", () => {
expect(DnDCharacter.getModifierFor(14)).toEqual(2);
});
it("Ability modifier for score 15 is 2", () => {
expect(DnDCharacter.getModifierFor(15)).toEqual(2);
});
it("Ability modifier for score 16 is 3", () => {
expect(DnDCharacter.getModifierFor(16)).toEqual(3);
});
it("Ability modifier for score 17 is 3", () => {
expect(DnDCharacter.getModifierFor(17)).toEqual(3);
});
it("Ability modifier for score 18 is 4", () => {
expect(DnDCharacter.getModifierFor(18)).toEqual(4);
});
});
describe("Ability generator", () => {
it("Random ability is within range", () => {
const abilityScore = DnDCharacter.generateAbilityScore();
expect(abilityScore).toBeGreaterThanOrEqual(3);
expect(abilityScore).toBeLessThanOrEqual(18);
});
});
describe("Character creation", () => {
it("Random character is valid", () => {
const character = new DnDCharacter();
expect(character.hitpoints).toEqual(
10 + DnDCharacter.getModifierFor(character.constitution)
);
expect(character.strength).toBeGreaterThanOrEqual(3);
expect(character.strength).toBeLessThanOrEqual(18);
expect(character.dexterity).toBeGreaterThanOrEqual(3);
expect(character.dexterity).toBeLessThanOrEqual(18);
expect(character.constitution).toBeGreaterThanOrEqual(3);
expect(character.constitution).toBeLessThanOrEqual(18);
expect(character.intelligence).toBeGreaterThanOrEqual(3);
expect(character.intelligence).toBeLessThanOrEqual(18);
expect(character.wisdom).toBeGreaterThanOrEqual(3);
expect(character.wisdom).toBeLessThanOrEqual(18);
expect(character.charisma).toBeGreaterThanOrEqual(3);
expect(character.charisma).toBeLessThanOrEqual(18);
});
it("Each ability is only calculated once", () => {
const character = new DnDCharacter();
expect(character.strength === character.strength).toBeTruthy();
});
});

View File

@@ -0,0 +1,47 @@
export class DnDCharacter {
private _strength: number;
private _dexterity: number;
private _constituion: number;
private _intelligence: number;
private _wisdom: number;
private _charisma: number;
constructor() {
this._strength = DnDCharacter.generateAbilityScore();
this._dexterity = DnDCharacter.generateAbilityScore();
this._constituion = DnDCharacter.generateAbilityScore();
this._intelligence = DnDCharacter.generateAbilityScore();
this._wisdom = DnDCharacter.generateAbilityScore();
this._charisma = DnDCharacter.generateAbilityScore();
}
public static generateAbilityScore(): number {
return Math.floor(3 + Math.random() * (18 - 3));
}
public static getModifierFor(abilityValue: number): number {
return Math.floor((abilityValue - 10) / 2);
}
get hitpoints(): number {
return 10 + DnDCharacter.getModifierFor(this._constituion);
}
get strength(): number {
return this._strength;
}
get dexterity(): number {
return this._dexterity;
}
get constitution(): number {
return this._constituion;
}
get intelligence(): number {
return this._intelligence;
}
get wisdom(): number {
return this._wisdom;
}
get charisma(): number {
return this._charisma;
}
}

View File

@@ -0,0 +1,19 @@
module.exports = {
verbose: true,
projects: ['<rootDir>'],
testMatch: [
'**/__tests__/**/*.[jt]s?(x)',
'**/test/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[jt]s?(x)',
],
testPathIgnorePatterns: [
'/(?:production_)?node_modules/',
'.d.ts$',
'<rootDir>/test/fixtures',
'<rootDir>/test/helpers',
'__mocks__',
],
transform: {
'^.+\\.[jt]sx?$': 'babel-jest',
},
}

15996
typescript/dnd-character/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
{
"name": "@exercism/typescript-dnd-character",
"version": "1.0.0",
"description": "Exercism practice exercise on dnd-character",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/exercism/typescript"
},
"type": "module",
"engines": {
"node": "^14.13.1 || >=16.0.0"
},
"devDependencies": {
"@exercism/babel-preset-typescript": "^0.1.0",
"@exercism/eslint-config-typescript": "^0.4.1",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.24",
"babel-jest": "^27.5.1",
"core-js": "^3.21.0",
"eslint": "^8.9.0",
"jest": "^27.5.1",
"typescript": "^4.5.4"
},
"scripts": {
"test": "yarn lint:types && jest --no-cache",
"lint": "yarn lint:types && yarn lint:ci",
"lint:types": "yarn tsc --noEmit -p .",
"lint:ci": "eslint . --ext .tsx,.ts"
}
}

View File

@@ -0,0 +1,28 @@
{
"display": "Configuration for Exercism TypeScript Exercises",
"compilerOptions": {
// Allows you to use the newest syntax, and have access to console.log
// https://www.typescriptlang.org/tsconfig#lib
"lib": ["ESNEXT", "dom"],
// Make sure typescript is configured to output ESM
// https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#how-can-i-make-my-typescript-project-output-esm
"module": "ES2020",
// Since this project is using babel, TypeScript may target something very
// high, and babel will make sure it runs on your local Node version.
// https://babeljs.io/docs/en/
"target": "ESNext", // ESLint doesn't support this yet: "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
// Because we'll be using babel: ensure that Babel can safely transpile
// files in the TypeScript project.
//
// https://babeljs.io/docs/en/babel-plugin-transform-typescript/#caveats
"isolatedModules": true
},
"include": ["*.ts", "*.tsx", ".meta/*.ts", ".meta/*.tsx"],
"exclude": ["node_modules"]
}