// PROGRAM ca2 #include "TrueBASIC.h" #include "csgraphics.h" int main(); void setrule(int update[], int *L); void initial(int cell[][51], int L); void iterate(int cell[][51], int update[], int L); void neighborhood(int cell[][51], int i, int j, int *sum, int L); int main() { int k = 0; int L, cell[51][51], update[512]; char flag[_LBUFF_]; GWopen(0); setrule(update, &L); strcpy(flag, ""); do { initial(cell, L); do { iterate(cell, update, L); if(TBkeyinput()) { k = TBgetkey(); if((k == 's') || (k == 'S')) strcpy(flag, "stop"); } } while(k == 0); k = 0; } while(strcmp(flag, "stop")); GWquit(); return 0; } void setrule(int update[], int *L) { int i, index; int nn1, nn2, nn3; float xwin, ywin; char Stmp1_[_LBUFF_]; // ライフゲームの規則 for(i = 0; i <= 511; ++i) update[i] = 0; // 3つの隣接セルが生きている for(nn1 = 0; nn1 <= 5; ++nn1) { for(nn2 = nn1+1; nn2 <= 6; ++nn2) { for(nn3 = nn2+1; nn3 <= 7; ++nn3) { index = (1 << nn1) + (1 << nn2) + (1 << nn3); update[index] = 1; // 中央のセルは死んでいる update[index + 256] = 1; // 中央のセルは生きている } } } // 2つの隣接セルと中央のセルが生きている for(nn1 = 0; nn1 <= 6; ++nn1) { for(nn2 = nn1+1; nn2 <= 7; ++nn2) { index = 256 + (1 << nn1) + (1 << nn2); update[index] = 1; } } GWcolor(BLACK, CLR_BACKGRND); GWcolor(WHITE, CLR_TEXT); if(GWinput("lattice size = ", Stmp1_, _LBUFF_)) sscanf(Stmp1_, "%d", L); else (*L) = 20; compute_aspect_ratio((float)(*L), &xwin, &ywin); GWindow(-0.2f*xwin, -0.2f*ywin, 1.2f*xwin, 1.2f*ywin); } void initial(int cell[][51], int L) { int i, j; float x, y; GWclear(-1); GWsetpen(BLACK, -1, -1, 4); GWcmbmrk(1, 5, 1.0f, YELLOW, -1, 4); GWcmbmrk(2, 5, 1.0f, BLUE, -1, 4); for(i = 1; i <= L; ++i) { for(j = 1; j <= L; ++j) { cell[i][j] = 0; GWsetogn(0, j*L+i); GWputcmb(1, (float)(i), (float)(j), 1.0f, 1.0f, 0); } } // セルの状態を変えたいときはセルを, // 更新するときは格子の外側をクリックする do { GWcappnt(&x, &y, "click on cell to toggle or outside of lattice to continue."); if(x > 0.5 && x < L + 0.5 && y > 0.5 && y < L + 0.5) { i = (int)(x+0.5); j = (int)(y+0.5); GWerase(j*L+i, 0); GWsetogn(0, j*L+i); if(cell[i][j] == 0) { GWputcmb(2, (float)(i), (float)(j), 1.0f, 1.0f, 0); cell[i][j] = 1; } else { GWputcmb(1, (float)(i), (float)(j), 1.0f, 1.0f, 0); cell[i][j] = 0; } } } while(!(x < 1 || x > L || y < 1 || y > L)); GWsetmsg("Hit any key for new lattice, 's' to stop "); while(GWmouse(NULL, NULL, NULL)); } void iterate(int cell[][51], int update[], int L) { int i, j, k, sum; int cellnew[51][51]; for(i = 0; i <= L; ++i) for(j = 0; j <= L; ++j) cellnew[i][j] = 0; for(i = 1; i <= L; ++i) { for(j = 1; j <= L; ++j) { neighborhood(cell, i, j, &sum, L); cellnew[i][j] = update[sum]; if(cell[i][j] == 1 && cellnew[i][j] == 0) k = 1; else if(cell[i][j] == 0 && cellnew[i][j] == 1) k = 2; else k = 0; if(k > 0) { GWerase(j*L+i, 0); GWsetogn(0, j*L+i); GWputcmb(k, (float)(i), (float)(j), 1.0f, 1.0f, 0); } } } for(i = 0; i <= L; ++i) for(j = 0; j <= L; ++j) cell[i][j] = cellnew[i][j]; } void neighborhood(int cell[][51], int i, int j, int *sum, int L) { int im, ip, jm, jp; ip = i + 1; im = i - 1; jp = j + 1; jm = j - 1; if(i == 1) im = L; else if(i == L) ip = 1; if(j == 1) jm = L; else if(j == L) jp = 1; (*sum) = cell[i][jp] + 2*cell[i][jm] + 4*cell[im][j]; (*sum) += 8*cell[ip][j]+ 16*cell[ip][jp] + 32*cell[ip][jm]; (*sum) += 64*cell[im][jp] + 128*cell[im][jm] + 256*cell[i][j]; }