Lenny`s Dairy Notes

とある大学生のブログ

ビンゴーゲーム

去年の講義の課題でビンゴーゲームを作ったのですが、よくこんなものが書けたなと感心してしまいました。今の自分に同じようなものを作れと言われると、書ける自信がありません。

アルゴリズム自体というよりも、プレイヤーがプレイしやすいようにUIとかを色々考えているのがほんとに素晴らしいと思うし、昔の自分を褒めてあげたい。

ただ、今の自分が与えられるアドバイスとしては、入力を整数型(int)じゃなくて、文字列型(char)にした方が、入力エラーに対応できるんじゃないかとおもいますねぇ。

/* ビンゴゲーム */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 5
#define M 100

/* ビンゴのカードをを作る */
/* 111は閉じている、100は開いている */
void card(int s[][N], int n[][N])
{
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            s[i][j] = 111;
            n[i][j] = 0;
        }
    }
            s[N/2][N/2] = 100;
            n[N/2][N/2] = 1;
}

/* カードの状態を出力する */
/* 見やすくするため111はX、100はOにする */
void out(int s[][N])
{
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            if(s[i][j] == 111)
                printf("  X ");
            else if(s[i][j] == 100)
                printf("  O ");
            else printf("%3d ", s[i][j]);
        }
        printf("\n");
    }
    printf("\n\n\n");
}

int main(void)
{
    int i, j, k, a[N][N], s[N][N], n[N][N], x[M], y[M], c, L, A, fa, fb, fc, fd, z;

/* ゲームのイントロ */
    printf("\n-----> BINGO GAME <-----\n\n");
    printf("何回挑戦する?(5 ~ 100): ");
    scanf("%d", &L);
    printf("\n\n[0 ~ 99 の数を入力してね]\n\n");

    card(s, n);     out(s);     //カードを出力

/* 数字の被り防止のため、0~99を配列に入れ真理値を1にする */
    for(i = 0; i < M; i++) {
        x[i] = 1;      y[i] = 1;
    }

/* 乱数でカードに数字を振り分ける */ 
/* 被る数があればやり直す */
    srand(time(NULL));
    for(i = 0; i < N; i++) {
        j =0;
        while(j < N) {
            k = rand() % M;
            if(x[k] == 1)    {
                a[i][j] = k;
                x[k] = 0;
            }
            else continue;
            j++;
        }
    }
    
    a[N/2][N/2] = 100;       //カードの中心は入力値の範囲外で常に真

    //out(a);          //デバッグ用、onにすると予めに答えがわかる

/* 入力値がカードの値に一致するかどうか、ビンゴの判定、カウント */
    c = L;
    while(c > 0) {                                            //挑戦回数のカウント
        printf("あと %d\n\n", c);
        printf("A = "); scanf("%d", &A);
        
        if(A < 0 || A > 99) {                             //入力値の範囲を制限
            printf("(0 ~ 99) の数を入力しろ\n\n\n");
            continue;
        }
        
        if(y[A] == 1) {                                      //入力値が被らなかった場合
            y[A] = 0;
            int flag = 0;
            for(i = 0; i < N; i++)
                for(j =0; j < N; j++) {
                    if(A == a[i][j]) {                        //数値の一致を判定
                        printf("GREAT!!\n\n");
                        s[i][j] = a[i][j];
                        n[i][j] = 1;
                        out(s); //out(n);
                        flag = 1;
                        break;
                    }
                    if(flag)  break;
                    if(i == N - 1 && j == N - 1)        printf("はずれ!\n\n\n");
                }
        }
        else if(y[A] == 0) {                               //入力値が被った場合
            printf("数字が被ってるよ!もう一度!\n\n\n");
            continue;
        }
        
        for(i = 0; i < N; i++) {                          //縦、横、斜めでのビンゴの判定
            fa = 1;    fb = 1;    fc = 1;    fd = 1;
            for(j = 0; j < N; j++) {
                if(n[i][j] != 1)     fa = 0;
                if(n[j][i] != 1) fb = 0;
                if(n[j][j] != 1) fc = 0;
                if(n[N - (j + 1)][j] != 1)  fd = 0;
            }
            if(fa || fb || fc || fd) {
                printf("BINGO!!!\tYOU WIN !!!\n\n");
                break;
            }
        }
        if(fa || fb || fc || fd)      break;
        c--;
    }
    if(c == 0) {                                         //挑戦回数が0になったらアウト
        printf("残り %d\n\nYOU LOSE !!!\n\n", c);
    }

/* カードの答え合わせが可能 */  
    while(1) {
        printf("答え合わせをしますか?\n(YES = 1 ; NO = 0):");
        scanf("%d", &z);
        printf("\n");
        
        if(z == 1) {
            printf("--->答え合わせ<---\n\n");
            out(a);     break;
        }
        else if(z == 0) break;
        else printf("\nちょと何いってるかわからない\n\n\n");
    }
    
    return 0;
}


/* 説明
変数
・i, j, k,  c, L, A, fa, fb, fc, fd, z;
   a[N][N], s[N][N], n[N][N], x[M], y[M],:int型 
   for文の引数i, j, k, カウントc, 挑戦回数L, 入力値A, ビンゴ判定fa, fb, fc, fd,
   答え合わせz, カードの値a[][], s[][], 真理値n[][], 全数値x[][], y[][], 
処理内容
・12〜22行:ビンゴのカードをを作る
・26〜39行:カードの状態を出力する
・66〜74行:乱数でカードに数字を振り分ける
・79〜109行:入力値がカードの値への一致を判定
・111〜129行:縦、横、斜めでのビンゴの判定
・132〜143行:カードの答え合わせ */

ターミナルで実行

/* 実行結果(中略あり)
-----> BINGO GAME <-----

何回挑戦する?(5 ~ 100): 40


[0 ~ 99 の数を入力してね]

  X   X   X   X   X 
  X   X   X   X   X 
  X   X   O   X   X 
  X   X   X   X   X 
  X   X   X   X   X 



あと 40 回

A = 10
はずれ!


あと 39 回

A = 11
GREAT!!

  X   X   X   X   X 
  X   X   X   X   X 
  X   X   O   X   X 
  X  11   X   X   X 
  X   X   X   X   X 



あと 38 回

A = 11
数字が被ってるよ!もう一度!


あと 38 回

A = 111
(0 ~ 99) の数を入力しろ


あと 38 回

A = 19
はずれ!


あと 37 回

A = 30
はずれ!
〜〜〜〜〜〜〜〜〜〜(中略)
あと 1 回

A = 79
GREAT!!

  9   X   2   X  79 
  X   X  94  78   X 
  X   X   O   X   X 
  X  11   X   X   X 
 83  87  80   X   X 



BINGO!!!   YOU WIN !!!

答え合わせをしますか?
(YES = 1 ; NO = 0):1

--->答え合わせ<---

  9   34   2   23  79 
 54  15  94  78  62 
 77   0   O   18  43 
 32  11  96   40  22 
 83  87  80   25   1               */

モンキーハンティングのシミュレーション

約1年ぶりの投稿になります。新2年生になりました。

年度初の投稿は、学校で発信する新入生向け通信(一部変更あり)です。電子媒体だと、コードもコピペしやすいし、gifも載せられて便利ですね。

以下本編です。

モンキーハンティングとは

木にぶら下がっている猿がいます。その猿を猟銃で狙っている猟師がいます。銃の発射とともに、(発射音に驚いた)猿が木から手を離しますが、どんなに離れていても、銃弾は必ず猿に命中するという話です。

まず、この話の問題設定をまとめてみましょう。

  1. 自由落下をする物体(猿)と放物運動をする物体(銃弾)が存在します。
  2. 放物運動をする物体の運動の向きは、自由落下をする物体の位置の方向です。
  3. 2つの物体は同時に運動を開始します。

しかし、実際は、銃の発射と銃声が届くタイミングがずれていたり、銃弾が届く前に地面に着いたりしてしまうので、上の3項目だけを満たした理想な状態を考えましょう。

理論

最初に、モンキーハンティングがどういう理論で成り立っているのかを、数式を用いてみていきましょう。

f:id:LennyQ:20170401191237p:plain 

図1:説明図

モンキーハンティングを簡単な図に表すと、図1のようになります。青ボールは銃弾、緑ボールは猿を表しています。では、必要な文字を定義していきましょう。2つのボールの水平の距離を \( l \) 、垂直の距離を \( h \) とします。青のボールは水平面に対して仰角 \( \theta \) 、初速度 \( v \) で打ち出します。重力加速度は \( g \) とします。

この問題で大切なことは、初速度 \( v \) を水平方向と垂直方向に、それぞれ \( v\cos\theta \) と \( v\sin\theta \) に分解することです。これを踏まえた上で、この問題を証明する手順を説明していきましょう。

何を証明するのかといいますと、この2つのボールは本当にぶつかるのかということ証明します。

2つのボールがぶつかるというのはどういうことか。これをもっと単純化して、2つのボールが同じ位置にいるときという認識にしましょう。それはつまり、

  • 青ボールが水平方向に \( l \) 進んだとき、高さが緑ボールと同じになる

ということです。これを用いて、証明してみましょう。

証明

まず、青ボールが水平方向に \( l \) だけ進んだときの時間を求めましょう。放物運動の水平方向の運動は等速直線運動な\begin{align*} l = v\cos\theta \cdot t \end{align*} という式が書けますね。したがって、 \begin{align*} t = \frac{l}{v\cos\theta} (*) \end{align*} という式ができます。つまり、2つのボールはこの時間に同じ高さにいないといけないというわけですね。

次に、時間 \( t \) のときのそれぞれのボールの高さを調べてみましょう。青ボールの初期位置を基準として、青ボールの高さを \( y_1 \) 、緑ボールの高さ \( y_2 \) としますと、 \begin{align*} y_1 = v\sin\theta \cdot t - \frac{1}{2}gt^2 \end{align*}

\begin{align*} y_2 = h - \frac{1}{2}gt^2 \end{align*}

と表せます。この二つの高さが等しい、つまり、\( y_1 = y_2 \) を示せば証明することができます。これを、 \begin{align*} v\sin\theta \cdot t - \frac{1}{2}gt^2 = h - \frac{1}{2}gt^2 \end{align*} と書けかえると、両辺に同じ \( - \frac{1}{2}gt^2 \) があるので消去して、 \begin{align*} v\sin\theta \cdot t = h \end{align*} となります。つまり、この式の (左辺) = (右辺) を示すことになります。左辺の式に式 \( (*) \) を代入すると、 \begin{align*} (左辺) = v\sin\theta \cdot \frac{l}{v\cos\theta} = l\tan\theta = l \cdot \frac{h}{l} = h \end{align*} となり、(左辺) = (右辺) が示され、すなわち、\( y_1 = y_2 \) が示されたのです。これで、モンキーハンティングが証明されました。

しかし、最初の問題設定でも書かれていた通り、青ボールの運動方向は緑ボールに向かっていなければならないのです。このことを表している条件が、 \begin{align*} \tan\theta = \frac{h}{l} \end{align*} という式です。この式を満たしていれば、2つのボールは必ずぶつかるということです。

シミュレーション

そうはいっても、現実でそんな場面に遭遇することもないだろうし、イメージが湧きにくいですよね。そんなときに用いるのが、物理演算によるシミュレーションです。今回は、Processingという描画専門の統合開発環境を用いて、プログラミングの力でこの問題を確かめてみましょう。

Processingについて

Processingでは描画が簡単にできますが、静止画はもちろん、動画も作ることができます。シミュレーションはものが動いていないとできませんので、今回は動画を作ります。

さて、この動画の仕組みですが、簡単に説明しますと、実は画像をパラパラ漫画のように1枚ずつ描画しています。Processingの基本設定だと60fpsですので、1秒間に60枚の画像、つまり、1/60秒ごとに1つの画像を表示しているんです。この1つの画像のことを1フレームといいます。

この知識を踏まえて次をみていきましょう。

コードを書く前に

まずは下のことを頭に入れておきましょう。

  • 現在の速度=直前の速度+加速度

  • 現在の位置=直前の位置+現在の速度

「現在」というのは今のフレームにおいて、「直前」というのは1コ前のフレームにおいてと考えましょう。

実はこれ、何も難しい話ではなく、数式に直してみると当たり前だと感じるはずです。

現在の速度を\( v \)、直前の速度を\( v' \)とし、現在の位置を\( y \)、直前の位置を\( y' \)とします。また、加速度を\( a \)とします。そしてここで、隠れた要素である、1フレームの時間を\( t \)(= 1/60秒)とします。役者がそろったところで、数式に直してみましょう。

  • \( v = v' + at \)
  • \( y = y' + vt \)

こうしてみるとどれも見たことあるような数式ばかりですね。もっと簡単に説明すると、

  • (速度の変化)=(加速度)×(経過時間)
  • (移動距離)=(速度)×(経過時間)

ということを表しているんですね。

コード

いよいよシミュレーションを作るためのコードを書いていきましょう。

/********************/
/** メインファイル ****/
/********************/

//PVectorはProcessingにおいてベクトルを扱うクラス
PVector acc;                    //重力加速度ベクトル
boolean isClicked = false;        //マウスのクリック判定用変数

FObject[] obj = new FObject[2];  //2つのボールの生成宣言

/* 前準備 */
void setup() {
  size(1200,600); //キャンバスの大きさ(横,縦)
  background(255); //キャンバスの背景の色(白)
  
  //1つ目のボールの生成とそのパラメータ
  obj[0] = new FObject(20, height-100, 30, 10,0,255);  
  //2つ目のボールの生成とそのパラメータ
  obj[1] = new FObject(width-200, 20, 30, 20,200,20);  
  //1つ目のボール:銃弾(青)
  //2つ目のボール:猿(緑)
  //パラメータはクラスファイルを参照(下にある)
  
  //猿の初速度と射角(クラスファイル参照)
  obj[1].move(0.0, 0.0);             
  
  //重力加速度をベクトルとして生成(x方向,y方向)
  acc = new PVector(0.0/60, 9.8/60);  
  //パラメータを1/60倍している理由は、Processingのfpsに合わせることで物体の動きを見
  //やすい速度に落とすため。
}

/* メイン関数(1/60秒ごとに実行) */
void draw() {
  //2つの球の初期位置を描画(クラスファイル参照)
  for(int i=0; i<2; i++) {
    obj[i].position();
  }
  
  //マウスをクリックしたらボールが動き出す(クラスファイル参照)
  if(isClicked) {
    for(int i=0; i<2; i++) {
      obj[i].diplay();
    }
  }
  
  //2つのボールがぶつかったら動きを止める(クラスファイル参照)
  if(isHitted(obj[0].getPos(), obj[0].getRadius(), 
    obj[1].getPos(), obj[1].getRadius())) {
    noLoop();  
  }
}

/* マウスがクリックされたら発動 */
void mouseClicked() {
  obj[0].move(1200.0, -atan2(mouseY-(height-100), mouseX-20)); 
  //銃弾の初速度:1200
  //銃弾の射角 :銃弾を原点にした水平面に対するマウスカーソルと原点を結んだ直線の仰角
  //          つまり、銃弾をマウスカーソルの方向に打ち出せる。
  isClicked = true;
}

/* 2つのボールがぶつかったかどうかを判定 */
boolean isHitted(PVector pos1, float r1, PVector pos2, float r2) {
  if(dist(pos1.x, pos1.y, pos2.x, pos2.y) <= r1+r2)  
    //dist()は2点間の距離を求める関数
    return true;
  return false;
}
/****************************/
/**** ボールのクラスファイル ****/
/****************************/

class FObject {
  //メンバ変数の宣言
  PVector pos;      //位置ベクトル
  PVector vel;      //速度ベクトル
  int diameter;        //ボールの直径
  int R, G, B;     //ボールの色の要素
  PVector tempos;   //記憶用変数
  
  /* ボールのパラメータの設定(コンストラクタ) */
  //(左から順に)位置のX座標、位置のy座標、直径、色の要素(赤)、色の要素(緑)、色の要素(青)
  FObject(float posX, float posY, int tempDiameter, int RED, int GREEN, int BLUE) {
    pos = new PVector(posX, posY);    //位置ベクトルの生成
    tempos = pos;                   //初期位置を記憶
    diameter = tempDiameter;        
    R = RED;
    G = GREEN;
    B = BLUE;
  }
  
  /* 初速度と射角を決めるメソッド */
  void move(float vel0, float rad) {
    vel = new PVector(vel0*cos(rad)/60, -vel0*sin(rad)/60);
  }
  
  /* 描画するメソッド */
  void diplay() {
    vel.add(acc);   //現在の速度=直前の速度+加速度
    pos.add(vel);   //現在の位置=直前の位置+現在の速度
    
    //キャンバスの底に着いたら上に戻る
    if(pos.y > height) {
      pos.y = 20;
    }
    
    //ボールの描画
    fill(255,20);noStroke();rect(0,0,width,height); //軌跡を残すためのぼかし
    stroke(R,G,B); fill(R,G,B);                     //線色・面色
    ellipse(pos.x, pos.y, diameter, diameter);      //円の描画
  }
  
  /* 初期位置を描画するメソッド */
  void position() {
    stroke(R,G,B); fill(R,G,B);
    ellipse(tempos.x, tempos.y, diameter, diameter);
  }
  
  /* 今の位置をベクトルで返すメソッド */
  PVector getPos() {
    return pos;
  }
  
  /* 半径を返すメソッド */
  float getRadius() {
    return diameter/2.0;
  }  
}

注意点

途中で出てくる「キャンバス」という言葉がありますが、シミュレーションを実行する画面を指しています。f:id:LennyQ:20170401200025p:plain

図2:キャンバス

図2のように、キャンバスの原点は左上の角にあり、幅は右方向に、高さは下方向に伸びています。そのため、ベクトルを考えるときは、この方向に合わせて考えなければいけません。

実行結果

それでは、このコードで書かれたシミュレーションがどのような動きをするのかを見てみましょう。 f:id:LennyQ:20170401215023g:plain 見事にぶつかりました!

次に、青ボールの初速度を半分に落としてみましょう。もし証明が正しければ、初速度に関係なく2つのボールはぶつかるはずです。コードにある青ボールの初速度を1200から600に書き換えましょう。

さてどうなるでしょうか。 f:id:LennyQ:20170401215405g:plain こちらも見事にぶつかりました!

これでシミュレーションによって、モンキーハンティングが確かめられましたね。

最後に

今回は物理とプログラミングを融合させてシミュレーションというものをやってみました。すでに気づいている人もいるかもしれませんが、シミュレーションには現実ではできないメリットがあります。それはパラメーターを色々いじることで、容易に動作を確かめることができることにあります。パラメーターというのは、シミュレーションを形作る様々な数値だと思ってください。今回でいう、銃弾の初速度や重力加速度がそれです。

今までプログラミングを学んできた人や、これから学ぶ人もこの考えを大事にして欲しいのですが、何度でもパラメーターやコードを変えて、「実験」を繰り返してみましょう。色々実験してみることで理解を深めたり、新しく学ぶこともあると思います。

シミュレーションを使って問題を確かめることは、今まででは思いもしなかった新鮮なことだったかもしれません。しかし、プログラミングを知っていても、「プログラミングという知識」と「物理という知識」を分けてしまっていたら、今回のシミュレーションはやろうとしなかったと思います。

プログラミングは決して単独な知識ではなく、手段にすぎません。自然科学(数学や物理など)の問題でも、身近の問題でもなんでもいいです。自分が理解を深めるための手段という視点で、ぜひプログラミングを学んでみてください。

追記(2017/4/1/22:06)

スマートフォンだと数式がうまく見れないかもしれないので、どーしてもみたい方だけ(←ここ重要)PCでみてください。

退屈な日々に疲れていませんか?・・・私は疲れました。。。

ブログで何を書けば良いか分からず一ヶ月以上が経ちました。。。

 

・・・嘘です本当は忘却の彼方にありました。

 

久々に思い出してわざわざ引っ張り出してきたので

近況報告でもしたいと思います。

 

キャンパスライフ

学校生活めちゃくちゃ楽しい!・・・と言いたいところですが、

正直退屈してきました。。。

楽しみがほぼ借りたDVDとYouTubeになりました。

学校関係ねぇ・・・!って思ったらDVDは学校で借りるんだった。

 

入学当初は新鮮な気持ちでワクワクドキドキしていましたが、

実家通いなので地味に遠いし、授業眠いし、課題めんどくさいし、

、、、と愚痴がこぼれるくらい退屈です。

 

これは完全に私の努力不足、というか向上心が足りてないせいですが、

同じような日々を繰り返すとやっぱり疲れてしまいますよね。。。

 

しかしもちろんこのまま四年間過ごすつもりは、毛頭ない!!!

 

打開策

じゃあ、どうするのか・・・私は、考えました。

 

退屈の原因は、今までと変わらずに学校に通っては勉強し帰っては寝る

というくだらない日々を繰り返しているからじゃないのか。

 

退屈なのは、流れる新鮮な命の水が窮屈な日常という壁にせき止められ

腐っていっているからではないのか。

 

せき止められ流れが止まった水は、また流させれば新鮮さを取り戻せる

のではないのか!!!

 

 

・・・ということで私はこの夏にかけることにしました。

具体的には何をするのか

 

その1 海外旅行

その2 一人暮らし           ・・・です。

 

 まず、高校の時と比べ物にならないほどの夏休みを利用し、

日本列島の外に飛び出してみる!

なんてワクワクするんだろう!

 

・・・え?どこに行くかって?

う〜ん、中国かな

・・・なんでかって?

う〜ん、近いから?

 

ということで約3週間中国に行くことになりました。

 

・・・距離は問題じゃない!大切なのはその行為だろ!?

 

 

はい、次

一人暮らしですが、これは元から決まっていたことなので

特に言うことはありませんが、

何しろ人生初めての部屋探しとかするんだから

色々と楽しみですよね。

 

一人暮らしを始めたら、通学距離が短くなるのはもちろん

夜の帰る時間だって気にしなくていいし、

男だって部屋に連れ込めるし。。。ぐへへ・・・

 

あ、ホモじゃないっす。

 

 

 

つまり、今年の夏がとても楽しみだということを伝えたかっただけです。

 

 

これでまたネタがなくなったから

あと2ヶ月はブログに書くことない笑、わーい

 

それではまた。

初めてのプログラミング

前回でも言ったように、先月私は大学デビューし、

自由気ままにキャンパスライフを満喫しています。

 

何よりもずっと習いたかったプログラミングを今学べていることが幸せと感じています。

今日はプログラミングを習い始めて1ヶ月の成果&感想を書きたいと思います。

 

 

初めてのプログラミング

プログラミングはなんでも作れる万能なツールとしか漠然と理解していなく、

どうやって書くのか、どこに書くのかすら知らなかったプログラミング初心者。

 

そんな私が最初に手をつけた言語はC言語でした。

 

C言語はポプュラで凡用性が高いためプログラミングの概念を学ぶのに良いと、

学校に言われるがまま始めましたが、

 

プログラミングとはなんとも趣が深いものなんだ!

 

と、さっそくハマってしまいました。

 

 

printfでの"Hello world"の出力から始まり、

四則演算、scanfでの入力、if elseの条件文、

そして今はfor whileのループ文までたどり着きました。

 

 

一番最初に、ソース文を書いてコンパイル(コンピュータがわかるように翻訳)して実行が成功したときは、

喜びのあまり絶叫しそうになりました。

 

まさに、「ちょー気持ち!」

 

そんな感覚にどハマりして学校の課題以外でも色々とプログラムを書いてみましたが(実験がてらに)、

さすがに現在の知識では限界があり少々退屈になっていたところでした。

 

 

しかし、ちょうど一昨日のこと

 

 

 

先輩「ループ文を使って『干支の判別』ができるよ」

 

 

。。。!?!?!?!?

 

 

 

衝撃でした。

 

基本的に簡単な計算や場合分けぐらいしかプログラムしていなく、

今までに習った少数のツールでこんなに実用的(?)なものが書けるなんて思いもしなかった。。。(注:← 初心者です)

 

 

 

これはもうやるしかない!

 

 

先輩の言葉を信じ、私はすべて自力でその『干支の判別』に挑戦することにしたのです。

 

 

 プログラム自体は簡単なもので、

西暦を入れたら干支が返ってくるといったものですが、

それを書くとなると相当に悩ましいものでした。(注:← 初心者です)

 

その日の帰りも次の日もひたすらそのプログラムを考えました。

…もちろん講義はちゃんと出ましたよ?

 

ソースを考えては書いて実行し、

繰り返すこと十数回。

 

 

 

ようやくプログラムが正しく動いた!!!

 

 

 

文法自体は間違っていないはずだったから、

ただひたすらソースの並びを変えて

 いろんなパターンを試していただけですが、

 

 

ビンゴした時の喜び!

嬉しさのあまり絶叫しそうでした(再び)。

 

 

でも残念ながらその時は図書館にいて大声で騒ぐこともできないし、

近くに喜びを共有できる人もいないため、

拷問のような時間が過ぎました。。。(泣)

(実はこれがブログを始めたきっかけの一つでもありますが、、、)

 

 

 

そんなことは置いといて、

 

成果発表です!

以下ソース文

/* 西暦による干支の判別 */

#include <stdio.h>

int main(void)

{
    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, c, x;

    printf("\nその年の干支がわかるよ.\n");

    for( ; ; ){

        printf("\n西暦 = ");
        scanf("%d" ,&c);

 

        for(x = 0; ; x++){

            a1 = 4 + 12 * x;
            a2 = 5 + 12 * x;
            a3 = 6 + 12 * x;
            a4 = 7 + 12 * x;
            a5 = 8 + 12 * x;
            a6 = 9 + 12 * x;
            a7 = 10 + 12 * x;
            a8 = 11 + 12 * x;
            a9 = 12 + 12 * x;
            a10 = 1 + 12 * x;
            a11 = 2 + 12 * x;
            a12 = 3 + 12 * x;

            if(c == a1) {printf("干支 = 子\n\n");break;}
            else if(c == a2) {printf("干支 = 丑\n");break;}
            else if(c == a3) {printf("干支 = 寅\n\n");break;}
            else if(c == a4) {printf("干支 = 卯\n\n");break;}
            else if(c == a5) {printf("干支 = 辰\n\n");break;}
            else if(c == a6) {printf("干支 = 巳\n\n");break;}
            else if(c == a7) {printf("干支 = 午\n\n");break;}
            else if(c == a8) {printf("干支 = 未\n\n");break;}
            else if(c == a9) {printf("干支 = 申\n\n");break;}
            else if(c == a10) {printf("干支 = 酉\n\n");break;}
            else if(c == a11) {printf("干支 = 戌\n\n");break;}
            else if(c == a12) {printf("干支 = 亥\n\n");break;}

        }

    }

    return 0;
}

 

 一応説明しておきますが、

 

西暦1年から永遠に、つまりどんな数字を入れても

その年の干支がわかります。

 

西暦1年が酉年だということもちゃんと逆算して計算しました。

 

また、無限ループしますので

プログラムをやめたいときは強制終了をしないといけませんが、

 

 

 

自分の中では最高傑作だと思っています(←何度も言いますが、初心者ですよ!)

 

 

 

興味ある方はぜひコピーして実行を試してみてください!

また、詳しい方は改善点を見つけてくださるとありがたいです!

 

 

 

 

 

 

 

 

 

 

…とまぁ、こんな感じにプログラミングをやって1ヶ月が経ちましたが、

 

私が感じたこと

 

・作るって楽しい!

 

・理工系にすすんでよかったぁ!

 

・プログラミングまじ神!

 

以上3点です。

 

 

ただ伝えたいことはたった一つです。

 

 

 

何ごとも興味を持ったら積極的にやってみることです。

そこには予想だにしない宝が待っているかもしれません。

 

 

 

 

 

 

 

 

 

 

…いやぁ noob は説得力がないですね …

 

 

プロになれる日を夢に見て

 

 

それではまた会いましょう

  

初めてブログを書きます

インターネットが普及して世界が広くなりました。

でもそれに伴って人と人が繋がりやすくなったゆえ、

世界は狭くなったとも言えますね。

 

 

・・・なんてことはどうでもいいんです。

 

先月私は無事に大学に入学し、

ついに Campus Life Enjoy 勢にデビューしました。

 

様々な目標を立てて充実した4年間にしようと決めたわけですが、

初めて見るもの知ること感じること、

それらは大学生にとってはあまりにも多すぎる!

とこの1ヶ月間思ったわけです。

 

そこで、この4年間での体験を何か見えるものに残そうと思い、

目をつけたのがブログです。

 

ブログだと日記のように書くこともできるし、

何よりも自分以外の読者がいて

その人とその記憶を共有できることが素晴らしいと思います。

 

なので、コメントやアドバイスをくださると嬉しいです!ぜひぜひ!

 

 

不定期の更新になると思いますが、できるだけ書いていきたいと思います。

 

どうぞよろしくお願いします!