Skip to content

Commit 9c58163

Browse files
committed
refactoring language-related code for better practice
1 parent 1057216 commit 9c58163

File tree

13 files changed

+365
-81
lines changed

13 files changed

+365
-81
lines changed

assets/languages/eng.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
/* Used to create an instance of the language
4+
* interpreter defined in this file.
5+
*/
6+
const createLanguageInterpreter = () => {
7+
return new EnglishInterpreter();
8+
}
9+
10+
/*
11+
*
12+
*/
13+
class EnglishInterpreter {
14+
constructor() {
15+
// Nothing needs to be done!
16+
}
17+
18+
/* Takes a character/letter from this language's
19+
* character set, and returns the sequence of key-
20+
* board presses required to match that character.
21+
* May throw an exception if the character argument
22+
* is not from this language.
23+
*/
24+
key2seq(key) {
25+
return key;
26+
}
27+
28+
/* Returns a safe copy of an iterable collection
29+
* containing all keys from this language.
30+
*/
31+
allKeys() {
32+
return 'abcdefghijklmnopqrstuvwxyz';
33+
}
34+
}

assets/languages/jpn_h.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
3+
/* Used to create an instance of the language
4+
* interpreter defined in this file.
5+
*/
6+
const createLanguageInterpreter = () => {
7+
return new JapaneseHiraganaInterpreter();
8+
}
9+
10+
/*
11+
*
12+
*/
13+
class JapaneseHiraganaInterpreter {
14+
constructor() {
15+
// Setup Japanese romanization:
16+
let jpn_r = [];
17+
for (let cons of ['', ...'kstnhmrgzdbp'])
18+
for (let vow of 'aiueo')
19+
jpn_r.push(cons + vow);
20+
jpn_r[11] = 'shi';
21+
jpn_r[16] = 'chi';
22+
jpn_r[17] = 'tsu';
23+
jpn_r[27] = 'fu';
24+
jpn_r[46] = 'ji';
25+
jpn_r[51] = 'ji';
26+
jpn_r[52] = 'zu';
27+
jpn_r.push('ya', 'yu', 'yo', 'wa', 'wo', 'n');
28+
29+
this.k2s = new Map();
30+
31+
// Setup Japanese Hiragana:
32+
[...'あいうえおかきくけこさしすせそ',
33+
...'たちつてとなにぬねのはひふへほ',
34+
...'まみむめもらりるれろがぎぐげご',
35+
...'ざじずぜぞだぢづでどばびぶべぼ',
36+
...'ぱぴぷぺぽやゆよわをん',
37+
].forEach((c, i) => {
38+
k2s.set(c) = jpn_r[i];
39+
});
40+
}
41+
42+
/* Takes a character/letter from this language's
43+
* character set, and returns the sequence of key-
44+
* board presses required to match that character.
45+
* May throw an exception if the character argument
46+
* is not from this language.
47+
*/
48+
key2seq(key) {
49+
let seq = '';
50+
51+
52+
53+
return seq;
54+
}
55+
56+
/* Returns a safe copy of an iterable collection
57+
* containing all keys from this language.
58+
*/
59+
allKeys() {
60+
return null;
61+
}
62+
}

assets/languages/jpn_k.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict';
2+
3+
/* Used to create an instance of the language
4+
* interpreter defined in this file.
5+
*/
6+
const createLanguageInterpreter = () => {
7+
return new JapaneseKatakanaInterpreter();
8+
}
9+
10+
/*
11+
*
12+
*/
13+
class JapaneseKatakanaInterpreter {
14+
constructor() {
15+
// Setup Japanese romanization:
16+
let jpn_r = [];
17+
for (let cons of ['', ...'kstnhmrgzdbp'])
18+
for (let vow of 'aiueo')
19+
jpn_r.push(cons + vow);
20+
jpn_r[11] = 'shi';
21+
jpn_r[16] = 'chi';
22+
jpn_r[17] = 'tsu';
23+
jpn_r[27] = 'fu';
24+
jpn_r[46] = 'ji';
25+
jpn_r[51] = 'ji';
26+
jpn_r[52] = 'zu';
27+
jpn_r.push('ya', 'yu', 'yo', 'wa', 'wo', 'n');
28+
29+
this.k2s = new Map();
30+
31+
// Setup Japanese Katakana:
32+
[...'アイウエオカキクケコサシスセソ',
33+
...'タチツテトナニヌネノハヒフヘホ',
34+
...'マミムメモラリルレロガギグゲゴ',
35+
...'ザジズゼゾダヂヅデドバビブベボ',
36+
...'パピプペポヤユヨワヲン',
37+
].forEach((c, i) => {
38+
this.k2s.set(c) = jpn_r[i];
39+
});
40+
}
41+
42+
/* Takes a character/letter from this language's
43+
* character set, and returns the sequence of key-
44+
* board presses required to match that character.
45+
* May throw an exception if the character argument
46+
* is not from this language.
47+
*/
48+
key2seq(key) {
49+
return this.k2s.get(key);
50+
}
51+
52+
/* Returns a safe copy of an iterable collection
53+
* containing all keys from this language.
54+
*/
55+
allKeys() {
56+
return null;
57+
}
58+
}

