ページ 1 / 1
課題の質問
Posted: 2007年6月06日(水) 19:56
by elmes
初めて投稿させていただきます。
早速なんですが、課題が分からず質問させていただきます。
[1本の道に,食べ物が多数落ちている.
ランダムに動く動物が,それらを全て食べ尽くすと終了するようなプログラムを作成せよ.
<仕様>
「道」は要素数20程度の1次元配列で表現する.
「食べ物」は,上記配列の各要素に値1があればその場所に存在し,値0であればその場所には存在しないものとする.
「動物」は,1回の移動で配列中の1つ左または1つ右に移動できる.
「動物」の訪れた場所のエサは食べられたものとする.
「道のうち食べ物のない箇所」,「道のうち食べ物のある箇所」,「動物」は,それぞれ -, *, O で表現する.それらを横一列の文字で表示する.
繰り返し処理中は,毎回数十~数百ミリ秒程度の時間,実行を一時停止させることで,状態の推移を見やすくする.
余力があれば,cursesライブラリを使用して,毎回コンソール内の同じ箇所にスクロール無しで表示できるようにする.]
という問題なんですが、どうぞよろしくお願いします。
ちなみに配列まで習っており、標準ライブラリはまだ習ってません。
Re:課題の質問
Posted: 2007年6月06日(水) 20:21
by バグ
えっと、いくつか確認させてください。
まず、コンパイラは何をお使いでしょうか?
それから、cursesライブラリって何ですか?
最後に、標準ライブラリを習ってないという事は、使用してはいけないという意味でしょうか?
Re:課題の質問
Posted: 2007年6月06日(水) 20:29
by elmes
返信ありがとうございます。
コンパイラについてですが、申し訳ないんですがちょっと確認ができないんです。
ちなみにOSはリナックスです。
次にcursesライブラリについてですが、
(余力があればcursesライブラリを使用して・・・・・・スクロール無しで表示できるようにする)
↑の行は無視していただいて結構です。
最後に標準ライブラリについてですが、これは使用してはいけないという解釈でお願いします。
Re:課題の質問
Posted: 2007年6月06日(水) 21:00
by バグ
ごめんなさい、OSがLinuxという時点で私では力になれそうにありません…。
更に標準関数も使えないのでは余計に…です(;´Д`)
申し訳ないですm(__)m
Re:課題の質問
Posted: 2007年6月06日(水) 22:06
by Justy
>標準ライブラリについてですが、これは使用してはいけないという解釈でお願いします
これはなかなか大変な縛りですね。
rand()や srand()、time()も使えないとなると /dev/randomとか/dev/urandomとか使うんでしょうかね。
Re:課題の質問
Posted: 2007年6月06日(水) 22:20
by elmes
すいません、標準ライブラリについてですが、
使用してもいいということが分かりました☆
Re:課題の質問
Posted: 2007年6月07日(木) 00:03
by elmes
いろいろなヒントを元に、
#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;
}
といった感じまでは仕上がったんですが、「一時停止するコード」がどうしても分かりませんでした。
この部分を何とかお願いしたいのですが・・・
Re:課題の質問
Posted: 2007年6月07日(木) 00:36
by Justy
>「一時停止するコード」がどうしても分かりませんでした
Linuxなら getch()とかどうでしょう?
キーボードの入力待ちで一時停止しますよ。
Re:課題の質問
Posted: 2007年6月07日(木) 04:38
by バグ
>>繰り返し処理中は,毎回数十~数百ミリ秒程度の時間,実行を一時停止させることで,状態の推移を見やすくする.
とあるので、getchだとまずいのではないでしょうか?
課題文を見る限りでは、ウェイト用タイマー関数を自作するのも課題みたいですね。
たしか、time.h内に経過時間を返す関数があったような…
Re:課題の質問
Posted: 2007年6月07日(木) 09:48
by バグ
私なら、こうするというものを載せてみます。変数名等も全て私の好みでつけましたので、参考程度に…
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;
}
Re:課題の質問
Posted: 2007年6月07日(木) 10:00
by Justy
>とあるので、getchだとまずいのではないでしょうか?
んー、たしかにそうなんですが、既にサンプルのなかで usleepを使っているのにも
関わらず「一時停止」と訊かれていたので、時間的に止めたいというわけじゃないのかな
とも思ったわけです。
そう言われるてみると、そうではなくただ単に usleep()などを使った時間的な一時停止で
いいのかもしれませんね。
Re:課題の質問
Posted: 2007年6月07日(木) 10:08
by バグ
なるほど、そう言われてみればそうですね(^_^;)
usleepという関数がどこで定義されているのか分からないですけど…あ、ひょっとしたら、最初の方に出てきたcursesというライブラリ内に存在しているのかもしれませんね。
Re:課題の質問
Posted: 2007年6月08日(金) 14:51
by hoge
ごめん。インデント崩れた。あと最後に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;
}