[ メニューへもどる ]

+++ カードゲームを作ろう +++

▼ 内容の一括ダウンロード (準備中) 2003/11/15
 ※吉里吉里 2.18 / KAG3.18 にて動作確認しています

 カードゲームに使えそうな処理を解説してみます〜。

 ■ シャッフル処理 ― KAG編 / TJS編応用編

 同じ数字がいくつ出ても OK な場合は、普通にランダムで数字を選べばいいわけですが、トランプゲームや

 全てを違う数字にしたい場合は、それに合わせた処理を考える必要が出てきます。

 では、まず KAG だけで組んでみましょう。

 わかりやすいように 1 から 10 までの数字で考えてみます。



  1.配列変数に、使う数字を代入

 例として二通り方法を挙げておきます。

 まず、手動で書き込む方法。

 使う数字が少ない場合や、特殊な場合はこちらのほうがわかりやすいかと。

  ; 1 から 10 まで代入

  @eval exp="f.suji = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]"

  ; 特定の数字を並べ替えたいときなどの一例

  @eval exp="f.suji = [ 1, 1, 1, 3, 3, 6, 6, 6, 8, 8 ]"

 もうひとつは、自動代入方法。

 トランプなどのように使う数字が多い場合はこちらのほうが楽かも。

  ; 配列変数を用意します

  @eval exp="f.suji = []"

  ; 処理を繰り返して、数字を順番に代入していきます
  ; 代入する対象の要素番号を変数 f.c で表します
  ; 要素番号の最初は 0 なので、初期値として 0 を代入します

  @eval exp="f.c = 0"

  ; 繰り返し用のラベルを置きます

  *suji_set

  ; 数値を代入します
  ; 今回は 1 から 10 までの数字を使うので、数値は要素番号 f.c に 1 を足して代入します
  ; たとえば f.c が 3 のときは f.suji[3] = 4 という式に置き換わります
  ; ※使う数字が 0 からならば、
  ;   @eval exp="f.suji[f.c] = f.c"
  ;  にすれば良いです

  @eval exp="f.suji[f.c] = f.c + 1"

  ; 処理が済んだら、代入する対象を次に移します
  ; 要素番号を表している変数 f.c に 1 を加算します
  ; ( f.c += 1 や f.c = f.c + 1 にしても同じです )
  ; たとえば今済んだのが [1] だったら、次は [2] が代入対象になります

  @eval exp="f.c++"

  ; 全ての数値を代入し終わるまで処理を繰り返します
  ; 今回は 10 個の数字を使うため、変数 f.c が 10 未満のうちは繰り返し用のラベルまで戻ります
  ; ※配列は [0] から始まるので、10 個の数字を使う場合は [0] 〜 [9] に代入されるわけです

  @jump cond="f.c < 10" target="*suji_set"

 ※あまりたくさんの数字 ( 5000 以上とか ) を自動代入させると、低スペックのパソコンでは処理に

  少し時間がかかってしまうので、そういう場合は TJS で書くほうが速いです。

  高スペックマシンなら KAG でも大丈夫かと。



  2.数字をランダムに並べ替える

 数字が用意できたら、シャッフルします。

 一回だけだと正確なシャッフルができないので、前からと後ろから、二回入れ替えます。

  ; 処理を繰り返して、数字を順番に入れ替えていきます
  ; 入れ替える対象の配列位置を変数 f.c で表します
  ; 配列変数の最初は [0] なので、初期値として 0 を代入します

  @eval exp="f.c = 0"

  ; 繰り返し用のラベルを置きます

  *rnd_set1

  ; 入れ替える相手をランダムに選び、変数 f.i に入れます
  ; ランダムに選ぶ場合、乱数用の関数 intrandom を使います
  ; 最小値は入れ替える対象の次、つまり f.c より 1 つ大きい数字になるので、 f.c + 1 と記述します
  ; 最大値は配列の最後を表す数字として、配列の要素数を表す .count を利用します
  ; 今回は使う数字が 10 個なので f.suji.count は 10 になります
  ; この .count は要素の合計数で、実際の要素番号は 0 から始まるため、 f.suji.count から 1 を
  ; 引いたものを最大値に指定しておきます
  ; これで、たとえば入れ替える対象が [1] なら [2] から [9] までが入れ替える相手になるわけです

  @eval exp="f.i = intrandom ( f.c + 1, f.suji.count - 1 )"

  ; 数字の位置を入れ替えます
  ; 入れ替え用の <-> という演算子を使います
  ; [f.c] や [f.i] は配列の何番目なのかを表しています
  ; 用意している数字を入れてある変数 f.suji の、入れ替える対象が f.c 、入れ替える相手が f.i です
  ; たとえば入れ替える対象が 1 で入れ替える相手が 8 だったとすると、f.suji[1] <-> f.suji[8] という
  ; 式に置き換わることになります

  @eval exp="f.suji[f.c] <-> f.suji[f.i]"

  ; 入れ替える処理が済んだら、入れ替える対象を次に移します
  ; 入れ替える対象を表している変数 f.c に 1 を加算します
  ; ( f.c += 1 や f.c = f.c + 1 にしても同じです )
  ; たとえば今済んだのが [1] だったら、次は [2] が入れ替える対象になります

  @eval exp="f.c++"

  ; 全ての数字が入れ替え終わるまで処理を繰り返します
  ; 配列の最後は入れ替え相手がいないので、 f.c が最後の要素番号より小さいうちは繰り返し用の
  ; ラベルまで戻ります
  ; ※今回の場合は、ここで f.c が 9 になったら処理終了

  @jump target="*rnd_set1" cond="f.c < f.suji.count - 1"

  ; 次に、逆からの入れ替え処理をします
  ; 対象用変数 f.c は初期化しないでそのまま利用します

  ; 繰り返し用のラベルを置きます
  ; ※上のラベルと名前が重複しないよう注意

  *rnd_set2

  ; 入れ替える相手をランダムに選び、変数 f.i に入れます
  ; 後ろから入れ替えていくため、最小値は要素番号の最初である 0 です
  ; 最大値は入れ替える対象の前、つまり f.c より 1 つ小さい数字になるので、 f.c - 1 と記述します
  ; たとえば入れ替える対象が [7] なら [0] から [6] までが入れ替える相手になるわけです

  @eval exp="f.i = intrandom ( 0, f.c - 1 )"

  ; 数字の位置を入れ替えます

  @eval exp="f.suji[f.c] <-> f.suji[f.i]"

  ; 入れ替える処理が済んだら、入れ替える対象を次に移します
  ; 入れ替える対象を表している変数 f.c から 1 を減算します
  ; ( f.c -= 1 や f.c = f.c - 1 にしても同じです )
  ; たとえば今済んだのが [7] だったら、次は [6] が入れ替える対象になります

  @eval exp="f.c--"

  ; 全ての数字が入れ替え終わるまで処理を繰り返します
  ; 入れ替え対象の最後は 0 なので、 f.c が 0 より大きいうちは繰り返し用ラベルまで戻ります
  ; ※ここで f.c が 0 になったら処理終了

  @jump target="*rnd_set2" cond="f.c > 0"



 こんな感じですね。

 次は TJS で表記してみます ...


 このサンプル処理の内容に対する質問やご意見は、当サイトの掲示板かメールにてお受け致します。

 サンプルの内容についてを W.Dee 氏に質問するのはご容赦くださいね(^^;

 混乱させてしまうのではないかと思いますので…

 また、動作確認は一通りしましたが、気付いていない不具合とかがあるかもしれません。

 発見した場合は、ぜひご一報頂けますと助かります m(_ _)m

[ メニューへもどる ]