• 締切済み

携帯用パズルのシャッフルについて

noname#35109の回答

noname#35109
noname#35109
回答No.1

ご質問の意味自体が今ひとつわかりません。 書かれているスクリプト自体は,正常に動作しますよね。 重複しないランダムな0~15までの整数が, 変数 p0 ~ p15 にそれぞれ代入されます。 ですから, 各マスに p0 ~p15 という変数名をつけてあると, ちゃんとランダムな数が表示されます。 したがって, 書かれているスクリプト自体の間違いを指摘して欲しいわけではないのですよね。 ということは, MC0 ~ MC15 のインスタンス名のムービークリップを, その求められた変数を元に,ランダムに配置したいと言うことでしょうか? 仮にそうだとしても, 変数名 p0 ~p15 のマス(テキストフィールド)と, インスタンス名 MC0 ~ MC15 のムービークリップ との表示上の位置関係がどうしたいのかがわかりません。 なので,勝手に p0 ~ p15 のマスの座標と, MC0 ~ MC15 の座標を一致させるという方法を書きます。 Flash MX 以上(Flash Player 6 以上)だと, テキストフィールドにインスタンス名が付けられるので, テキストフィールド の座標プロパティなどを取ってくることができますが, Flash Lite 1.1 までではそれができません。 したがって, マス(テキストフィールド)をムービークリップの中に入れてそのムービークリップの座標を取ってくるという方法を使います。 まず, ステージ上に,例えば 「num」 という "変数名" のテキストフィールドを用意します。 そしてそのテキストフィールドをムービークリップに変換します。 その,変換したムービークリップに 「p0」 という "インスタンス名" を付けます。 あとは,この 「p0」 をコピペで増やして,増やした物に, 残りの 「p1」~「p15」 という "インスタンス名" を付けます。 この書くインスタンスの中の,変数 num に,ランダムな数を入れれば良いと思います。 それで, 例えば,p0 という ムービークリップ の,変数num の値が 5 であれば, MC5 の座標を p0 と合わせる, 例えば,p1 という ムービークリップ の,変数num の値が 15 であれば, MC15 の座標を p1 と合わせる,   …  … という処理を for 文ですれば良いと思います。 ですから, 上で書いたような場合スクリプトは次のようになります。 --------------------------------------- // MC p0 ~ p15 の各変数 num に,ランダムな数を代入 for (i=0; i<16; i++) { while (1) { eval("p" add i add "/:num") = random(16); flag = 0; for (j=0; j<i; j++) { if (eval("p" add i add "/:num") == eval("p" add j add "/:num")) { flag = 1; } } if (flag == 0) { break; } } } // MC0~15の座標を上で得た 変数num の入った p? と一致させる for (i=0; i<16; i++) { myX = getProperty("p" add i, _x); myY = getProperty("p" add i, _y); setProperty("MC" add eval("p" add i add "/:num"), _x, myX); setProperty("MC" add eval("p" add i add "/:num"), _y, myY); } -------------------------------------- 勝手に座標を合わせることにしていますが, 合わせない場合は,プラスマイナスで補正すれば,適度にズレルと思います。 ご質問を勝手に解釈したところが多いですが, こんな感じの回答を求めていらっしゃるのでしょうか? >> 参考になるサイトなどもあれば >> 教えていただけると助かります。 私はヘルプがいちばん参考になると思います。 断片的にしかありませんよね,サイト上は。

unagi127
質問者

お礼

こんなにわかりにくい質問なのに、丁寧に答えて頂きまして 本当にありがとうございます。 あと、できればでいいのですがプラスマイナス補正は どこに書けばよいのでしょうか? シャッフルはちゃんとできたのですが、ステージの上のピースが x軸とy軸に同じだけずれています。 よろしくおねがいします。

