7行テトリスコードのわからない点と解説

このQ&Aのポイント
  • 7行テトリスコードの中で理解できない箇所がいくつかあります。タイトルにしたわからない点について解説します。
  • 7行テトリスコードの中でわからない箇所を解説します。初心者でも理解しやすい解説を行います。
  • 7行テトリスコードの中にいくつか理解できない点がありますが、それぞれの意味について解説します。
回答を見る
  • ベストアンサー

7行テトリスコードで分からない所があります

某所の以下のテトリスのコードなのですが、何点かわからない点があります。初歩的な質問も混ざっているかもしれません。理解できるというお方おりましたらご教授いただけると幸いです。 下記の左の数字は行番号で、ソースを読む際の目安にしていただければと思います(大体の番号です;) ソース http://zapanet.info/blog/item/1125 7      d=K-37?1:-1 // d:x方向の差分 ★d=K-37がtrueなら1、falseなら-1を返すと私は読んだのですが、d=K-37がtrueというのはどういう意味か分かりません。どういう意味なのでしょうか? 10        f+=Z[h+E[i]+d]==S; // 移動先が空白かどうか ★fに配列Zの添字h+配列Eの添字i+dを足したものをfに代入。までは多分あっていると思うのですが、次の==Sの意味がわかりません。どうよめばよいのでしょうか? 17        v=Math.round(p/12); // 回転先の x 座標 18        w=p-v*12; // 回転先の y 座標 19        C[i]=w*12-v; // 回転先の座標計算 ★なぜpを12で割って丸めているのでしょうか?17、18、19とどういう計算をしているのでしょうか? 24      t*!f?E=B[t]=C:0; // すべて空白なので回転決定 ★t*fの否定がtrueならばEにB[t]を代入するのは分かりますが、Cはどこにはいるのでしょうか?=が2つ続いたときどう読めば良いでしょうか? 40    for(j=11;--j&&Z[i*12+j]==S;); // そろったラインを検索 ★j=11から、1減らしたjかつ配列Z添字i*12+jがSになるまで・・・3つめの;の後ろがありませんが、これはどういう意味でしょうか? そして、for()の後ろに;がありますが、それはどういう意味でしょうか? 43      for(j=++i*12;j>2*12;)Z[j]=Z[j---12] // 全体を一段下げる ★Z[j]=Z[j---12]の---12の意味は、12を2減らしたのを・・・であっていますか? 51  Z[5]!=S?setTimeout(Y,99):0; // 入り口にブロックがあったら終了 ★配列Z添字5がSじゃなければset~、Sなら0を返すで読みはあっていますか? 59 for(K=t=P=i=0;i<240;){ ★K、t、P、iに0をセット、iが240以下になるまで・・・これも2つめの;の後がないのですがどうなっているのでしょうか? 61  Z[240+i]=Z[i]=++i%12<2||i>228?S="□":" "; // 床と壁の設定、番兵にもなる ★Z[240+i]、Z[i]に++i%12を代入したものが2以下または、i>228がtrueなら"□"、falseなら" "を返す。で読みはあっていますか?

質問者が選んだベストアンサー

  • ベストアンサー
  • suzuki-_-
  • ベストアンサー率77% (152/195)
回答No.1

