トランプその5

このページではカードを使って併合処理を行うアルゴリズムについて学びます

準備

HTMLとCSSを準備します。
トランプその4で作成したプログラムをForkしましょう。
今回はちょっと準備に時間がかかります。

まずはHTML部分を大改造します。

完成予想図です。

これまで作ったボタンを移動して名前を変更したりしています。

<html>
   <body>
       <form name="form1">         
           <br>
            <INPUT TYPE="button" NAME="cmdCalc" value="開始" onclick="start()">           
       </form>
       
       <div id="disp">
        </div>
       <form name="form2">
               
        <br> 
       どのマーク?(0:♠,1:♣, 2:♥, 3:♦)<INPUT TYPE="text" NAME="txtA"><br>
       どの数字?(1~13)<INPUT TYPE="text" NAME="txtB"><br>
        <INPUT TYPE="button" NAME="cmdPut2" value="指定したカードを返す" onclick="putcard2()">           
 <br>
 手札1
       <INPUT TYPE="button" NAME="cmdGet" value="手札1にカードをもらう" onclick="getcard()">                    
        <INPUT TYPE="button" NAME="cmdPlace" value="手札1のカードを場札へ" onclick="placecard()">                    
       <INPUT TYPE="button" NAME="cmdPut" value="手札1のカードを返す" onclick="putcard()">                    
         <INPUT TYPE="button" NAME="cmdSort1" value="並べ替え1" onclick="mycardsort1()">           
        <INPUT TYPE="button" NAME="cmdSort2" value="並べ替え2" onclick="mycardsort2()">           
      <div id="disp2">
                
        </div>
  場札
        <div id="disp3">

       </div>
  手札2
       <INPUT TYPE="button" NAME="cmdGet2" value="手札2にカードをもらう" onclick="getcard2()">                    
   <INPUT TYPE="button" NAME="cmdPlace2" value="手札2のカードを場札へ" onclick="placecard2()">                    
         <INPUT TYPE="button" NAME="cmdSort3" value="並べ替え" onclick="mycardsort3()">           
      <div id="disp4">
           
        </div>
      </form>
 </body>
</html>


</form>で閉じる位置を後ろへずらしました。

<div id="disp3">〜</div>タグで表示領域を増やしています。同様にdisp4も作成します。
それぞれ手札1、場札、手札2と名称を付けています。

以下のボタンはここまでの練習課題等で作成済みのボタンです。これから作るボタンのために、名前を変えています。
手札1にカードをもらう   getcard()
手札1のカードを返す    putcard()
並べ替え1      mycardsort1()
並べ替え2      mycardsort2()

以下のボタンはこれから新規で作ります。関数名称が重複しないように注意しましょう。
手札1のカードを場札へ   placecard()
手札2にカードをもらう   getcard2()
手札2のカードを場札へ   placecard2()
並べ替え    mycardsort3()

ここまで修正ができたところで、ここまでのプログラムが動作しているか確認しておきましょう。

JavaScriptにプログラムを追加します。
大域変数を追加します。
var cards=[];
var mycards=[];
var mycards2=[];    //手札2用の配列 (追加)
var placecards=[]; //場札用の配列 (追加)
var cardcnt;
var mycardcnt;
var mycardcnt2;     //手札2の枚数 (追加)
var placecardcnt;  //場札の枚数 (追加)

initCardの最後で場札の枚数を初期化しましょう。
function initCard()
{
x=0;
for(i=1;i<=13;i++) {
    for(j=0;j<4;j++) {
   	cards[x]=new Card(j,i);
    	x++;
    }
}
cardcnt=13*4;
   
placecardcnt=0; // 場札の枚数初期化
}

initMyCardでは手札2用のmycardcnt2も初期化します。
function initMyCard()
{
   mycardcnt=0;
   mycardcnt2=0;  // 手札2の枚数初期化
}


