ページ 11

C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 17:28
by gamera
こんにちは。先月学校で出された課題を取り組んでみたのですがいくつかできなかったことがあり、ここで質問させていただきます・・・
[1] 質問文
 [1.1] 自分が今行いたい事は何か
 ①プログラムが実行されるときに’A’’B’’C’’D’をランダムにスタート地点((x,y)=(0,0))以外の5*5のマスに配置したいのですがたまに3個しか表示しなくなってしまいます。
 ②このゲームはプレイヤー(’P’ 移動はx,y軸上に1だけ動けます)のターンの後、’A’’B'’C’’D'が同時にx,y軸上に1だけランダムに動くようにしています(if文によって枠の外にはださないようにしています。)。’A’’B'’C’’D'がいる場所にプレイヤーが体当たりした場合ゲームオーバーにしたいのですが、ゲームオーバーになりません;;
 ③ゴール地点((x,y)=(4,4))の際、if分によってもしゴール地点にゾンビが存在していて、そこにプレイヤーがゴール地点に移動したらゲームオーバーにしたいのですができませんでした。


 [1.2] どのように取り組んだか(プログラムコードがある場合記載)

コード:

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


	int main(void){
	int move_x = 0, move_y = 0, zmove1x = 0, zmove1y = 0,ZX1 = 0,ZY1 = 0,zmove2x = 0,zmove2y = 0,ZX2 = 0,ZY2 = 0,zmove3x = 0,zmove3y = 0,ZX3 = 0,ZY3 = 0,zmove4x = 0,zmove4y = 0,ZX4 = 0,ZY4 = 0; 
	int direction, zombie_decision1, zombie_decision2, zombie_decision3, zombie_decision4;
	int error;										   //座標入力の際再度入力を促すためにループさせる変数

	int masu[5][5] = { { '-', '-', '-', '-', '-' },			   //配列の初期化
	{ '-', '-', '-', '-', '-' },
	{ '-', '-', '-', '-', '-' },
	{ '-', '-', '-', '-', '-' },
	{ '-', '-', '-', '-', '-' },
	};
	int masu2[5][5] = { { '-', '-', '-', '-', '-' },			   //配列の初期化	
	{ '-', '-', '-', '-', '-' },
	{ '-', '-', '-', '-', '-' },
	{ '-', '-', '-', '-', '-' },
	{ '-', '-', '-', '-', '-' },
	};
	

	srand(time(NULL));                                             //乱数生成
	do{
		do{
			ZX1 = rand() % 5;
			if (ZX1 == 0){
				zmove1x = 0;
			}
			else if (ZX1 == 1){
				zmove1x = 1;
			}
			else if (ZX1 == 2){
				zmove1x = 2;
			}
			else if (ZX1 == 3){
				zmove1x = 3;
			}
			else if (ZX1 == 4){
				zmove1x = 4;
			}

			ZY1 = rand() % 5;
			if (ZY1 == 0){
				zmove1y = 0;
			}
			else if (ZY1 == 1){
				zmove1y = 1;
			}
			else if (ZY1 == 2){
				zmove1y = 2;
			}
			else if (ZY1 == 3){
				zmove1y = 3;
			}
			else if (ZY1 == 4){
				zmove1y = 4;
			}
		} while (ZX1 == 0 && ZY1 == 0);
		do{
			ZX2 = rand() % 5;
			if (ZX2 == 0){
				zmove2x = 0;
			}
			else if (ZX2 == 1){
				zmove2x = 1;
			}
			else if (ZX2 == 2){
				zmove2x = 2;
			}
			else if (ZX2 == 3){
				zmove2x = 3;
			}
			else if (ZX2 == 4){
				zmove2x = 4;
			}

			ZY2 = rand() % 5;
			if (ZY2 == 0){
				zmove2y = 0;
			}
			else if (ZY2 == 1){
				zmove2y = 1;
			}
			else if (ZY2 == 2){
				zmove2y = 2;
			}
			else if (ZY2 == 3){
				zmove2y = 3;
			}
			else if (ZY2 == 4){
				zmove2y = 4;
			}
		} while (ZX2 == 0 && ZY2 == 0);

		do{
			ZX3 = rand() % 5;
			if (ZX3 == 0){
				zmove3x = 0;
			}
			else if (ZX3 == 1){
				zmove3x = 1;
			}
			else if (ZX3 == 2){
				zmove3x = 2;
			}
			else if (ZX3 == 3){
				zmove3x = 3;
			}
			else if (ZX3 == 4){
				zmove3x = 4;
			}

			ZY3 = rand() % 5;
			if (ZY3 == 0){
				zmove3y = 0;
			}
			else if (ZY3 == 1){
				zmove3y = 1;
			}
			else if (ZY3 == 2){
				zmove3y = 2;
			}
			else if (ZY3 == 3){
				zmove3y = 3;
			}
			else if (ZY3 == 4){
				zmove3y = 4;
			}
		} while (ZX3 == 0 && ZY3 == 0);

		do{
			ZX4 = rand() % 5;
			if (ZX4 == 0){
				zmove4x = 0;
			}
			else if (ZX4 == 1){
				zmove4x = 1;
			}
			else if (ZX4 == 2){
				zmove4x = 2;
			}
			else if (ZX4 == 3){
				zmove4x = 3;
			}
			else if (ZX4 == 4){
				zmove4x = 4;
			}

			ZY4 = rand() % 5;
			if (ZY4 == 0){
				zmove4y = 0;
			}
			else if (ZY4 == 1){
				zmove4y = 1;
			}
			else if (ZY4 == 2){
				zmove4y = 2;
			}
			else if (ZY4 == 3){
				zmove4y = 3;
			}
			else if (ZY4 == 4){
				zmove4y = 4;
			}
		} while (ZX4 == 0 && ZY4 == 0);
	} while (((ZY1 == ZY2) && (ZX1 == ZX2)) || ((ZY1 == ZY3) && (ZX1 == ZX3)) || ((ZY1 == ZY4) && (ZX1 == ZX4)) || ((ZY2 == ZY3) && (ZX2 == ZX3)) || ((ZY2 == ZY4) && (ZX2 == ZY4)) || ((ZY3 == ZY4) && (ZX3 == ZY4)));
	//*************************座標記入*************************************
	while (1){
		//********************************MAP***************************************************
		masu[move_x][move_y] = 'P';						  //プレイヤーの位置を表示
		masu[zmove1x][zmove1y] = 'A';                                            //A,B,C,Dの位置を表示
		masu[zmove2x][zmove2y] = 'B';
		masu[zmove3x][zmove3y] = 'C';
		masu[zmove4x][zmove4y] = 'D';
		printf("%3c%3c%3c%3c%3c\n", masu[0][0], masu[1][0], masu[2][0], masu[3][0], masu[4][0]);
		printf("%3c%3c%3c%3c%3c\n", masu[0][1], masu[1][1], masu[2][1], masu[3][1], masu[4][1]);
		printf("%3c%3c%3c%3c%3c\n", masu[0][2], masu[1][2], masu[2][2], masu[3][2], masu[4][2]);
		printf("%3c%3c%3c%3c%3c\n", masu[0][3], masu[1][3], masu[2][3], masu[3][3], masu[4][3]);
		printf("%3c%3c%3c%3c%3c\n", masu[0][4], masu[1][4], masu[2][4], masu[3][4], masu[4][4]);
		//*************************************処務**********************************************
		if (masu[move_x][move_y] == 'A'){
			printf("You lost!!\n");
			break;
		}
		if (masu[move_x][move_y] == 'B'){
			printf("You lost!!\n");
			break;
		}
		if (masu[move_x][move_y] == 'C'){
			printf("You lost!!\n");
			break;
		}
		if (masu[move_x][move_y] == 'D'){
			printf("You lost!!\n");
			break;
		}
		masu[move_x][move_y] = masu2[move_x][move_y];      //足跡を消す
		masu[zmove1x][zmove1y] = masu2[move_x][move_y];     
		masu[zmove2x][zmove2y] = masu2[move_x][move_y];
		masu[zmove3x][zmove3y] = masu2[move_x][move_y];
		masu[zmove4x][zmove4y] = masu2[move_x][move_y];
		/**********************プレイヤーの移動**********************/
		do{
			printf("Input, where you going?(Up:8,Down:2,Left:4,Right:6): ");	//座標を入力
			scanf("%d", &direction);
			error = 0;															//無限ループを防ぐ為にerrorの値を初期化する

			switch (direction){													//directionの値によって移動する方向を決定する
			case 2:
				move_y = move_y + 1;

				if (move_y > 4){
					printf("Error please enter value again!\n");
					move_y = move_y - 1;
					error = error + 1;
				}
				break;
			case 4:
				move_x = move_x - 1;

				if (move_x < 0){
					printf("Error please enter value again!\n");
					move_x = move_x + 1;
					error = error + 1;
				}
				break;
			case 6:
				move_x = move_x + 1;

				if (move_x > 4){
					printf("Error please enter value again!\n");
					move_x = move_x - 1;
					error = error + 1;
				}
				break;
			case 8:
				move_y = move_y - 1;

				if (move_y < 0){
					printf("Error please enter value again!\n");
					move_y = move_y + 1;
					error = error + 1;
				}
				break;
			default:
				printf("Error please enter value again!\n");
				error = error + 1;
			}

		} while (error != 0);


	/****************ゾンビ移動******************/
		do{
			do{
				zombie_decision1 = rand() % 5;

				error = 0;															//無限ループを防ぐ為にerrorの値を初期化する
				switch (zombie_decision1){												
				case 0:
					zmove1y = zmove1y + 1;

					if (zmove1y > 4){
						zmove1y = zmove1y - 1;
						error = error + 1;
					}
					break;
				case 1:
					zmove1x = zmove1x - 1;

					if (zmove1x < 0){
						zmove1x = zmove1x + 1;
						error = error + 1;
					}
					break;
				case 2:
					zmove1x = zmove1x + 1;

					if (zmove1x > 4){
						zmove1x = zmove1x - 1;
						error = error + 1;
					}
					break;
				case 3:
					zmove1y = zmove1y - 1;

					if (zmove1y < 0){
						zmove1y = zmove1y + 1;
						error = error + 1;
					}
					break;
				}
			} while (error != 0);//errorが0ならループ脱出

			do{
				zombie_decision2 = rand() % 5;
				error = 0;															//無限ループを防ぐ為にerrorの値を初期化する

				switch (zombie_decision2){													
				case 0:
					zmove2y = zmove2y + 1;

					if (zmove2y > 4){
						zmove2y = zmove2y - 1;
						error = error + 1;
					}
					break;
				case 1:
					zmove2x = zmove2x - 1;

					if (zmove2x < 0){
						zmove2x = zmove2x + 1;
						error = error + 1;
					}
					break;
				case 2:
					zmove2x = zmove2x + 1;

					if (zmove2x > 4){
						zmove2x = zmove2x - 1;
						error = error + 1;
					}
					break;
				case 3:
					zmove2y = zmove2y - 1;

					if (zmove2y < 0){
						zmove2y = zmove2y + 1;
						error = error + 1;
					}
					break;
				}
			} while (error != 0);

			do{
				zombie_decision3 = rand() % 5;
				error = 0;															//無限ループを防ぐ為にerrorの値を初期化する

				switch (zombie_decision3){													
				case 0:
					zmove3y = zmove3y + 1;

					if (zmove3y > 4){
						zmove3y = zmove3y - 1;
						error = error + 1;
					}
					break;
				case 1:
					zmove3x = zmove3x - 1;

					if (zmove3x < 0){
						zmove3x = zmove3x + 1;
						error = error + 1;
					}
					break;
				case 2:
					zmove3x = zmove3x + 1;

					if (zmove3x > 4){
						zmove3x = zmove3x - 1;
						error = error + 1;
					}
					break;
				case 3:
					zmove3y = zmove3y - 1;

					if (zmove3y < 0){
						zmove3y = zmove3y + 1;
						error = error + 1;
					}
					break;
				}
			} while (error != 0);//errorが0ならループ脱出

			do{
				zombie_decision4 = rand() % 5;
				error = 0;															//無限ループを防ぐ為にerrorの値を初期化する

				switch (zombie_decision4){						
				case 0:
					zmove4y = zmove4y + 1;

					if (zmove4y > 4){
						zmove4y = zmove4y - 1;
						error = error + 1;
					}
					break;
				case 1:
					zmove4x = zmove4x - 1;

					if (zmove4x < 0){
						zmove4x = zmove4x + 1;
						error = error + 1;
					}
					break;
				case 2:
					zmove4x = zmove4x + 1;

					if (zmove4x > 4){
						zmove4x = zmove4x - 1;
						error = error + 1;
					}
					break;
				case 3:
					zmove4y = zmove4y - 1;

					if (zmove4y < 0){
						zmove4y = zmove4y + 1;
						error = error + 1;
					}
					break;
				}
			} while (error != 0);
		} while (((zmove1y == zmove2y) && (zmove1x == zmove2x)) || ((zmove1y == zmove3y) && (zmove1x == zmove3x)) || ((zmove1y == zmove4y) && (zmove1x == zmove4x)) || ((zmove2y == zmove3y) && (zmove2x == zmove3x)) || ((zmove2y == zmove4y) && (zmove2x == zmove4x)) || ((zmove3y == zmove4y) && (zmove3x == zmove4x)));


		//***********************************************************************

		


		//***************勝利判定************************

		if (move_x == 4 && move_y == 4){
			if (!((move_x == zmove1x) && (move_y == zmove1y)) || ((move_x == zmove2x) && (move_y == zmove2y)) || ((move_x == zmove3x) && (move_y == zmove3y)) || ((move_x == zmove4x) && (move_y == zmove4y))){
				printf("You win!!\n");
				break;
			}
			if(((move_x == zmove1x) && (move_y == zmove1y)) || ((move_x == zmove2x) && (move_y == zmove2y)) || ((move_x == zmove3x) && (move_y == zmove3y)) || ((move_x == zmove4x) && (move_y == zmove4y))){
				printf("You lost!!\n");
				break;
			}
		}
		//***********************************************
	}
	exit(0);
}
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
  [1.1]に記載しました
 [1.4] 今何がわからないのか、知りたいのか