7 d=K-37?1:-1  K-37がture だったら1、falseだったら-1を、dに代入する  ここでは条件(K-37)がNumber型なのではBoolean型に変更され評価される  数値が 0->false それ以外(0より下 or 0より上)->true 10 f+=Z[h+E[i]+d]==S;  Z[h+E[i]+d] == S の結果を fに加えたものが fに代入される  結果はBoolean(true or false)になるが、  += によりString型の連結かNumber型の加算が行われ代入される  fの初期値がNumber型 (f=0) なのでここではおそらくNumber型による加算 true->1 false->0 17 v=Math.round(p/12); // ブロックの各位置 18 w=p-v*12; // 回転先の y 座標 19 C[i]=w*12-v; // 回転先の座標計算  全体の関係がちょっとよくわからないので不明 24 t*!f?E=B[t]=C:0; // すべて空白なので回転決定  t*fの否定がtrueならば、B[t]にCが代入され、更にEにも代入される  それ以外はとりあえず0を宣言  単純にCがEとB[t]に代入されると理解すれば良し  0宣言自体に意味はなく、構文として成り立たせるためだけに存在 40 for(j=11;--j&&Z[i*12+j]==S;);  3つ目の;の後ろは、forで一連の動作をループ中、一連の動作を行う毎の最後に何をするか  ここでは何もしないということ、  最後の;は、forの条件内で既にループさせたい動作が満たされていると思われるので(--jの部分)、  やることがないからforの終止として付けている  条件に使われるNumber型の評価は 7 と一緒 43 for(j=++i*12;j>2*12;)Z[j]=Z[j---12]  j---12は"j--"と"-12"で分ける  式だけの結果は j-12、式を終えるとj自体は j-1 になる 51 Z[5]!=S?setTimeout(Y,99):0; // 入り口にブロックがあったら終了  配列Z添字5がSじゃなければsetTimeoutによる時間軸処理を行うよう設定  そうでなければ0を宣言、0宣言に意味はなし 59 for(K=t=P=i=0;i<240;){  ;の後がないのは40と同じ 61 Z[240+i]=Z[i]=++i%12<2||i>228?S="□":" "; // 床と壁の設定、番兵にもなる  ++i%12が2未満または、i>228がtrueなら"□"、falseなら" "を、Z[240+i]とZ[i]に代入する  trueならば Sにも"□"が代入される 理解を深める為に、全体を通して覚えたほうがよいこと ・三項演算 A ? B : C ・forの使い方とその行われ方 ・代入演算子(=)及び複合代入演算子(+= -=等)の動作と、  比較演算子{関係演算子(== !=等)}の動作の違い どっか間違ってるかもしれませんが、 時間をかけて細かくデバッグのような形で確認しないと これ以上はちょっとわからなそうなので以上です

e271828
質問者

お礼

どうもありがとうございました!すごいです・・・ だらだらと質問してすみませんでした。 とても分かりやすかったです、嬉しいです! アドバイスを参考にじっくり理解してみようと思います

