ちぇりーの館

1−13 C言語プログラミング講座 色々なプログラムを作ってみよう 〜勝てる? ジャンケンプログラム〜



こんにちは! 今回は、『勝てる? ジャンケンプログラム』と題して、コンピュータとジャンケンをするプログラムを作りたいと思います。 今回作るジャンケンプログラムは、以下の通りです。

  @ 画面に『ジャンケンしましょ、じゃんけん〜ポン!』の文字を表示します。
  A ユーザーに0〜2の文字(グー:0 / チョキ:1 / パー:2)を入力してもらいます。
  B 乱数を使い、コンピュータ側のジャンケンの手を決めます。
  C ジャンケン結果を画面表示します。

以上です。それでは、プログラムを書いてみましょう。

【ジャンケンプログラム】

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

#define _KATI	0	//勝ち
#define _AIKO	1	//相子
#define _MAKE	2	//負け
/***********************************/
/*   ジャンケンプログラム    */
/***********************************/
int main()
{
	int  cpu_te;		//コンピュータの手
	int  user_te;		//ユーザーの手
	int  kekka;		//結果
	char cWork;

	/* ジャンケン処理本体 */
	kekka = _AIKO;		//初期状態は、相子にしておく
	printf("ジャンケンしましょ、じゃんけん〜ポン!\n");
	while(kekka == _AIKO)
	{
		printf("0〜2の文字を入力してください(グー:0 / チョキ:1 / パー:2) >>> \n");
		cWork = getch();
		if((cWork == '0')||(cWork == '1')||(cWork == '2'))
		{
			user_te = atoi(&cWork);	//数字が入力された場合
			cpu_te = rand()%3;	//乱数を取得

			switch(user_te)
			{
				//グーの時
				case 0:
					if(cpu_te == 0)      kekka = _AIKO;	//相子
					else if(cpu_te == 1) kekka = _KATI;	//負け
					else                 kekka = _MAKE;	//勝ち
				break;
				//チョキの時
				case 1:
					if(cpu_te == 0)      kekka = _MAKE;	//勝ち
					else if(cpu_te == 1) kekka = _AIKO;	//相子
					else                 kekka = _KATI;	//負け
				break;
				//パーの時
				case 2:
					if(cpu_te == 0)      kekka = _KATI;	//負け
					else if(cpu_te == 1) kekka = _MAKE;	//勝ち
					else                 kekka = _AIKO;	//相子
				break;
			}
			/* ジャンケン結果 */
			if(kekka == _AIKO)
			{//相子の場合(もう一度処理を続行させる)
				printf("あ〜いこで、しょ!\n");
			}
			else
			{//勝負がついている場合
				printf("アナタの手は、");
				switch(user_te)
				{
					case 0: printf("グー");   break;
					case 1: printf("チョキ"); break;
					case 2: printf("パー");   break;
				}
				printf("で、CPUの手は、");
				switch(cpu_te)
				{
					case 0: printf("グー");   break;
					case 1: printf("チョキ"); break;
					case 2: printf("パー");   break;
				}
				printf("です。結果は、 ---->あなたの");
				if(kekka == _KATI)	printf("勝ちです。 \n");	
				else			printf("負けです。 \n");
				break;
			}
		}
		else
		{
			printf("不明な番号が入力されましたのであなたの負けです。\n");
			break;		//処理を終了させる
		}
	}
	scanf("a");
	return 0;
}

今回のプログラムは、switch文やif文が多く使われていて、今までよりも格段に複雑になっています。 複雑なプログラムを見るコツは、処理全体を見るのではなく部分的に処理を見て行く事です。 それでは、部分的に処理を見て行きましょう。

【ヘッダー処理】

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

まずは、『おまじない』部分から見て行きましょう。今回は、"conio.h"が追加されています。 #includeの意味が判らない場合は、こちらを参考にしてください。 "conio.h"を追加した理由は、getchと言う関数を使うためです。

#define _KATI	0	//勝ち
#define _AIKO	1	//相子
#define _MAKE	2	//負け

ジャンケンの結果を定義している部分です。ジャンケンプログラムでは、勝ちを0、相子を1、負けを2と決めています。 更に、数字を直接書くのでは、判りにくいので数字に別名を与えています。#defineの意味がわからない場合は、 こちらを参考にしてください。

