ジャンケンで勝ち続けないと涼めないファン by Obniz


# 🌀️便利なハンディファンは不便にしよう
この暑い夏、ハンディファンを持って歩く人をよく見ますね。そんな便利で欠かせないファンを不便にします。理由は特にありません。

## 使用したもの
* [Obniz](https://obniz.io/ja)
* [市販のハンディファン] (https://storyweb.jp/prtimes/71569/)  （パルコで買ってきた）
* [convForm](https://github.com/eduardotkoller/convForm)  （チャット風レイアウトのためだけに）


# 作りたかったもの
市販のハンディファンを分解したところ
「M+ M-」「L+ L-」 と明らかにモーターとLEDに繋がる導線が出てきたので、あとはObnizでコントロールしてしまうだけかと思っていましたが・・・
![IMG_6841.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178043/abbc2bfe-7aed-0081-2e35-6a714deb2532.jpeg)
![IMG_5376.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178043/6acfb931-6227-e60f-806f-83fcf7d72355.jpeg)
![IMG_9121.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178043/c47996c8-fe6f-f6b5-ae21-0b0663a8082c.jpeg)





# 🐈できたもの
![IMG_6480.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178043/295bbc71-4582-69be-340e-91c04bcb122c.jpeg)
んっっっっ？？！？？？！？？！？？？！

<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/srWSItabmV">pic.twitter.com/srWSItabmV</a></p>&mdash; 哲学する@WIer (@Ratchooo) <a href="https://twitter.com/Ratchooo/status/1163453019301670912?ref_src=twsrc%5Etfw">August 19, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

違うものができました。
市販のファン（ステッパーモーターやら何やら）をどうやったらObnizでコントロールできるのか試行錯誤した結果、破壊と創造が行われたのです。

## ソースコード

<details><summary>index.html（クリックで開く）</summary><div>

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <title>じゃんけんファン</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
  <link rel="stylesheet" type="text/css" href="dist/jquery.convform.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css" href="demo.css">
  <script src="https://unpkg.com/obniz@2.2.0/obniz.js"></script>
</head>

<body>
  <section id="demo">
    <div class="vertical-align">
      <div class="container">
        <div class="row">
          <div class="col-sm-6 col-sm-offset-3 col-xs-offset-0">
            <div class="card no-border">
              <div id="chat">
                <form action="" method="GET" class="hidden">
                  <select data-conv-question="なんてことだ！！<br>じゃんけんに勝たないと扇風機の前からどいてくれない猫が現れてしまった！！
                    <br><img src='animal_stand_neko_white.png' style='width:80px;'>
                    <img src='senpuuki_handyfan.png' style='width:60px;'>
                    <br><br>このままだとこの殺人的な猛暑のなか涼むことができない！！
                    <br><br>どうする？じゃんけん勝負を挑む？
                  " name="first-question">
                    <option value="3">涼むために挑む</option>
                    <option value="end">涼むのを諦める</option>
                  </select>
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>
  <script type="text/javascript" src="jquery-1.12.3.min.js"></script>
  <script type="text/javascript" src="dist/autosize.min.js"></script>
  <script type="text/javascript" src="dist/jquery.convform.js"></script>

  <script>
    const answersArray = ['グー✊🏻', 'チョキ✌🏻', 'パー🖐🏻', 'では行くぞ！'];
    let resultMsg = '・・・';
    let power = 0;
    let status = 0;
    const obniz = new Obniz("OBNIZ_ID");
    obniz.onconnect = async function () {
      const motor = obniz.wired("DCMotor", { forward: 0, back: 1 });
      jQuery(function ($) {
        let count = 0;
        var convForm = $('#chat').convform({
          eventList: {
            onInputSubmit: function (convState, ready) {

              if (convState.current.answer.value === 'end') {
                convState.current.next = convState.newState({
                  type: 'select',
                  name: 'dynamic-question-' + count,
                  questions: ['猫「ﾆｬ…(ならば消えるがいい)」'],
                });
                setTimeout(ready, Math.random() * 300 + 100);
              } else {

                // プレイヤーがグーチョキパー選択したか否か
                if (convState.current.answer.value != '3') {
                  var playerRoll = Number(convState.current.answer.value);
                  console.log('playerRoll', playerRoll);

                  //　コンピューターが何出すか
                  var computerRoll = Math.floor(Math.random() * 3);
                  console.log('computerRoll', computerRoll)

                  // 勝敗
                  if (playerRoll == computerRoll) {
                    // あいこ
                    resultMsg = '<<あいこ>>';
                  } else if (playerRoll === 0 && computerRoll === 1 ||
                    playerRoll === 1 && computerRoll === 2 ||
                    playerRoll === 2 && computerRoll === 0) {
                    // プレイヤーの勝ち
                    resultMsg = '<<プレイヤーの勝ち>>';
                    status += 1;
                  } else {
                    // コンピュータの勝ち
                    resultMsg = '<<コンピュータの勝ち>>';
                    status -= 1;
                  }
                }
                else {
                  console.log('挑むを選択');
                }

                // モーター稼働処理
                if (status == 0) {
                  power = 0;
                  motor.power(power);
                  motor.move(false);

                } else if (status >= 1 && status <= 5) {
                  power = status * 10;
                  motor.power(power);
                  motor.move(false);

                } else if (status > 5) {
                  status = 5;
                  motor.power(75);
                  motor.move(false);

                } else {
                  status = 0;
                  power = 0;
                  motor.power(power);
                  motor.move(false);
                }

                if (computerRoll == undefined) computerRoll = 3;
                convState.current.next = convState.newState({
                  type: 'select',
                  noAnswer: true,
                  name: 'dynamic-question-' + count,
                  questions: ['猫「ﾆｬ!!(' + answersArray[computerRoll] + ')」'],
                });
                convState.current.next.next = convState.newState({
                  type: 'select',
                  noAnswer: true,
                  name: 'dynamic-question-' + count,
                  questions: [resultMsg],
                });
                convState.current.next.next.next = convState.newState({
                  type: 'select',
                  name: 'dynamic-question-' + count,
                  questions: ['猫「ﾆｬﾝﾆｬﾝ…(じゃんけん…)」'],
                  answers: [
                    { text: 'グー✊🏻', value: '0' },
                    { text: 'チョキ✌🏻', value: '1' },
                    { text: 'パー🖐🏻', value: '2' }
                  ]
                });
                setTimeout(ready, Math.random() * 500 + 0);
              }
              count++;
            }
          }
        });
      });
    };
  </script>
</body>

</html>
```

</div></details>

勝つとポイントアップ、負けるとポイントダウン。ポイントに比例してDCモーターの回転数が上がりますが、全然涼める気がしません。

### チャット風デザイン
静的ページですがLINEのようなチャット風デザインにしてみようと、jQueryプラグインの[convForm](https://github.com/eduardotkoller/convForm)を使ってみました。
[![Image from Gyazo](https://i.gyazo.com/d8a1a8adf745333a03b523511f79ea4d.gif)](https://gyazo.com/d8a1a8adf745333a03b523511f79ea4d)

チャチャっとLINE Botを作れるほどその方面の筋肉が養われていないので、
筋肉があるであろうjQueryプラグインで省エネでチャット風レイアウトを実現しよう！と思いましたが
使用したconvFormは一癖二癖もあって意外と躓きました。根本的に利用用途が違うので当たり前ですが…。普通にLINE Botで作ればよかったですが。。。
(いつかWebサイトのデザインに使えそうなのでポジティブに考えて良し)
<br>

#まとめ
このトライアンドエラーのしやすさもObnizの良いところですね！