日別アーカイブ: 2015-01-24

1000人あみだくじ

1000人あみだくじの概要

前回の多人数あみだくじを改良し参加人数を1000人まで増やし再表示機能を追加しました。多人数のくじ結果表示は見にくくなるので、エルドラドの迷路のような表示はされません。一画面に20名ずつ表示させ20名を超える場合は表示をいったん停止して表示されます。

1000人あみだくじの使い方

1000人あみだくじ

スピンボタンを操作してあみだくじ参加人数を3~1000人の範囲で入力し、表示ボタンをクリックします。
②次に《くじ引き結果表示》のメッセージ出力後、OKを指定して順番号=引き当て番号:逆リンク先番号を最大20名ぶん表示させます。
③20名を越す場合は、すべての参加者が表示されるまでOKを指定し続けます。
④同一結果をもう一度表示するには再表示ボタンをクリックし②項から繰り返します。
⑤シャッフルをやり直したり、参加人数を変更するなど異なる条件で新たなあみだくじを作成するには、表示ボタンを押し「処理は終了しています。シャッフルして実行しますか?」の問い合わせにOKを指定します。

用途例

このあみだくじは大勢の人数の順番を決めるときなどに利用されます。50人を10人ずつ5チームに分ける場合にも便利に使えます。まず、50人に0~49のID番号を割り振ります。この行為は必須です。出席順や参加名簿の順番などを用います。

くじを引いてID番号(i)を引き当て番号(n)に変換し、先頭から10名ずつ5チームに分けます。引き当て番号を10で割り、少数点以下を切り捨てると0~4の値(c)が求まります。この値で5チームに分けられます。

c = n / 10;部屋割り表

数学的には除算して余りを求める剰余演算(CやJavaでは%演算子)をするのが一般的ですが、割り算結果の商の値が親しみやすいです。

次の例は20人を4人ずつ2部屋、6人ずつ2部屋に振り分ける例を示します。上から順に4,4,6,6と線引きして部屋決めしています。ID番号13,0,18,5の参加者が部屋番号5010に宿泊するように決定した例です。

注意事項

ビジュアルテキスト①サンプル動作にはHTMLコードを埋め込みますが、編集作業の最終段階で、テキストモードにして挿入しこのモードでファイルを更新します。ビジュアルモードではHTMLのタグコードが自動で付加され、正しい動作にならないことがありました。

②1000人のあみだくじを引く処理はHTML5+canvasを用いているので新しいブラウザを利用してください。

③力量不足とあいまって謎めいた動作になることがありました。ブラウザごとに動作が異なり難解です。canvasをサポートするブラウザは開発途上のこともあり、すべてのブラウザで期待した結果を得ることは至難です。パワーの小さい機種ほど、動作が跳ぶ体験をしました。徐々に解決に向かうことでしょう。

④アラートのメッセージボックス、□このページでこれ以上ダイアログボックスを生成しないの□にチェックマークを入れないでください。

⑤20名以下のあみだくじ結果は表示画面をコピーしてプリントすれば掲示板に貼り付けることができます。せっかくの多人数くじ引きを効果的にするには、くじ引き結果をファイル化したり結果を印刷する機能強化が望ましいです。

サンプルコード

<html>
<body onLoad="init();">
<canvas id="tutorial" width="385" height="405"  style="background-color:lightyellow;"></canvas><BR>&nbsp;&nbsp;
<input type="number" id="spepper" name="spepper" min="3" max="1000" value="20"/>&nbsp;&nbsp;<input type="button" onClick="saveValue('spepper');" value="表示"/>&nbsp;&nbsp;<input type="button" onClick="MouseDown2();" value="再表示"/><BR>
</body>
<head>
<script type="text/javascript">
var p = q = 0;
var NUMBER=0;
var count=0;
var canvas=0;
var ctx;
var img2;
var img3;
var StringColor = ["lightyellow", "blue"];
var person = [];                          // +---------------+--------------+
var member = [];                          // |生成した乱数値 | ID番号      |
                                          // +---------------+--------------+
function init(){                          // when onload, init-top
  img2 = new Image();                     // 新規画像オブジェクト,早めにロードしておく
  img2.src = "https://aidesign.lolipop.jp/wp-content/uploads/2014/09/happy-1.png";
  img3 = new Image();                     // 新規画像オブジェクト,早めにロードしておく
  img3.src = "https://aidesign.lolipop.jp/wp-content/uploads/2014/09/chusenkai.png";
}                                         // when click, init-bottom
function saveValue(target){               // value="表示", 参加人数を設定
  if(NUMBER){
    if(confirm("処理は終了しています。シャッフルして実行しますか?")==true){
       count = 0;
       ResultOut(p, q, 0);
       NUMBER = document.getElementById(target).value;  // onClickの設定値を取り出す
    }
    else return false;
  }
  else NUMBER = document.getElementById(target).value;  // onClickの設定値を取り出す
    canvas = document.getElementById('tutorial');
    ctx = canvas.getContext('2d');
    ctx.fillStyle = "black";              // 参加者の名前を表示
    ctx.font = "normal 14px arial black";
    ctx.fillText("2015,copyright Aidesign", 155, 40);// Version
    ctx.font = "normal 20px arial black";
    ctx.fillText("1000人あみだくじ,V0.49", 155, 20);// Version
    ctx.drawImage(img2, 170,  50, 180, 150);// <<<<< 抽選箱を描画 >>>>>
    ctx.drawImage(img3, 160, 215, 210, 150);// <<<<< うちわを描画 >>>>>
    for(var i=0; i<NUMBER; i++){            // +---------------+--------------+
      w = Math.floor(Math.random() * 65536);// 0~65535までの乱数を発生させる
      person[i] = w * 65536 + i;          // 生成した乱数値とID番号を合成する
    }
    person.length = NUMBER;               // 配列の再利用対策
    person.sort();                        // 小さい順に並び替える
    for(i=0; i<NUMBER; ++i){              // 移動先を把握する
      x = person[i] % 65536;
      member[x] = i;
    }
    report();                             // くじ引き結果を描画する
}
function fmt(n){                          // 右寄せで表示する
  return ("000"+n).slice(-3);
}
function ResultOut(a, b, color){
  for(i=a; i<b; ++i){                     // 並び替えられた結果を表示する
    x = person[i] % 65536;
    v = "=" + fmt(x);
    s = ":" + fmt(member[i]);
    ctx.fillStyle = StringColor[color];   // 参加者の名前を表示
    x = i % 20;
    ctx.fillText(fmt(i)+v+s, 1, 20+20*x); // result
  }
}
function report(){
    alert("《くじ引き結果》\n20名ずつ区切って表示します。");
    while(w = count * 20, w < NUMBER){
      if(q != 0) ResultOut(p, q, 0);
      p = w;
      q = (++count) * 20;
      if(q > NUMBER) q = NUMBER;
      ResultOut(p, q, 1);
      alert(p+" ~ "+(q-1)+" を表示しました。");
    }
}
function MouseDown2(){                    // value="再表示"
  if(NUMBER==0) alert("参加人数が設定されておりません。");
  else{
    count = 0;
    report();                             // くじ引き結果を描画する
  }
}
</script>
</head>
</html>

サンプル動作