【メイン処理】

int main()
{
	/* ジャンケン処理本体 */
	kekka = _AIKO;		//初期状態は、相子にしておく
	while(kekka == _AIKO)
	{
		処理
	}
}

相子の場合、決着がつくまでジャンケンを繰り返すので、while文のループ条件を『結果(kekka)が相子(_AIKO)の時に繰り返す』とします。 ここで、一つ注意する事があります。それは、while文に入る前に、kekka変数に_AIKO(相子)をセットしておく必要がある事です。 もし、値のセットを忘れてしまうと、whileループに入った瞬間に、while文の終了チェックが行われ、処理が行われる前に ループを抜けてしまいます。この辺の詳しい内容は、こちらを参考にしてください。

cWork = getch();
if((cWork == '0')||(cWork == '1')||(cWork == '2'))
{
	user_te = atoi(&cWork);	//数字が入力された場合
	cpu_te = rand()%3;	//乱数を取得

getch関数は、入力された一文字を取得する関数です。ここで取得した文字を元に、ジャンケンの勝敗を判定します。
atoi関数は、文字型をint型に変換させる関数です。この関数の引数で、"&cWork"とありますが、これはポインタという C言語独特の機能です。ポインタはC言語で、最もややこしい話なので、もう少しプログラムに慣れてからゆっくりと説明します。 とりあえず今は、この関数の引数には、"&"をつけるんだと思って読み飛ばしてください。
rand関数は、乱数を発生させる関数です。この関数の結果を、"%3"としていますが、皆さんは"%"を覚えていますか? "%"とは、割り算の余りを求める演算子となります。なぜ、このような事をするかと言うと乱数で出力される値を0〜2の間で求めたいからです。 つまり、3で割り算を行った場合、必ず余りは3以下になります。このような書き方は、乱数から値を取得する際に用いる定番の方法です。

	switch(user_te)
	{
		//グーの時
		case 0:
			if(cpu_te == 0)      kekka = _AIKO;	//相子
			else if(cpu_te == 1) kekka = _KATI;	//負け
			else                 kekka = _MAKE;	//勝ち
		break;
		//チョキの時
		case 1:
			if(cpu_te == 0)      kekka = _MAKE;	//勝ち
			else if(cpu_te == 1) kekka = _AIKO;	//相子
			else                 kekka = _KATI;	//負け
		break;
		//パーの時
		case 2:
			if(cpu_te == 0)      kekka = _KATI;	//負け
			else if(cpu_te == 1) kekka = _MAKE;	//勝ち
			else                 kekka = _AIKO;	//相子
		break;
	}

この処理が、ジャンケンの結果判定となります。ユーザーが出した手でケース分類を行い 更にその中で、CPUの出した手を考慮して勝敗を確定しています。

	/* ジャンケン結果 */
	if(kekka == _AIKO)
	{//相子の場合(もう一度処理を続行させる)
		printf("あ〜いこで、しょ!\n");
	}
	else
	{//勝負がついている場合
		printf("アナタの手は、");
		switch(user_te)
		{
			case 0: printf("グー");   break;
			case 1: printf("チョキ"); break;
			case 2: printf("パー");   break;
		}
		printf("で、CPUの手は、");
		switch(cpu_te)
		{
			case 0: printf("グー");   break;
			case 1: printf("チョキ"); break;
			case 2: printf("パー");   break;
		}
		printf("です。結果は、 ---->あなたの");
		if(kekka == _KATI)	printf("勝ちです。 \n");	
		else				printf("負けです。 \n");
		break;
	}
最後に結果を表示する部分です。複雑に書いていますが、画面に出ている結果から逆に見ていくと 特に問題はないと思います。

ジャンケンプログラム結果


 今回は、新しい関数が多く使われています。これらの関数は、非常に便利な関数なので、覚えておくと 非常に便利です☆
 毎回の事ですが、疑問・質問等がありましたら時間の許す限りお答えしようと思いますのでどしどしメールを 送ってください。でわでわ、お疲れ様でした (^_^)/

< 一覧ページへ戻る


当サイトが面白いと感じた方は、お手数ですが下記リンクをクリックしてください。
クリック毎に当ホームページの評価が上がります。ご協力お願いします!
inserted by FC2 system