[1.1]に記載したことがわからないです。
[2] 環境  
 [2.1] OS : Windows, Linux等々
  windows
 [2.2] コンパイラ名 : VC++ 2008EE, Borand C++, gcc等々
VS2013
[3] その他
 ・どの程度C言語を理解しているか
Cの参考書でいうだいたい関数まで少し理解しています。
 

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 17:34
by みけCAT
まだ読みきれていないのですが、前半部分は

コード:

        do{
            ZX1 = rand() % 5;
            if (0 <= ZX1 && ZX1 <= 4) zmove1x = ZX1;
 
            ZY1 = rand() % 5;
            if (0 <= ZY1 && ZY1 <= 4) zmove1y = ZY1;
        } while (ZX1 == 0 && ZY1 == 0);
のように書いてはいけないのですか?縛りプレイもしくは課題の条件ですか?

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 17:42
by gamera
みけCAT さんが書きました:まだ読みきれていないのですが、前半部分は

コード:

        do{
            ZX1 = rand() % 5;
            if (0 <= ZX1 && ZX1 <= 4) zmove1x = ZX1;
 
            ZY1 = rand() % 5;
            if (0 <= ZY1 && ZY1 <= 4) zmove1y = ZY1;
        } while (ZX1 == 0 && ZY1 == 0);