assets/languages/kor_kbd.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
/* Used to create an instance of the language
4+
* interpreter defined in this file.
5+
*/
6+
const createLanguageInterpreter = () => {
7+
return new KoreanKeyboardInterpreter();
8+
}
9+
10+
/*
11+
*
12+
*/
13+
class KoreanKeyboardInterpreter {
14+
constructor() {
15+
16+
}
17+
18+
/* Takes a character/letter from this language's
19+
* character set, and returns the sequence of key-
20+
* board presses required to match that character.
21+
* May throw an exception if the character argument
22+
* is not from this language.
23+
*/
24+
key2seq(key) {
25+
let seq = '';
26+
27+
28+
29+
return seq;
30+
}
31+
32+
/* Returns a safe copy of an iterable collection
33+
* containing all keys from this language.
34+
*/
35+
allKeys() {
36+
return null;
37+
}
38+
}

assets/languages/kor_rmn.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
/* Used to create an instance of the language
4+
* interpreter defined in this file.
5+
*/
6+
const createLanguageInterpreter = () => {
7+
return new KoreanRomanizationInterpreter();
8+
}
9+
10+
/*
11+
*
12+
*/
13+
class KoreanRomanizationInterpreter {
14+
constructor() {
15+
16+
}
17+
18+
/* Takes a character/letter from this language's
19+
* character set, and returns the sequence of key-
20+
* board presses required to match that character.
21+
* May throw an exception if the character argument
22+
* is not from this language.
23+
*/
24+
key2seq(key) {
25+
let seq = '';
26+
27+
28+
29+
return seq;
30+
}
31+
32+
/* Returns a safe copy of an iterable collection
33+
* containing all keys from this language.
34+
*/
35+
allKeys() {
36+
return null;
37+
}
38+
}

index.html

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,28 @@
2222
type='text/css'
2323
href='style.css'>
2424
</style>
25+
26+
<!-- List of language filenames (no spaces): -->
27+
<script> const languageSourceFileNames = [
28+
'eng', 'jpn_h', 'jpn_k', 'kor'
29+
]; </script>
30+
<!-- Variable Language: -->
31+
<link rel='stylesheet'
32+
type='text/css'
33+
id='languageSource'>
34+
2535
<!-- List of color scheme filenames (no spaces): -->
26-
<script>
27-
const csFileNames = [
28-
'dark_theme_nw', 'sheep',
29-
];
30-
</script>
36+
<script> const coloringSourceFileNames = [
37+
'dark_theme_nw', 'sheep',
38+
]; </script>
3139
<!-- Variable Color Scheme: -->
3240
<link rel='stylesheet'
3341
type='text/css'
34-
href='assets/colors/dark_theme_nw.css'
35-
id='coloring'>
42+
id='coloringSource'>
3643
</head>
37-
44+
45+
46+
3847
<body style='margin:0px;'>
3948
<div class='background'></div>
4049

@@ -56,4 +65,7 @@
5665
const game = new Game();
5766
</script>
5867
</body>
68+
69+
70+
5971
<html>

