課題の質問

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
elmes

課題の質問

#1

投稿記事 by elmes » 18年前

初めて投稿させていただきます。
早速なんですが、課題が分からず質問させていただきます。

[1本の道に,食べ物が多数落ちている.
ランダムに動く動物が,それらを全て食べ尽くすと終了するようなプログラムを作成せよ.

<仕様>
「道」は要素数20程度の1次元配列で表現する.
「食べ物」は,上記配列の各要素に値1があればその場所に存在し,値0であればその場所には存在しないものとする.
「動物」は,1回の移動で配列中の1つ左または1つ右に移動できる.
「動物」の訪れた場所のエサは食べられたものとする.
「道のうち食べ物のない箇所」,「道のうち食べ物のある箇所」,「動物」は,それぞれ -, *, O で表現する.それらを横一列の文字で表示する.
繰り返し処理中は,毎回数十~数百ミリ秒程度の時間,実行を一時停止させることで,状態の推移を見やすくする.
余力があれば,cursesライブラリを使用して,毎回コンソール内の同じ箇所にスクロール無しで表示できるようにする.]

という問題なんですが、どうぞよろしくお願いします。
ちなみに配列まで習っており、標準ライブラリはまだ習ってません。

バグ

Re:課題の質問

#2

投稿記事 by バグ » 18年前

えっと、いくつか確認させてください。

まず、コンパイラは何をお使いでしょうか?

それから、cursesライブラリって何ですか?

最後に、標準ライブラリを習ってないという事は、使用してはいけないという意味でしょうか?

elmes

Re:課題の質問

#3

投稿記事 by elmes » 18年前

返信ありがとうございます。

コンパイラについてですが、申し訳ないんですがちょっと確認ができないんです。
ちなみにOSはリナックスです。
次にcursesライブラリについてですが、
(余力があればcursesライブラリを使用して・・・・・・スクロール無しで表示できるようにする)
↑の行は無視していただいて結構です。
最後に標準ライブラリについてですが、これは使用してはいけないという解釈でお願いします。

バグ

Re:課題の質問

#4

投稿記事 by バグ » 18年前

