トランプその3

今まで作って来たトランプを基本に配列のずらしこみを学びます。

準備

HTMLとCSSを準備します。
トランプその2で作成したプログラムをForkしましょう。
線形探索のプログラムも後半で使います。

HTMLとCSSを準備します。
このページで作成するプログラムで共通で使用します。

HTML
<html>
   <body>
       <form name="form1">         
           <br>
            <INPUT TYPE="button" NAME="cmdCalc" value="開始" onclick="start()">           
       </form>        
     
   <div id="disp">
        </div>
	<form name="form2">
        <INPUT TYPE="button" NAME="cmdGet" value="カードをもらう" onclick="getcard()">                    
        <INPUT TYPE="button" NAME="cmdPut" value="カードを返す" onclick="putcard()">                    
 
        <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()">           
      </form>
       <div id="disp2">
        </div>
  </body>
</html>

トランプその2で作成したHTMLにボタンをいくつか追加しています。

getcard() カードをもらうボタン
putcard() カードを返すボタン
putcard2() 指定したカードを返すボタン

手札の準備

カードをもらって手札にする処理を考えます。
カードの枚数が増減しますから、それぞれのカード枚数を保存するための変数を用意します。
プログラムではカードの枚数に合わせた処理になるよう修正していきます。

先頭に以下の変数を定義します。
var cards=[]; //既に定義済みのトランプを保存する配列
var mycards=[]; // 追加。手札のカードを保存する配列
var cardcnt; // 追加。トランプの枚数を保存する変数
var mycardcnt; // 追加。手札の枚数を保存する変数。

カードの初期化を行う関数(initCard)を修正します。
最後に以下の一文を追加してください.
cardcnt=13*4;
最初のカードの枚数で初期化しています。

新しく手札を初期化する関数(initMyCard)も作ります。
function initMyCard()
{
   mycardcnt=0;
}
最初は手札がありません。枚数が0枚であることを設定しています。

次に表示用のプログラム(dispCard)を修正します。
これまではカードの枚数が決まっていましたが、カードの枚数が変数cardcntに格納されています。
繰り返し条件を変更して以下のようにします。
for(i=0;i<cardcnt;i++) {
   tempHtml = tempHtml+ markimg[cards[i].mark] + ":" + numimg[cards[i].num] +"</font> ";
}

次に手札の表示用のプログラムを新しく書きます。(dispMyCard)
dispCardとほぼ同じプログラムです。
function dispMyCard()
{    
   var tempHtml = "";
   for(i=0;i<mycardcnt;i++) {
       tempHtml = tempHtml+ markimg[mycards[i].mark] + ":" + numimg[mycards[i].num] +"</font> ";
   }
   tempHtml += "<BR>";   
   document.getElementById("disp2").innerHTML = tempHtml;
}
変更点はcards >> mycardscardcnt >> mycardcnt , 表示する領域は disp2 です。

また、今までdispCardの中で宣言されていた markimgとrumimgは共通で使うため関数の外部に移動します。
var markimg = ["<font color='black'>♠","<font color='black'>♣","<font color='red'>♥","<font color='red'>♦"];
var numimg = ["","A","2","3","4","5","6","7","8","9","10","J","Q","K"];

ここで、手札を含めて初期化できるようにstart関数を修正します。
function start()
{
   initCard();  
   initMyCard(); //追加
   shuffleCard(); 
   dispCard(); 
   dispMyCard(); //追加
}
手札の初期化と表示を追加しましょう。

ここまでで動作確認をしておきましょう。特に新しい機能が追加されたわけではありませんが、修正によって現状維持できているかを確認する事は大切です。

配列ずらしこみ

ボタンを押すとカードを一枚手札に入れる処理を書きます。
場のカードの一番先頭を手札に最後に入れることにします。

まずは処理イメージからです。
先頭のカードを抜いて一時保存の領域に保存しておきます。

続いてずらしこみのイメージです。
空けたカードの位置へ向かって順次繰り返しで隣のカードをコピーしていきます。処理中は同じカードが2枚存在するように見えます。


関数 getcardを作成します。
function getcard()
   ここにプログラムを書く
}

カードを一時保存する変数cと繰り返し用の変数iを宣言しておきます。
var c; 
var i;

引くカードが無ければ処理を続けることはできません。
最初にカードの枚数が0より大きいことを確認します。
if( cardcnt>0 ) {
   ここに処理を書く
}

カードを引く処理では、最初に先頭のカードを一時保存用の変数cに代入します。
 c = cards[0];

ずらしこみの基本的なプログラムです。先頭のカードは一時保存用の変数に入れましたから、そこへ次々とカードをずらしていきます。cards[i]cards[i+1]は常に隣のカードを表しています。
 for(i=0;i<cardcnt;i++) {
   cards[i]=cards[i+1];   
 }

カードのずらしこみが終わったら、カード枚数を一枚減らします。
cardcnt--;

続いて、一時保存しておいたカードを手札のカードの配列に入れます。

mycardcntにはカードの枚数が入っていますが、配列の最後の添え字も表しています。さらに手札の枚数を一枚増やしておきます。
mycards[mycardcnt]=c;
mycardcnt++;

最後に移動したカードを表示するためにカード表示用関数を呼び出します。
dispCard();
dispMyCard();

ここまでの完成版のプログラムです。カードを返すボタンは練習で作成するので、まだ未完成です。

練習

  • 手札のカードの先頭のカードを場札のカードに返す関数 putcard を作成しましょう。
    • 基本的にはgetcardの逆の操作を行えばOKです。
  • 手札にカードをもらう時に、最後では無く先頭にカードをもらうように修正してみましょう。
    • 先頭にカードをもらうためには、後ろの方にカードをずらしこみをして先頭をあけてから新しいカードを入れましょう。
    • 繰り返す順番に注意
最終更新:2012年12月18日 00:18