関連するQ&A

  • FlashLite1.1(as1)の質問です。

    携帯Flashゲームの書籍で勉強中なのですが、 以下のasで理解できないところがありまして、 教えていただけたらとても助かります。 ---------------------------------- /*もぐらの数をランダムで*/ m_kazu = random(4)+1; for (i=1; i<=m_kazu; i++) { /*出現する場所をランダムにしてmyNumberに格納*/ eval("myNumber" add i) = random(9)+1; /*ランダムな数字が重ならないように*/ for (j=1; j<=m_kazu; j++) { while (eval("myNumber" add i) == eval("myNumber" add (i-j))) { eval("myNumber" add i) = random(9)+1; } } m_basyo = "../mg" add eval("myNumber" add i); tellTarget (m_basyo) { gotoAndPlay(2); } } ---------------------------------- この for (j=1; j<=m_kazu; j++) { while (eval("myNumber" add i) == eval("myNumber" add (i-j))) { eval("myNumber" add i) = random(9)+1; } の部分がわからないのです。どうして"myNumber" add iとmyNumber" add (i-j)が等しかったら ランダムの数字が同じものだという事になるのでしょうか? iとjは同じm_kazuを使っているのではないのでしょうか?? プログラム初心者が勉強を始めたばかりなので、 質問も要領を得ていないので、大変申し訳ないのですが どなたか教えてください~!!

    • ベストアンサー
    • Flash
  • 15パズルの作り方が分かりません!

    ご閲覧ありがとうございます。 実は大学で、「15パズル」のプログラムを作れという課題が出たのですが、上手く動きません。プログラミングに関してはほぼ初心者で、どこがどうまちがっているのか、どのように直したらきちんと動くのかが全く分かりません・・・。!il||li(っω-`。)il||li 助けて下さい!お願いします(´;ω;`) 以下が私がいじっていたプログラムです <html> <head> <title>15パズル</title> <script type="text/javascript"> // 初期盤面を生成するプロシージャ function gstart() { var checked=new Array(15); // 「使用済み」のチェック用 var i, j; // カウンタ var n; // パネル番号 var p; // パリティ計算用 var parity = false; // 奇順列の状態 var flag; // その数が使用済みかどうか while(parity==false){ // 奇順列の間は繰り返す for(i=0;i<16;i++) checked[i]=false; // すべて未使用状態化 for(i=0;i<16;i++){ // パネル番号を順に決める flag = false; // 最初はパネル番号未決定とする while(flag==false){ // 未使用状態の間は繰り返す n = Math.floor(Math.random()*16); // nに0~8の乱数を設定 if(checked[n]==false){ // nが未使用なら pnum[i] = n; // i番目のパネルのパネル番号をn checked[n] = true; // nを使用済みにする flag = true; // パネル番号決定 } } } p = 0; // 偶順列か奇順列かの計算 for(i=0;i<15;i++){ for(j=i+1;j<16;j++){ if(pnum[i]!=0 && pnum[j]!=0){ if(pnum[i]>pnum[j]) p++; // 互換の数を勘定 } } } if((p%2)==0) parity=true; // 互換の数が偶数なら偶順列 } for(i=0;i<16;i++){ if(pnum[i]==0) document.forms[0].elements[i].value= ""; else document.forms[0].elements[i].value= pnum[i]; } } function move(obj) { var i,j,k; for(j=0;j<16;j++) if(obj.value==pnum[j]) i=j; // objのパネル位置を調べる for(j=-4;j<2;j=j+3){ // 上下左右の隣接パネルの調査 k = i+j; if((k>=0&&k<16) && ((Math.floor(i/2)==Math.floor(k/2))||(i%2==k%2))){ if(pnum[k]==0){ // 隣が空なら入れ替え pnum[k] = pnum[i]; document.forms[0].elements[k].value= pnum[k]; pnum[i] = 0; document.forms[0].elements[i].value= ""; } } } } </script> </head> <body> <h1>15パズル</h1> [開始]ボタンクリックでスタート。 <form id="Form1"> <script type="text/javascript"> var i; var s; var pnum=new Array(16); // パネル番号記憶用 for(i=0;i<16;i++){ document.write("<input style='width:30px; height:30px;' type='button' value='"+(i+1)+"' onClick='move(this)'>"); if((i+1)%4==0) document.write("<br />"); } document.forms[0].elements[15].value= ""; </script> <br /> <input style="width:60px; height:30px;" type="button" value="開始" onClick="gstart()"><br /> </form> </body> </html>

  • 一度に複数の値を取得できる乱数ってありますか?

    PHP Version 5.1.6を使っています。 例えば、1から10まで整数の中から値が重複しないように ランダムに8個選びたいような時で、自分が思いつた選び方は、 for($i=0; $i<8; $i++){ $r = rand(1, 10); $flag = false; for($j=0; $j<Count($list); $j++){ if($r == $list[$j]){ $flag = true; break; } } if($flag){ $i--; continue; } $list[] = $r; } print_r($list); なんですが、これだと効率が悪いような気がします・・・ そこで重複しないようにランダムに選べる乱数や またはそういう関数はあるのでしょうか?

    • 締切済み
    • PHP
  • java

    java プログラミングで3×3の○×ゲームを作りたいのですが、エラーが出てしまいます。 どこに問題があるかわかりません。 教えていただけたら嬉しいです。 長くなってしまいますが、ご了承ください(コメント一部略)。 import java.io.*; // マスにの中身が // 空白: 0 // O : 1 // X : 2 class ox { // 勝敗の判定をするメソッド // 勝敗が付いていなければ0 を // O の勝ちなら1 を // X の勝ちなら2 を // 引き分けなら-1 を // それぞれ返す。 static int judge( int board[][] ) { int i, j, flag; for( i = 0; i < 3; ++i ) { flag = 1 | 2; for( j = 0; j < 3; ++j ) flag &= board[j][i]; // <=> flag = flag & board[j][i] if( flag != 0 ) return flag; } // 縦の列を調べる for( i = 0; i < 3; ++i ) { flag = 1 | 2; for( j = 0; j < 3; ++j ) flag &= board[i][j]; if( flag != 0 ) return flag; } // 左上→右下のナナメ flag = 1 | 2; for( j = 0; j < 3; ++j ) flag &= board[j][j]; if( flag != 0 ) return flag; // 右上→左下のナナメ flag = 1 | 2; for( j = 0; j < 3; ++j ) flag &= board[2-j][j]; if( flag != 0 ) return flag; // まだ置けるマスがあるかの判定 flag = 1; for( i = 0; i < 3; ++i ) { for( j = 0; j < 3; ++j ) flag *= board[i][j]; } // flag != 0 ってことは、置けるマスは無い→勝負が付いた // どちらかが勝ったのなら、上でreturn しているはず // ということで、引き分け if( flag != 0 ) return -1; // 何事もなければ、勝負続行 return 0; } // 番面の様子を表示するメソッド static void show ( int board[][] ) { String display = ""; String masu[] = { " ", "O", "X" }; int i; display += " |1|2|3\n"; for( i = 0; i < 3; ++i ) { display += "-+-+-+-\n"; display += (i+1) + "|" + masu[board[0][i]] + "|" + masu[board[1][i]] + "|" + masu[board[2} System.out.println( display ); } static int isreach( int three[], int turn ) { int i, result; // 各マスの値を2 乗して足し合わせる result = 0; for( i=0; i<3; ++i ) result += three[i]*three[i]; // リーチなら、下の条件を満たすはず if( result == 2*turn*turn ) { for( i=0; i<3; ++i ) if( three[i] == 0 ) break; return i; } return -1; } static int rival( int board[][] ) { int x,y,i,j,n; int three[] = new int[3]; // x, y が未定である事を明示 for( i=0; i<3; ++i ) { for( j=0; j<3; ++j ) three[j] = board[j][i]; 続きは追記にて

  • DXライブラリによるパズルゲーム制作について

     今、私はDXライブラリによるパズルゲーム制作に取り掛かっています。 そこで、画像をランダムに表示する際のプログラムの書き方に詰まってしまったので、教えていただければと思い投稿しました。 LoadDivGraph( "BLOCK.png" , 16 , 4 , 4 , 32 , 32 , Block ); for(int i=0;i<15;i++) {     for(int j=0;j<20;j++)     {         int n =GetRand(14);   if(i==0||i==14||j==0||j==19)   { DrawGraph( j*32, i*32 , Block[7], TRUE );   }   else   { DrawGraph( j*32, i*32 , Block[n], TRUE );   }     } } ※インデントに関してはご容赦ください。 かなり端折っていますが、上記のような感じで打ってしまうと、(ここには書いていませんが)while文があるおかげで、一秒間に60回のペースでBlock[n]の中身が変化してしまいます。 これを解消したいのですが、かといって、いちいち変数を用意してコピーするのでは効率が悪いですよね。あと、パズルゲームですので、この先、表示した画像を入れ替えたり消したりといった処理があることを念頭に入れたうえでのベストな書き方を教えていただければと思います。 ちなみに、C言語・C++の書き方でお願いします。

  • FLASH LITE1.1 任意に問題を表示

    40問の問題をランダムに表示させようとしていますがうまくいきません。 MCにq1~q40のラベルをつくり、ランダム関数で任意に表示させようとしています。 具体的には次の関数を書きました。 //m1~m40に順に1~40を代入 for(i=1;i<=40;i++){set("m" add i,i);} //m1~m40の値をシャッフル for(i=0;i<100;i++){ r1=random(40)+1; r2=random(40)+1; tV=eval("m" add r1); set("m" add r1,eval("m" add r2)); set("m" add r2,tV); } //ムービークリップqtの中の任意のラベル(q1~q40)を再生 tellTarget("/qt"){gotoAndPlay("q" add m1);} ("q" add m1)のところを例えば("q5")などと、具体的なラベル名を入れると動くので、 変数のどこかの取り扱いに間違いがあると思うのですが、どこがおかしいのかわかりません。 おわかりの方がいたら是非、ご教授願いたく思います。 よろしくお願いいたします。

    • ベストアンサー
    • Flash
  • java シャッフルについて

    こんいちは。 今、カードゲームを作っているのですが、 リストに格納された先頭の8件に3件以上、重複したものがあったら、 再シャッフルし続けると言うロジックを組んでいるのですが、 ログを見ると、3件以上なのに終了したり、最初の8件に3件以上無いのに シャッフルしてます。 このロジックに間違いないと思っているんですが、 どこか間違っていますでしょうか? boolean flg = true; do { Collections.shuffle(list, new Random()); flg = true; for (int i = 0; i < 8; i++) { int cnt = 0; for (int j = 0; j < 8; j++) { if (list.get(i).id.equals(list.get(j).id)) cnt++; } if (cnt > 2) { flg = false; break; } } } while (flg);

    • ベストアンサー
    • Java
  • AS3でattachMovie()どうするの?

    FlashCS4でAS3.0です。 http://hakuhin.jp/as/block.html 上のサイトを見ながらブロック崩しのプログラム練習をしています。 壊すブロックについてなのですが、 ブロックのMCをライブラリでリンケージして書き出して、 下のようにしてステージに並べました。 for (var i:int = 0 ; i<32; i++){ var mc:block_class = new block_class(); mc.name = "block"+i; mc.x = i % 4 * 40 +40; mc.y = Math.floor(i/4) * 15 + 25; stage.addChild(mc); } ここからがわからないところです。 ボールがブロックに当たったら消える、という文を書こうとして for (var i = 0; i<32 ; i++){   if (ball_mc.hitTestObject(mc)){ mc.visible=false;   } このような形にしているのですが、 複製したすべてのブロックに適応させるにはどうしたらよいかわかりません。 どうもAS2.0のときはattachMovie()やeval()を使ってできたことみたいなのですが・・・ どうぞよろしくお願いします。

    • ベストアンサー
    • Flash
  • 行列の和のプログラミング

    以下のをCソースを打ち込んでコンパイルすると、 warning: passing arg 1 of `mat_add' from incompatible pointer type warning: passing arg 2 of `mat_add' from incompatible pointer type となります。これは、どういうエラーでどう直せばいいのでしょうか? #include <stdio.h> void mat_add(const int ma[2][3], const int mb[2][3], int mc[2][3]) { int i, j; for (i = 0; i < 2; i++) for (j = 0; j < 3; j++) mc[i][j] = ma[i][j] + mb[i][j]; } int main(void) { int i, j; int ma[2][3] = { {10, -5, 4}, {18, -2, -18} }; int mb[2][3] = { {23, 16, -9}, {-3, 20, 5} }; int mc[2][3] = { 0 }; mat_add(ma, mb, mc); for (i = 0; i < 2; i++) { for (j = 0; j < 3; j++) printf("%3d", mc[i][j]); putchar('\n'); } return (0); }

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }