三目並べのプログラムを組みました!

02giri
記事: 22
登録日時: 12年前

三目並べのプログラムを組みました!

投稿記事 by 02giri » 12年前

フォーラムの方でプログラムが8秒ほどで強制終了してしまう、という問題を相談させていただきましたが、
いろんな方々にアドバイスをいただき、無事に解決することができました!
返信をいただいた方、ありがとうございました!(特にsoftya様には大感謝です…!!)

おかげさまでようやく作っていた三目並べ(●×ゲーム)のデバッグ・修正が一通り終わりましたので、
こちらにアップさせていただきます。
最終的にソースコードが700行オーバーになってしまったので、
とりあえずプログラム本体のzipファイルをあげておきます。

バグや不具合は一通り取り除いたつもりですが、
「作品」とはとても言えないできですので、作品掲示板の方にあげるのは遠慮させていただきました。

お時間のある方、ご指導をいただける方はプレイしていただけますと幸いでございます。

なお、現時点ではまだファイルやクラス分けをせずにメインのコードファイル一つだけで
作ってありますので、ヘッダファイルや各クラスに整理し直した後で、
改めてソースコードを上げさせていただこうと考えております。

よろしくお願いいたします。

[追記(2013/06/06)]
いただいたアドバイスをもとに、演出面の見直しおよびレイアウトの変更を行ないました。
また、お楽しみモードとしてEXモードを実装しました。

ソースコードを自分なりにファイル分けしてみたのですが、
全く動作しなくなってしまったので、mainファイルひとまとめのソースコードを上げさせていただきます。
お時間がある方は添削していただけると幸いです。
(EXモードを実装した結果、結局700行オーバーになってしまいました…。)

CODE:

#include 
#include 
using namespace std;


//変数・配列
double rule=0;				//ルールを確認するかどうかの選択時に使用。
double a=0, b=0;			//モード選択、cpuの強さ選択時に使用
char stage[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};		//石を置くステージ
int stone[9];			//石を格納
int temp;				//入力された石の場所を一時的に格納
int turn;				//経過ターン数を格納
int message;			//time(NULL)によって得た乱数を格納し、EXモードのメッセ―ジ表示に使用

//関数
void show_rule();		//ルールを表示する
void vs_mode();			//二人で戦う
void cpu_mode();		//CPUと戦う(各難易度共通)
void check_stage();		//そこに石が置けるかどうかを判定し、間違っていたら修正させる(返り値なし)
void show_stage();		//現在のステージの状況を表示する
void show_laststage();	//ステージの最終結果を表示する
int check_end1();		//プレイヤー1の勝利フラグを判定
int check_end2();		//プレイヤー2の勝利フラグを判定

int stop_reach();		//プレイヤーのリーチに反応してビンゴを阻止
int make_bingo();		//CPUにリーチができていたら優先してビンゴにする

int easy_cpu();			//弱いCPUのAI
int normal_cpu();		//普通のCPUのAI
int hard_cpu();			//強いCPUのAI
int ex_cpu();			//EXモードのCPUのAI

void show_rule()
{
	cout 9) {
		cout > temp;
	}
	while(stage[temp-1]=='X' || stage[temp-1]=='O') {
		cout > temp;
	}
}

int check_end1()		//プレイヤー1(先攻)の勝利フラグを判定(勝利なら1を返す)
{
	if(stage[0]=='O' && stage[1] == 'O' && stage[2]=='O')
		return 1;
	else if(stage[0]=='O' && stage[4] == 'O' && stage[8]=='O')
		return 1;
	else if(stage[0]=='O' && stage[3] == 'O' && stage[6]=='O')
		return 1;
	else if(stage[3]=='O' && stage[4] == 'O' && stage[5]=='O')
		return 1;
	else if(stage[6]=='O' && stage[7] == 'O' && stage[8]=='O')
		return 1;
	else if(stage[1]=='O' && stage[4] == 'O' && stage[7]=='O')
		return 1;
	else if(stage[2]=='O' && stage[5] == 'O' && stage[8]=='O')
		return 1;
	else if(stage[2]=='O' && stage[4] == 'O' && stage[6]=='O')
		return 1;
	else return 0;
}

int check_end2()			//プレイヤー2(後攻、CPU)の勝利フラグを判定(勝利なら1を返す)
{
	if(stage[0]=='X' && stage[1] == 'X' && stage[2]=='X')
		return 1;
	else if(stage[0]=='X' && stage[4] == 'X' && stage[8]=='X')
		return 1;
	else if(stage[0]=='X' && stage[3] == 'X' && stage[6]=='X')
		return 1;
	else if(stage[3]=='X' && stage[4] == 'X' && stage[5]=='X')
		return 1;
	else if(stage[6]=='X' && stage[7] == 'X' && stage[8]=='X')
		return 1;
	else if(stage[1]=='X' && stage[4] == 'X' && stage[7]=='X')
		return 1;
	else if(stage[2]=='X' && stage[5] == 'X' && stage[8]=='X')
		return 1;
	else if(stage[2]=='X' && stage[4] == 'X' && stage[6]=='X')
		return 1;
	else return 0;
}

int stop_reach()		//プレイヤーのリーチに反応してビンゴを阻止する(阻止するのに必要な各ステージの値を返す)
{
	if(stage[0]=='O' && stage[1]=='O' && stage[2]=='3')
		return 3;
	else if(stage[1]=='O' && stage[2]=='O' && stage[0]=='1')
		return 1;
	else if(stage[0]=='O' && stage[2]=='O' && stage[1]=='2')
		return 2;
	else if(stage[3]=='O' && stage[4]=='O' && stage[5]=='6')
		return 6;
	else if(stage[4]=='O' && stage[5]=='O' && stage[3]=='4')
		return 4;
	else if(stage[3]=='O' && stage[5]=='O' && stage[4]=='5')
		return 5;
	else if(stage[6]=='O' && stage[7]=='O' && stage[8]=='9')
		return 9;
	else if(stage[6]=='O' && stage[8]=='O' && stage[7]=='8')
		return 8;
	else if(stage[7]=='O' && stage[8]=='O' && stage[6]=='7')
		return 7;
	else if(stage[0]=='O' && stage[3]=='O' && stage[6]=='7')
		return 7;
	else if(stage[0]=='O' && stage[6]=='O' && stage[3]=='4')
		return 4;
	else if(stage[3]=='O' && stage[6]=='O' && stage[0]=='1')
		return 1;
	else if(stage[1]=='O' && stage[4]=='O' && stage[7]=='8')
		return 8;
	else if(stage[1]=='O' && stage[7]=='O' && stage[4]=='5')
		return 5;
	else if(stage[4]=='O' && stage[7]=='O' && stage[1]=='2')
		return 2;
	else if(stage[2]=='O' && stage[5]=='O' && stage[8]=='9')
		return 9;
	else if(stage[2]=='O' && stage[8]=='O' && stage[5]=='6')
		return 6;
	else if(stage[5]=='O' && stage[8]=='O' && stage[2]=='3')
		return 3;
	else if(stage[0]=='O' && stage[4]=='O' && stage[8]=='9')
		return 9;
	else if(stage[0]=='O' && stage[8]=='O' && stage[4]=='5')
		return 5;
	else if(stage[4]=='O' && stage[8]=='O' && stage[0]=='1')
		return 1;
	else if(stage[2]=='O' && stage[4]=='O' && stage[6]=='7')
		return 7;
	else if(stage[2]=='O' && stage[6]=='O' && stage[4]=='5')
		return 5;
	else if(stage[4]=='O' && stage[6]=='O' && stage[2]=='3')
		return 3;
	else return 0;
}

int make_bingo()		//CPUにリーチができていたら優先してビンゴにする(ビンゴにするのに必要なステージの値を返す)
{
	if(stage[0]=='X' && stage[1]=='X' && stage[2]=='3')
		return 3;
	else if(stage[1]=='X' && stage[2]=='X' && stage[0]=='1')
		return 1;
	else if(stage[0]=='X' && stage[2]=='X' && stage[1]=='2')
		return 2;
	else if(stage[3]=='X' && stage[4]=='X' && stage[5]=='6')
		return 6;
	else if(stage[4]=='X' && stage[5]=='X' && stage[3]=='4')
		return 4;
	else if(stage[3]=='X' && stage[5]=='X' && stage[4]=='5')
		return 5;
	else if(stage[6]=='X' && stage[7]=='X' && stage[8]=='9')
		return 9;
	else if(stage[6]=='X' && stage[8]=='X' && stage[7]=='8')
		return 8;
	else if(stage[7]=='X' && stage[8]=='X' && stage[6]=='7')
		return 7;
	else if(stage[0]=='X' && stage[3]=='X' && stage[6]=='7')
		return 7;
	else if(stage[0]=='X' && stage[6]=='X' && stage[3]=='4')
		return 4;
	else if(stage[3]=='X' && stage[6]=='X' && stage[0]=='1')
		return 1;
	else if(stage[1]=='X' && stage[4]=='X' && stage[7]=='8')
		return 8;
	else if(stage[1]=='X' && stage[7]=='X' && stage[4]=='5')
		return 5;
	else if(stage[4]=='X' && stage[7]=='X' && stage[1]=='2')
		return 2;
	else if(stage[2]=='X' && stage[5]=='X' && stage[8]=='9')
		return 9;
	else if(stage[2]=='X' && stage[8]=='X' && stage[5]=='6')
		return 6;
	else if(stage[5]=='X' && stage[8]=='X' && stage[2]=='3')
		return 3;
	else if(stage[0]=='X' && stage[4]=='X' && stage[8]=='9')
		return 9;
	else if(stage[0]=='X' && stage[8]=='X' && stage[4]=='5')
		return 5;
	else if(stage[4]=='X' && stage[8]=='X' && stage[0]=='1')
		return 1;
	else if(stage[2]=='X' && stage[4]=='X' && stage[6]=='7')
		return 7;
	else if(stage[2]=='X' && stage[6]=='X' && stage[4]=='5')
		return 5;
	else if(stage[4]=='X' && stage[6]=='X' && stage[2]=='3')
		return 3;
	else return 0;
}



