Skip to content

Commit 5b83f3f

Browse files
authored
Merge pull request #12 from proppy/promise
shiritori: switch interact to promise
2 parents 6726f7c + 0c86fbc commit 5b83f3f

File tree

9 files changed

+95
-108
lines changed

9 files changed

+95
-108
lines changed

action.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
}
1717
},
1818
"fulfillment": {
19-
"conversationName": "shiritori-v2"
19+
"conversationName": "shiritori-v3"
2020
}
2121
}
2222
],
2323
"conversations": {
24-
"shiritori-v2": {
25-
"name": "shiritori-v2",
26-
"url": "https://us-central1-shiritori-internal.cloudfunctions.net/shiritoriV2",
24+
"shiritori-v3": {
25+
"name": "shiritori-v3",
26+
"url": "https://us-central1-shiritori-internal.cloudfunctions.net/shiritoriV3",
2727
"fulfillmentApiVersion": 2
2828
}
2929
}

functions/.eslintignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
shiritori/node_modules/*
1+
shiritori/*

functions/.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"parserOptions": {
33
"ecmaVersion": 7,
4-
"sourceType": "script"
4+
"sourceType": "module"
55
},
66
"extends": ["semistandard"],
77
"env": {

functions/index.js

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,33 +49,31 @@ app.intent('actions.intent.MAIN', (conv) => {
4949
conv.ask('どうぞ、始めて下さい');
5050
});
5151

52-
app.intent('actions.intent.TEXT', (conv, input) => new Promise((resolve, reject) => {
53-
shiritori.loaded.then(() => {
54-
shiritori.interact(dict, input, conv.data.used, {
55-
lose () {
56-
conv.close('ざんねん。あなたの負けです。');
57-
resolve();
58-
},
59-
win (word, kana) {
60-
if (word) {
61-
conv.close(`${word} [${kana}]`);
62-
resolve();
63-
} else {
64-
conv.close('すごい!あなたの勝ちです。');
65-
resolve();
66-
}
67-
},
68-
next (word, kana) {
69-
conv.data.used.unshift(input);
70-
conv.data.used.unshift(word);
71-
conv.ask(new SimpleResponse({
72-
speech: word,
73-
text: `${word} [${kana}]`
74-
}));
75-
resolve();
76-
}
77-
});
52+
app.intent('actions.intent.TEXT', (conv, input) => {
53+
return shiritori.loaded.then(() => {
54+
return shiritori.interact(dict, input, conv.data.used)
55+
.then(result => {
56+
conv.data.used.unshift(input);
57+
conv.data.used.unshift(result.word);
58+
conv.ask(new SimpleResponse({
59+
speech: result.word,
60+
text: `${result.word} [${result.kana}]`
61+
}));
62+
})
63+
.catch(result => {
64+
if (result.win) {
65+
if (result.word) {
66+
conv.close(`${result.word} [${result.kana}]`);
67+
} else {
68+
conv.close('すごい!あなたの勝ちです。');
69+
}
70+
} else if (result.loose) {
71+
conv.close('ざんねん。あなたの負けです。');
72+
} else {
73+
throw result;
74+
}
75+
});
7876
});
79-
}));
77+
});
8078

81-
exports.shiritoriV2 = functions.https.onRequest(app);
79+
exports.shiritoriV3 = functions.https.onRequest(app);

functions/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
"scripts": {
1212
"lint": "eslint --fix \"**/*.js\"",
1313
"start": "firebase serve --only functions",
14-
"deploy": "firebase deploy --only functions",
15-
"test": "npm run lint"
14+
"deploy": "firebase deploy --only functions:shiritoriV3"
1615
},
1716
"dependencies": {
1817
"actions-on-google": "^2.1.x",

functions/shiritori/.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@
66
"extends": ["standard"],
77
"env": {
88
"node": true
9+
},
10+
"rules": {
11+
"prefer-promise-reject-errors": "off"
912
}
1013
}

functions/shiritori/index.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,29 +98,32 @@ exports.kanas = (word) => new Set((() => {
9898
})())
9999

