C言語で、タイピングゲーム。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
STEER
記事: 4
登録日時: 4年前

C言語で、タイピングゲーム。

#1

投稿記事 by STEER » 4年前

C言語でタイピングゲームを作っている者でございます。(VisualC++ 2010)
経歴としてはまだまだ浅いですが、各地のサイトを見て回り、
現在、下記のような、簡易的な基盤プログラムを作ってみました。
「タイプ数」別で単語の「ローマ字」を代入した文字列を、
main(または他の関数)で1文字ずつ入力、認識させるためのコードです。
今このゲームは、すべての処理をmainでやっています。

つきましてはここに、

① 更に「タイプ数別の単語を選ぶ処理」のパターンを増やすために、
この一連の作業の短くできるところを短く関数などにまとめる。

② ①に乗っ取り、「タイプ数」のパターンも増やす。 タイプ数が7回の単語、10回の単語など。

③ かかった時間の表示を、「小数点第2位」を四捨五入。「小数点第1位」まで表示させる。
というの仕様やコードの改変でゲーム性を出してみようと思います。
ちなみにコードのエラーは今のところなく、正常稼働します。

何か上記の3つを作るためのアドバイスや参考のコード、あるいは
このコードじゃ上の3つの実現は難しいから、一部を書き直した方がいい。などの提案でも
良いので、ご助言をお願いします。

コード:

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

//タイプ数が5回の文字列を出力する関数
int main(void)
{
	int wr5, typed;
	int i, j;
	char w5[6];
	int falsetype = 0;

	printf("出てくるローマ字をタイプせよ!\n");
	printf("☆PRESS ANY KEY TO START☆\n\n");

	_getch();

	clock_t start, end;
	start = clock();

	for(i = 1; i <= 5; i++) {
		srand((unsigned)time(NULL));
		wr5 = (rand() % 5);  //5パターン

switch(wr5){

	case 0:
	strcpy(w5, "iruka"); //イルカ
	printf("イルカ\n");
	break;

	case 1:
	strcpy(w5, "saito"); //サイト
	printf("サイト\n");
	break;

	case 2:
	strcpy(w5, "manto"); //マント
	printf("マント\n");
	break;

	case 3:
	strcpy(w5, "tanki"); //短期
	printf("短期\n");
	break;

	case 4:
	strcpy(w5, "yuusi"); //勇志
	printf("勇志\n");
	break;
	}
	printf("%s\n",w5);
	
	for(j = 0; j <= 4; j++){
	utinaosi:						//gotoのやり直し処理後の開始地点
	typed = _getch();
		if(typed == w5[j]) {	//タイプされた文字を正しいものと認識したら、
			_putch(w5[j]);					 //タイプした文字を画面に出力する。
		
		} else {							//タイプされた文字を違うものと認識したら、
			printf("×\b");
			falsetype = falsetype + 1;
			goto utinaosi;						//gotoでやり直させる。
			}
		}
		printf("\n○OK\n\n");
	}
	end = clock();
	printf("かかった時間: %f秒\n", (double)(end - start) / CLOCKS_PER_SEC);

	printf("ミスタイプ %d回\n",falsetype);
	_getch();
	return 0;
}

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

Re: C言語で、タイピングゲーム。

#2

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

STEER さんが書きました: ① 更に「タイプ数別の単語を選ぶ処理」のパターンを増やすために、
この一連の作業の短くできるところを短く関数などにまとめる。

② ①に乗っ取り、「タイプ数」のパターンも増やす。 タイプ数が7回の単語、10回の単語など。
  • 候補を配列に格納しておく。(「関数など」の「など」に配列が含まれると解釈しました)
  • 文字数(タイプ数)を決め打ちしない。
STEER さんが書きました: ③ かかった時間の表示を、「小数点第2位」を四捨五入。「小数点第1位」まで表示させる。
かかった時間の10倍を整数に四捨五入し、その値を10で割る。
コメントに//が使われていることから、C99以降が使用されていると解釈し、round関数を使用します。

コード:

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