確認が出来たら以下の練習課題に取り組みましょう。基本的にはこれまでに作ったプログラムと同様に作れます。
以下の課題は、併合を学ぶためのツールになる予定です。

練習

  • 手札2、場札の表示用の関数(dispMyCard2(),dispPlaceCard())を作成しましょう。参考は手札1の表示用関数dispMyCard()です。
    • 表示領域の指定も間違えないようにしましょう。
    • この段階では動作確認できません。次の課題に着手してから確認しましょう。
  • 手札2にカードをもらうボタン(getcard2())を作成しましょう。
    • 手札1にカードをもらうボタン(getcard())を参考にしましょう。
    • カードは手札の最後に追加するようにしてください
  • 手札1のカードを場札に出すボタン(placecard())を作成しましょう。
    • 手札1のカードを返すボタン(putcard())を参考にしましょう。
    • 手札1の先頭のカードを場札の最後に追加するようにしてください。
  • 手札2のカードを場札に出すボタン(placecard2())を作成しましょう。
    • 手札1のカードを場札に出すボタン(placecard())を参考にしましょう。
    • 手札2の先頭のカードを場札の最後に追加するようにしてください。
  • 手札2のカードを並べ替えるボタン(mycardsort3())を作成しましょう。
    • バブルソートでも挿入ソートでもどちらを使っても良いです。参考にするプログラムはmycardsort()mycardsort2()です。

マージ

マージ(併合)処理をする手順について説明します。
マージ処理とは、順番通りに並んだ2組のデータを1組に混ぜる処理です。
当然、マージ後にも順番通りに並ぶように処理します。


前提として、マージする2組は既に順に並んでいるものとします。
また、最後に9999という特殊な値を埋め込みます。
HIGH-VALUEと言いますが、最後の処理が簡単になります。
まず、先頭のカード同士を比較して小さい方のカードを出す事にします。


一枚出し終わりました。また先頭同士の比較を行います。
等しい場合は、下のカードを出す事にしましょう。


再び、比較を行います。こんどは上のカードが小さいです。

今度は下のカードが小さいです。

同じ値の場合は、下のカードを出します。

ここでHIGH-VALUE(9999)との比較です。
HIGH-VALUEは最も大きい数字を決めておきます。
小さいカードは、HIGH-VALUEではない方に決まります。

HIGH-VALUEは最後を表していますから、両方ともHIGH-VALUEになればマージ処理は終了です。
(プログラムの繰り返し条件で表すと、どちらかがHIGH-VALUEの間繰り返します)

プログラミングに進みましょう。
まずは準備です。

HTML部分に以下のようなボタンを作りましょう。
場所はFORM内ならどこでも良いですが、場札を表示する辺りが良いでしょう。
merge()という関数からプログラムを始めます。
<INPUT TYPE="button" NAME="cmdMerge" value="マージ" onclick="merge()">           


JavaScriptで、merge()関数を作成します。
function merge() {
 
}

HIGH-VALUEを作ります。9999というカードを考えてそれを手札の最後に入れておきます。
カードの枚数には入れないで、mycardcntとmycardcnt2は増やしません。
 var highcard = new Card(0,9999);
 mycards[mycardcnt]=highcard;
 mycards2[mycardcnt2]=highcard;

手札のカードをそれぞれ比較します。小さい方を場札に出します。
placecard()が手札1から場に出す処理、placecard2()が手札2から場に出す処理です。
また、HIGH-VALUEが移動しませんから改めて最後の位置にHIGH-VALUEを入れておきましょう。
 if(mycards[0].num<mycards2[0].num) {
    placecard();
    mycards[mycardcnt]=highcard;
 } else {
    placecard2();
    mycards2[mycardcnt2]=highcard;
 }       
ここまでで、ボタンを連続で押すとカードが場札の位置でマージされていきます。
マージする前に手札を並び替えるのを忘れずに。

練習

  • merge()を完成させましょう。
    • 繰り返す条件をHIGH-VALUEを使って表してください。
最終更新:2013年02月12日 00:39