のように書いてはいけないのですか?縛りプレイもしくは課題の条件ですか?
これについては私の勝手な判断でこういうふうに書きました。
みけCATさんの文のほうがスマートですね・・・ 
回答ありがとうございます。

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 17:52
by みけCAT
gamera さんが書きました:③ゴール地点((x,y)=(4,4))の際、if分によってもしゴール地点にゾンビが存在していて、そこにプレイヤーがゴール地点に移動したらゲームオーバーにしたいのですができませんでした。
429行目にカッコが足りないようですね。

コード:

			if (!(((move_x == zmove1x) && (move_y == zmove1y)) || ((move_x == zmove2x) && (move_y == zmove2y)) || ((move_x == zmove3x) && (move_y == zmove3y)) || ((move_x == zmove4x) && (move_y == zmove4y)))){
とするといいかもしれません。…と言いたいところですが、428行目~437行目を

コード:

		if (move_x == 4 && move_y == 4){
			if(((move_x == zmove1x) && (move_y == zmove1y)) || ((move_x == zmove2x) && (move_y == zmove2y)) || ((move_x == zmove3x) && (move_y == zmove3y)) || ((move_x == zmove4x) && (move_y == zmove4y))){
				printf("You lost!!\n");
			} else {
				printf("You win!!\n");
			}
			break;
		}
とする方がいいと思います。
さらに、zmoveNx、zmoveNyを配列にすると、より良いコードが書けると思います。

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 18:15
by gamera
みけCAT さんが書きました:
gamera さんが書きました:③ゴール地点((x,y)=(4,4))の際、if分によってもしゴール地点にゾンビが存在していて、そこにプレイヤーがゴール地点に移動したらゲームオーバーにしたいのですができませんでした。
429行目にカッコが足りないようですね。

コード:

			if (!(((move_x == zmove1x) && (move_y == zmove1y)) || ((move_x == zmove2x) && (move_y == zmove2y)) || ((move_x == zmove3x) && (move_y == zmove3y)) || ((move_x == zmove4x) && (move_y == zmove4y)))){
とするといいかもしれません。…と言いたいところですが、428行目~437行目を

コード:

		if (move_x == 4 && move_y == 4){
			if(((move_x == zmove1x) && (move_y == zmove1y)) || ((move_x == zmove2x) && (move_y == zmove2y)) || ((move_x == zmove3x) && (move_y == zmove3y)) || ((move_x == zmove4x) && (move_y == zmove4y))){
				printf("You lost!!\n");
			} else {
				printf("You win!!\n");
			}
			break;
		}
とする方がいいと思います。
さらに、zmoveNx、zmoveNyを配列にすると、より良いコードが書けると思います。

返信遅くて申し訳ないです。
みけCATさんの指摘してくれた箇所を修正して確かめてみたところ、'B'がゴール地点にいる状態で'P'が(4,3)の地点から下に行ったときに、
”You Win!!”と表示されてしまいました;
さらに、zmoveNx、zmoveNyを配列にすると、より良いコードが書けると思います。
このことが気になったのですがもし、、

コード:

if (move_x == 4 && move_y == 4){
			if ((masu[move_x][move_y] == masu[zmove1x][zmove1y]) || (masu[move_x][move_y] == masu[zmove2x][zmove2y]) || (masu[move_x][move_y] == masu[zmove3x][zmove3y]) || (masu[move_x][move_y] == masu[zmove4x][zmove4y])){
				printf("You lost!!\n");
				break;
			}
			else {
				printf("You win!!\n");
				break;
			}
		}
という配列を使って条件を作ることは可能なのでしょうか?
回答ありがとうございます。

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 18:54
by みけCAT
gamera さんが書きました:みけCATさんの指摘してくれた箇所を修正して確かめてみたところ、'B'がゴール地点にいる状態で'P'が(4,3)の地点から下に行ったときに、
”You Win!!”と表示されてしまいました;
たまたまBがそのターンで左に移動しただけではないですか?すなわち
gamera さんが書きました:②このゲームはプレイヤー(’P’ 移動はx,y軸上に1だけ動けます)のターンの後、’A’’B'’C’’D'が同時にx,y軸上に1だけランダムに動くようにしています(if文によって枠の外にはださないようにしています。)。’A’’B'’C’’D'がいる場所にプレイヤーが体当たりした場合ゲームオーバーにしたいのですが、ゲームオーバーになりません;;
の方の不都合(未修正)のせいだと思います。
gamera さんが書きました:

コード:

if (move_x == 4 && move_y == 4){
			if ((masu[move_x][move_y] == masu[zmove1x][zmove1y]) || (masu[move_x][move_y] == masu[zmove2x][zmove2y]) || (masu[move_x][move_y] == masu[zmove3x][zmove3y]) || (masu[move_x][move_y] == masu[zmove4x][zmove4y])){
				printf("You lost!!\n");
				break;
			}
			else {
				printf("You win!!\n");
				break;
			}
		}
という配列を使って条件を作ることは可能なのでしょうか?
回答ありがとうございます。
「(コード)という配列」は、masuという意味ですか?
もしそうだとすると、今のプログラムでは不可能だと思います。

[hr]
大変申し訳ないのですが、あまりにひどいコードだと感じたので、最初から自分なりに実装してみました。
► スポイラーを表示

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 20:46
by gamera
みけCATさん、長々と付き合っていただきありがとうございました。
一旦、みけCATさんのコードを拝見させていただき整理した後、またこの課題に取り組みたいと思います。
「(コード)という配列」は、masuという意味ですか?
もしそうだとすると、今のプログラムでは不可能だと思います。
はい、そうです。 了解しました!

Re: C言語の脱出ゲームについて質問したいです。

Posted: 2014年7月21日(月) 20:48
by gamera
〆ます