//文字列を出力する関数
int main(void)
{
	struct {
		const char *word;
		const char *yomi;
	} word_candidates[] = {
		{"iruka", "イルカ"}, //イルカ
		{"saito", "サイト"}, //サイト
		{"manto", "マント"}, //マント
		{"tanki", "短期"}, //短期
		{"yuusi", "勇志"}, //勇志
		{"zikkenn", "実験"}, //実験
		{"iguchiyuka", "井口裕香"} //井口裕香
	};

	int wr, typed;
	int i, j;
	const char *w;
	const char *y;
	int falsetype = 0;

	printf("出てくるローマ字をタイプせよ!\n");
	printf("☆PRESS ANY KEY TO START☆\n\n");

	_getch();

	clock_t start, end;
	start = clock();

	srand((unsigned)time(NULL)); //乱数の初期化は毎回するべきではない
	for(i = 1; i <= 5; i++) {
		wr = (rand() % (sizeof(word_candidates) / sizeof(word_candidates[0])));
		w = word_candidates[wr].word; //無駄にコピーしない
		y = word_candidates[wr].yomi;

		printf("%s\n",y);
		printf("%s\n",w);
	
		for(j = 0; w[j] != '\0'; j++){ //文字数を決め打ちせず、文字列の終端に来たら終わり
			int utinaosi = 1;
			while(utinaosi){
				utinaosi = 0;						//やり直し処理後の開始地点
				typed = _getch();
				if(typed == w[j]) {	//タイプされた文字を正しいものと認識したら、
					_putch(w[j]);					 //タイプした文字を画面に出力する。
				
				} else {							//タイプされた文字を違うものと認識したら、
					printf("×\b");
					falsetype = falsetype + 1;
					utinaosi = 1;						//gotoは使わずにやり直させる。
				}
			}
		}
		printf("\n○OK\n\n");
	}
	end = clock();
	printf("かかった時間: %.1f秒\n", round(((double)(end - start) / CLOCKS_PER_SEC) * 10.0) / 10.0);

	printf("ミスタイプ %d回\n",falsetype);
	_getch();
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

STEER
記事: 4
登録日時: 4年前

Re: C言語で、タイピングゲーム。

#3

投稿記事 by STEER » 4年前

当日にアドバイスをを書いていただいたというのに返信もせずで申し訳ありませんでした。
いただいたコードをVC++にコピペしたのですが、ビルドエラーが発生してしまいました。
65行目の round に赤色の波下線が引かれていたので、恐らくround関数が機能していないものと考えています。
エラーメッセージは、「error C3861: 'round': 識別子が見つかりませんでした」のみです。
<math.h>は確実にインクルードされているはずなんですが・・・

MILLE

Re: C言語で、タイピングゲーム。

#4

投稿記事 by MILLE » 4年前

Visual Studioでよくわからない現象が起こったら、とりあえずプロジェクトを作り直してもう一度コンパイルしてみましょう。
それで直ることがまれによくある。

アバター
へにっくす
記事: 628
登録日時: 7年前
住所: 東京都

Re: C言語で、タイピングゲーム。

#5

投稿記事 by へにっくす » 4年前

STEER さんが書きました:エラーメッセージは、「error C3861: 'round': 識別子が見つかりませんでした」のみです。
Visual Studio 2013以降でないとC99は対応していませんよ(完全とはいかないみたいですが 笑)。
C99 library support in Visual Studio 2013
written by へにっくす

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

Re: C言語で、タイピングゲーム。

#6

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

round関数のかわりにこのraunndo関数を使ってください。

コード:

double raunndo(double n) {
	if (-0.5 < n && n < 0.0) return -0.0;
	return (int)(n + (n >= 0 ? 0.5 : -0.5));
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

MILLE

Re: C言語で、タイピングゲーム。

#7

投稿記事 by MILLE » 4年前

2008でも動いた気がするんだけど
C99含むUpdateあてたからかなぁ・・・

STEER
記事: 4
登録日時: 4年前

Re: C言語で、タイピングゲーム。

#8

投稿記事 by STEER » 4年前

MILLE様<<
追加でアドバイスをご返信頂きありがとうございます。プロジェクトをソリューションから
作り直してもう一度コピペしてコンパイルしてみましたが、やはり上手くいきませんでした。
エラーメッセージも先日私が採り上げた同様のものが出現する結果となってしまいました。

みけCAT様<<
今回はコードを書いて頂き本当にありがとうございました。
せっかくまたひとつ関数を使っていただいた手前申し上げにくいのですが、
raunndo関数について、貼り付ける場所(行)を教えて頂けないでしょうか?
何卒、よろしくお願い致します。

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

Re: C言語で、タイピングゲーム。

#9

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

STEER さんが書きました:raunndo関数について、貼り付ける場所(行)を教えて頂けないでしょうか?
文法的に正しければどこでもいいです。
例えば7行目とか。
※もちろん貼り付けるだけではなく、roundをraunndoに置き換えないとだめですよ!
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

STEER
記事: 4
登録日時: 4年前

Re: C言語で、タイピングゲーム。

#10

投稿記事 by STEER » 4年前

みけCAT様<<
おかげさまで問題は3つとも解決されて、全てが円滑に動いています。
言葉のパターンを増やし易くて、本当に素晴らしいコードを頂きました。
コードの仕組みの解らない部分は、なんとかこちらで解析しようと思います。
大変ありがとうございました。

閉鎖

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