ページ 11

人生ゲームを作っています

Posted: 2008年12月06日(土) 16:46
by かなこ
始めまして。C言語を使った簡単な人生ゲームを作っています。
ルールは、体力が0になったらゲームオーバーで、知力とセンスを足した「友達の数」が多いほうが最終的な勝者というものです。
プロローグやマスの詳細はまだ製作途中なので省略してあります。

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

struct boad {
int g; //進む数
int t; //体力関係
int a; //知力関係
int s; //センス関係
int f; //友達関係
char c[50];//コメント
};

int p_power=100,a_power=100;
int p_intellect=0,a_intellect=0;
int p_sense=0,a_sense=0;
int p_friend=0,a_friend=0;
int p_iti=0,a_iti=0;

struct boad zinsei[15]={
{0,0,0,0,0,"スタート"},//0
{0,-5,0,0,0,"あいうえお"},//1
{2,3,2,2,0,"いうえお"},//2
{5,0,1,0,0,"うえおか"},//3
{2,0,2,1,0,"えおかき"},//4
{4,0,0,0,0,"おかきく"},//5
{0,-5,1,2,0,"かきくけ"},//6
{2,3,2,2,0,"きくけこ"},//7
{0,0,1,0,0,"くけこさ"},//8
{0,0,2,1,0,"けこさし"},//9
{0,0,0,0,0,"こさしす"},//10
{0,-5,1,2,0,"さしすせ"},//11
{2,3,2,2,0,"しすせそ"},//12
{0,0,1,0,0,"すせそた"},//13
{0,0,2,1,0,"せそたち"},//14
};

int main(void)
{
//題名
printf("人生ゲーム\n");
//プロローグ
printf("プロローグ\n\n");
長くなるので省略
sleep(1);
while(1){
int player=0,com=0,x=14;
while(p_iti<=x && com==0){
srand(time(NULL));
player=rand()%6+1;
printf("サイコロを振ります。エンターキーを押してください。\n");
while(getchar()!='\n'){}
printf("あなたがサイコロを振って、%dが出ました。\n",player);
p_iti += player;
printf("%s\n",zinsei[p_iti].c);
p_power += zinsei[p_iti].t;
printf("体力%d\n",p_power);
p_intellect += zinsei[p_iti].a;
printf("知力%d\n",p_intellect);
p_sense += zinsei[p_iti].s;
printf("センス%d\n",p_sense);
p_friend += zinsei[p_iti].f+p_intellect+p_sense;
printf("友達の数%d\n",p_friend);
p_iti +=zinsei[p_iti].g;
printf("あなたは現在%d/14マス目にいます。\n",p_iti);

printf("Aのターンです。エンターキーを押してください。");
while(getchar()!='\n'){}
player=0;
com=1;
}
while(a_iti<=x && player==0){
//改行
printf("\n\n");
com=rand()%6+1;
printf("Aがサイコロを振って%dがでました。\n",com);
a_iti += com;
a_iti += player;
printf("%s\n",zinsei[p_iti].c);
a_power += zinsei[a_iti].t;
printf("体力%d\n",a_power);
a_intellect += zinsei[a_iti].a;
printf("知力%d\n",a_intellect);
a_sense += zinsei[a_iti].s;
printf("センス%d\n",a_sense);
a_friend += zinsei[a_iti].f+p_intellect+p_sense;
printf("友達の数%d\n",a_iti);
a_iti += zinsei[a_iti].g;
printf("Aは現在%d/14にいます。\n",a_iti);
com=0;player=1;
//ゴールの判定
if(p_iti>=x){
p_iti=x;
}
else if(a_iti>=x){
a_iti=x;
}
else if(p_iti>=x&&a_iti<x){
printf("あなたが1番です。友達が10人増えました。\n Aは2番です。");
p_friend+=10;
break;}
else if(p_iti<x&&a_iti>=x){
printf("Aが1番です。友達が10人増えました。\n あなたは2番です。");
a_friend+=10;
break;}

//勝利判定
if(p_friend<a_friend){printf("Aの勝ち\n");return 0;}
else if(a_friend<p_friend){printf("プレイヤーの勝ち\n");return 0;}
}
}
return 0;
}