source/game.js

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@ function weightedChoice(weights) {
7575
*
7676
*
7777
* TODO:
78-
* work on tutorial pane.
78+
* change populations implementation to be separate class:
79+
* array of arrays of keys. outer array holds pool of keys
80+
* that have been spawned <outer-index> times. Initially all in
81+
* outer entry #zero, which is shuffled once on start. When spawned,
82+
* shuffled into next outer-entry at random spot. When spawning,
83+
* go through each key in order until one is found that can spawn there.
84+
*
85+
* fix the broken progress/difficulty bar (broken because of cs selectors)
7986
* fix bugs with the new backtracking.
8087
*
8188
* make game runner_catch and gameover sounds.
@@ -193,18 +200,15 @@ class Game {
193200
this.restartButton.blur();
194201

195202
// Apply any restart-only settings changes:
196-
this.language = new Map(Object.entries(languages[
197-
document.getElementById('langSelect').value]
198-
));
203+
document.getElementById('languageSource').href =
204+
'assets/languages/' + langSel.value + '.js';
205+
this.language = createLanguageInterpreter();
199206
this.speed = Object.assign({}, Game.speeds[
200207
document.getElementById('speedSelect').value]
201208
);
202209

203210
// Reset all display-key populations:
204-
this.populations = new Map();
205-
for (const key of this.language.keys()) {
206-
this.populations.set(key, 0);
207-
}
211+
this.populations = new Populations(this.language.allKeys());
208212
this.targets = [];
209213
this.corrupted = [];
210214
this.heat = 0;
@@ -318,11 +322,13 @@ class Game {
318322
const weights = new Map();
319323
const lowest = Math.min(...this.populations.values());
320324

325+
// TODO: see note for this class.
321326
const neighbors = this.adjacent(pos, 2);
322-
this.language.forEach((val, key, map) => {
323-
if (!neighbors.some((nbTile) =>
324-
(nbTile.seq.includes(val) || val.includes(nbTile.seq))
325-
)) {
327+
this.language.allKeys().forEach((key) => {
328+
if (!neighbors.some((nbTile) => {
329+
let seq = this.language.key2seq(key);
330+
return (nbTile.seq.includes(seq) || seq.includes(nbTile.seq));
331+
})) {
326332
weights.set(key, 4 ** (lowest - this.populations.get(key)));
327333
}
328334
}, this);
@@ -331,7 +337,7 @@ class Game {
331337
this.populations.set(choice, this.populations.get(choice) + 1);
332338
const tile = this.tileAt(pos);
333339
tile.key = choice;
334-
tile.seq = this.language.get(choice);
340+
tile.seq = this.language.key2seq(choice);
335341

336342
// If corrupting a tile:
337343
} else {
@@ -438,9 +444,11 @@ class Game {
438444
return closest;
439445
}
440446

441-
/* TODO: this will need to somehow tell
442-
* which player triggered the event.
443-
* triggered by some incoming remote data package:
447+
/* Handles restart and pause key commands,
448+
* and delegates backtrack and move commands
449+
* to their corresponding player. Players
450+
* make their inputs unique through keyboard
451+
* toggles {CapsLock, NumLock, & ScrollLock}.
444452
*/
445453
movePlayer(event) {
446454
// Check if a single player wants to pause or restart:
@@ -466,13 +474,21 @@ class Game {
466474
if (event.key.length > 1 && !(Player.backtrackKeys.has(event.key))) {
467475
return;
468476
}
469-
// Temporary way to decide which
470-
// player the move belongs to:
471-
if (!event.shiftKey) {
472-
this.allPlayers[0].move(event.key);
473-
} else if (this.allPlayers.length > 1) {
474-
this.allPlayers[1].move(event.key);
477+
// Decide which player the move belongs to:
478+
let playerNum = 0;
479+
playerNum &= event.getModifierState( 'CapsLock') << 0;
480+
playerNum &= event.getModifierState( 'NumLock') << 1;
481+
playerNum &= event.getModifierState('ScrollLock') << 2;
482+
483+
// Clean input and send to handler:
484+
let key = event.key;
485+
if (key.length == 0) {
486+
key = key.toLowerCase();
487+
if (event.shiftKey) {
488+
key = key.toUpperCase();
489+
}
475490
}
491+
this.allPlayers[playerNum].move(key);
476492
}
477493

478494
/* Chaser moves in the direction of the player.
@@ -831,7 +847,9 @@ class Game {
831847
return counter;
832848
}
833849
tileAt(pos) { return this.grid[pos.y * this.width + pos.x]; }
834-
isCharacter(tile) { return !(this.language.has(tile.key)); }
850+
isCharacter(tile) {
851+
return tile.key in Object.entries();
852+
}
835853

836854
get misses() {
837855
return parseInt(this.misses_.innerHTML);

0 commit comments

Comments
 (0)