Improve doc
This commit is contained in:
parent
455f4ffa27
commit
e8da0bcd80
File diff suppressed because it is too large
Load Diff
|
@ -181,6 +181,7 @@
|
||||||
"sass-loader": "7.0.3",
|
"sass-loader": "7.0.3",
|
||||||
"seedrandom": "2.4.3",
|
"seedrandom": "2.4.3",
|
||||||
"showdown": "1.8.6",
|
"showdown": "1.8.6",
|
||||||
|
"showdown-highlightjs-extension": "0.1.2",
|
||||||
"single-line-log": "1.1.2",
|
"single-line-log": "1.1.2",
|
||||||
"speakeasy": "2.0.0",
|
"speakeasy": "2.0.0",
|
||||||
"style-loader": "0.21.0",
|
"style-loader": "0.21.0",
|
||||||
|
|
|
@ -7,6 +7,8 @@ html(lang= lang)
|
||||||
title
|
title
|
||||||
| #{title} | Misskey Docs
|
| #{title} | Misskey Docs
|
||||||
link(rel="stylesheet" href="/docs/assets/style.css")
|
link(rel="stylesheet" href="/docs/assets/style.css")
|
||||||
|
link(rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css")
|
||||||
|
script(src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js")
|
||||||
link(rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous")
|
link(rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous")
|
||||||
block meta
|
block meta
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
# MisskeyリバーシBotの開発
|
||||||
|
Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。
|
||||||
|
|
||||||
|
1. `reversi`ストリームに以下のパラメータを付けて接続する:
|
||||||
|
* `i`: botアカウントのAPIキー
|
||||||
|
|
||||||
|
2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる
|
||||||
|
* イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている
|
||||||
|
|
||||||
|
3. `reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する
|
||||||
|
|
||||||
|
4. 上手くいくとゲーム情報が返ってくるので、`reversi-game`ストリームへ、以下のパラメータを付けて接続する:
|
||||||
|
* `i`: botアカウントのAPIキー
|
||||||
|
* `game`: `game`の`id`
|
||||||
|
|
||||||
|
5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う
|
||||||
|
|
||||||
|
6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する
|
||||||
|
|
||||||
|
7. ゲームが開始すると、`started`イベントが流れてくる
|
||||||
|
* イベントの中身にはゲーム情報が含まれている
|
||||||
|
|
||||||
|
8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述)
|
||||||
|
|
||||||
|
9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる
|
||||||
|
* `color`として石の色が含まれている
|
||||||
|
* `pos`として位置情報が含まれている
|
||||||
|
|
||||||
|
## 位置の計算法
|
||||||
|
8x8のマップを考える場合、各マスの位置(Posと呼びます)は次のようになっています:
|
||||||
|
```
|
||||||
|
+--+--+--+--+--+--+--+--+
|
||||||
|
| 0| 1| 2| 3| 4| 5| 6| 7|
|
||||||
|
+--+--+--+--+--+--+--+--+
|
||||||
|
| 8| 9|10|11|12|13|14|15|
|
||||||
|
+--+--+--+--+--+--+--+--+
|
||||||
|
|16|17|18|19|20|21|22|23|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### X,Y座標 から Pos に変換する
|
||||||
|
```
|
||||||
|
pos = x + (y * mapWidth)
|
||||||
|
```
|
||||||
|
`mapWidth`は、ゲーム情報の`settings.map`から、次のようにして計算できます:
|
||||||
|
```
|
||||||
|
mapWidth = settings.map[0].length
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pos から X,Y座標 に変換する
|
||||||
|
```
|
||||||
|
x = pos % mapWidth
|
||||||
|
y = Math.floor(pos / mapWidth)
|
||||||
|
```
|
||||||
|
|
||||||
|
## マップ情報
|
||||||
|
マップ情報は、ゲーム情報の`settings.map`に入っています。
|
||||||
|
文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。
|
||||||
|
それをもとにマップのデザインを知る事が出来ます:
|
||||||
|
* `(スペース)` ... マス無し
|
||||||
|
* `-` ... マス
|
||||||
|
* `b` ... 初期配置される黒石
|
||||||
|
* `w` ... 初期配置される白石
|
||||||
|
|
||||||
|
例えば、4*4の次のような単純なマップがあるとします:
|
||||||
|
```text
|
||||||
|
+---+---+---+---+
|
||||||
|
| | | | |
|
||||||
|
+---+---+---+---+
|
||||||
|
| | ○ | ● | |
|
||||||
|
+---+---+---+---+
|
||||||
|
| | ● | ○ | |
|
||||||
|
+---+---+---+---+
|
||||||
|
| | | | |
|
||||||
|
+---+---+---+---+
|
||||||
|
```
|
||||||
|
|
||||||
|
この場合、マップデータはこのようになります:
|
||||||
|
```javascript
|
||||||
|
['----', '-wb-', '-bw-', '----']
|
||||||
|
```
|
||||||
|
|
||||||
|
## ユーザーにフォームを提示して対話可能Botを作成する
|
||||||
|
ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。
|
||||||
|
例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。
|
||||||
|
|
||||||
|
フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します:
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
type: 'init-form',
|
||||||
|
body: [フォームコントロールの配列]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
フォームコントロールの配列については今から説明します。
|
||||||
|
フォームコントロールは、次のようなオブジェクトです:
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
id: 'button1',
|
||||||
|
type: 'button',
|
||||||
|
label: 'Enable hoge',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
`id` ... コントロールのID。
|
||||||
|
`type` ... コントロールの種類。後述します。
|
||||||
|
`label` ... コントロールと一緒に表記するテキスト。
|
||||||
|
`value` ... コントロールのデフォルト値。
|
||||||
|
|
||||||
|
### フォームの操作を受け取る
|
||||||
|
ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。
|
||||||
|
イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。
|
||||||
|
例えば、上で示したボタンをユーザーがオンにしたとすると、次のイベントが流れてきます:
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
id: 'button1',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### フォームコントロールの種類
|
||||||
|
#### ボタン
|
||||||
|
type: `button`
|
||||||
|
ボタンを表示します。何かの機能をオン/オフさせたい場合に有用です。
|
||||||
|
|
||||||
|
##### プロパティ
|
||||||
|
`desc` ... ボタンの詳細な説明。
|
||||||
|
|
||||||
|
#### ラジオボタン
|
||||||
|
type: `radio`
|
||||||
|
ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。
|
||||||
|
|
||||||
|
##### プロパティ
|
||||||
|
`items` ... ラジオボタンの選択肢。例:
|
||||||
|
```javascript
|
||||||
|
items: [{
|
||||||
|
label: '弱',
|
||||||
|
value: 1
|
||||||
|
}, {
|
||||||
|
label: '中',
|
||||||
|
value: 2
|
||||||
|
}, {
|
||||||
|
label: '強',
|
||||||
|
value: 3
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### テキストボックス
|
||||||
|
type: `textbox`
|
||||||
|
テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。
|
||||||
|
|
||||||
|
## ユーザーにメッセージを表示する
|
||||||
|
設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。
|
||||||
|
例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。
|
||||||
|
メッセージを表示するには、次のメッセージをストリームに送信します:
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
type: 'message',
|
||||||
|
body: {
|
||||||
|
text: 'メッセージ内容',
|
||||||
|
type: 'メッセージの種類'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
メッセージの種類: `success`, `info`, `warning`, `error`。
|
|
@ -110,10 +110,9 @@ table
|
||||||
min-width 128px
|
min-width 128px
|
||||||
|
|
||||||
code
|
code
|
||||||
display inline-block
|
padding 4px 8px
|
||||||
padding 8px 10px
|
|
||||||
font-family Consolas, 'Courier New', Courier, Monaco, monospace
|
font-family Consolas, 'Courier New', Courier, Monaco, monospace
|
||||||
color #295c92
|
//color #295c92
|
||||||
background #f2f2f2
|
background #f2f2f2
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
|
|
||||||
|
@ -122,3 +121,4 @@ pre
|
||||||
|
|
||||||
> code
|
> code
|
||||||
display block
|
display block
|
||||||
|
padding 16px
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as showdown from 'showdown';
|
import * as showdown from 'showdown';
|
||||||
|
import 'showdown-highlightjs-extension';
|
||||||
import ms = require('ms');
|
import ms = require('ms');
|
||||||
import * as Router from 'koa-router';
|
import * as Router from 'koa-router';
|
||||||
import * as send from 'koa-send';
|
import * as send from 'koa-send';
|
||||||
|
@ -220,7 +221,7 @@ router.get('/*/*', async ctx => {
|
||||||
|
|
||||||
const conv = new showdown.Converter({
|
const conv = new showdown.Converter({
|
||||||
tables: true,
|
tables: true,
|
||||||
extensions: ['urlExtension', 'apiUrlExtension']
|
extensions: ['urlExtension', 'apiUrlExtension', 'highlightjs']
|
||||||
});
|
});
|
||||||
const md = fs.readFileSync(`${__dirname}/../../../src/docs/${doc}.${lang}.md`, 'utf8');
|
const md = fs.readFileSync(`${__dirname}/../../../src/docs/${doc}.${lang}.md`, 'utf8');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue