地球防衛軍が作れない

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

地球防衛軍が作れない

#1

投稿記事 by ヒヨコ » 9年前

地球防衛軍モドキを作る課題が出たのですが、上手く作れません。
自分の戦艦と相手の戦艦が4艦(両艦共HP100)あって、
自分が1~4番を選ぶと乱数分HPが減り、どちらかの戦艦が全滅すると終了するゲームです。

ある程度は作ってみたのですが自分の戦艦と相手の戦艦の両方にHPが0の戦艦がいると強制終了されます。
while分を抜けるだけでなく、そこで勝手に切れます。
どなたか教えてください。
ちなみに乱数はまだ習っておらず、元々用意されたものを使っているだけです。



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

int boat[4]={100,100,100,100}; // 地球防衛軍戦艦
int boatx[4]={100,100,100,100}; // エイリアン戦艦

/*乱数発生関数*/
/*引数 n:0~n-1までの乱数を発生する*/
int Random(int n)
{
static int first=0;
if(first==0)
{
srand((unsigned)time(NULL));
first=1;
}
return(int)(rand()/(float)RAND_MAX*n);
}

void hyouji()
{
int i;
printf("地球防衛軍戦艦\n");

printf("1番艦");
for(i=0;i<boat[0]/10;i++)
putchar('*');
printf("(HP:%d/100)",boat[0]);
putchar('\n');
printf("2番艦");
for(i=0;i<boat[1]/10;i++)
putchar('*');
printf("(HP:%d/100)",boat[1]);
putchar('\n');
printf("3番艦");
for(i=0;i<boat[2]/10;i++)
putchar('*');
printf("(HP:%d/100)",boat[2]);
putchar('\n');
printf("4番艦");
for(i=0;i<boat[3]/10;i++)
putchar('*');
printf("(HP:%d/100)",boat[3]);
putchar('\n');
putchar('\n');

printf("エイリアン戦艦\n");

printf("1番艦");
for(i=0;i<boatx[0]/10;i++)
putchar('*');
printf("(HP:%d/100)",boatx[0]);
putchar('\n');
printf("2番艦");
for(i=0;i<boatx[1]/10;i++)
putchar('*');
printf("(HP:%d/100)",boatx[1]);
putchar('\n');
printf("3番艦");
for(i=0;i<boatx[2]/10;i++)
putchar('*');
printf("(HP:%d/100)",boatx[2]);
putchar('\n');
printf("4番艦");
for(i=0;i<boatx[3]/10;i++)
putchar('*');
printf("(HP:%d/100)",boatx[3]);
putchar('\n');
putchar('\n');
}

int kougeki(int x)
{
int xx = Random(4);
boatx[x]=boatx[x]-Random(51); //自軍最大与ダメージ 50
if(boatx[x]<0)
boatx[x]=0;
boat[xx]=boat[xx]-Random(51); //敵軍最大与ダメージ 50
if(boat[xx]<0)
boat[xx]=0;
}


main()
{
int num;
printf("貴方は地球防衛軍の指揮官です。\n"); //前フリ
printf("現在、エイリアンの軍勢が地球を侵略しに接近してきました。\n");
printf("全艦に指示を出してエイリアンの軍勢を殲滅してください。\n\n");

/*地球軍が全滅*/ /*敵軍が全滅*/
while((boat[0]!=0 && boat[1]!=0 && boat[2]!=0 && boat[3]!=0) || (boatx[0]!=0 && boatx[1]!=0 && boatx[2]!=0 && boatx[3]!=0))
{
hyouji();
printf("何番船を攻撃しますか?:");
while(scanf("%d",&num),(num<1 || num>4) || (boatx[num-1]==0)) //1~4以外の場合、繰り返す
{
printf("何番船を攻撃しますか?:");
}
kougeki(num-1);
}

hyouji();
if(boatx[0]==0 && boatx[1]==0 && boatx[2]==0 && boatx[3]==0) //敵軍の戦艦が全滅
{
printf("敵戦艦を全滅させました。");
printf("貴方の勝利です!");
}

if(boat[0]==0 && boat[1]==0 && boat[2]==0 && boat[3]==0) //地球軍の戦艦が全滅
{
printf("自戦艦が全滅しました。\n");
printf("地球が侵略されました。\n\n");
}
}

