見出し画像

カード配るってどうやって?~RND関数について

Pi STARTER(ラズベリーパイ用BASIC言語パッケージ)版
ひとりで遊べる人狼ゲームを公開中(要ラズパイ&Pi STARTER)

http://www.ne.jp/asahi/chitose/net/download/jinrou/

人狼ゲーム」はまず各プレイヤーに役職カードを配ることで始まります。

画像1

今回作ろうとしている「人狼ゲーム」は10人のプレイヤーに対して

村人・・・4人
予言者・・・1人
ボディーガード・・・1人
霊媒師・・・1人
裏切り者・・・1人
人狼・・・2人

という風に役職カードを振り分けるので、まずこの処理を作ります…って、どうすんのこれ。ラズパイがカード配ってくれるわけじゃないよね?

はい、ここで登場するのが「RND関数」というヤツです。
あ、ほらそこ「関数」って文字見ただけで逃げ出さないの!
私だって学生の頃、数学はいつも赤点で、「関数」って言葉聞くだけで逃げていくクチだったんだから。

以前にこちらでも書きましたが、RND関数とは分かりやすく言うとサイコロの目を出す命令です(正確さはその辺に置いといて解説してます)。
例えば0を起点とする6面サイコロの目を出したければ、

X=RND(6)

と書いて実行すれば、Xの中に0~5のいずれかの数値が入ります。
カンタンっしょ?
関数とか言ったってぶっちゃけこんなもんっすよ。
(↑お前それ関数舐めすぎだから)

今回は役職がちょうど6種類なんで、こうすることにしました。

サイコロの目が「0」村人・・・4人
サイコロの目が「1」予言者・・・1人
サイコロの目が「2」ボディーガード・・・1人
サイコロの目が「3」霊媒師・・・1人
サイコロの目が「4」裏切り者・・・1人
サイコロの目が「5」人狼・・・2人

おぉ~、これで出来ちゃうやん!私って天才やね!!

画像2

↑なんか定例化してきたなこのネタも。

…あれ?でもこれに従って決めてくと、予言者が3人いたり人狼がいなかったりしてしまうぞ?
そっか、ただプレイヤーごとにサイコロ振ってるだけだもん、そりゃそうなるよな…。

いろいろ考えたあげく、最初はサイコロを10面にしてみました。

X=RND(10)

RND関数は( )内の数値を変えることによって何面サイコロだって作れるのです。昔これで100万単位の数当てゲームとか作りました。まぁそれはともかく、これで賽は投げられた(文字通り!)コロコロ…。

サイコロの目が「0~3」村人・・・4人
サイコロの目が「4」予言者・・・1人
サイコロの目が「5」ボディーガード・・・1人
サイコロの目が「6」霊媒師・・・1人
サイコロの目が「7」裏切り者・・・1人
サイコロの目が「8~9」人狼・・・2人

このようにしてサイコロを各プレイヤーごとに振らせ、各役職の人数を最後にチェック、適正な割り振りが出来てなかったら最初からやり直させる、というプログラムを書いたのです。
ただこのプログラムは誤作動が多く(理由はよく分からない)、ほどなくして改良を迫られることになったのでした。グズン。

最終的には、やはりサイコロを6面(X=RND(6))に戻し、次のようなプログラムを書いて決着したのでした。

1.プレイヤーAから順にサイコロを振る。
2.「0」だったらそのまま村人になる(初期値が0だから)。
3.「1~4」の役職者はそれぞれ1名ずつなので、そこの枠が空いてれば「1」を代入する。空いてなければサイコロを振りなおす。
4.「5」の人狼は2名いるので、2名を超えないかどうかをチェックする。
枠が空いてれば「1」を加算。空いてなければサイコロを振りなおす。
5.次のプレイヤーがサイコロを振り、2~4を繰り返す。
6.プレイヤーJまで終わったら次に進む。
7.全役職が適正人数いるかを確認する。
8.役職の人数が合っていれば次に進み、そうでなければ1からやり直す。

