第28講 細胞構成法による魔方陣の作成△
第5話 細胞の作成の解説その3
コード例
・
・
//細胞の作成関数
void sbs(char g){
char i,j,k,h;
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
h=1;
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
if(h==1){
if(g+1<4){
sbs(g+1);
}
else{
for(j=0;j<2;j++){
for(k=0;k<2;k++){
sbr[cn][j][k]=sb[j][k];
}
}
cn++;
}
}
}
}
・
・
解説の続きその2
ではトレースしていきましょう。世界次元番号(セル番号)を
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
で表し、内容を
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
で表すことにします。空間識別番号(世界次元番号)と内容が似ていますが、
くどいようですが、空間識別番号はビール瓶のラベルですし、内容はビール瓶に入っているビールに相当するものなので、
全然違うものです。
void sbs(char g){
char i,j,k,h;
for(i=1;i<5;i++){
gとiの役割の違いを明確に理解することが、コード理解のミソです。
ではトレースを開始します。
最初、private: System::Void button1_Clickから
sbs(0); //細胞の作成
によって、次元番号0の世界が呼び出されます。
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
の最初のループによって
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
となります。
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
if(h==1){
if(g+1<4){
sbs(g+1);
}
else{
for(j=0;j<2;j++){
for(k=0;k<2;k++){
sbr[cn][j][k]=sb[j][k];
}
}
cn++;
}
}
g = 0ですから、
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
は無視され、
if(h==1){
if(g+1<4){
sbs(g+1);
}
が実行されて、
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
空間識別番号1の世界に入ります。
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
の最初のループによって
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 1 |
1 | 3 | 4 |
となりますが、今回はg = 1ですから、
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
に抵触し、
if(h==1){
if(g+1<4){
sbs(g+1);
}
else{
for(j=0;j<2;j++){
for(k=0;k<2;k++){
sbr[cn][j][k]=sb[j][k];
}
}
cn++;
}
}
がスルーされ、
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
の2回目のループによって
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
となります。今回は、
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
をクリアして、
if(h==1){
if(g+1<4){
sbs(g+1);
}
が実行されて、空間識別番号2の世界へと飛翔します。
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
の最初のループによって
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 1 | 4 |
となりますが、
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
の1巡目でチェックされ、
if(h==1){
if(g+1<4){
sbs(g+1);
}
else{
for(j=0;j<2;j++){
for(k=0;k<2;k++){
sbr[cn][j][k]=sb[j][k];
}
}
cn++;
}
}
は行われず、
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
の2巡目となり、
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 2 | 4 |
となりますが、
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
の2巡目でチェックされ、
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
の3巡目となり、
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
でようやく検査
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
をクリアして、
if(h==1){
if(g+1<4){
sbs(g+1);
}
が実行され、最後の次元世界3へと跳躍します。
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
for(i=1;i<5;i++){
sb[sy[g]][sx[g]]=i;
によって、
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 1 |
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 2 |
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 3 |
0 | 1 | |
0 | 0 | 1 |
1 | 2 | 3 |
0 | 1 | |
0 | 1 | 2 |
1 | 3 | 4 |
と動いていって、はじめて試験
if(g>0){
for(j=0;j<g;j++){
if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
}
}
突破しますが、g = 3であるため
if(h==1){
if(g+1<4){
sbs(g+1);
}
else{
for(j=0;j<2;j++){
for(k=0;k<2;k++){
sbr[cn][j][k]=sb[j][k];
}
}
cn++;
}
}
の否定側がはじめて遂行され、細胞の1個目がchar sbr[24][2][2];に登録され、
カウンタもcn++;により、1となります。
第4話へ 第6話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座