1989年開業 情報工学部門 文部科学省登録番号 第22082号 公益社団法人日本技術士会会員 東大阪商工会議所会員

≫サンプルプログラム一覧 

オープンソース/C言語サンプルプログラム あみだくじ(アスキーアート)

●アスキーアートのあみだくじです。
●内容は次のとおりです。
 (1) 縦 YMAX 行、横 XMAX 桁の矩形領域を画面上に想定する。(配列 buf[][] で実装)
 (2) 縦線を等間隔に発生させる。
 (3) 横線は乱数によって発生させる。
 (4) くじの番号を入力する。
 (5) 入力された番号の線を、下まで自動でなぞる。
 (6) 範囲外の数字が入力されるまで、くじ引きを繰り返す。
●乱数の種にはtime関数で得られた時刻を使うので、実行するたびにちがうパターンになります。

≫ソースファイルのダウンロード: amidakuji01.c
【問題】
●画面の行数や線の数を変えて試してみよう 。
●乱数の種を変数 seed ではなく、定数(0など)にすると、毎回同じパターンになることを確認しよう。
●一度入力した番号を再度入力するとどうなるか考察し、実際に確認してみよう。

/**********************************/
/*  あみだくじ(アスキーアート)  */
/*                                */
/*  横線は乱数で設定              */
/**********************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define LMAX  5                                         // 縦線MAX
#define CMAX 15                                         // 桁MAX
#define XMAX 50                                         // 領域水平方向MAX
#define YMAX 25                                         // 領域垂直方向MAX

char  buf[YMAX][XMAX];                                  // 領域配列
int   dsx=XMAX/(LMAX-1);                                // 縦線間隔

void  INIbuf(void);                                     // 領域設定
void  KUJI(int);                                        // くじをなぞる
void  DISP(void);                                       // 画面表示


void  main( )
/*----------*/
/*  主処理  */
/*----------*/
{
    char c[128];
    int  N;

    printf("\nあみだくじ(AA)\n");

    INIbuf( );                                          // 領域設定
    DISP( );                                            // 画面表示

    while( 1 )
      {
        printf("\n番号を入力してください(1〜%d以外で終了): ",LMAX);
        fflush(stdout);
        gets(c); N=atoi(c);                             // 番号入力
        if ( N<1 || N>LMAX ) break;                     // 範囲外

        KUJI(N);                                        // くじをなぞる
        DISP( );                                        // 画面表示
      }
}


void  INIbuf( )
/*------------*/
/*  領域設定  */
/*------------*/
{
    int  i,j,y,x;
    unsigned long seed;                                 // 乱数の種

    memset(&buf[0][0],' ',XMAX*YMAX);                   // 領域初期化

    //--縦線--
    for( i=0,x=0; i<LMAX; i++,x+=dsx )
      {
        for( y=0; y<YMAX; y++ ) buf[y][x]='*';          // 縦線設定
      }

    //--横線--
    time(&seed);                                        // 時刻取得(秒)
    srand(seed);                                        // 乱数の種をまく
    for( j=0; j<CMAX; )
      {
        i=j%(LMAX-1);                                   // 縦線添字(0〜3)
        x=i*dsx;                                        // 縦線位置
        y=rand( )%YMAX-1;                               // 横線位置
        if ( buf[y][x]=='+' || buf[y][x+dsx]=='+' )     // 交点
            continue;
        memset(&buf[y][x],'*',dsx);                     // 横線設定
        buf[y][x]='+';                                  // 交点(左)
        buf[y][x+dsx]='+';                              // 交点(右)
        j++;
      }
}


void  KUJI(
/*----------------*/
/*  くじをなぞる  */
/*----------------*/
int  N)    // くじ番号
{
    int  x,y,dx,dy;   // 位置,増分

    x=dsx*(N-1); y=0;                                   // 開始位置
    dx=0; dy=1;                                         // 進行方向

    while( y<YMAX )
      {
        if ( buf[y][x]!='+' )                           // 交点でない
          {
            buf[y][x]='0'+N;                            // 通過番号設定
          }
        else
          {
            if ( dy==0 )                                // 横に移動中
              { dx=0; dy=1; }                           // 下へ方向転換
            else                                        // 下に移動中
              {
                dx=1; dy=0;                             // 右へ方向転換
                if ( x>0 )                              // 左端でない
                  {
                    if ( buf[y][x-1]!=' ' )             // 左に線あり
                         dx=-1;                         // 左へ方向転換
                  }
              }
          }

        x+=dx; y+=dy;                                   // 移動
      }
}


void  DISP( )
/*------------*/
/*  画面表示  */
/*------------*/
{
    char c[128];
    int  i,x,y;

    //--番号表示--
    memset(c,' ',XMAX); c[XMAX]='\0';                   // 番号1行
    for( i=0,x=0; i<LMAX; i++,x+=dsx )
      { c[x]='1'+i; }
    printf("\n%.*s\n",x,c);                             // 1行表示

    //--領域表示--
    for( y=0; y<YMAX; y++ )
      { printf("\n%.*s",XMAX,&buf[y][0]); }             // 1行表示
    printf("\n");

    //--結果表示--
    memset(c,' ',XMAX); c[XMAX]='\0';                   // 番号1行
    for( i=0,x=0; i<LMAX; i++,x+=dsx )
      { c[x]='A'+i; }
    printf("\n%.*s\n",x,c);                             // 1行表示
}
   

※SSL暗号化通信対応

佐伯英子技術士事務所 〒542-0073 大阪市中央区日本橋 1-14-13 サンオフィス日本橋601  E-mail: info@saeki-pe.com