100100
// しりとりのゲームループ。
101-
exports.interact = (dict, word, previousInputs, callbacks) => {
101+
exports.interact = (dict, word, chain) => new Promise((resolve, reject) => {
102102
const next = exports.kanas(word)
103-
if ((next.size === 0) || !exports.check(word, previousInputs)) {
104-
return callbacks.lose()
103+
if ((next.size === 0) || !exports.check(word, chain)) {
104+
return reject({loose: true})
105105
}
106106
const key = next.values().next().value
107107
dict(key).then((words) => {
108108
const unused = []
109109
if (words) {
110110
for (const k of Object.keys(words)) {
111-
if (!previousInputs.includes(words[k])) {
111+
if (!chain.includes(words[k])) {
112112
unused.push(k)
113113
}
114114
}
115115
}
116116
if (unused.length === 0) {
117-
return callbacks.win()
117+
return reject({win: true})
118118
}
119119
const w = unused[Math.floor(Math.random() * unused.length)]
120120
const wk = words[w]
121+
if (wk.length === 0) {
122+
return reject({error: 'empty dictionary entry for key: ' + w})
123+
}
121124
if (wk[wk.length - 1] === 'ん') {
122-
return callbacks.win(w, wk)
125+
return reject({win: true, word: w, kana: wk})
123126
}
124-
return callbacks.next(w, wk)
127+
resolve({word: w, kana: wk})
125128
})
126-
}
129+
})

functions/shiritori/main.js

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,32 @@ const rl = readline.createInterface({
2727
output: process.stdout
2828
})
2929

30-
const previousInputs = ['しりとり']
31-
console.log(previousInputs[0])
30+
const chain = ['しりとり']
31+
console.log(chain[0])
3232
rl.prompt()
3333
shiritori.loaded.then(() => {
34-
rl.on('line', (input) => {
35-
shiritori.interact(kana => Promise.resolve(
36-
corpus[kana]), input, previousInputs, {
37-
win (word, kana) {
38-
if (word) {
39-
console.log(`${word} [${kana}]`)
40-
} else {
41-
console.log('すごい!')
42-
}
34+
rl.on('line', input => {
35+
shiritori
36+
.interact(
37+
kana => Promise.resolve(corpus[kana]),
38+
input,
39+
chain
40+
)
41+
.then(result => {
42+
console.log(`${result.word} [${result.kana}]`)
43+
chain.unshift(input)
44+
chain.unshift(result.kana)
45+
rl.prompt()
46+
})
47+
.catch(reason => {
48+
if (reason.win) {
49+
console.log('すごい!')
4350
process.exit(0)
44-
},
45-
lose () {
51+
} else if (reason.loose) {
4652
console.log('ざんねん。')
4753
process.exit(-1)
48-
},
49-
next (word, kana) {
50-
previousInputs.unshift(input)
51-
previousInputs.unshift(kana)
52-
console.log(`${word} [${kana}]`)
53-
rl.prompt()
54+
} else {
55+
throw reason
5456
}
5557
})
5658
})

functions/shiritori/test.js

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -79,57 +79,39 @@ const dict = k => Promise.resolve({
7979
}
8080
}[k])
8181

82-
test.cb('internal.next', t => {
83-
t.plan(2)
84-
shiritori.interact(dict, 'べんと', [], {
85-
next (word, kana) {
86-
t.is('とんかつ', kana)
87-
t.is('とんかつ', word)
88-
t.end()
89-
}
90-
})
82+
test('internal.next', async t => {
83+
const result = await shiritori.interact(dict, 'べんと', [])
84+
t.is('とんかつ', result.kana)
85+
t.is('とんかつ', result.word)
9186
})
9287

93-
test.cb('interact.lose', t => {
94-
t.plan(1)
95-
shiritori.interact(dict, 'つと', ['とつ', 'つと'], {
96-
lose (result) {
97-
t.is(undefined, result)
98-
t.end()
99-
}
100-
})
88+
test('interact.lose', async t => {
89+
const result = await t.throws(shiritori.interact(dict, 'つと', ['とつ', 'つと']))
90+
t.is(true, result.loose)
10191
})
10292

103-
test.cb('internal.win without result', t => {
104-
t.plan(1)
105-
shiritori.interact(dict, 'つと', ['とんかつ', 'べんと'], {
106-
win (result) {
107-
t.is(undefined, result)
108-
t.end()
109-
}
110-
})
93+
test('internal.win without result', async t => {
94+
const result = await t.throws(shiritori.interact(dict, 'つと', ['とんかつ', 'べんと']))
95+
t.is(true, result.win)
11196
})
11297

113-
test.cb('internal.win with result', t => {
114-
t.plan(2)
115-
shiritori.interact(dict, 'とんかつ', ['べんと'], {
116-
win (word, kana) {
117-
t.is('つけまん', kana)
118-
t.is('つけまん', word)
119-
t.end()
120-
}
121-
})
98+
test('internal.win with result', async t => {
99+
const result = await t.throws(shiritori.interact(dict, 'とんかつ', ['べんと']))
100+
t.is(true, result.win)
101+
t.is('つけまん', result.kana)
102+
t.is('つけまん', result.word)
122103
})
123104

124-
test.cb('interact.win kanji', t => {
125-
t.plan(2)
126-
shiritori.loaded.then(() => {
127-
shiritori.interact(dict, '銀座', ['鰻'], {
128-
win (word, kana) {
129-
t.is('ざぶとん', kana)
130-
t.is('座布団', word)
131-
t.end()
132-
}
133-
})
134-
})
105+
test('interact.win kanji', async t => {
106+
await shiritori.loaded
107+
const result = await t.throws(shiritori.interact(dict, '銀座', ['鰻']))
108+
t.is(true, result.win)
109+
t.is('ざぶとん', result.kana)
110+
t.is('座布団', result.word)
111+
})
112+
113+
test('interact.error ', async t => {
114+
const result = await t.throws(shiritori.interact(k => Promise.resolve({'つけまん': ''}),
115+
'とんかつ', ['べんと']))
116+
t.true(result.error.length > 0)
135117
})

0 commit comments

Comments
 (0)