int easy_cpu()		//イージーモードのCPUのAI(石を置く場所のintを返す)
{
	int t;
	for(t=0;t> temp;				//石を置く場所を受け取り、tempに格納
			check_stage();				//受け取ったtempが有効かどうか判定し、無効なら再びtempを受け取る(有効になるまでループ)

			stone[turn-1]=temp;			
			stage[(int)stone[turn-1]-1]='O';		//先攻が石を置いた場所(stage[])には'O'を格納する

			cout > i;						//ユーザーが1を入力するまで画面を表示しておくために無限ループ
				}
				exit(1);							//勝利フラグが立っていれば、最終結果を表示して終了
			}
		}
		if(turn%2==0) {								//偶数ターン
			cout > temp;
			check_stage();

			stone[turn-1]=temp;
			stage[(int)stone[turn-1]-1]='X';		//プレイヤー2(後攻)が石を置いた場所には'O'ではなく'X'を格納

			cout > i;
				}
				exit(1);
			}
		}
		else if(turn==9)		//最終ターンには引き分けの判定を行う
		 {
			cout > temp;
			check_stage();

			stone[turn-1]=temp;
			stage[(int)stone[turn-1]-1]='O';

			cout > i;
				}
				exit(1);
			}
			else cout > i;
			}
			exit(1);
		}
	}
}

void cpu_mode()			//CPUと戦う。基本はvs_modeと同じ流れ
{
	if(b==1 || b==2 || b==3) {
		for(turn=1; turn> temp;
				check_stage();

				stone[turn-1]=temp;
				stage[(int)stone[turn-1]-1]='O';

				cout > i;
					}
					exit(1);
				}
			}
			if(turn%2==0) {			//偶数ターン。CPUのターンとなるため、vs_modeとは少し異なる
				cout > i;
					}
					exit(1);
				}
			}
			else if(turn==9)		//最終ターン。vs_modeと同じ流れ
			 {
				cout > temp;
				check_stage();
			
				stone[turn-1]=temp;
				stage[(int)stone[turn-1]-1]='O';

				cout > i;
					}
					exit(1);
				}
				else cout > i;
				}
				exit(1);
			}
		}
	}
	if(b==99) {				//EXモードの処理
		for(turn=1; turn> temp;
				check_stage();

				stone[turn-1]=temp;
				stage[(int)stone[turn-1]-1]='O';

				cout > i;
					}
					exit(1);
				}
			}
			if(turn%2==0) {			//偶数ターン。CPUのターンとなるため、vs_modeとは少し異なる
				cout > i;
					}
					exit(1);
				}
			}
			else if(turn==9)		//最終ターン。vs_modeと同じ流れ
			 {
				cout > temp;
				check_stage();
			
				stone[turn-1]=temp;
				stage[(int)stone[turn-1]-1]='O';

				cout > i;
					}
					exit(1);
				}
				else cout > i;
				}
				exit(1);
			}
		}
	}
}


