typing-game-cli 4.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Results.js CHANGED
@@ -2,13 +2,19 @@ import React from 'react';
2
2
  import { Text, Box } from 'ink';
3
3
  import { nanoid } from 'nanoid';
4
4
  import { format, parseISO } from 'date-fns';
5
- import { getResults, getSortedByString } from './helpers.js';
5
+ import { getBestResultCompactString, getResults, getSortedByString } from './helpers.js';
6
6
  import Menu from './Menu.js';
7
7
  export default function Results({
8
8
  sortBy,
9
- isShowAllHistory
9
+ isShowAllHistory,
10
+ isCompactFormat,
11
+ topN
10
12
  }) {
11
- return /*#__PURE__*/React.createElement(Box, {
13
+ return isCompactFormat ? /*#__PURE__*/React.createElement(Box, {
14
+ flexDirection: "column",
15
+ justifyContent: "center",
16
+ paddingX: 1
17
+ }, /*#__PURE__*/React.createElement(Text, null, ` ${getBestResultCompactString()}`), /*#__PURE__*/React.createElement(Menu, null)) : /*#__PURE__*/React.createElement(Box, {
12
18
  flexDirection: "column"
13
19
  }, /*#__PURE__*/React.createElement(Box, {
14
20
  flexDirection: "row",
@@ -22,7 +28,8 @@ export default function Results({
22
28
  flexDirection: "column"
23
29
  }, getResults({
24
30
  sortBy: '-cpm',
25
- showAll: false
31
+ showAll: false,
32
+ topN
26
33
  }).map((result, i, array) => /*#__PURE__*/React.createElement(Box, {
27
34
  key: nanoid(),
28
35
  justifyContent: "center",
package/dist/app.js CHANGED
@@ -7,7 +7,7 @@ import Gradient from 'ink-gradient';
7
7
  import { proxy, useSnapshot } from 'valtio';
8
8
  import random from 'just-random';
9
9
  import { formatISO } from 'date-fns';
10
- import { getBorderColor, getDefaultSuite, getRobotBorderColor, getStatusVariant, getMessageOrPlaceholder, isFinished, isWordTyped, calculateWPM, getTypingWord, getRemainingPart, getWpmTextColor, calculateCPS, calculateCPM, getBestResult, getScoreTextColor, getCompetitionResult, registerResult, registerBestFrames, getBestFrames, getOpponentFrames } from './helpers.js';
10
+ import { getBorderColor, getDefaultSuite, getRobotBorderColor, getStatusVariant, getMessageOrPlaceholder, isFinished, isWordTyped, calculateWPM, getTypingWord, getRemainingPart, getWpmTextColor, calculateCPS, calculateCPM, getBestResult, getScoreTextColor, getCompetitionResult, registerResult, registerBestFrames, getBestFrames, getOpponentFrames, getSuiteByTopic } from './helpers.js';
11
11
  import { optionKeyColor } from './constants.js';
12
12
  import Results from './Results.js';
13
13
  import { config } from './config.js';
@@ -16,12 +16,13 @@ import { exitNow } from './cli.js';
16
16
  const currentTime = () => Date.now();
17
17
  const state = proxy({
18
18
  status: 'PAUSED',
19
+ topic: null,
19
20
  suite: getDefaultSuite(),
20
21
  source: null,
21
22
  firstPart: '',
22
23
  highlightedPart: '',
23
24
  erroredPart: '',
24
- highlighingColor: 'green',
25
+ highlightingColor: 'green',
25
26
  showOkCancelQuestion: false,
26
27
  gameOver: false,
27
28
  okCancelMessage: '',
@@ -53,14 +54,18 @@ const state = proxy({
53
54
  isTimerVisible: true,
54
55
  timerVisibilityCounter: 0,
55
56
  isAnimatingEnd: false,
56
- showGameResult: false
57
+ showGameResult: false,
58
+ topN: undefined
57
59
  });
58
60
  export default function App({
59
61
  robotLevel,
62
+ topic,
60
63
  displayResults = false,
61
64
  sortBy,
62
65
  isShowAllHistory,
63
- isCompetingAgainstBestResult
66
+ isCompactFormat,
67
+ isCompetingAgainstBestResult,
68
+ topN
64
69
  }) {
65
70
  const snap = useSnapshot(state);
66
71
  const {
@@ -76,7 +81,14 @@ export default function App({
76
81
  if (isCompetingAgainstBestResult) {
77
82
  state.isAgainstMyselft = true;
78
83
  }
79
- }, [displayResults, isCompetingAgainstBestResult]);
84
+ if (topN) {
85
+ state.topN = topN;
86
+ }
87
+ if (topic) {
88
+ state.topic = topic;
89
+ state.suite = getSuiteByTopic(topic);
90
+ }
91
+ }, [displayResults, isCompetingAgainstBestResult, topN, topic]);
80
92
  useInput((input, key) => {
81
93
  if (input === 'y') {
82
94
  const foundBestResult = getBestResult();
@@ -214,7 +226,9 @@ export default function App({
214
226
  if (snap.status === 'RESULTS') {
215
227
  return /*#__PURE__*/React.createElement(Results, {
216
228
  sortBy: sortBy,
217
- isShowAllHistory: isShowAllHistory
229
+ isShowAllHistory: isShowAllHistory,
230
+ isCompactFormat: isCompactFormat,
231
+ topN: topN
218
232
  });
219
233
  }
220
234
  return snap.status === 'PAUSED' ? /*#__PURE__*/React.createElement(Box, {
package/dist/cli.js CHANGED
@@ -24,7 +24,9 @@ const cli = meow(`
24
24
  --low Start a round with a robot having low typing speed.
25
25
  --display-results Show cpm and wpm results
26
26
  --sort-by Sort results by specified value (-cpm, cpm, -wpm, wpm, -date, date), Starting "-" indicates descending order, default is "-date"
27
- --all-hostory Show all history when displaying results (otherwise (default) display last 10 results respecting sorting parameter)
27
+ --all-history Show all history when displaying results (otherwise (default) display last 10 results respecting sorting parameter)
28
+ --topic Use sentences from works written by specified author
29
+ --top-n Display top n results in displaying results mode
28
30
 
29
31
  Short flags and aliases for options:
30
32
  --against-my-best: -b, --best, --my-best, --myself, --against-my-best-result
@@ -36,6 +38,8 @@ const cli = meow(`
36
38
  --sort-by -s
37
39
  --show-all-history: -a, --all, --all-history
38
40
  --clear-results: -c, --clear
41
+ --topic: --author
42
+ --top-n: --top
39
43
 
40
44
 
41
45
  Examples
@@ -47,11 +51,14 @@ const cli = meow(`
47
51
  $ typing-game-cli -m
48
52
  $ typing-game-cli --low
49
53
  $ typing-game-cli --display-results
54
+ $ typing-game-cli --display-results --top 5
50
55
  $ typing-game-cli -r
51
56
  $ typing-game-cli -r --sort-by="-wpm"
52
57
  $ typing-game-cli -r -s="wpm"
53
58
  $ typing-game-cli -r -s="-wpm" --all-history
54
59
  $ typing-game-cli -r -s="-wpm" -a
60
+ $ typing-game-cli --topic mark-twain
61
+ $ typing-game-cli --author ambrose-bierce
55
62
  `, {
56
63
  importMeta: import.meta,
57
64
  flags: {
@@ -99,6 +106,19 @@ const cli = meow(`
99
106
  shortFlag: 'b',
100
107
  aliases: ['best', 'myBest', 'myself', 'againstMyBestResult'],
101
108
  default: false
109
+ },
110
+ compactResult: {
111
+ type: 'boolean',
112
+ aliases: ['cmpc'],
113
+ default: false
114
+ },
115
+ topN: {
116
+ type: 'number',
117
+ aliases: ['top']
118
+ },
119
+ topic: {
120
+ type: 'string',
121
+ aliases: ['author']
102
122
  }
103
123
  }
104
124
  });
@@ -113,13 +133,19 @@ const {
113
133
  displayResults,
114
134
  sortBy,
115
135
  showAllHistory,
116
- againstMyBest
136
+ againstMyBest,
137
+ compactResult,
138
+ topN,
139
+ topic
117
140
  } = cli.flags;
118
- render( /*#__PURE__*/React.createElement(App, {
141
+ render(/*#__PURE__*/React.createElement(App, {
119
142
  robotLevel: robotLevel,
120
143
  displayResults: displayResults,
121
144
  sortBy: sortBy,
122
145
  isShowAllHistory: showAllHistory,
123
- isCompetingAgainstBestResult: againstMyBest
146
+ isCompetingAgainstBestResult: againstMyBest,
147
+ isCompactFormat: compactResult,
148
+ topN: topN,
149
+ topic: topic
124
150
  }));
125
151
  export { exitNow };
package/dist/helpers.js CHANGED
@@ -3,8 +3,9 @@ import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { fdir as Fdir } from 'fdir';
5
5
  import random from 'just-random';
6
+ import compose from 'just-compose';
6
7
  import sortBy from 'just-sort-by';
7
- import { formatISO, isValid, parseISO } from 'date-fns';
8
+ import { format, formatISO, isValid, parseISO } from 'date-fns';
8
9
  import Config from './config.js';
9
10
  import { frames } from './robotFrames.js';
10
11
  const __filename = fileURLToPath(import.meta.url);
@@ -15,6 +16,13 @@ const sourcesPath = path.join(__dirname, 'sentences');
15
16
  const isWon = value => value === won;
16
17
  const isLost = value => value === lost;
17
18
  const files = new Fdir().filter((path, _isDirectory) => path.endsWith('.json')).withFullPaths().crawl(sourcesPath).sync();
19
+ const getFilesByTopic = topic => {
20
+ return new Fdir().filter((path, _isDirectory) => path.endsWith('.json')).withFullPaths().crawl(path.join(sourcesPath, topic)).sync();
21
+ };
22
+ const readFile = file => fs.readFileSync(file, 'utf8');
23
+ const getSuiteByTopic = topic => {
24
+ return compose(getFilesByTopic, random, readFile, JSON.parse)(topic);
25
+ };
18
26
  const getDefaultSuite = () => {
19
27
  return JSON.parse(fs.readFileSync(random(files), 'utf8'));
20
28
  };
@@ -109,7 +117,8 @@ const getRemainingPart = (source, typed, hasErroredPart = false) => {
109
117
  };
110
118
  const getResults = ({
111
119
  sortBy: sortByValue = '-wpm',
112
- showAll = false
120
+ showAll = false,
121
+ topN
113
122
  }) => {
114
123
  const config = new Config();
115
124
  const data = config.get();
@@ -140,7 +149,7 @@ const getResults = ({
140
149
  return -parseISO(item.date);
141
150
  });
142
151
  if (!showAll) {
143
- return result.slice(0, 10);
152
+ return result.slice(0, topN === undefined ? 10 : topN);
144
153
  }
145
154
  return result;
146
155
  };
@@ -159,6 +168,13 @@ const getBestResult = () => {
159
168
  if (targetItems.length === 0) return null;
160
169
  return sortBy(targetItems, item => -item.value.cpm)[0];
161
170
  };
171
+ const getBestResultCompactString = () => {
172
+ const result = getBestResult();
173
+ if (!result) {
174
+ return 'There is no data, please run some rounds to collect stats.';
175
+ }
176
+ return `Date: ${format(parseISO(result.date), 'MM/dd/yyyy HH:mm')}; wpm: ${result.value.wpm}; cpm: ${result.value.cpm}.`;
177
+ };
162
178
  const getResultByWordCount = ({
163
179
  wordCount
164
180
  }) => {
@@ -203,4 +219,4 @@ const registerBestFrames = (config, frames) => {
203
219
  bestFrames: frames
204
220
  });
205
221
  };
206
- export { getDefaultSuite, getStatusVariant, getWpmTextColor, getScoreTextColor, getMessage, getMessageOrPlaceholder, getBorderColor, getRobotBorderColor, getIntervalMs, isFinished, isWordTyped, calculateWPM, calculateCPS, calculateCPM, getCompetitionResult, getTypingWord, getRemainingPart, getResults, getBestResult, getBestFrames, getOpponentFrames, getResultByWordCount, getBestWpmResult, getSortedByString, getWordCount, registerResult, registerBestFrames };
222
+ export { getDefaultSuite, getStatusVariant, getWpmTextColor, getScoreTextColor, getMessage, getMessageOrPlaceholder, getBorderColor, getRobotBorderColor, getIntervalMs, isFinished, isWordTyped, calculateWPM, calculateCPS, calculateCPM, getCompetitionResult, getTypingWord, getRemainingPart, getResults, getBestResult, getBestResultCompactString, getBestFrames, getOpponentFrames, getResultByWordCount, getBestWpmResult, getSortedByString, getWordCount, getSuiteByTopic, registerResult, registerBestFrames };
@@ -0,0 +1,16 @@
1
+ {
2
+ "sentences": [
3
+ "For several days, in snow and rain, General Schofield's little army had crouched in its hastily constructed defenses at Columbia, Tennessee. It had retreated in hot haste from Pulaski, thirty miles to the south, arriving just in time to foil Hood, who, marching from Florence, Alabama, by another road, with a force of more than double our strength, had hoped to intercept us. Had he succeeded, he would indubitably have bagged the whole bunch of us.",
4
+ "As it was, he simply took position in front of us and gave us plenty of employment, but did not attack; he knew a trick worth two of that. Duck River was directly in our rear; I suppose both our flanks rested on it. The town was between them. One night--that of November 27, 1864--we pulled up stakes and crossed to the north bank to continue our retreat to Nashville, where Thomas and safety lay - such safety as is known in war.",
5
+ "It was high time too, for before noon of the next day Forrest's cavalry forded the river a few miles above us and began pushing back our own horse toward Spring Hill, ten miles in our rear, on our only road. Why our infantry was not immediately put in motion toward the threatened point, so vital to our safety, General Schofield could have told better than I. Howbeit, we lay there inactive all day. The next morning - a bright and beautiful one - the brigade of Colonel P. Sidney Post was thrown out, up the river four or five miles, to see what it could see.",
6
+ "What it saw was Hood's head-of-column coming over on a pontoon bridge, and a right pretty spectacle it would have been to one whom it did not concern. It concerned us rather keenly. As a member of Colonel Post's staff, I was naturally favored with a good view of the performance. We formed in line of battle at a distance of perhaps a half-mile from the bridge-head, but that unending column of gray and steel gave us no more attention than if we had been a crowd of farmer-folk. Why should it?",
7
+ "It had only to face to the left to be itself a line of battle. Meantime it had more urgent business on hand than brushing away a small brigade whose only offense was curiosity; it was making for Spring Hill with all its legs and wheels. Hour after hour we watched that unceasing flow of infantry and artillery toward the rear of our army. It was an unnerving spectacle, yet we never for a moment doubted that, acting on the intelligence supplied by our succession of couriers, our entire force was moving rapidly to the point of contact. The battle of Spring Hill was obviously decreed.",
8
+ "Obviously, too, our brigade of observation would be among the last to have a hand in it. The thought annoyed us, made us restless and resentful. Our mounted men rode forward and back behind the line, nervous and distressed; the men in the ranks sought relief in frequent changes of posture, in shifting their weight from one leg to the other, in needless inspection of their weapons and in that unfailing resource of the discontented soldier, audible damning of those in the saddles of authority. But never for more than a moment at a time did anyone remove his eyes from that fascinating and portentous pageant.",
9
+ "Toward evening we were recalled, to learn that of our five divisions of infantry, with their batteries, numbering twenty-three thousand men, only one--Stanley's, four thousand weak--had been sent to Spring Hill to meet that formidable movement of Hood's three veteran corps! Why Stanley was not immediately effaced is still a matter of controversy. Hood, who was early on the ground, declared that he gave the needful orders and tried vainly to enforce them; Cheatham, in command of his leading corps, declared that he did not.",
10
+ "Doubtless the dispute is still being carried on between these chieftains from their beds of asphodel and moly in Elysium. So much is certain: Stanley drove away Forrest and successfully held the junction of the roads against Cleburne's division, the only infantry that attacked him. That night the entire Confederate army lay within a half mile of our road, while we all sneaked by, infantry, artillery, and trains. The enemy's camp-fires shone redly - miles of them - seeming only a stone's throw from our hurrying column.",
11
+ "His men were plainly visible about them, cooking their suppers - a sight so incredible that many of our own, thinking them friends, strayed over to them and did not return. At intervals of a few hundred yards we passed dim figures on horseback by the roadside, enjoining silence. Needless precaution; we could not have spoken if we had tried, for our hearts were in our throats. But fools are God's peculiar care, and one of his protective methods is the stupidity of other fools. By daybreak our last man and last wagon had passed the fateful spot unchallenged, and our first were entering Franklin, ten miles away.",
12
+ "Despite spirited cavalry attacks on trains and rear-guard, all were in Franklin by noon and such of the men as could be kept awake were throwing up a slight line of defense, inclosing the town. Franklin lies - or at that time did lie; I know not what exploration might now disclose - on the south bank of a small river, the Harpeth by name. For two miles southward was a nearly flat, open plain, extending to a range of low hills through which passed the turnpike by which we had come.",
13
+ "From some bluffs on the precipitous north bank of the river was a commanding overlook of all this open ground, which, although more than a mile away, seemed almost at one's feet. On this elevated ground the wagon-train had been parked and General Schofield had stationed himself - the former for security, the latter for outlook. Both were guarded by General Wood's infantry division, of which my brigade was a part. \"We are in beautiful luck,\" said a member of the division staff. With some prevision of what was to come and a lively recollection of the nervous strain of helpless observation, I did not think it luck."
14
+ ],
15
+ "tags": ["ambrose-bierce", "what-occured-at-franklin"]
16
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "sentences": [
3
+ "Last night I dreamt I went to Manderley again. It seemed to me I stood by the iron gate leading to the drive, and for a while I could not enter, for the way was barred to me. There was a padlock and a chain upon the gate. I called in my dream to the lodge-keeper, and had no answer, and peering closer through the rusted spokes of the gate I saw that the lodge was uninhabited.",
4
+ "There was a padlock and a chain upon the gate. I called in my dream to the lodge-keeper, and had no answer, and peering closer through the rusted spokes of the gate I saw that the lodge was uninhabited. No smoke came from the chimney, and the little lattice windows gaped forlorn. Then, like all dreamers, I was possessed of a sudden with supernatural powers and passed like a spirit through the barrier before me.",
5
+ "The drive wound away in front of me, twisting and turning as it had always done, but as I advanced I was aware that a change had come upon it; it was narrow and unkept, not the drive that we had known. At first I was puzzled and did not understand, and it was only when I bent my head to avoid the low swinging branch of a tree that I realised what had happened.",
6
+ "Nature had come into her own again and, little by, little, in her stealthy, insidious way had encroached upon the drive with long tenacious fingers. The woods, always a menace even in the past, had triumphed in the end. They crwoded, dark and uncrontrolled, to the borders of the drive. The beeches with white. naked limbs leant close to one another, their branches intermingled in a strange embrace, making a vault above my head like the archway of a church.",
7
+ "And there were other trees as well, trees that I did not recognise, squat oaks and tortured elms that straggled cheek by jowl with the beeches, and had trust themselves out of the quiet earth, along with monster shrubs amd plants, none of which I remembered. The drive was a ribbon now, a thread of its former self, with gravel surface gone, and choked with grass and moss. The trees had thrown out low branches, making an impediment to progress; the gnarled roots looked like skeleton claws.",
8
+ "Scattered here and again amongs his jungle growth I would recognise shrubs that had been land-marks in our time, things of culture and of gracem hydrangeas whose blue heads had been famous. No hand had checked their progress, and they had gone native now, rearing to monster height without a bloom, back and ugly as the nameless parasites that grew beside them.",
9
+ "On and on. now east, now west, would the poor thread that once had been out drive. Sometimes I thought it lost, but it appeared again, beneath a fallen tree perhaps or struggling on the other side of a muddied ditch created by the winter rains. I had not thought the way so long. Surely the miles had multiplied, even as the trees had done, and this path led but to a labirynth, some choked wilderness, and not to the house at all."
10
+ ],
11
+ "tags": ["daphne-du-maurier", "maurier"]
12
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typing-game-cli",
3
3
  "description": "Command line game to practice your typing speed by competing against typer-robot or against your best result",
4
- "version": "4.0.0",
4
+ "version": "6.0.0",
5
5
  "homepage": "https://github.com/akgondber/typing-game-cli",
6
6
  "repository": "akgondber/typing-game-cli",
7
7
  "author": "Rushan Alyautdinov <akgondber@gmail.com>",
@@ -19,7 +19,7 @@
19
19
  "scripts": {
20
20
  "build": "babel --out-dir=dist source --copy-files",
21
21
  "dev": "babel --out-dir=dist --watch source",
22
- "test": "prettier --check . && xo && ava",
22
+ "test": "prettier --check . && xo && loadr -- ava",
23
23
  "justtest": "ava --serial",
24
24
  "lint": "xo",
25
25
  "go": "node dist/cli.js",
@@ -50,13 +50,14 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@babel/cli": "^7.22.5",
53
- "@babel/preset-react": "^7.22.5",
53
+ "@babel/preset-react": "^7.25.9",
54
54
  "ava": "^6.1.2",
55
55
  "eslint-config-xo-react": "^0.27.0",
56
56
  "eslint-plugin-react": "^7.34.1",
57
57
  "eslint-plugin-react-hooks": "^4.6.0",
58
58
  "import-jsx": "^5.0.0",
59
59
  "ink-testing-library": "^3.0.0",
60
+ "loadr": "^0.1.1",
60
61
  "prettier": "^3.2.5",
61
62
  "xo": "^0.58.0"
62
63
  },
@@ -66,7 +67,8 @@
66
67
  },
67
68
  "nodeArguments": [
68
69
  "--loader=import-jsx"
69
- ]
70
+ ],
71
+ "timeout": "20s"
70
72
  },
71
73
  "xo": {
72
74
  "extends": "xo-react",
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # typing-game-cli [![NPM version][npm-image]][npm-url]
2
2
 
3
- > Command line game to practice your typing speed by competing against typer-robot or against your best result.
3
+ > Command-line game to practice your typing speed by competing against typer-robot or against your best result.
4
4
 
5
5
  ## Install
6
6
 
@@ -30,6 +30,9 @@ $ npm install --global typing-game-cli
30
30
  --display-results Show cpm and wpm results
31
31
  --sort-by Sort results by specified value (-cpm, cpm, -wpm, wpm, -date, date), Starting "-" indicates descending order, default is "-date"
32
32
  --all-hostory Show all history when displaying results (otherwise (default) display last 10 results respecting sorting parameter)
33
+ --compact-result Display top result in compact format
34
+ --topic Use sentences from works written by specified author
35
+ --top-n Display top n results when `--display-results` is being used
33
36
 
34
37
  Short flags and aliases for options:
35
38
  --against-my-best: -b, --best, --my-best, --myself, --against-my-best-result
@@ -41,6 +44,9 @@ $ npm install --global typing-game-cli
41
44
  --sort-by -s
42
45
  --show-all-history: -a, --all, --all-history
43
46
  --clear-results: -c, --clear
47
+ --compact-result --cmpc
48
+ --topic --author
49
+ --top-n --top
44
50
 
45
51
 
46
52
  Examples
@@ -52,11 +58,14 @@ $ npm install --global typing-game-cli
52
58
  $ typing-game-cli -m
53
59
  $ typing-game-cli --low
54
60
  $ typing-game-cli --display-results
61
+ $ typing-game-cli --display-results --top 3
55
62
  $ typing-game-cli -r
56
63
  $ typing-game-cli -r --sort-by="-wpm"
57
64
  $ typing-game-cli -r -s="wpm"
58
65
  $ typing-game-cli -r -s="-wpm" --all-history
59
66
  $ typing-game-cli -r -s="-wpm" -a
67
+ $ typing-game-cli --topic ambrose-bierce
68
+ $ typing-game-cli --author mark-twain
60
69
  ```
61
70
 
62
71
  ## Demo
@@ -65,7 +74,7 @@ $ npm install --global typing-game-cli
65
74
 
66
75
  ## Screenshots
67
76
 
68
- ### Competition agains fast robot
77
+ ### Competition against fast robot
69
78
 
70
79
  ```
71
80
  $ typing-game-cli --fast
@@ -73,7 +82,7 @@ $ typing-game-cli --fast
73
82
 
74
83
  ![](media/competition-against-fast-robot.png)
75
84
 
76
- ### Competition agains best result
85
+ ### Competition against best result
77
86
 
78
87
  ```
79
88
  $ typing-game-cli --my-best
@@ -91,6 +100,10 @@ $ tgc -b
91
100
 
92
101
  ![](media/competition-against-best-result-2.png)
93
102
 
103
+ #### Example - Display top n results
104
+
105
+ ![](media/display-top-n-results.png)
106
+
94
107
  ## License
95
108
 
96
109
  MIT © [Rushan Alyautdinov](https://github.com/akgondber)