ヒヨコ

Re: 地球防衛軍が作れない

#2

投稿記事 by ヒヨコ » 9年前

トピ主です。
OSはwindows、ソフトはvisual studio2010を使っています。
プログラミング初心者です。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 地球防衛軍が作れない

#3

投稿記事 by みけCAT » 9年前

ソースコードを提示する際は、BBCodeを有効にした(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
ヒヨコ さんが書きました:自分の戦艦と相手の戦艦の両方にHPが0の戦艦がいると強制終了されます。
while分を抜けるだけでなく、そこで勝手に切れます。
本当ですか?
こちらで試してみたところ、地球防衛軍戦艦とエイリアン戦艦の両方にHP0の戦艦が出た時点で、
「少なくとも1個のグループにおいて、HPが0の戦艦が無い」というwhile文の条件を満たさなくなるので、
普通にwhile文を抜け、きちんとhyouji関数の呼び出しとその後のif文の判定を行って終了しました。
GNU gdb (GDB) 7.6.1でmain関数のwihle文の後のhyouji();にブレークポイントを置き、ステップ実行で確認しました。

Windows 7 Home Premium SP1 64ビット
gcc (GCC) 4.8.1
コンパイルオプション: -Wall -Wextra -g3 -static
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

トピ主

Re: 地球防衛軍が作れない

#4

投稿記事 by トピ主 » 9年前

トピ主です。
みけCATさん回答ありがとうございます。
BBCodeとは

コード:

で囲むということですよね?
初心者なのでよく読まずに投稿してしまいました。すみません。

一応PCのスペックはwin7の3.3Ghzぐらいなのですが、これでもスペック不足なのでしょうか・・・?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 地球防衛軍が作れない

#5

投稿記事 by みけCAT » 9年前

while文の条件が不自然な上、他にも全滅判定はあって無駄なので、消してみました。
また、戻り値を返しても使ってもいないkougeki関数の戻り値の型をvoidにしました。
ついでに、main関数の型を標準に合わせました。

コード:

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

int boat[4]={100,100,100,100};			// 地球防衛軍戦艦
int boatx[4]={100,100,100,100};			// エイリアン戦艦

/*乱数発生関数*/
/*引数 n:0~n-1までの乱数を発生する*/
int Random(int n)
{
	static int first=0;
	if(first==0)
	{
		srand((unsigned)time(NULL));
		first=1;
	}
		return(int)(rand()/(float)RAND_MAX*n);
}

void hyouji(void)
{
	int i;
	printf("地球防衛軍戦艦\n");

	printf("1番艦");
	for(i=0;i<boat[0]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boat[0]);
	putchar('\n');
	printf("2番艦");
	for(i=0;i<boat[1]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boat[1]);
	putchar('\n');
	printf("3番艦");
	for(i=0;i<boat[2]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boat[2]);
	putchar('\n');
	printf("4番艦");
	for(i=0;i<boat[3]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boat[3]);
	putchar('\n');
	putchar('\n');

	printf("エイリアン戦艦\n");

	printf("1番艦");
	for(i=0;i<boatx[0]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boatx[0]);
	putchar('\n');
	printf("2番艦");
	for(i=0;i<boatx[1]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boatx[1]);
	putchar('\n');
	printf("3番艦");
	for(i=0;i<boatx[2]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boatx[2]);
	putchar('\n');
	printf("4番艦");
	for(i=0;i<boatx[3]/10;i++)
		putchar('*');
	printf("(HP:%d/100)",boatx[3]);
	putchar('\n');
	putchar('\n');
}

void kougeki(int x)
{
	int xx = Random(4);
	boatx[x]=boatx[x]-Random(51);	//自軍最大与ダメージ 50
	if(boatx[x]<0)
		boatx[x]=0;
	boat[xx]=boat[xx]-Random(51);	//敵軍最大与ダメージ 50
	if(boat[xx]<0)
		boat[xx]=0;
}

int main(void)
{
	int num;
	printf("貴方は地球防衛軍の指揮官です。\n");		//前フリ
	printf("現在、エイリアンの軍勢が地球を侵略しに接近してきました。\n");
	printf("全艦に指示を出してエイリアンの軍勢を殲滅してください。\n\n");

	for(;;)
	{
		hyouji();

		if(boatx[0]==0 && boatx[1]==0 && boatx[2]==0 && boatx[3]==0)		//敵軍の戦艦が全滅
		{
			printf("敵戦艦を全滅させました。");
			printf("貴方の勝利です!");
			break;
		}

		if(boat[0]==0 && boat[1]==0 && boat[2]==0 && boat[3]==0)		//地球軍の戦艦が全滅
		{
			printf("自戦艦が全滅しました。\n");
			printf("地球が侵略されました。\n\n");
			break;
		}

		printf("何番船を攻撃しますか?:");
		while(scanf("%d",&num),(num<1 || num>4) || (boatx[num-1]==0))		//1~4以外の場合、繰り返す
		{	
			printf("何番船を攻撃しますか?:");
		}
		kougeki(num-1);
	}

	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ヒヨコ
記事: 2
登録日時: 9年前

Re: 地球防衛軍が作れない

#6

投稿記事 by ヒヨコ » 9年前

みけCAT さんが書きました:while文の条件が不自然な上、他にも全滅判定はあって無駄なので、消してみました。
また、戻り値を返しても使ってもいないkougeki関数の戻り値の型をvoidにしました。
ついでに、main関数の型を標準に合わせました。
トピ主です。名前変更が何回かあってすみません。
みけCATさんのでやってみたところしっかりと起動しました。ありがとうございます。
判定や条件が不自然なため処理が重くなってしまったのでしょうかね?

しかし今度はまた新たな問題に気づいてしまいました。
自軍が攻撃する対象がHP0だと再選択させるのですが、
敵軍が攻撃する場合は再選択することになっておらず、
何をどこに入れればいいのかよくわかりません。
ご教授ください。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 地球防衛軍が作れない

#7

投稿記事 by みけCAT » 9年前

ヒヨコ さんが書きました:判定や条件が不自然なため処理が重くなってしまったのでしょうかね?
いいえ。
この程度の無駄な条件分岐を入れても!重さはほとんど変わらないでしょう。
あなたのプログラムは論理的に間違っています。
強制終了するというあなたの考察も間違っています。

潔く間違いを認め、次につなげましょう。
ヒント:ド・モルガンの法則 - Wikipedia
ヒヨコ さんが書きました:自軍が攻撃する対象がHP0だと再選択させるのですが、
敵軍が攻撃する場合は再選択することになっておらず、
何をどこに入れればいいのかよくわかりません。
とりあえず適当にやるなら、敵軍の攻撃対象がHP0だったら再選択させる処理を敵軍の攻撃対象を選ぶところに入れればいいでしょう。
または、最初からHP0でないものをリストアップしてその中から選ぶ、という方法もあります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ヒヨコ
記事: 2
登録日時: 9年前

Re: 地球防衛軍が作れない

#8

投稿記事 by ヒヨコ » 9年前

みけCAT さんが書きました: いいえ。
この程度の無駄な条件分岐を入れても!重さはほとんど変わらないでしょう。
あなたのプログラムは論理的に間違っています。
強制終了するというあなたの考察も間違っています。

潔く間違いを認め、次につなげましょう。
ヒント:ド・モルガンの法則 - Wikipedia

とりあえず適当にやるなら、敵軍の攻撃対象がHP0だったら再選択させる処理を敵軍の攻撃対象を選ぶところに入れればいいでしょう。
または、最初からHP0でないものをリストアップしてその中から選ぶ、という方法もあります。
私のプログラムが間違っていたのですね。
自信満々だったため間違っていないと思っていました・・・。

みけCATさんのアドバイス通り

コード:

boat[xx]=boat[xx]-Random(51); //敵軍最大与ダメージ 50
の前に

コード:

while(boat[xx]==0)
		xx=Random(4);
上のwhile文を入れて再選択させるようにしてみました。
何度か実行してみたところ完成したと思うのですが確認してもらえないでしょうか?
長文になりますが、一応実行結果も貼り付けておきます。

貴方は地球防衛軍の指揮官です。
現在、エイリアンの軍勢が地球を侵略しに接近してきました。
全艦に指示を出してエイリアンの軍勢を殲滅してください。

地球防衛軍戦艦
1番艦**********(HP:100/100)
2番艦**********(HP:100/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

エイリアン戦艦
1番艦**********(HP:100/100)
2番艦**********(HP:100/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:1
地球防衛軍戦艦
1番艦**********(HP:100/100)
2番艦*********(HP:90/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

エイリアン戦艦
1番艦*******(HP:77/100)
2番艦**********(HP:100/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:1
地球防衛軍戦艦
1番艦******(HP:68/100)
2番艦*********(HP:90/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

エイリアン戦艦
1番艦***(HP:31/100)
2番艦**********(HP:100/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:1
地球防衛軍戦艦
1番艦******(HP:68/100)
2番艦******(HP:64/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦**********(HP:100/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:2
地球防衛軍戦艦
1番艦******(HP:68/100)
2番艦******(HP:64/100)
3番艦**********(HP:100/100)
4番艦******(HP:61/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦*********(HP:93/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:2
地球防衛軍戦艦
1番艦******(HP:68/100)
2番艦******(HP:64/100)
3番艦**********(HP:100/100)
4番艦******(HP:60/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦*******(HP:77/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:2
地球防衛軍戦艦
1番艦******(HP:68/100)
2番艦******(HP:64/100)
3番艦*******(HP:71/100)
4番艦******(HP:60/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦****(HP:48/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:2
地球防衛軍戦艦
1番艦****(HP:49/100)
2番艦******(HP:64/100)
3番艦*******(HP:71/100)
4番艦******(HP:60/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦***(HP:33/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:2
地球防衛軍戦艦
1番艦****(HP:49/100)
2番艦******(HP:64/100)
3番艦***(HP:35/100)
4番艦******(HP:60/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:1/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:2
地球防衛軍戦艦
1番艦****(HP:49/100)
2番艦*****(HP:55/100)
3番艦***(HP:35/100)
4番艦******(HP:60/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦**********(HP:100/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:3
地球防衛軍戦艦
1番艦****(HP:49/100)
2番艦****(HP:42/100)
3番艦***(HP:35/100)
4番艦******(HP:60/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦********(HP:87/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:3
地球防衛軍戦艦
1番艦****(HP:49/100)
2番艦****(HP:42/100)
3番艦***(HP:35/100)
4番艦**(HP:29/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦********(HP:86/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:3
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦****(HP:42/100)
3番艦***(HP:35/100)
4番艦**(HP:29/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦*******(HP:73/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:3
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦****(HP:42/100)
3番艦***(HP:35/100)
4番艦*(HP:12/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦***(HP:37/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:3
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦****(HP:42/100)
3番艦(HP:3/100)
4番艦*(HP:12/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦(HP:1/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:3
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦****(HP:42/100)
3番艦(HP:3/100)
4番艦(HP:0/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦(HP:0/100)
4番艦**********(HP:100/100)

何番船を攻撃しますか?:4
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦(HP:2/100)
3番艦(HP:3/100)
4番艦(HP:0/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦(HP:0/100)
4番艦*****(HP:54/100)

何番船を攻撃しますか?:4
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦(HP:2/100)
3番艦(HP:0/100)
4番艦(HP:0/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦(HP:0/100)
4番艦*(HP:14/100)

何番船を攻撃しますか?:4
地球防衛軍戦艦
1番艦****(HP:47/100)
2番艦(HP:0/100)
3番艦(HP:0/100)
4番艦(HP:0/100)

エイリアン戦艦
1番艦(HP:0/100)
2番艦(HP:0/100)
3番艦(HP:0/100)
4番艦(HP:0/100)

敵戦艦を全滅させました。
貴方の勝利です!
続行するには何かキーを押してください . . .

閉鎖

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