/* ダブルナンバーサーチ・トレーニング(最近の10回の日時とベストテンの表示) curses.hを使うにはhttp://bd.tank.jp/d/20071208.htmlにゃかもとの日記参を参照する ダブルナンバーリサーチの表示がbestten3は表示はされるのですが 順番になっていない。どこが悪いのかいろいろやったのですが どうしてもうまくいきません。とにかく正しい表示になるようにしたいです。 */ #include <stdio.h> #include <time.h> #include <float.h> #include <ctype.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include "getputch.h" #define MAX_STAGE 3 #define swap(type, x, y) do { type t = x; x = y; y = t; } while (0) #define MAX_NUM 10 char dtfile[] = "LACKNUM3.DAT"; char dtfile2[] = "LACKNUM4.DAT";/* 最高記録用のファイル */ typedef struct { int tm_year; int tm_mon; int tm_mday; int tm_hour; int tm_min; int tm_sec; double best; } BEST_TEN; // --------------- 比較用の関数 cmp ------------------- int cmpptr( const void *p, const void *q ) { return (*(BEST_TEN**)p)->best - (*(BEST_TEN**)q)->best; } // ---------------------------------------------------- //1回実行したとき進むポイントの大きさを求める int kaime_p(fpos_t* kaime_p1) { FILE *fp; struct tm local; double best; fp = fopen(dtfile, "rb"); fread(&local, sizeof(struct tm), 1, fp); fread(&best, sizeof(double), 1, fp); //ファイルポインタの位置を取得 fgetpos(fp,kaime_p1); //ファイルfpの現在のファイル位置を取得して // kaime_p1の示す場所に格納します。 printf("ファイルポインタの位置kaime_p1は「%d」です。\n",*kaime_p1); fclose(fp); return *kaime_p1; } //local のデータを新しい順にならべる。 void new_local_data(fpos_t ft,int k) { FILE *fp; // これまでの履歴を指すポインタ FILE *fp2; // これまでの最短所要時間を指すポインタ double best; //これまでの履歴の所要時間 double best2; //これまでの最短所要時間のベストテンも保存しておく int i; //構造体変数 localの大きさ struct tm local; if ((fp = fopen(dtfile, "rb")) == NULL) { printf("ファイルを作成します。\n\n"); best = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ } else { printf("最近の10回の点数とそれらの実行日時は\n\n"); for(i=ft-k; i>=ft-10*k; i -= k){ //構造体変数 localの大きさkaime_p1で44 //ファイルポインタを先頭からiまで移動 fseek(fp,i,SEEK_SET); fread(&local, sizeof(struct tm), 1, fp); printf("%d年 %d月 %d日 %d時 %d分 %d秒\n", local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); fread(&best, sizeof(double), 1, fp); printf("得点(所要時間)は%.1f秒\n\n", best); } printf("enterキーで開始します。\n"); fflush(stdin); getchar(); } fclose(fp); } /*--- 過去のトレーニング情報を取得・表示して最高得点を返す ---*/ double get_data(int *count) { FILE *fp; /* これまでの履歴を指すポインタ */ FILE *fp2; /* これまでの最短所要時間を指すポインタ */ double best; //これまでの履歴の所要時間 double best2; //これまでの最短所要時間 int i,j=0; BEST_TEN best_ten[100]={0}; if ((fp = fopen(dtfile, "rb")) == NULL) { printf("ファイルを作成します。\n\n"); best = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ } else { struct tm local; double line[256]; printf("\n過去の履歴\n-------------------------- \n"); while((i = fread(&local, sizeof(struct tm), 1, fp)) > 0 ){ printf("%d年 %d月 %d日 %d時 %d分 %d秒\n", local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); fread(&best, sizeof(double), 1, fp); printf("得点(所要時間)は%.1f秒\n\n", best); best_ten[j].tm_year=local.tm_year; best_ten[j].tm_mon=local.tm_mon; best_ten[j].tm_mday=local.tm_mday; best_ten[j].tm_hour=local.tm_hour; best_ten[j].tm_min=local.tm_min; best_ten[j].tm_sec=local.tm_sec; best_ten[j].best=best; j++; (*count)++; } printf("count1は%d\n\n", *count); } BEST_TEN *plst[*count]; for( i = 0; i < *count; i++ ) plst[i] = &best_ten[i]; qsort( plst, *count, sizeof(BEST_TEN*), cmpptr ); printf("\n過去のbestten3\n-------------------------- \n"); // 並べ替え後の内容を表示 for(i=0;i<10;i++){ printf( "%d年 %d月 %d日 %d時 %d分 %d秒 %.lf秒\n" ,plst[i]->tm_year+1900, plst[i]->tm_mon+1, plst[i]->tm_mday, plst[i]->tm_hour,plst[i]->tm_min,plst[i]->tm_sec ); printf("得点(所要時間)は %.1f秒です。\n\n", plst[i]->best); } best=plst[0]->best; fflush(stdin); fclose(fp); printf("count2は%d\n\n", *count); return best; } /*--- 今回のトレーニング情報を書き込む ---*/ void put_data(double best, double best2) { FILE *fp; //fpはfopenされたdtfileを指すポインタ FILE *fp2; //fp2はfopenされたdtfile2を指すポインタ、最短時間が格納されている time_t t = time(NULL); struct tm *local = localtime(&t); time(&t); local = localtime(&t); if ((fp = fopen(dtfile, "ab")) == NULL){ printf("ファイルがあーりません"); fflush(stdout); }else { fwrite(local, sizeof(struct tm), 1, fp); //fpに書き込む fwrite(&best, sizeof(double), 1, fp); //fpに書き込む fclose(fp); } if(best <= best2){ if((fp2 = fopen(dtfile2, "wb")) ==NULL){ printf("ファイルがあーりません"); fflush(stdout); }else{ //point配列にbestをいれ、best2をベスト2にいれる。dtfile[0]にbest1,dtfile[1]にbest2.....dtfile[9]にbest10 fwrite(local, sizeof(struct tm), 1, fp2); fwrite(&best2, sizeof(double), 1, fp2); fclose(fp2); } } } /*--- トレーニングを実行して得点(所要時間)を返す ---*/ double go(void) { int i, j, x,no,stage; int dgt[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int a[10]; double jikan; // 時間 clock_t start, end; // 開始時刻・終了時刻 printf("\n\nダブっている数字を入力してください。\n"); printf("スペースキーで開始します。\n"); while (getch() != ' ') ; start = time(NULL); for (stage = 0; stage < MAX_STAGE; stage++) { x = rand() % 9; /* 0~8の乱数を発生 */ i = j = 0; while (i < 9) { /* dgt[x]をダブらせてコピー */ a[j++] = dgt[i]; if (i == x) a[j++] = dgt[i]; i++; } for (i = 9; i > 0; i--) { /* 配列aをシャッフル */ int j = rand() % (i + 1); if (i != j) swap(int, a[i], a[j]); } for (i = 0; i < 10; i++) /* 全要素を表示 */ printf("%d ", a[i]); printf(":"); fflush(stdout); do { no = getch(); if (isprint(no)) { /* 表示可能であれば */ putch(no); /* 押されたキーを表示 */ if (no != dgt[x] + '0') /* 正解でなければ */ putch('\b'); /* カーソルを一つ戻す */ else printf("\n"); /* 改行 */ } } while (no != dgt[x] + '0'); } end = time(NULL); jikan = (double)difftime(end, start) printf("%.1f秒かかりました。\n", jikan); if (jikan > 25.0) printf("鈍すぎます。\n"); else if (jikan > 20.0) printf("少し鈍いですね。\n"); else if (jikan > 17.0) printf("まあまあですね。\n"); else printf("素早いですね。\n"); term_getputch(); return (jikan); } int main(void) { int retry,count=0; // もう一度? double score; // 今回の所要時間 double best; // 最短所要時間 double jikan; // 時間 FILE *fp; fpos_t ft; fpos_t kaime_p1; struct tm local ; int k; int i, j, x, stage; best= get_data(&count); // get_data()で前回までの最短所要時間を // ファイルから読み込んでbestに代入する。 printf("bestは%.1f1\n\n", best); printf("count3は%d\n\n", count); fp = fopen(dtfile, "rb"); kaime_p(&kaime_p1); k=kaime_p1; //ファイルポインタの位置を取得 printf("mainのkaime_p(&kaime_p1)後のkの値は「%d」です。\n\n",k); //ファイルポインタを末尾まで移動 fseek(fp,0,SEEK_END); //ファイルポインタの位置を取得 fgetpos(fp,&ft); //ファイルfpの現在のファイル位置を取得して // &ftの示す場所に格納します。 new_local_data(ft,k); fgetpos(fp,&ft); //best = get_data(ft); // get_data()で前回までの最短所要時間を //ファイルから読み込んでbestに代入する。 init_getputch(); //ライブラリの初期処理235p、initscr(),cbreak(),noecho(),refresh() srand(time(NULL)); // 乱数の種を初期化 do { score = go(); // トレーニング(go)で実行、返却された所要時間(jika)をscoreに代入する。 if (score < best) { printf("最短所要時間を更新しました!!\n"); best = score; /* 最高得点更新 */ } printf("もう一度しますか … (0)いいえ (1)はい:"); scanf("%d", &retry); } while (retry == 1); put_data(score,best); /* 今回の日付・時刻・得点を書き込む */ fflush(stdout); fclose(fp); term_getputch(); //ライブラリの初期処理235p,endwin() return 0; } /* 実行結果 C:\Users\username\chap09\kadai\kadai9-2>gcc -I. -o kad9_2_1b kad9_2_1b.c pdcurses.a C:\Users\username\chap09\kadai\kadai9-2>kad9_2_1b 過去の履歴 -------------------------- 2015年 10月 27日 19時 9分 59秒 得点(所要時間)は11.0秒 2016年 1月 4日 19時 15分 11秒 得点(所要時間)は8.0秒 ......省略...... count1は12 過去のbestten3 -------------------------- 2016年 1月 4日 19時 21分 44秒 0秒 得点(所要時間)は 8.0秒です。 2016年 1月 4日 19時 15分 11秒 0秒 得点(所要時間)は 8.0秒です。 2016年 3月 19日 11時 43分 16秒 0秒 得点(所要時間)は 7.8秒です。 2016年 1月 4日 19時 16分 8秒 0秒 得点(所要時間)は 9.0秒です。 2016年 1月 4日 19時 21分 11秒 0秒 得点(所要時間)は 10.0秒です。 2016年 1月 4日 19時 19分 7秒 0秒 得点(所要時間)は 10.0秒です。 2016年 1月 5日 21時 33分 29秒 0秒 得点(所要時間)は 10.0秒です。 2016年 3月 19日 11時 41分 52秒 0秒 得点(所要時間)は 10.7秒です。 2016年 1月 4日 19時 16分 39秒 0秒 得点(所要時間)は 10.0秒です。 2015年 10月 27日 19時 9分 59秒 0秒 得点(所要時間)は 11.0秒です。 count2は12 bestは8.0 cunt3は12 ファイルポインタの位置kaime_p1は「44」です。 mainのkaime_p(&kaime_p1)後のkの値は「44」です。 最近の10回の点数とそれらの実行日時は 2016年 3月 19日 11時 43分 16秒 得点(所要時間)は7.8秒 2016年 3月 19日 11時 41分 52秒 得点(所要時間)は10.7秒 ........省略........ enterキーで開始します */ コード
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/03/19 10:28
退会済みユーザー
2016/03/19 10:29
2016/03/19 10:42
退会済みユーザー
2016/03/19 13:21
2016/03/19 15:23
退会済みユーザー
2016/03/19 23:50