文字ベースにすると何かゴチャっとしてますね。
ホントはこういうのを分かりやすくするためにフローチャートとかいうのがあるんだろうなぁ(作ったことないから分からんけど)。

ちょっと長くなりますが、役職カードを配る部分のコードを記載します。
(多少、記事用に編集しています)

@ROLE
'やくわり けってい'
CLS
PRINT "では それぞれ の やくわり を"
PRINT "けってい します。"
LINPUT N$
PRINT
@J '← それぞれのプレイヤーの役職決定'
'(A~Jまで同じ処理を行なう。ここでは「J」の処理のみ掲載)'
J[2]=RND(6) '← サイコロを振る'
IF J[2]==1 THEN '← 1が出たら'
 IF K[1]==1 THEN @J '← もう予言者決まっていたらサイコロを振りなおす'
 IF K[1]==0 THEN K[1]=1 '← まだ予言者いなければ決定。'
ENDIF
 IF J[2]==2 THEN '← 2が出たら'
 IF K[2]==1 THEN @J '← もうボディーガード決まっていたらサイコロを振りなおす'
 IF K[2]==0 THEN K[2]=1 '← まだボディーガードいなければ決定。'
ENDIF
IF J[2]==3 THEN '← 3が出たら'
 IF K[3]==1 THEN @J '← もう霊媒師決まっていたらサイコロを振りなおす'
 IF K[3]==0 THEN K[3]=1 '← まだ霊媒師いなければ決定。'
ENDIF
IF J[2]==4 THEN '← 4が出たら'
 IF K[4]==1 THEN @J '← もう裏切り者決まっていたらサイコロを振りなおす'
 IF K[4]==0 THEN K[4]=1 '← まだ裏切り者いなければ決定。'
ENDIF
IF J[2]==5 THEN '← 5が出たら'
 IF K[5]==2 THEN @J '← もう人狼2名決まっていたらサイコロを振りなおす'
 IF K[5]<2 THEN K[5]=K[5]+1 '← まだ人狼2名以下なら人狼1名決定。'
ENDIF
'やくわり が たりない ばあい の しょり'
K[0]=10-K[1]-K[2]-K[3]-K[4]-K[5] '← 10から残り役職者の数を引いて村人の数を求める'
IF K[0]==4 AND K[1]==1 AND K[2]==1 AND K[3]==1 AND K[4]==1 AND K[5]==2 THEN @FIX '← 役職者は適正人数いるか?いたら先に進む'
K[0]=0:K[1]=0:K[2]=0:K[3]=0:K[4]=0:K[5]=0
GOTO @A '← そうでなければ最初からやり直せ'
@FIX
'やくわり ほうこく'
IF A[2]==0 THEN K$="ふつうのむらびと" '← 役職の文字変数'
IF A[2]==1 THEN K$="よげんしゃ" '← 役職の文字変数'
IF A[2]==2 THEN K$="ボディーガード" '← 役職の文字変数'
IF A[2]==3 THEN K$="れいばいし" '← 役職の文字変数'
IF A[2]==4 THEN K$="うらぎりもの" '← 役職の文字変数'
IF A[2]==5 THEN K$="じんろう" '← 役職の文字変数'
PRINT "あなた の やくわり が"
PRINT "きまりました。"
LINPUT N$
PRINT
COLOR RGB(0,255,0)
PRINT K$;" です。" '← 役職を宣言する'

一見複雑怪奇っぽいですが、実際はほとんどRND関数とIF~THEN(ENDIF)を含んだ基本的な命令しか使ってません。
むしろこんなわずかなコード覚えるだけでここまで出来ちゃうんだと思ってもらえたら幸いなのですが…。

画像3

さて、カードを配る処理がこうして何とかできました。
やればできる子やん私。

次回取り上げるのは「プレイヤーが誰かを指名する」という処理について。
これまでベーマガとかに載ってたプログラムを打ち込むだけで、ロクに勉強しなかったツケを私はここで思い知ることになるのです…。

この記事が気に入ったらサポートをしてみませんか?