関連するQ&A

  • JavaScriptの配列について

    var old_array = Array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '<', '#', '/', '>', '%', '.', '*', '0', '!', '?', ':', '=', '|'); var new_array = Array('b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '<', '#', '/', '>', '%', '.', '*', '0', '!', '?', ':', '=', '|'); のような配列があり、 abcと入力するとbcd DEFと入力するとEFG 012と入力すると!23 というようなものを作りたいのですがどうすればいいでしょうか。

  • fprintfでの文字化け

    Cで作ったプログラムなのですが最後の部分でファイルに出力すると数字が 文字化けして出てきます(‰など)その原因を教えて頂ければ嬉しいです 他にも何かあれば教えてください プログラミングは詳しくないのでゴロゴロ見つかるかもしれません 【プログラム】 #include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> int a,i,j,k,t; double p,p1,b; int X[999][1000],Y[999][1000]; int s0,s1,delta; int main(void) { int**X = calloc(sizeof(int),sizeof(int)*1000); int**Y = calloc(sizeof(int),sizeof(int)*1000); FILE *output; output=fopen("monte.dat","w"); b = 0.01; /*逆温度*/ srand((unsigned int)time(0)); /*メモリの確保*/ if( X == NULL ){ exit( EXIT_FAILURE ); } for(i=0; i<=999; ++i){ /* 各列分の領域を割り当てる */ X[i] = (int*)calloc(sizeof(int),sizeof(int)*1000); } if( Y == NULL ){ exit( EXIT_FAILURE ); } for(i=0; i<=999; ++i){ /* 各列分の領域を割り当てる */ Y[i] = (int*)calloc(sizeof(int),sizeof(int)*1000); } /*終わり*/ /*初期配列の設定*/ for(i=0;i<1000;i++){ X[0][i]=a; a = (int)((rand() / ((double)RAND_MAX+1.0)) * 2);//debag } /*終わり*/ for(t=0;t<2;t++){ //debag /*配列中a番目を抽出*/ a = 10; //debag /*終わり*/ /*a番目のスピンを逆にした配列作成*/ for(j=0;j<1000;j++){ Y[t][j] = X[t][j]; } Y[t][a] = (X[t][a]+1)%2; /*終わり*/ /*遷移確率p1計算*/ s0=0; s1=0; for(k=0;k<1000;k++){ s0=s0+pow(-1,X[t][k]+X[t][k+1]);//(11),(00)なら値1 s1=s1+pow(-1,Y[t][k]+Y[t][k+1]);//(10),(01)なら値-1 } delta = -s1 + s0; p1 = 0.5 * (1 - tanh(0.5 * b * delta)); printf("%d %d %d %f ",s0,s1,delta,p1); //←この時点ではX[t][]は正しく出力する /*終わり*/ /*新しい配列(i番目の符号を交換するか)*/ p = (double)((rand() / ((double)RAND_MAX+1.0)) * 1); for(j=0;j<1000;j++){ X[t+1][j] = X[t][j]; } if(p<=p1){ X[t+1][a] = (X[t][a]+1)%2; printf("交換したよ! %d → %d\n",X[t][a],X[t+1][a]); } else{ X[t+1][a] = X[t][a]; printf("交換しないよ!\n"); } /*終わり*/ } /*記入*/ for(i=0;i<1000;i++){ fprintf(output,"%d ",X[0][i]); //←ここが文字化けする } fprintf(output,"\n"); for(i=0;i<1000;i++){ fprintf(output,"%d ",Y[0][i]); //←出力されない } /*終わり*/ fclose(output); return 0; } 【プログラム終】

  • 多次元配列の初期化

    多次元配列の初期化を行いたいのですが、 下記の方法では、配列の値が多くなったときに大変 なので他に良い方法はありませんでしょうか? char lesson[7][6] = { {'A', 'B', 'C', 'D', 'E', 'F'}, {'G', 'H', 'I', 'J', 'K', 'L'}, {'M', 'N', 'O', 'P', 'Q', 'R'}, {'S', 'T', 'U', 'V', 'W', 'X'}, {'Y', 'Z', 'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h', 'i', 'j'}, {'k', 'l', 'm', 'n', 'o', 'p'}, };

  • 2行のセルの入れ替え。

     初めまして、よろしくお願いします。  セルに A B C D E F G H I J K L 1 a b c d e f 2 g h i j k l 3 m n o p q r 4 s t u v w x 5 " ・ " ・ " ・ " 100 "  という表があります。これを A B C D E F G H I J K L 1 a b c d e f g h i j k l 2 m n o p q r s t u v w x 3 " 4 " 5 " ・ " ・ " ・ " 100 "  という風に、偶数行のデーターを奇数行の後ろにつけるようにしたいと思います。無理ならば奇数行だけのデーター、偶数行だけのデーターとなるように、何かよい方法を教えて頂きたく、よろしくお願いします。

  • 順列・数え上げ

    よろしくお願いします。 ここに下のような390個の文字があります。 (A,B,C,D,E,F,G,H,I,J,K,L,M がそれぞれ10個ずつ、 N,O,P,Q,R,S,T,U,V,W,X,Y,Z がそれぞれ20個ずつあります。) この390個の文字から235文字を選んで一列に並べる方法は全部で何通りありますか。 A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M A B C D E F G H I J K L M N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z N O P Q R S T U V W X Y Z 以下、私が考えたことを書きます。 この390個の文字から235個の文字を選ぶ組み合わせの総数は、 (Σ[k=0~10]x^k)^13*(Σ[k=0~20]x^k)^13 を展開したときのx^235の係数ですから、 23463540513956137996043929988 通りだということは分かります。 この23463540513956137996043929988 通りのそれぞれについて235個の文字 の順列(同種のものを含む順列)を数え上げれば答えは出ると思いますが、これは あまりにも大変な作業です。 何かよい知恵はないでしょうか。

  • ややこしいコード

    #include<iostream> using namespace std; int main() { const int num = 5; int test[num]; cout << num << "人の点数を入力して下さい。\n"; for (int i = 0; i < num; i++) { cin >> test[i]; } for (int s= 0; s < num - 1; s++) { for (int t = s + 1; t < num; t++) { if (test[t] > test[s]) { int tmp = test[t]; test[t] = test[s]; test[s] = tmp; } } } for (int j = 0; j < num; j++) { cout << j + 1 << "番目の人の点数は" << test[j] << "です。\n"; } return 0; } 配列を並べ替える(ソート)する練習コードなんですが、 ちょっとややこしいので解りやすく教えて欲しいです。 因みに点数は、 22,80,57,60,50の順でお願いします。

  • 行・列の整理! perl

    perlでデータを並び替えて整理したいです。 【元データ】 A a b A c d A e f A g h B i j B k l B m n C o p C q r C s t C u v ・ ・ ・ 上記のデータを下記のように並び替えしたいのですが上手くできずに困っています。 どのような記述をすれば良いのでしょうか。間の空白はタブ区切りです。 【目標】 A a b c d e f g h B i j k l m n C o p q r s t u v D ・ 現在、元データから A B C D ・ ・ というデータを作り、元データと比較していますが上手くいきません。 for($i=0; $i<@key; $i++){ print OUT "$key[$i]"; for($j=0; $j<@data; $j++){ if($key[$i] =~ /$data[$j]/){    #部分一致 print OUT "$'"; } } print OUT "\n"; } 部分一致の行を正規表現を用いて上手く処理したいのですがやり方がわからず躓いています。 宜しくお願いします。

    • ベストアンサー
    • Perl
  • プログラミングの変数について質問です。

    プログラミングの変数について質問です。 次のプログラミングは自分で書いたプログラムの一部です。 void inputmonster(int x[][3], struct monster monster) { int i, s, t, m, n; for(t = 0; t < 2; t++){ s = 0; while (s < 1){ printf("player%dは好きなモンスターを3つ選んでください\n\n", t+1); for (i = 0; i<3; i++){ printf("%d体目を選んでください。\n\n", i+1); for(m = 0; m < 5; m++) printf("%d, %s\n", m+1, monster[m].name); scanf("%d", &x[t][i]); printf("%d体目 : %s\n\n", i+1, monster[x[t][i]-1].name); } printf("これでよろしいですか?\n"); for(i = 0; i<3; i++) printf("%d体目 : %s ", i+1, monster[x[t][i]-1].name); printf("1、はい 2、いいえ\n"); scanf("%d", &n); if(n == 1) s = 1; else s = 0; } } } これをコンパイルすると次のようなエラーが表示されます。 monsterbattle.c: 関数 ‘inputmonster’ 内: monsterbattle.c:497:63: エラー: 添字が付けられた値が、配列、ポインタまたはベクト ルではありません for(m = 0; m < 5; m++) printf("%d, %s\n", m+1, monster[m].name); ^ monsterbattle.c:499:45: エラー: 添字が付けられた値が、配列、ポインタまたはベクト ルではありません printf("%d体目 : %s\n\n", i+1, monster[x[t][i]-1].name); ^ monsterbattle.c:503:68: エラー: 添字が付けられた値が、配列、ポインタまたはベクト ルではありません for(i = 0; i<3; i++) printf("%d体目 : %s ", i+1, monster[x[t][i]-1].na me); どのように改変すればこのようなエラーを表示しないようにできるのでしょうか? 基本的な質問ではあると思いますが、是非教えていただけるとありがたいです。 よろしくお願いします。

  • 座標系の回転の問題です

    大学物理入門の問題です 【問題】 空間に固定された座標系Sと、回転している別の座標系S'を考える。座標系S'は、Sに対して角速度ω=Ωi+Ωjで回転しているものとする。ただしこれらの座標系の原点は一致するとする。また、時刻t=0においてこれらの2つの座標系は一致するとする。時刻tにおいて、座標系S'のx'軸、y'軸、z'軸方向の単位ベクトルをそれぞれi'(t)、j'(t)、k'(t)とする。 時刻tにおけるベクトルi'(t)、j'(t)、k'(t)を求めよ 問題は以上です 文中のωはベクトル、i、j、kはそれぞれ座標系Sのx軸、y軸、z軸方向の単位ベクトルです できれば、ベクトルi'(t)、j'(t)、k'(t)がどのような回転をするのか、図を用いて説明していただけると嬉しいです どなたか知恵をお貸しください よろしくお願いします

  • ソースコードを簡潔に直したいのですが…

    有限積分法(参考 http://www.akita-nct.jp/yamamoto/study/thesis/2005/thesis_namekawa.pdf) を用いて、格子点 ( i, j, k )の磁場成分 Bx, By, Bz をその周辺を囲む電場成分 Ex, Ey, Ez で逐次計算するコードは次のようになります。 for ( i = 0; i < i_max; i++ ) {   for ( j = 0; j < j_max; j++ ) {     for ( k = 0; k < k_max; k++ ) {       Bx [ i ][ j ][ k ] = Ey [ i + 1 ][ j ][ k ] - Ey [ i + 1 ][ j ][ k + 1 ] + Ez [ i + 1 ][ j + 1 ][ k ] - Ez [ i + 1 ][ j ][ k ];       By [ i ][ j ][ k ] = Ez [ i ][ j + 1 ][ k ] - Ez [ i + 1 ][ j + 1 ][ k ] + Ex [ i ][ j + 1 ][ k + 1 ] - Ex [ i ][ j + 1 ][ k ];       Bz [ i ][ j ][ k ] = Ex [ i ][ j ][ k + 1 ] - Ex [ i ][ j + 1 ][ k + 1 ] + Ey [ i + 1 ][ j ][ k + 1 ] - Ey [ i ][ j ][ k + 1 ];     }   } } 電場成分の係数行列 C ( 0, 1, -1 のいずれかをもつ ) を求める必要が生じた、すなわち CCC  E  B CCC * E = B CCC  E  B のような行列計算に変更するため、次のように書き直しましたが係数行列 C を求める部分を簡潔にできませんでした。 for ( i = 0; i < i_max; i++ ) {   for ( j = 0; j < j_max; j++ ) {     for ( k = 0; k < k_max; k++ ) {       for ( x = 0; x < 3; x++ ) {         row = index ( x, i, j, k, i_max, j_max, k_max );         y = ( x + 1 ) % 3;         z = ( x + 2 ) % 3;         if ( x == 0 ) {           C[ row ][ index ( y, i + 1, j,   k,   i_max, j_max, k_max )] = 1;           C[ row ][ index ( y, i + 1, j,   k + 1, i_max, j_max, k_max )] = -1;           C[ row ][ index ( z, i + 1, j + 1, k,   i_max, j_max, k_max )] = 1;           C[ row ][ index ( z, i + 1, j,   k,   i_max, j_max, k_max )] = -1;         }         if ( x == 1 ) {           C[ row ][ index ( y, i,   j + 1, k,   i_max, j_max, k_max )] = 1;           C[ row ][ index ( y, i + 1, j + 1, k,   i_max, j_max, k_max )] = -1;           C[ row ][ index ( z, i,   j + 1, k + 1, i_max, j_max, k_max )] = 1;           C[ row ][ index ( z, i,   j + 1, k,   i_max, j_max, k_max )] = -1;         }         if ( x == 2 ) {           C[ row ][ index ( y, i,   j,   k + 1, i_max, j_max, k_max )] = 1;           C[ row ][ index ( y, i,   j + 1, k + 1, i_max, j_max, k_max )] = -1;           C[ row ][ index ( z, i + 1, j,   k + 1, i_max, j_max, k_max )] = 1;           C[ row ][ index ( z, i,   j,   k + 1, i_max, j_max, k_max )] = -1;         }       }     }   } } int index ( const int d, const int i, const int j, const int k, const int i_max, const int j_max, const int k_max ) {   return ( ( d * i_max + i ) * j_max + j ) * k_max + k; } void Solver ( const int i_max, const int j_max, const int k_max) {   int row, col,     cell_num = i_max * j_max * k_max;   for ( row = 0; row < cell_num; row++ ) {     for ( col = 0; col < cell_num; col++ ) {       B [ row ] += C [ row ][ col ] * E [ col ];     }   } } 添え字計算が多く、非常に複雑なソースコードですが、規則性があるので、 皆様の力をお借りして簡潔に表現したいです。 よろしくお願いします。

専門家に質問してみよう