int main()
{
	cout > rule;
	while(rule!=1 && rule!=2) {
		cout > rule;
	}
	cout > a;
	cout > a;
	}

	if(a==1) {
		cout > b;
		cout > b;
		}

		if(b==1.0) {
			cout << "モンスター(弱)と戦います。\n" << endl;
			cout << "[バトルスタート!]\n" << endl;
			cpu_mode();
		}
		else if(b==2.0) {
			cout << "マジシャン(普通)と戦います。\n" << endl;
			cout << "[バトルスタート!]\n" << endl;
			cpu_mode();
		}
		else if(b==3.0) {
			cout << "ドラゴン(強)と戦います。\n" << endl;
			cout << "[バトルスタート!]\n" << endl;
			cpu_mode();
		}
		else if(b==99.0) {
			cout << "[Extraモード]\n" << "目の前に魔王が現れた!!" << endl;
			cout << "「待ちくたびれたぞ、人間よ」" << "\n" << "「さぁ、このわしが相手をしてやろう。かかってくるがよい。」\n" << endl;
			cout << "魔王はとても強いぞ!頭をフル回転させて倒そう!\n" << endl;
			cpu_mode();
		}

		return 0;
	}
}

添付ファイル

[拡張子 zip は無効化されているため、表示できません]

[拡張子 zip は無効化されているため、表示できません]

最後に編集したユーザー 02giri on 2013年6月06日(木) 23:30 [ 編集 1 回目 ]

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前

Re: 三目並べのプログラムを組みました!

投稿記事 by softya(ソフト屋) » 12年前

事務的で淡白ですかね。ゲームとしてのサービスが足らないというか。
派手なことじゃなくて良いんですが、ちょっと気を利かすだけで良くなるものです。

ちなみにゲーム会社だと演出面のセンスもチェックされる事が多いと思います。

02giri
記事: 22
登録日時: 12年前

Re: 三目並べのプログラムを組みました!

投稿記事 by 02giri » 12年前

>> softya様

そうですよね。とりあえずちゃんと動くプログラムを組むことを最優先していたため、
演出面にまで気を配れていませんでした。

次回は遊ぶ人の気持ちまで考えて、演出やギミックを考えてみようと思います。
いつもありがとうございますー!

ぼずお
記事: 1
登録日時: 14年前

Re: 三目並べのプログラムを組みました!

投稿記事 by ぼずお » 12年前

ゲームはエンタテインメントなので、softyaさん仰るように演出やインタフェースというものが重要です。
ただ、ロジカルな部分を固めるのが第一ですので、順番的には正しいと思います。

はじめて4ヶ月で700行のソースが構築できるのは、大したものだと思います。
(自分はそのころソートの練習問題と格闘していました・・)

順次、演出やUI・グラフィカルな領域へ進めるとよいのではないでしょうか。
最後に編集したユーザー ぼずお on 2013年6月05日(水) 21:31 [ 編集 1 回目 ]

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 15年前

Re: 三目並べのプログラムを組みました!

投稿記事 by Dixq (管理人) » 12年前

良くできてますね。
もしゲームとして改善するなら、せめて「あなたの勝ちです、おめでとう!」とか位言ってほしいなと思いました。
後はDXライブラリを使う等してグラフィカルな演出をしてみるとよいかと思います。
グラフィカルな演出はとても深いですよ、特にエフェクトに凝り始めると終わりがありません。
例えば私のゲームでは、単なるメニュー画面にでもこだわりました。
[youtube][/youtube]
beatmaniaIIDXの演出方法を模倣したものですが、自分がかっこいいと思う演出を真似してみるのはいい勉強になると思います。
最後に編集したユーザー Dixq (管理人) on 2013年6月05日(水) 23:14 [ 編集 1 回目 ]

02giri
記事: 22
登録日時: 12年前

Re: 三目並べのプログラムを組みました!

投稿記事 by 02giri » 12年前

>> ぼずお様
コメントありがとうございます!
実は700行といっても昨日クラス分けとファイル分けをしながら余計なものを取り除いた結果、
500行程度まで短くなりました!笑

アドバイスをいただいた通り、次はUIや演出面に気を配りながら
プログラムを組んでいきたいと思います!
もしよろしければ今後ともアドバイスの程よろしくおねがいします!

02giri
記事: 22
登録日時: 12年前

Re: 三目並べのプログラムを組みました!

投稿記事 by 02giri » 12年前

>>Dixq様

コメントありがとうございます。
いつもこちらのサイトでお世話になっております!
ゲームプログラミングの館の方も拝見させていただいておりますが、
丁寧な解説を示していただき、助かっております。

やはり、「ゲーム」を作るうえではグラフィカルな演出が不可欠ですよね。
こんなにすごいプログラムが組めるようになるには何年かかるのだろうと気が遠くなりますが、
一歩一歩近づいていけるよう頑張りたいと思います!
なのでもう少し勉強を進めてDXライブラリを使用したサンプルプログラムを組んでみたうえで、
改めて「ゲームプログラム」を上げさせていただこうと思います。

今後ともよろしくお願いいたします!