Arduinoで作るジャンケンマンライクな電子工作!スマホアプリでCPUとオンライン対決できます。
こんにちは、せでぃあ(@cediablog)です。
Arduino UNO R4 WIFIを使って、Arduino IoT Cloudを使ったオンラインジャンケンマン電子工作の作り方を紹介します。
準備するもの
- Arduino UNO R4 WIFI
- スマートフォン
- パソコン
- USB TypeCケーブル
Arduino UNO R4 WiFi本体と、Arduino IoT Remoteアプリをインストールしたスマホがあれば、難しい配線など一切不要の親切設計となっています。
ジャンケンマンの実機で遊んだことがある方も、ない方も楽しめる工作テーマになっています。
- オンラインジャンケンマンの概要と遊び方
- Arduino Cloud側の設定方法
- Arduino動作プログラムの作り方
せでぃあはこんな人物です
✅プライム企業に勤める電気・機械設計エンジニア
✅親子の絆を深めるため、夏休みに子供と一緒に電子工作を製作
✅Arduinoプログラミングを用いて作ったプログラミング電子工作「信GO機」が市の発明くふう展で「優秀賞」を受賞
✅本ブログにてArduinoスクラッチプログラミングLESSON記事投稿中
✅YouTubeチャンネル「せでぃあブログちゃんねる」運営中
Arduino UNO R4 WiFiはここで買えます
通信ケーブルは別売りとなっていますので、別途準備が必要です。
Arduino UNO R4 WIFIの使い方について詳しく知りたい方には、こちらの記事がおすすめです!
ジャンケンマンの話
今回のプログラミングネタである「ジャンケンマン」について、簡単に紹介します。
ジャンケンマンとは
ジャンケンマンとは、コンピューターとじゃんけんを行うメダルゲームです。
メダルを投入するとじゃんけんがはじまり、「グー」「チョキ」「パー」のボタンを押してじゃんけんをします。
じゃんけんに勝つとメダルをゲットできるというものです。
かつては、ゲームセンターやショッピングセンターのアミューズメントコーナーに設置されていました。
私のような昭和世代の方は、一度は遊んだことがあるのではないでしょうか?
ゲームの内容は極めて簡単で、ゲーム筐体を相手にじゃんけんを行なうものである。勝敗によってプレイヤーの保有するメダルが増減する。じゃんけんの拳は点画の様に多数のLEDを使い、グーの型を基本に、指を2本加えてチョキ、5本加えてパーを現す。
遊び方は以下の通り。
コインまたはメダルを投入すると、「じゃーん、けーん、」の音声が発せられるので、「グー」「チョキ」「パー」いずれかのボタンを押す。ボタンを押すと同時に「ぽん!」が発声される。
wikipediaより引用
勝敗の判定がされ、勝敗に応じて以下の動作が行われる。
あいこになった場合は、再び「じゃーん、けーん、」の音声が発せられ、また1からの繰り返しとなる。後期以降のあいこ時は「あーい、こーで、」の音声が発せられ、ボタンを押すと同時に「しょー!」が発声される。
勝った場合は「やっぴー」の音声と共に、盤面の「かち」「2」ランプ、及びスタートボタン・メダルもどしボタンのLEDが点灯する。スタートボタンを押すと現在の当たり枚数を賭け、再度勝負できる(ダブルアップ)。メダルもどしボタンを押すと獲得したメダルが払い出される。枚数は初期状態では2枚で、最大32枚=5戦まで続けられる。なお続編では勝利の後に付加機能が働く。
負けた場合は「ズコー」の音声と共に盤面の「まけ」ランプが点灯し、何も出ないままゲームオーバーとなる。
ジャンケンマンにはタイプがある
ジャンケンマンは大きく分けて2種類存在しています。
大きな違いは、じゃんけんに勝った後の払い出しメダル枚数の決め方です。
- 初期型:勝つたびに得られる枚数が増加するが、負けたら1枚も獲得できない。
- 後期型:勝つとルーレットが回り、止まった場所に書かれた枚数が排出される。
初期型は勝ち続けると排出メダル枚数が「2→4→8→16→32」と増加して行き、メダルもどしボタンを押すと現在の払い出し枚数分が排出される仕組みです。
せっかく連勝を重ねても負けてしまうとその時点で0枚になってしまう世知辛い機種でした。。。
1度勝つだけで多くの枚数をゲットできる可能性がある、後期型の方が優しいイメージが持てますね。
私の記憶では、初期型はじゃんけんで勝つと「やったね!」という音声が出ていたので、今回の動作プログラムもこちらを採用しています。
負けたときは、「負け~」だった気がしますが、あえてwikipediaにあわせて「ズコー!」にしました。
オンラインジャンケンマンの遊び方
今回のジャンケンマンライクな電子工作は、スマホアプリ「Arduino IoT Cloud Remote」を使って、スマホ画面を操作してArduino本体のLEDマトリクスとじゃんけん対決ができるプログラム動作になっています。
- プログラム動作を開始して「じゃんけん待ち」になる。
- スマホのメッセンジャーウィジェットに「じゃんけん」と入力するとじゃんけん開始。
- スマホ画面のじゃんけんボタンを押してArduinoと対決する。
Arduinoの手はLEDマトリクスに表示れて、結果がメッセンジャーウィジェットに表示される。 - 「あいこ」の場合は、勝敗が決まるまでじゃんけんが続く。
プログラム転送後、または本体のリセットボタンを押すとプログラム動作を開始します。
プログラム動作を開始すると、自動的にWiFiネットワークへ接続してArduino IoT Cloudとつながります。
Arduino本体のLEDマトリクスにグー・チョキ・パーがゆっくり順に表示され、「じゃんけん待ち状態」になります。
スマホのメッセンジャーウィジェットにCPUとじゃんけんをする方法がコメント表示されます。
スマホのメッセンジャーウィジェットで、「じゃんけん」と入力することでじゃんけんが開始されます。
メッセンジャーウィジェットに「じゃんけん」と入力すると、LEDマトリクスに表示されたグー・チョキ・パーの表示が素早く切り替わります。
メッセンジャーウィジェットには「じゃん、けん、」と表示されて、プレイヤーのじゃんけんボタン選択待ちの状態になります。
スマホ画面のじゃんけんボタン「グー」「チョキ」「パー」のいずれかを押します。
スマホ画面には、相手のじゃんけんの手が表示され、じゃんけん結果がメッセンジャーウィジェットに表示されます。
じゃんけん結果が「あいこ」の場合は、「あいこ」であることが表示されたのち「あいこで、」と表示されもう一度じゃんけんを行う動作が始まります。
このとき、LEDマトリクスの表示はグーチョキパーの高速アニメーション動作となります。
「グー」「チョキ」「パー」いずれかのじゃんけんボタンを押すと、「しょ!」というコメントとともにじゃんけん結果が表示されます。
さらに「あいこ」だった場合、決着がつくまで何度もじゃんけんが継続します。
なるべく、ジャンケンマンライクな動作になるように作りました。
POINT
Arduinoが出す「じゃんけんの手」は乱数と言われるランダムに値を抽出する関数を使って選択しています。
乱数(ランダム)プログラムについては、こちらの記事にて詳しく説明しています。
Arduino Cloudの設定方法と使い方
今回の動作を行うための設定方法と使い方を紹介します。
Arduino Cloudの設定項目
- Devices
接続するマイコンボード - Things
制御やデータ収集を行うデバイス - Dashboards
情報を見える化して操作可能なツール - Sketches
Arduinoを動作させるプログラム
Arduino Cloudで設定すべき項目は上記の4項目になります。
それぞれの設定方法を解説していきます。
Arduino Cloudへのサインイン
まずはじめに、Arduino Cloudサイトにログインします。
ユーザー登録方法については、こちらの記事にて詳しく説明しています。
「SIGN IN」をクリックして、サインインページに移動します。
登録したユーザー名またはメールアドレスとパスワードを入力し、「SIGN IN」ボタンをクリックします。
Arduino CloudのHome画面に移動したらサインイン完了です。
Devicesの設定
Devicesでは、接続するマイコンボードの選択と設定を行います。
Home画面のメニューからDevicesを選択して、「ADD DEVICE」をクリックします。
Arduino boardをクリックします。
USBケーブルで接続されたArduino UNO R4 WIFI本体との接続が行われます。
Arduino Create Agentがパソコンにインストールされていない場合は、インストール要求がされます。
「INSTALL」ボタンをクリックして、インストールを進めます。
ダウンロードフォルダに保存された、インストール実行ファイルを起動します。
「NEXT」をクリックします。
承認ボタンをONにして、「NEXT」をクリックします。
インストールフォルダを選択して「承認ボタンをONにして、「NEXT」をクリックします。
特にこだわりがなければ、初期表示フォルダのまま進めてOKです。
「NEXT」をクリックします。
インストールが行われるので、待ちます。
インストールが完了したら「Finish」をクリックします。
Arduino UNO R4 WIFIを検出したら「CONFIGRE」をクリックします。
デバイス名を入力して、「NEXT」をクリックします。
任意のデバイス名を入力してください。
デバイスIDとシークレットキーが表示されるので、控えます。
画面下のチェックを入れて「CONTINUE」をクリックします。
セットアップが開始されます。
「CONFIRM」をクリックします。
セットアップが完了したら「DONE」をクリックします。
Home画面のDevicesをクリックすると、登録したデバイスが表示されます。
Thingsの設定
Thingsでは、接続するデバイス「モノ」の選択と設定を行います。
Home画面のメニューからThingsを選択して、「CREATE THING」をクリックします。
Thing名がUntitledになっているので、Renameをクリックして名前を変えます。
Thing名を変えなくても動作に支障はありませんが、変えておくとデータを紐づけるときにわかりやすいです。
新しいThing名を入力して、RENAMEをクリックします。
Thing名が「UNO_R4_WIFI」に変更されました。
SetupタブのADDをクリックして4つのクラウド変数を追加します。
- btn_g:グーボタンON-OFF情報
- btn_c:チョキボタンON-OFF情報
- btn_p:パーボタンON-OFF情報
- message:メッセンジャーウィジェット表示文字列情報
クラウド変数「btn_g、btn_c、btn_c」の設定方法
クラウド変数情報を設定して、「ADD VARIABLE」をクリックします。
クラウド変数の設定内容
- 変数名:btn_g、btn_c、btn_p
- 変数の型:Boolean
- 権限:Read & Write
- 更新頻度:On change
クラウド変数「message」の設定方法
クラウド変数情報を設定して、「ADD VARIABLE」をクリックします。
クラウド変数の設定内容
- 変数名:message
- 変数の型:Character String
- 権限:Read & Write
- 更新頻度:On change
Select Deviceリンクボタンをクリックします。
ASSOCIATEをクリックして、登録済のデバイス「Arduino UNO R4 WiFi」を紐づけます。
Arduino UNO R4 WiFiが紐づけられました。
Configureリンクボタンをクリックします。
ネットワーク接続設定情報を入力して、SAVEをクリックします。
ネットワーク情報が設定されました。
Metadataタブをクリックして、Timezoneを設定します。
sketchタブをクリックすると、自動でプログラムが作られています。
このプログラムを編集して、動作させたいプログラムを作り上げていきます。
プログラムの作り方は、このあと詳しく説明します。
プログラムが作れたら検証ボタンをクリックして、プログラムコードを検証します。
検証後に画面下のウインドウに緑文字が表示されたら検証成功です。
プログラムに間違いがある場合は、赤文字でエラー表示されるので指摘された内容に応じて修正してください。
転送ボタンをクリックして、プログラムコードをArduino本体に転送します。
Dashboardsの設定
Dashboardsでは、デバイスから得た情報を見える化して操作可能なツールの設定を行います。
配置するもの
- メッセンジャーウィジェット
- プッシュボタンウィジェット×3つ
メニューのDashboardsを選択し、「+CREATE DASHBOARD」をクリックします。
すでにダッシュボードを作った実績がある場合は、画面右上の「+DASHBOARD」ボタンをクリックしてダッシュボードを追加します。
Dashboard名がUntitledになっているので、Renameをクリックします。
新しいDashboard名「janken」を入力して、RENAMEをクリックします。
Dashboard名が「janken」に変更されました。
ADDボタンをクリックしてウィジェットウィンドウを開き、Messengerボタンをクリックします。
メッセンジャーウィジェットが表示されました。
Link Variableボタンをクリックします。
Variablesにmessageを選択して、LINK VARIABLEボタンをクリックします。
DONEボタンをクリックしてメッセンジャーウィジェットの設定を完了させます。
じゃんけんの手「グー」「チョキ」「パー」を選択するための、押しボタンを作ります。
グーボタンを作る
まずはグーボタンから作っていきます。
ADDボタンをクリックしてウィジェットウィンドウを開き、「Push Button」をクリックします。
Link Variableボタンをクリックします。
Variablesに「btn_g」を選択して、LINK VARIABLEボタンをクリックします。
ボタン名を「グー」と入力し、「DONE」をクリックして設定を完了させます。
チョキ・パーボタンを配置する
グーと同様の手順であと2つのプッシュボタンウィジェットを配置していきます。
紐づけるVariables(クラウド変数)は以下になります。
- チョキボタン:btn_c
- パーボタン:btn_p
スマホのレイアウト画面に変更して、サイズや位置を調整します。
これでダッシュボードの設定が完了しました。
Arduino UNO R4 WIFIにプログラムデータを転送済であれば、「じゃんけん」と入力することでオンラインジャンケンマン遊びを始めることができます。
ウィジェットのサイズと配置は、スマホの画面サイズに合わせて調整してください。
スマホアプリからの操作方法
ここではスマホアプリ「Arduino IoT Cloud Remote」のインストール方法と、ジャンケンマン遊びの操作方法を紹介します。
Arduino UNO R4 WIFIに電源を供給して、オンライン接続状態にしてください。
Arduinoが提供するアプリ「Arduino IoT Cloud」をインストールします。
インストールができたらアプリを開きます。
アプリの初回起動画面が出るので、しばらく待ちます。
パソコンで登録したArduino Cloud登録情報を入力して、サインインします。
ダッシュボード画面から、先ほど作成したダッシュボード「janken」を選択します。
先ほど作成したメッセンジャーウィジェットが配置されています。
「じゃんけん」と入力するとCPUとじゃんけんができます、というコメントが表示されます。
入力メッセージ入力欄に「じゃんけん」と入力します。
すると、メッセンジャーウィジェットに「じゃん、けん、」と表示されるので、出したいじゃんけんの手に対応したボタンをタップします。
今回は「グー」をタップしました。
無作為に抽出されたCPUのじゃんけんの手と、勝ち負け、あいこのコメントが表示されます。
今回は相手も自分と同じ「グー」だったので、あいことなりもう一度じゃんけんを行うことになります。
次は「チョキ」をタップしました。
あいこの場合は「あいこで、」とコメントが表示され、結果も「しょ!」から表示されます。
勝ち負けが決まったら、勝負終了です。
もう一度じゃんけんするには、メッセンジャーウィジェットに「じゃんけん」と入力してください。
じゃんけんは何度も行うことができます。
じゃんけんに勝つと「やったね!」と表示されます。
手元にスマホがない場合でも、パソコンのArduino Cloud画面に設置したメッセンジャーウィジェットからでも、同様の動作が可能です。
LEDマトリクス表示の作り方
メインプログラムを作る前に、LEDマトリクス点灯パターンコード及びアニメーション表示プログラムを作ります。
- 単独表示:LEDマトリクス表示コードをプログラムに記載する。
- アニメーション表示:アニメーションファイルを作成し、メインプログラムにてインクルード命令で呼び出して使う。
今回作成する単独表示
- 「グー」表示
- 「チョキ」表示
- 「パ-」表示
今回作成するアニメーション表示
- ゆっくりグーチョキパー切り替え表示
- 高速グーチョキパー切り替え表示
既にお気づきかと思いますが、アニメーション動作も単独表示も結局「グー」「チョキ」「パー」の3種類作れば良いです。
ですので、まずはグーチョキパー切り替えアニメーションから作っていきます。
単独表示プログラムコードは、このアニメーションプログラム内に記述されるのでそのコードを使います。
今回は3種類の表示を作るだけなので、簡単ですよ!
LEDマトリクスエディタを使って作る
- マトリクス作画エリア
- 表示パターンエリア
- コード生成ボタン
これらの表示パターンはLEDマトリクスエディタを使って作ります。
マトリクスエディタを使った表示コードの作り方を説明していきます。
マトリクスエディタの使い方については、こちらの記事にて詳しく説明しています。
アニメーション表示プログラムを生成する
今回2つのアニメーション表示プログラムを作成します。
アニメーション表示:生成ファイル名
- じゃんけん待機表示:janken_animation_op.h
- じゃんけん中表示:janken_animation.h
じゃんけん待機中と、じゃんけん中の表示はグーチョキパー切り替え速度が異なるだけで表示パターンは同じです。
LEDマトリクスエディタではアニメーション切り替え速度が標準で「66msec」となっているため、高速切り替え表示させる「②じゃんけん中表示」を作ることにします。
じゃんけん待機中表示は、スケッチ作成時にプログラムコピーとコード書き換えにて対応します。
コード書き換え部分については、後述のプログラム解説部分で説明します。
グーの表示パターンを作ります。
コマ表示の下にある数字欄は「表示時間(msec)」で、数値変更が可能です。
続いて、チョキの表示パターンを作ります。
グーの表示をコピーして、2本の指を追加しています。
最後にパーの表示パターンを作ります。
チョキの表示をコピーして、3本の指を追加しています。
「グー」「チョキ」「パー」3つの表示パターンを作ったら、アニメーションファイルを生成します。
ファイル名は「janken_animation」とします。
グーチョキパーの表示を66msecごとに切り替えるファイル「janken_animation.h」が生成されます。
じゃんけん待機中の表示は、プログラム作成時に「janken_animation.h」をコピーして、表示切替周期を66msecから1000msecに変更して使います。
単独表示パターンコードを生成する
単独表示パターンについては、32ビット整列データをプログラム内に記述することで表示させます。
LEDマトリクスエディタを使って生成したアニメーションファイル内のコードから、各表示パターンの32ビット整列のデータを確認することができます。
ダウンロードフォルダに、生成したアニメーションファイルが保存されています。
このアニメーションファイル右クリック⇒プログラムから開く⇒メモ帳を選択してコードを確認します。
メモ帳を使ってファイルを開くと、コードの中身を確認することができます。
中かっこ内の4列のうち、上から1~3列目までがマトリクス表示コードです。
4列目はアニメーション表示時間になりますが、単独表示では使用しません。
単独表示プログラムでは、1~3列目のマトリクス表示コードのみを使用するため赤枠で囲ったコードをプログラム内に記述して使っていきます。
プログラムへの反映方法は、このあと詳しく解説していきます。
これでLEDマトリクス表示に関する事前作業は完了です。
アニメーションプログラムをインポートする。
スケッチ画面にて、メインプログラムから呼び出して使用する「アニメーションプログラム」をインポートします。
インポートするファイル
- janken_animation.h
インポートして改編するファイル
- janken_animation_op.h
janken_animation.hをインポートする
まずはじめに、じゃんけん中の高速アニメーションファイル「janken_animation.h」をインポートします。
Arduino Cloudのスケッチ画面の+タブをクリックします。
「Import File」をクリックすると、対象ファイルを選択するウィンドウが開きます。
事前に生成しておいたアニメーションプログラムファイル「janken_animation.h」を選択後、開くをクリックしてインポートします。
「janken_animation.h」のインポートが完了しました。
janken_animation_op.hを作る
次に、じゃんけん待機中のゆっくりアニメーションファイル「janken_animation_op.h」を作ります。
画面右上の「+」タブをクリック⇒「Import File」をクリックします。
「janken_animation.h」を選択して、インポートします。
ファイル名の右側の3つの点アイコンをクリックし、「Rename」をクリックします。
ファイル名を「janken_animation_op.h」に変更します。
変数名を「janken_animation_op」に、アニメーション速度を「1000」に手修正します。
この作業を忘れると、プログラム検証時にエラーになりますので、忘れないようにご注意ください。
動作プログラムの解説
ここからはプログラムの内容を解説していきます。
プログラム(スケッチ)はある程度自動で作成されるので、自分が動作させたい部分を追加編集して作っていきます。
/*
Sketch generated by the Arduino IoT Cloud Thing "Janken"
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
String message;
bool btn_c;
bool btn_g;
bool btn_p;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
// Arduino_LED_Matrixアニメーションファイルをインクルードする
#include "janken_animation.h"
#include "janken_animation_op.h"
//じゃんけんステータス変数(0:待機中 1:じゃんけん中)
int status = 0;
//あいこ状態変数(0:あいこではない 1:あいこのとき)
int aiko = 0;
//じゃんけんの手を格納する変数
int hum_janken = 0;
int cpu_janken = 0;
// マトリックスパネルのオブジェクトを作成する
ArduinoLEDMatrix matrix;
// LEDマトリクス表示「グー」
const uint32_t matrix_g[] = {
0x0,
0x1f81542,
0x54104088,
};
// LEDマトリクス表示「チョキ」
const uint32_t matrix_c[] = {
0xa00a00a,
0x1f81542,
0x54104088,
};
// LEDマトリクス表示「パー」
const uint32_t matrix_p[] = {
0xa00a80a,
0x91fa5542,
0x54104088,
};
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
// LEDマトリクス動作を開始する
matrix.begin();
//乱数の初期化
randomSeed(analogRead(0));
}
void loop() {
ArduinoCloud.update();
if (status == 1) {
// じゃんけん開始メッセージを表示
if (aiko == 0) {
message = "じゃん、けん、";
} else if (aiko == 1) {
message = "あいこで、";
}
// じゃんけん中LEDマトリクスアニメーションを読み出す。
matrix.loadSequence(janken_animation);
matrix.play(true);
delay(200);
//【じゃんけんの抽選】1:グー、2:チョキ、3:パー
cpu_janken = random(1, 4);
//【じゃんけんの組み合わせ】
//CPU:グー × HUM:グー
if (cpu_janken == 1 && hum_janken == 1) {
matrix.loadFrame(matrix_g);
if (aiko == 0) {
message = "ポン!相手はグーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
} else if (aiko == 1) {
message = "しょ!相手はグーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 1;
delay(1000);
}
//CPU:グー × HUM:チョキ
if (cpu_janken == 1 && hum_janken == 2) {
matrix.loadFrame(matrix_g);
if (aiko == 0) {
message = "ポン!相手はグーを出しました。あなたの「負け」です。ズコー!";
} else if (aiko == 1) {
message = "しょ!相手はグーを出しました。あなたの「負け」です。ズコー!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:グー × HUM:パー
if (cpu_janken == 1 && hum_janken == 3) {
matrix.loadFrame(matrix_g);
if (aiko == 0) {
message = "ポン!相手はグーを出しました。あなたの「勝ち」です。やったね!";
} else if (aiko == 1) {
message = "しょ!相手はグーを出しました。あなたの「勝ち」です。やったね!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:チョキ × HUM:グー
if (cpu_janken == 2 && hum_janken == 1) {
matrix.loadFrame(matrix_c);
if (aiko == 0) {
message = "ポン!相手はチョキを出しました。あなたの「勝ち」です。やったね!";
} else if (aiko == 1) {
message = "しょ!相手はチョキを出しました。あなたの「勝ち」です。やったね!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:チョキ × HUM:チョキ
if (cpu_janken == 2 && hum_janken == 2) {
matrix.loadFrame(matrix_c);
if (aiko == 0) {
message = "ポン!相手はチョキを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
} else if (aiko == 1) {
message = "しょ!相手はチョキを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 1;
delay(1000);
}
//CPU:チョキ × HUM:パー
if (cpu_janken == 2 && hum_janken == 3) {
matrix.loadFrame(matrix_c);
if (aiko == 0) {
message = "ポン!相手はチョキを出しました。あなたの「負け」です。ズコー!";
} else if (aiko == 1) {
message = "しょ!相手はチョキを出しました。あなたの「負け」です。ズコー!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:パー × HUM:グー
if (cpu_janken == 3 && hum_janken == 1) {
matrix.loadFrame(matrix_p);
if (aiko == 0) {
message = "ポン!相手はパーを出しました。あなたの「負け」です。ズコー!";
} else if (aiko == 1) {
message = "しょ!相手はパーを出しました。あなたの「負け」です。ズコー!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:パ- × HUM:チョキ
if (cpu_janken == 3 && hum_janken == 2) {
matrix.loadFrame(matrix_p);
if (aiko == 0) {
message = "ポン!相手はパーを出しました。あなたの「勝ち」です。やったね!";
} else if (aiko == 1) {
message = "しょ!相手はパーを出しました。あなたの「勝ち」です。やったね!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:パー × HUM:パー
if (cpu_janken == 3 && hum_janken == 3) {
matrix.loadFrame(matrix_p);
if (aiko == 0) {
message = "ポン!相手はパーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
} else if (aiko == 1) {
message = "しょ!相手はパーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 1;
delay(1000);
}
}
}
/*
Since Message is READ_WRITE variable, onMessageChange() is
executed every time a new value is received from IoT Cloud.
*/
void onMessageChange() {
// Add your code here to act upon Message change
//じゃんけん開始前のとき
if (cpu_janken == 0) {
// 待機中LEDマトリクスアニメーションを読み出す。
matrix.loadSequence(janken_animation_op);
matrix.play(true);
delay(100);
}
if (message == "じゃんけん") {
//じゃんけんの開始
if (hum_janken == 0) {
status = 1;
}
} else if (message != "じゃんけん") {
message = "じゃんけん と入力すると、CPUとじゃんけんができます。";
aiko = 0;
status = 0;
}
}
/*
Since BtnG is READ_WRITE variable, onBtnGChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBtnGChange() {
// Add your code here to act upon BtnG change
//プレイヤーが「グーを選択したとき」
if (btn_g == HIGH) {
hum_janken = 1;
}
}
/*
Since BtnC is READ_WRITE variable, onBtnCChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBtnCChange() {
// Add your code here to act upon BtnC change
//プレイヤーが「チョキを選択したとき」
if (btn_c == HIGH) {
hum_janken = 2;
}
}
/*
Since BtnP is READ_WRITE variable, onBtnPChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBtnPChange() {
// Add your code here to act upon BtnP change
//プレイヤーが「パーを選択したとき」
if (btn_p == HIGH) {
hum_janken = 3;
}
}
これが完成したメインプログラムになります。
自動作成されたプログラムから追加・変更した部分を解説していきます。
プログラミングの手入力に自信がない方は、必要な部分をコピペして使っていただくと作業が楽になりますよ。
初期化プログラム
初期化プログラム部で追加・変更した部分を抜き取って解説します。
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
// Arduino_LED_Matrixアニメーションファイルをインクルードする
#include "janken_animation.h"
#include "janken_animation_op.h"
//じゃんけんステータス変数(0:待機中 1:じゃんけん中)
int status = 0;
//あいこ状態変数(0:あいこではない 1:あいこのとき)
int aiko = 0;
//じゃんけんの手を格納する変数
int hum_janken = 0;
int cpu_janken = 0;
// マトリックスパネルのオブジェクトを作成する
ArduinoLEDMatrix matrix;
// LEDマトリクス表示「グー」
const uint32_t matrix_g[] = {
0x0,
0x1f81542,
0x54104088,
};
// LEDマトリクス表示「チョキ」
const uint32_t matrix_c[] = {
0xa00a00a,
0x1f81542,
0x54104088,
};
// LEDマトリクス表示「パー」
const uint32_t matrix_p[] = {
0xa00a80a,
0x91fa5542,
0x54104088,
};
初期化プログラムで追加したこと
- ファイルのインクルード命令
- 変数の宣言
ファイルのインクルード命令
インクルードするファイル
- Arduino_LED_Matrix.h:LEDマトリクス表示制御
- janken_animation.h:グーチョキパー切り替えアニメーション(高速)
- janken_animation_op.h:グーチョキパー切り替えアニメーション(低速)
LEDマトリクス表示させるための、「Arduino_LED_Matrix.h」と、グーチョキパー切り替えアニメーション表示させるための2ファイルをインクルードします。
変数の宣言
プログラム内で使用する変数を宣言します。
宣言する変数
- int status:じゃんけん待機中=0、じゃんけん中=1
- int aiko:じゃんけん結果があいこでない=0、あいこのとき=1
- int hum_janken:プレイヤーのじゃんけんの手「グー=1、チョキ=2、パー=3」
- int cpu_janken:CPUのじゃんけんの手「グー=1、チョキ=2、パー=3」
- ArduinoLEDMatrix matrix:ArduinoLEDMatrix型のオブジェクト
- const uint32_t matrix_g[]:グーの表示パターンコード
- const uint32_t matrix_c[]:チョキの表示パターンコード
- const uint32_t matrix_p[]:パーの表示パターンコード
じゃんけんに関する情報を格納する変数を宣言して、0を代入して初期化しておきます。
ArduinoLEDMatrix型のオブジェクト「matrix」を作成します。
LEDマトリクス表示パターンのコードを定義します。
マトリクスLEDの点灯制御については、こちらの記事にて詳しく解説しています。
setupプログラム
setup関数内のプログラムは、プログラム演算開始後1回だけ実行されます。
setupプログラム部で追加・変更した部分を抜き取って解説します。
void setup() {
// LEDマトリクス動作を開始する
matrix.begin();
//乱数の初期化
randomSeed(analogRead(0));
}
setupプログラムで追加したこと
- LEDマトリクス動作の開始命令
- 乱数の初期化命令
LEDマトリクス動作の開始命令
ここではLEDマトリクス動作を開始するためのbeginメソッドを実行します。
乱数の初期化命令
random関数を使って生成される乱数の生成値は、乱数の種が同じ場合は生成順序が決まっています。
つまり、プログラム開始後のCPUが出すじゃんけんの手順が決まっているということです。
初回は分からなくても、2回目以降はじゃんけんする前から次にCPUが出す手がわかってしまいます。
これではイカサマ状態になってしまい、まったく面白くありません。
そこで「randomseed関数」を使って、乱数の種にランダムな値「未接続のアナログピン入力値」を割り当てることで、CPUがじゃんけんで出す手を真にランダムなものにしています。
ランダムシード関数を使った乱数制御については、こちらの記事にて詳しく説明しています。
loopプログラム
loop関数内のプログラムは、繰り返し演算されます。
loopプログラムでは、じゃんけんの実行部分のプログラムを作っています。
void loop() {
if (status == 1) {
// じゃんけん開始メッセージを表示
if (aiko == 0) {
message = "じゃん、けん、";
} else if (aiko == 1) {
message = "あいこで、";
}
// じゃんけん中LEDマトリクスアニメーションを読み出す。
matrix.loadSequence(janken_animation);
matrix.play(true);
delay(200);
//【じゃんけんの抽選】1:グー、2:チョキ、3:パー
cpu_janken = random(1, 4);
//【じゃんけんの組み合わせ】
//CPU:グー × HUM:グー
if (cpu_janken == 1 && hum_janken == 1) {
matrix.loadFrame(matrix_g);
if (aiko == 0) {
message = "ポン!相手はグーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
} else if (aiko == 1) {
message = "しょ!相手はグーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 1;
delay(1000);
}
//CPU:グー × HUM:チョキ
if (cpu_janken == 1 && hum_janken == 2) {
matrix.loadFrame(matrix_g);
if (aiko == 0) {
message = "ポン!相手はグーを出しました。あなたの「負け」です。ズコー!";
} else if (aiko == 1) {
message = "しょ!相手はグーを出しました。あなたの「負け」です。ズコー!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:グー × HUM:パー
if (cpu_janken == 1 && hum_janken == 3) {
matrix.loadFrame(matrix_g);
if (aiko == 0) {
message = "ポン!相手はグーを出しました。あなたの「勝ち」です。やったね!";
} else if (aiko == 1) {
message = "しょ!相手はグーを出しました。あなたの「勝ち」です。やったね!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:チョキ × HUM:グー
if (cpu_janken == 2 && hum_janken == 1) {
matrix.loadFrame(matrix_c);
if (aiko == 0) {
message = "ポン!相手はチョキを出しました。あなたの「勝ち」です。やったね!";
} else if (aiko == 1) {
message = "しょ!相手はチョキを出しました。あなたの「勝ち」です。やったね!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:チョキ × HUM:チョキ
if (cpu_janken == 2 && hum_janken == 2) {
matrix.loadFrame(matrix_c);
if (aiko == 0) {
message = "ポン!相手はチョキを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
} else if (aiko == 1) {
message = "しょ!相手はチョキを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 1;
delay(1000);
}
//CPU:チョキ × HUM:パー
if (cpu_janken == 2 && hum_janken == 3) {
matrix.loadFrame(matrix_c);
if (aiko == 0) {
message = "ポン!相手はチョキを出しました。あなたの「負け」です。ズコー!";
} else if (aiko == 1) {
message = "しょ!相手はチョキを出しました。あなたの「負け」です。ズコー!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:パー × HUM:グー
if (cpu_janken == 3 && hum_janken == 1) {
matrix.loadFrame(matrix_p);
if (aiko == 0) {
message = "ポン!相手はパーを出しました。あなたの「負け」です。ズコー!";
} else if (aiko == 1) {
message = "しょ!相手はパーを出しました。あなたの「負け」です。ズコー!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:パ- × HUM:チョキ
if (cpu_janken == 3 && hum_janken == 2) {
matrix.loadFrame(matrix_p);
if (aiko == 0) {
message = "ポン!相手はパーを出しました。あなたの「勝ち」です。やったね!";
} else if (aiko == 1) {
message = "しょ!相手はパーを出しました。あなたの「勝ち」です。やったね!";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 0;
status = 0;
}
//CPU:パー × HUM:パー
if (cpu_janken == 3 && hum_janken == 3) {
matrix.loadFrame(matrix_p);
if (aiko == 0) {
message = "ポン!相手はパーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
} else if (aiko == 1) {
message = "しょ!相手はパーを出しました。「あいこ」なのでもう一度じゃんけんボタンを押してください。";
}
cpu_janken = 0;
hum_janken = 0;
aiko = 1;
delay(1000);
}
}
}
追加プログラムの流れ
- じゃんけん開始中(status = 1)になったら、じゃんけんプログラムを開始する。
- じゃんけんアニメーション(高速)を読み出す。
- CPUのじゃんけんの手をランダムに抽出する。
- プレイヤーが選択した手との組み合わせによる、勝ち負け判定を行う。
- 「あいこ」の場合は、②再度じゃんけんアニメーション(高速)読み出しから行う。
じゃんけん開始中(status = 1)になったら、じゃんけんプログラムを開始する
onMessageChangeプログラム内で、メッセンジャーウィジェットにて「じゃんけん」と入力されると、変数statusの値に1が代入されます。
status = 1になったら、じゃんけん動作プログラムを実行します。
ここでは、メッセンジャーウィジェットにじゃんけんが始まったことを表示させます。
メッセンジャーウィジェットへの表示内容
- あいこでない(aiko = 0)とき
「じゃん、けん、」と表示させる。 - あいこ(aiko = 1)のとき
「あいこで、」と表示させる。
初回のじゃんけんと、あいこで再度じゃんけんするときで「かけ声」のセリフを変えています。
手を出したあとも「ポン!」と「しょ!」と区別しています。
じゃんけんアニメーション(高速)を読み出す
高速アニメーション動作ファイルの「janken_animation」を読み出します。
matrix.play(true)を指定することで、動画アニメーションを無限ループさせることができます。
CPUのじゃんけんの手をランダムに抽出する
random関数を使って、「1:グー、2:チョキ、3:パー」の中から無作為に手を選びます。
random(MINの値 , MAXの値+1) で指定します。
プレイヤーが選択した手との組み合わせによる、勝ち負け判定を行う
手の組み合わせで「勝ち」「負け」「あいこ」を判定します。
判定結果に応じたメッセージをメッセンジャーウィジェットに表示させます。
「あいこ」のときは、あいこであることを識別する変数aikoに1を代入します。
「あいこ」でないときは、じゃんけんを終了するためstatusに0を代入します。
じゃんけん後は、CPUとプレイヤーのじゃんけんの手を初期化するために0を代入します。
「あいこ」の場合は、②再度じゃんけんアニメーション(高速)読み出しから行う。
じゃんけんの結果が「あいこ」のときは、status = 1の状態が継続するため、再度じゃんけんの動作が始まります。
onMessageChangeプログラム
メッセンジャーウィジェットを配置すると、onMessageChangeプログラムが自動的にスケッチ内に生成されます。
このプログラムは、メッセンジャーウィジェットのメッセージ内容に変化があったときに呼び出される関数になります。
void onMessageChange() {
// Add your code here to act upon Message change
//じゃんけん開始前のとき
if (cpu_janken == 0) {
// 待機中LEDマトリクスアニメーションを読み出す。
matrix.loadSequence(janken_animation_op);
matrix.play(true);
delay(100);
}
if (message == "じゃんけん") {
//じゃんけんの開始
if (hum_janken == 0) {
status = 1;
}
} else if (message != "じゃんけん") {
message = "じゃんけん と入力すると、CPUとじゃんけんができます。";
aiko = 0;
status = 0;
}
}
onMessageChangeプログラムで追加したこと
- じゃんけん待機中のアニメーション表示
- じゃんけん開始の判断
- メッセンジャーウィジェットに「じゃんけん」以外の文字が入力されたときの動作
じゃんけん待機中のアニメーション表示
じゃんけん開始前に、グーチョキパー切り替えアニメーション(低速)を実行させます。
CPUのじゃんけんの手がランダムに選択されていないときは、初期値の0が代入されていることを監視して、じゃんけん待機中であるかどうかを判断しています。
じゃんけん開始の判断
メッセンジャーウィジェットに「じゃんけん」と入力されると、じゃんけんが開始されたと判断します。
じゃんけんステータス変数「status」に1を代入してじゃんけん開始状態に変更します。
メッセンジャーウィジェットに「じゃんけん」以外の文字が入力されたときの動作
メッセンジャーウィジェットに「じゃんけん」以外の文字が入力されると、「じゃんけん と入力すると、CPUとじゃんけんができます。」と表示させます。
じゃんけん待機中のステータスを継続します。
onBtnGChangeプログラム
プッシュボタンウィジェットを配置すると自動的に生成されるプログラムです。
ここでは「グー」ボタンが押されたときの動作を記述します。
/*
Since BtnG is READ_WRITE variable, onBtnGChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBtnGChange() {
// Add your code here to act upon BtnG change
//プレイヤーが「グーを選択したとき」
if (btn_g == HIGH) {
hum_janken = 1;
}
}
プレイヤーのじゃんけんの手を格納する変数「hum_janken」に1を代入します。
onBtnCChangeプログラム
ここでは「チョキ」ボタンが押されたときの動作を記述します。
/*
Since BtnC is READ_WRITE variable, onBtnCChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBtnCChange() {
// Add your code here to act upon BtnC change
//プレイヤーが「チョキを選択したとき」
if (btn_c == HIGH) {
hum_janken = 2;
}
}
プレイヤーのじゃんけんの手を格納する変数「hum_janken」に2を代入します。
onBtnPChangeプログラム
ここでは「パー」ボタンが押されたときの動作を記述します。
/*
Since BtnP is READ_WRITE variable, onBtnPChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBtnPChange() {
// Add your code here to act upon BtnP change
//プレイヤーが「パーを選択したとき」
if (btn_p == HIGH) {
hum_janken = 3;
}
}
プレイヤーのじゃんけんの手を格納する変数「hum_janken」に3を代入します。
ジャンケンマンを思い出させてくれるおもしろ電子工作
今回はArduino UNO R4 WIFIをArduino Cloudに接続し、スマホアプリからオンラインでArduinoとじゃんけん対決できるプログラムを紹介しました。
LEDマトリクスを使ってじゃんけん対決することで、懐かしのジャンケンマンを思い出させてくれますね!
今回のプログラム工作を作ってみて、じゃんけんは誰もが知っているシンプルなルールの遊びでありながらやっていて面白いゲームだなぁと改めて感じました。
Arduino本体さえあれば楽しめるテーマのため、Arduino uno r4 wifiを購入したら、ぜひチャレンジしてみてください。
ジャンケンマンをご存じのかたも、そうでない方も楽しめる電子工作になっていますので、ぜひお試しください!
Arduino Cloudには4つのプランがあり、無料のプランも提供されています。
Arduino Cloudのプランについては、こちらの記事にて詳しく説明しています。
Arduino UNO R4 WiFiで遊んでみたい!と思った方は下記サイトで購入できますのでご検討ください。
Arduino UNO R4 WIFIが買える国内サイト
通信ケーブルは別売りですので、本体と併せて購入すると送料がお得になる場合があります。
Arduino UNO R4 WIFIの始め方は、こちらの記事にて詳しく説明しています。
Arduino UNO R4シリーズはビジュアルプログラミングには対応していません。
Arduino UNO R3はビジュアルプログラミングにも対応していますので、小学生にはこちらがおすすめです。
ELEGOOのArduino互換キットは、コスパに優れた初心者向けキットです!
マトリクスLEDの点灯制御については、こちらの記事にて詳しく解説しています。
乱数制御については、こちらの記事にて詳しく説明しています。
オンラインおみくじ電子工作も楽しいですよ!
コメント