ここまでがんばって作りました。しかしこれでは15マス以上でゴールせず、おかしなことになってしまいます。
15マス以上でゴールする方法、そして体力が0になったらプレイヤーをゲームオーバーにする方法を教えて下さい。お願いします。

Re:人生ゲームを作っています

Posted: 2008年12月06日(土) 19:19
by non
まず、小さなミスがあります。

コンピュータの番で
a_iti += player; が余分です。

printf("%s\n",zinsei[p_iti].c);  a_iti の間違いです。

a_friend += zinsei[a_iti].f+p_intellect+p_sense;  a_intellect、a_senseの間違いです。

ゲームのルールですが、かなこさんの考えでは、プレーヤーとコンピュータが交互にサイコロを
振り、片方が早く、ゴールしたときに、友人が10人増え、その後はゴールしてない方だけ
プレーが続き、両方ともゴールしたときに、終了する。または、途中でどちらかの体力が0に
なったときに終了するということでよろしいでしょうか?

それなら、
>>while(p_iti<=x && com==0){

>>while(a_iti<=x && player==0){
はwhileでなく、if文にすべきでしょう。

Re:人生ゲームを作っています

Posted: 2008年12月06日(土) 19:49
by conio
15マス以上になってもゲームが終了しないのは、if文の条件やプログラムの構成自体がおかしいからです。


まず、大まかにこのプログラムは、

while(1){
■①■■■■■■■■■■■■■■■
/*"あなた"のサイコロを振る処理*/
/*"あなた"のサイコロの目の表示*/
/*"あなた"の体力、知力、センス、友達の数、現在位置の表示*/

■②■■■■■■■■■■■■■■■
/*"A"のサイコロを振る処理*/
/*"A"のサイコロの目の表示*/
/*"A"の体力、知力、センス、友達の数、現在位置の表示*/

■③■■■■■■■■■■■■■■■
/*"あなた"の位置が14以上ならば位置を14にする*/
/*"A"の位置が14以上ならば位置を14にする*/

■④■■■■■■■■■■■■■■■
/*"あなた"の位置が14以上、かつ"A"の位置が14以下の場合、"あなた"の勝ち*/
/*"A"の位置が14以上、かつ"あなた"の位置が14以下の場合、"A"の勝ち*/

}

の4段階になっています。

まず、問題なのが③の判定を最後に持ってきている所です。
この判定は、"あなたは現在%d/14マス目にいます。"と表示させる前に実行しないと意味が無いです。
"あなたは現在 18/14マスにいます"と表示をしてしまうバグの原因です。

次に、④の判定がおかしいです。
最初にゴールに辿りつけば、その人が勝ちといのは自明の理ですので、"かつ"以降の条件は要りません。
【④の修正版】/*"あなた"の位置が14以上なら"あなた"の勝ち*/
【④の修正版】/*"A"の位置が14以上なら"A"の勝ち*/

また、バグの原因になります。例えば下記のようになった場合、
---------------------------------
"あなた"が15/14の位置になる
"A"が14/14の位置になる
---------------------------------
■条件■「"あなた"が14マス以上で"A"が14未満」
■条件■「"A"が14マス以上で"あなた"が14未満」
という条件は両方とも満たさないので、終了しません。
この判定も、それぞれサイコロの処理を行った後にすぐ判定させるべきです。

あと、体力が0になった時に終了させる方法は、

if(体力 == 0)
/*ゲームオーバーの処理*/

このようにすればいいと思います。

最後に、全体的に冗長な感じがするので、関数を作って簡略化、及び汎用性を持たせた方がいいと思います。
例えば、
「サイコロを振り、体力や現在位置などを表示する」
という関数を作っておけば、"A"の処理にも"あなた"の処理にも使えますし、
(プレイヤーを5人にする場合でも応用が効きます。)

この表示方法を、⇒ printf("あなたは現在%d/14マス目にいます。\n",p_iti);
printf("あなたは現在%d/%dマス目にいます。\n",p_iti,x);
という風にすれば、ゴールまでのマス数xを増やしたり減らしたりする事が出来ます。