1989年開業 情報工学部門 文部科学省登録番号 第22082号 公益社団法人日本技術士会会員 東大阪商工会議所会員
≫サンプルプログラム一覧
≫
オープンソース/C言語サンプルプログラム 粒子の凝集シミュレーション(アスキーアート)
※2021. 9.16 プログラムを訂正しました。(下から2行目)
{ printf("%.*s",XMAX,&buf[y][0]); } // 1行分表示
↓
{ printf("%.*s\n",XMAX,&buf[y][0]); } // 1行分表示
●粒子が一定のルールに従って凝集した様子を表示するプログラムです。
●ルールは次のとおりです。
(1) 縦 YMAX 行、横 XMAX 桁の矩形領域を画面上に想定する。(配列 buf[][] で実装)
(2) 粒子を領域の上端 (y=0) に一つ発生させる。桁位置 x は乱数によって決める。
(3) 粒子は、下、右、左の方向にランダムに1コマずつ進む。
(4) 粒子が領域の底か他の粒子に接したら、吸着されたとしてその位置に止める。
(5) 粒子が領域の外に出たら、その粒子は終了とする。
(6) あらかじめ決めておいた粒子の数だけ、(2)から(5)の操作を繰り返す。
(7) すべての粒子の操作が終わったら、結果を画面に表示する。
●乱数の種にはtime関数で得られた時刻を使うので、実行するたびにちがうパターンになります。
|
|
≫ソースファイルのダウンロード: gyousyuu02.C
【問題】
●粒子を表す文字を '*' から他の文字に変更してみよう。
※文字によってはパターンが気持ち悪く感じられる場合があるので、敏感な方は注意してください。
●画面の行数や粒子の数を変えて試してみよう 。
●乱数の種を変数 seed ではなく、定数(0など)にすると、毎回同じパターンになることを確認しよう。
●乱数の種を定数にして粒子数を多くしていくと、途中からパターンが変わらなくなることを確認し、意味を考察してみよう 。
●粒子の進む方向を下だけに改造して、得られる結果を比較してみよう。
●変数 seed の値を画面に表示し、気に入ったパターンを再現できるように改造してみよう。
|
// 粒子の凝集シミュレーション(アスキーアート)
// 粒子は領域の上からランダムにやって来て下、左、右に移動する
// 粒子は領域の底に到達したら吸着する
// 粒子は他の粒子に接すると吸着する
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define PMAX 300 // 粒子の数
#define XMAX 80 // 水平方向MAX
#define YMAX 20 // 垂直方向MAX
void main( )
{
unsigned long seed; // 乱数の種
char buf[YMAX][XMAX]; // 1画面分のマス
char pc='*'; // 粒子の文字
int n,x,y; // 粒子位置
int ir; // 吸着
int i;
printf("粒子の凝集シミュレーション(AA)\n");
memset(&buf[0][0],' ',XMAX*YMAX); // 配列を空白で初期化
time(&seed); // 時刻取得(秒)
srand(seed); // 乱数の種をまく
for( i=0; i<PMAX; i++ ) // 粒子発生
{
x=rand( )%XMAX; y=0; // 最初の位置
if ( buf[y][x]==pc ) continue; // すでに粒子あり
while( 1 )
{
ir=1; // 吸着(仮)
if ( y==YMAX-1 ) break; // 領域の底
if ( buf[y+1][x]==pc ) break; // 下に粒子あり
if ( x<XMAX-1 )
{ if ( buf[y+1][x+1]==pc ) break; } // 右下に粒子あり
if ( x<XMAX-1 )
{ if ( buf[y][x+1]==pc ) break; } // 右に粒子あり
if ( x<XMAX-1 && y>0 )
{ if ( buf[y-1][x+1]==pc ) break; } // 右上に粒子あり
if ( y>0 )
{ if ( buf[y-1][x]==pc ) break; } // 上に粒子あり
if ( x>0 && y>0 )
{ if ( buf[y-1][x-1]==pc ) break; } // 左上に粒子あり
if ( x>0 )
{ if ( buf[y][x-1]==pc ) break; } // 左に粒子あり
if ( x>0 ) // 左下に粒子あり
{ if ( buf[y+1][x-1]==pc ) break; }
ir=0; // 吸着なし
//--移動--
n=rand( )%3; // 3方向
switch( n )
{
case 0: y++; break; // 下
case 1: x++; break; // 右
case 2: x--; break; // 左
}
if ( y<0 || y>=YMAX ) break; // 領域の外
if ( x<0 || x>=XMAX ) break; // 領域の外
}
if ( ir==1 ) buf[y][x]=pc; // 粒子吸着
}
//--結果表示--
for( y=0; y<YMAX; y++ )
{ printf("%.*s\n",XMAX,&buf[y][0]); } // 1行分表示
}
|
※SSL暗号化通信対応
佐伯英子技術士事務所 〒542-0073 大阪市中央区日本橋 1-14-13 サンオフィス日本橋601 E-mail: info@saeki-pe.com
|