魔法陣 Game

4 9 2
3 5 7
8 1 6

魔方陣とは1~Nまでの数字を「縦、横、斜め、の合計がいずれも等しくなる」ように並べた行列です。
カードゲームのクラスファイル(card.js)を使って魔法陣ゲーム(3方陣~8方陣)を作成します。
カードゲームクラスは Card Game を参照して下さい。

HTML のソースコードは、[F12]キーから[デバッガー]タブで確認することが出来ます。
2020/08/04 Windows10 & Microsoft Edge と Google Chrome で実行を確認しましたが、ブラウザによっては動かないことがあるかも知れません。
  1. 魔法陣の枠を表示する。(mahou_waku.html)
    枠を表示する
    1. 3~8の魔法陣のサイズをタイプして枠を表示するソースコードです。
      window.alert(s); で編集したソースコードを確認しています。
      必要なければコメントアウトして下さい。
      <html>
      <head>
      <meta charset="utf-8">
      <link rel="stylesheet" href="javascript.css" type="text/css">
      <title>Mahou</title>
      </head>
      
      <body>
      <h3>魔法陣ゲーム(枠を表示)</h3>
      
      <script>
      function func(num)
      {   window.alert(num);
      }
      mode = 3;
      mode = Number(prompt("魔法陣の数(3~8)を入力して下さい","3"));
      document.write('<table border="1">');
      for(var y=0; y<mode; y++)
      {   document.write('<tr>');
          for(var x=0; x<mode; x++)
          {   var id = '"B' + (y*mode+x) + '"'; 
              var s = '<td width="40" height="25"> <div id=' + id + 'onclick=func(' + id + ')>??</div></td>';
              window.alert(s);
              document.write(s);
          }
          document.write('</tr>');
      }  
      document.write('</table>');
      </script>
      
      </body>
      </html>
      
    2. プログラムを起動すると魔法陣の数(3~8)を聞いてくるので3を入力して下さい。
      Table の <td> をデバッグするために window.alert(s) を9回実行するので応答して下さい。
      応答が終わると3*3のマスの中に??が表示されます。
    3. マスをクリックすると func() 関数が実行されて div に設定されたID(B0, B1, ...)が window.alert で知らされます。
  2. 数字を表示する。(mahou_num.html)
    マスに入れる数字を表示する

    1. カードゲームのクラスファイル(card.js)を使って、魔法陣に入れる数字を表示します。
      <script src="card.js">
      </script>
      </head>
      
      <body>
      <h3>魔法陣ゲーム(数字を表示)</h3>
      
      <script>
      function func(num)
      {   window.alert(num);
      }
      mode = 3;
      mode = Number(prompt("魔法陣の数(3~8)を入力して下さい","3"));
      document.write('<table border="1">');
      for(var y=0; y<mode; y++)
      {   document.write('<tr>');
          for(var x=0; x<mode; x++)
          {   var id = '"B' + (y*mode+x) + '"'; 
              var s = '<td width="40" height="25"> <div id=' + id + 'onclick=func(' + id + ')>??</div></td>';
              document.write(s);
          }
          document.write('</tr>');
      }  
      document.write('</table>');
      
      var card= new CARD("img/d48.gif", 30, 20, 300, 140);
      card.View(64, 0, 280);
      var num = mode * mode;
      for(i=0; i<num; i++)
      {   card.View(i, i%mode*30+20, Math.floor(i/mode)*20+280);
      }
      </script>
      
    2. head で "card.js" を組み込んで下さい。
      カードゲームクラスは Card Game に掲載しています。
      <script src="card.js">
      </script>
      </head>
      
    3. 魔法陣の下にマスに入れる数字を表示します。
      card.View(64, 0, 280); は数字が選択されたときに置き換える画像で、デバッグのために表示しています。
      var card= new CARD("img/d48.gif", 30, 20, 300, 140);
      card.View(64, 0, 280);
      var num = mode * mode;
      for(i=0; i<num; i++)
      {   card.View(i, i%mode*30+20, Math.floor(i/mode)*20+280);
      }
      
    4. 3~8をタイプして魔法陣と数字を確認して下さい。
      魔法陣の??をクリックすると func() 関数が呼び出されてIDが知らされるのは前回と同じです。
  3. 魔法陣 & 数字をクリックで選択する。(mahou_sel.html)
    数字のクリックを追加
    1. 数字をクリックすると func() 関数が呼ばれる処理を追加します。
      <script src="card.js">
      </script>
      </head>
      
      <body>
      <h3>魔法陣ゲーム(セル&数字を選択)</h3>
      
      <script>
      function func(num)
      {   window.alert(num);
      }
      mode = 3;
      mode = Number(prompt("魔法陣の数(3~8)を入力して下さい","3"));
      document.write('<table border="1">');
      for(var y=0; y<mode; y++)
      {   document.write('<tr>');
          for(var x=0; x<mode; x++)
          {   var id = '"B' + (y*mode+x) + '"'; 
              var s = '<td width="40" height="25"> <div id=' + id + 'onclick=func(' + id + ')>??</div></td>';
              window.alert(s);
              document.write(s);
          }
          document.write('</tr>');
      }  
      document.write('</table>');
      
      var card= new CARD("img/d48.gif", 30, 20, 300, 140);
      var num = mode * mode;
      for(i=0; i<num; i++)
      {   //card.View(i, i%mode*30+20, Math.floor(i/mode)*20+280);
          card.Func(i, i%mode*30+20, Math.floor(i/mode)*20+280, i, "func");
      }
      </script>
      
    2. カードクラス(card.js)を使った数字の描画を //card.View から card.Func に変えて func() 関数を呼び出します。
      魔法陣のクリックではIDに「 B0, B1, ...」を使ったのですが、数字のクリックでは「0, 1, 2, ...」を使います。
      魔法陣と数字をクリックしてIDを確認して下さい。
  4. 数字の選択とキャンセル。(mahou_cancel.html)
    数字の選択とキャンセル
    1. 数字の選択を制御する func() 関数です。
      <script>
      function func(num)
      {   window.alert(num);
          if (num.charAt(0)!='B')
          {   if (sel>63)
              {   sel = Number(num);
                  var s1 = card.Clip(64, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  var s2 = card.Position(64, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  s = s1 + ' ' + s2;
                  document.images[sel].style= s;
              }
              else
              {   var s1 = card.Clip(sel, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  var s2 = card.Position(sel, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  s = s1 + ' ' + s2;
                  document.images[sel].style= s;
                  sel = 64;
              }
          }
      }
      mode = 3;
      sel = 64;
      
    2. num の先頭文字が 'B' で無いときは、数字のクリックです。
      sel が選択された番号を保存する領域で、初期値に 64(?)を設定します。
      sel>63 のとき、クリックされた数字を sel に保存して、表示を?にします。
      sel==64 のときは、元の数字に戻します。
    3. 数字をクリックして?に変わることを確かめて下さい。
      もう一度クリックすると元の数字に戻ることを確かめて下さい。
  5. 魔法陣ゲームのα版。(mahou_alpha.html)
    魔法陣ゲームのα版です
    1. 一応プレイが出来る魔法陣ゲームのα版です。
      function func(num)
      {   //window.alert(num);
          if (num.charAt(0)!='B')
          {   if (sel>63)
              {   sel = Number(num);
                  var s1 = card.Clip(64, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  var s2 = card.Position(64, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  s = s1 + ' ' + s2;
                  document.images[sel].style= s;
              }
              else
              {   var s1 = card.Clip(sel, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  var s2 = card.Position(sel, sel%mode*30+20, Math.floor(sel/mode)*20+280);
                  s = s1 + ' ' + s2;
                  document.images[sel].style= s;
                  sel = 64;
              }
              return;
          }
          if (sel>63) return;
          document.getElementById(num).textContent= sel+1;
          var s1 = card.Clip(65, sel%mode*30+20, Math.floor(sel/mode)*20+280);
          var s2 = card.Position(65, sel%mode*30+20, Math.floor(sel/mode)*20+280);
          s = s1 + ' ' + s2;
          document.images[sel].style= s;
          sel = 64;
      }
      mode = 3;
      sel = 64;
      
    2. 数字をクリックで選択すると、?(64)に変わります。
      選択状態で、再度数字をクリックすると元に戻ります。
      数字を選択して、魔法陣をクリックすると数字が置かれます。
      後は魔法陣の完成チェックをすればOKです。
  6. 魔法陣ゲームのβ版。(mahou_beta.html)
    魔法陣ゲームのβ版です
    1. α版に完成チェック関数(check) を追加して完成です。
      魔法陣の全ての数字が埋まったら、もう一度魔法陣をクリックして下さい。
      func(num) 関数の先頭から check() 関数を呼び出します。
      function func(num)
      {   //window.alert(num);
          check();
          if (num.charAt(0)!='B')
      
    2. check() 関数のソースコードです。
      //コメントは3魔法陣のときの覚書です。
      function check()
      {   var n = new Array(0, 0, 0, 15, 34, 65, 111, 175, 260);
          var t = new Array();
          var s = new Array();
          var num = mode * mode;
          for(var i=0; i<num; i++)
          {   var id= document.getElementById('B' + i).textContent;
              if (id.charAt(0)=='?')  return;
              t[i]= Number(id);
          }
          // 完成チェック(縦・横・斜め)
          var num = mode + mode + 2;
          //var num = mode + mode;
          for(var i=0; i<num; i++)    s[i]= 0;
          for(var i=0; i<mode; i++)
          {   for(var j=0; j<mode; j++)
              {   s[i]= s[i] + t[i*mode+j];           //s[012]= 0,1,2  3,4,5  6,7,8
                  s[i+mode]= s[i+mode] + t[j*mode+i]; //s[345]= 0,3,6  1,4,7  2,5,8
              }
              s[mode*2]= s[mode*2] + t[i*(mode+1)];           //s[6]= 0,4,8  
              s[mode*2+1]= s[mode*2+1] + t[(i+1)*(mode-1)];   //s[7]= 2,4,6  
          }
          for(var i=0; i<num; i++)
          {   if (s[i]!=n[mode])
              {   window.alert("Error i:" + i + "  s[i]:" + s[i] + "  n[]:" + n[mode]);
                  return;
              }
          }
          window.alert("☆完成しました");
      }
      
    3. var n は、魔法陣の縦・横・斜めの合計がいくらになるかのテーブルです。
      var t は、魔法陣に格納されている数字を拾い出すテーブルです。
      var s は、縦・横・斜めの合計を計算するテーブルです。
      {   var n = new Array(0, 0, 0, 15, 34, 65, 111, 175, 260);
          var t = new Array();
          var s = new Array();
      
    4. 魔法陣に設定された div のIDでテキストを取得して、先頭が?なら数字が埋まっていません。
      魔法陣の数字をテーブル t に拾い出して完成のチェックをします。
      完成チェックは、[縦・横](方陣数の2倍)と斜め(2個)の合計がテーブル n で定義した値と一致するかを調べます。
      var num = mode + mode + 2;
      
    5. 魔法陣の縦横斜めの合計は、次のようになります。
      魔法陣 合計値
      3魔法陣 15
      4魔法陣 34
      5魔法陣 65
      6魔法陣 111
      7魔法陣 175
      8魔法陣 260
      12魔法陣 870
      16魔法陣 2056

前田稔の超初心者のプログラム入門
超初心者のプログラム入門(JavaScript)