ごめんなさい、OSがLinuxという時点で私では力になれそうにありません…。
更に標準関数も使えないのでは余計に…です(;´Д`)
申し訳ないですm(__)m

Justy

Re:課題の質問

#5

投稿記事 by Justy » 18年前

>標準ライブラリについてですが、これは使用してはいけないという解釈でお願いします
 これはなかなか大変な縛りですね。
 rand()や srand()、time()も使えないとなると /dev/randomとか/dev/urandomとか使うんでしょうかね。

elmes

Re:課題の質問

#6

投稿記事 by elmes » 18年前

すいません、標準ライブラリについてですが、
使用してもいいということが分かりました☆

elmes

Re:課題の質問

#7

投稿記事 by elmes » 18年前

いろいろなヒントを元に、

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define TABEMONO 20

int main(void)
{
int miti[TABEMONO];
int i,n,doubutu, tabemono=TABEMONO;
time_t t1,t2;

srand(time(NULL));

/*毒饅頭を全体に置く、毒が弱いので20個食べないと死なない*/
for(n=0;n<TABEMONO;n++) miti[n]=1;
/*動物を放す*/
doubutu=(rand()%19);
i=1;
while(tabemono>0){/*毒饅頭置いてある間は続ける*/*/
/*現在の状況を表示、動物に居る所に毒饅頭があれば食べる(毒饅頭が1個減る)。*/
printf("%5d:",i++);
for(n=0;n<TABEMONO;n++){
if(n==doubutu){
if(miti[n]!=0){
tabemono--;
miti[n]=0;
}
printf("○");
miti[n]=0;

}
else if(miti[n]==1)printf("*");
else printf("-");
}
if(doubutu==0)doubutu++;/*左端だから右にしかいけない*/
else if(doubutu==TABEMONO)doubutu--;/*右端だから以下省略*/
else if(rand()%2==0) doubutu++;/*端じゃないなら乱数で行く方向を決める*/
else doubutu--;
printf("\n");


/*------------*------------------*---------------*----------
ここに一時停止するコードを入れる
---------------------------*---------------*--------------*/
}
return 0;
}

といった感じまでは仕上がったんですが、「一時停止するコード」がどうしても分かりませんでした。
この部分を何とかお願いしたいのですが・・・

Justy

Re:課題の質問

#8

投稿記事 by Justy » 18年前

>「一時停止するコード」がどうしても分かりませんでした
 Linuxなら getch()とかどうでしょう?
 キーボードの入力待ちで一時停止しますよ。

バグ

Re:課題の質問

#9

投稿記事 by バグ » 18年前

>>繰り返し処理中は,毎回数十~数百ミリ秒程度の時間,実行を一時停止させることで,状態の推移を見やすくする.

とあるので、getchだとまずいのではないでしょうか?
課題文を見る限りでは、ウェイト用タイマー関数を自作するのも課題みたいですね。
たしか、time.h内に経過時間を返す関数があったような…

バグ

Re:課題の質問

#10

投稿記事 by バグ » 18年前

私なら、こうするというものを載せてみます。変数名等も全て私の好みでつけましたので、参考程度に…
Windows上での動作は確認しましたが、Linuxでは分かりません。標準関数しか使っていないので、多分大丈夫だとは思いますけど…(^_^;)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define WAIT 100 /* ミリ秒単位で一時停止時間を指定する */

int main(void)
{
	char szWay[21];
	int i, nAnimal, nFood, nWay[20];
	clock_t ctStart, ctEnd;

	/* 乱数生成の為の前準備 */
	srand((unsigned)time(NULL));

	/* 道の上に食べ物を配置する */
	for (i = 0; i < 20; i++) nWay = 1;

	/* 食べ物の数を初期化する */
	nFood = 20;

	/* 動物の初期位置の決定 */
	nAnimal = rand() % 20;

	/* 食べ物の数が0以上の間、ループさせる */
	do
	{
		/* 動物の位置と同じ位置に食べ物がある場合には、食べ物のカウントを1つ減らす */
		if (nWay[nAnima[/url] == 1) nFood--;

		/* 道の配列へ動物が居る位置を格納する */
		nWay[nAnima[/url] = 2;

		/* 道の表示用の文字列を作成する */
		for (i = 0; i < 20; i++)
		{
			switch (nWay)
			{
				case 0:
					szWay = '_';
					break;
				case 1:
					szWay = '*';
					break;
				case 2:
					szWay = 'O';
					break;
			}
		}

		/* 文字列の終端に終端記号を追加する */
		szWay[20] = '\0';

		/* 道を表示する */
		printf("%s\r", szWay);

		/* 動物の移動処理 */
		nWay[nAnima[/url] = 0;
		if (rand() % 2 == 0)
		{
			nAnimal++;
		}
		else
		{
			nAnimal--;
		}

		if (nAnimal < 0) nAnimal = 19;
		if (nAnimal > 19) nAnimal = 0;

		/* 一時停止処理用タイマー */
		ctStart = clock();
		do
		{
			ctEnd = clock();
		}
		while (ctEnd - ctStart <= WAIT);
	}
	while (nFood > 0);

	return 0;
}

Justy

Re:課題の質問

#11

投稿記事 by Justy » 18年前

>とあるので、getchだとまずいのではないでしょうか?
 んー、たしかにそうなんですが、既にサンプルのなかで usleepを使っているのにも
関わらず「一時停止」と訊かれていたので、時間的に止めたいというわけじゃないのかな
とも思ったわけです。

 そう言われるてみると、そうではなくただ単に usleep()などを使った時間的な一時停止で
いいのかもしれませんね。

バグ

Re:課題の質問

#12

投稿記事 by バグ » 18年前

なるほど、そう言われてみればそうですね(^_^;)

usleepという関数がどこで定義されているのか分からないですけど…あ、ひょっとしたら、最初の方に出てきたcursesというライブラリ内に存在しているのかもしれませんね。

hoge

Re:課題の質問

#13

投稿記事 by hoge » 18年前

ごめん。インデント崩れた。あと最後にmoveが無かった。
良ければ上のをけしといて。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <curses.h>

void init_load(int* load, int size)
{
    int i;
    for (i = 0; i < size; ++i) {
        load = rand() / (RAND_MAX / 2);
    }
}

void print_load(int* load, int size)
{
    int i;
    static char disp[/url] = {'-', '*', '0'};
    for (i = 0; i < size; ++i) {
       printw("%c", disp[load]);

    }
    printw(" food: %d\n", count_food(load, size));
}

int move_animal(int* load, int size, int pos)
{
    load[pos] = 0;
    if (rand() / (RAND_MAX / 2))
        ++pos;
    else
        --pos;
    if (pos < 0)
        pos = size -1;
    else if (pos > size -1)
        pos = 0;

    load[pos] = 2;
    return pos;
}

int count_food(int* load, int size)
{
    int i;
    int food = 0;
    for (i = 0; i < size; ++i) {
        if (load == 1)
            ++food;
    }
    return food;
}

int main(int argc, char* argv[/url])
{
    int *load;
    int size;
    int pos;
    WINDOW* win;

    if (argc != 2) {
        printf("%s num\n", argv[0]);
        return 1;
    }
    size = strtol(argv[1], NULL, 10);
    if (!size)
        return 1;
    load = (int*)calloc(size, sizeof(int));
    if (!load)
        return 1;

    win = initscr();

    srand(time(NULL));
    init_load(load, size);
    pos = rand() / (RAND_MAX / size);

    while (count_food(load, size) != 0) {
        move(1, 1);
        print_load(load, size);
        pos = move_animal(load, size, pos);
        wrefresh(win);
        usleep(100000);
    }
    move(1, 1);
    print_load(load, size);
    wrefresh(win);
    usleep(100000);

    endwin();
    return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る