ま総研2000(まどの総合研究所ver.5.1)

みんながみんなその物事に興味があると思っちゃいけないよという精神で綴る備忘録

そろそろあみだくじからの卒業間近? C言語適当練習日記 第7回

   

ポインタなる、何だかよくわからない呪文を使うことにした。あれこれ、いじくりまくって、関数も色々と増えてきた感じ。

あとは、くじを選択することで、そのマップ上のくじの番号の場所に登場した"P"を、あみだくじのルールに乗っ取って移動させれば、そろそろ、あみだくじ作成からの卒業かなあと。


[c language="++"]// Amida.cpp あみだくじゲームのメインです。
#include <stdio.h>
#include "amida.h"// amida.hはあみだくじ作成用の自作ヘッダファイル

int main(void)
{
int decide_stage_number; // 選択決定したステージ番号
int decide_kuji_number; // 選択決定したくじの番号
int final_kuji_number; // 選択できるくじの最大数、マップデータ読み込みにより取得

char mapdata[300]; // とりあえずのマップデータ用の各座標ごとの文字入れ300にしておく。

int *width = NULL; // マップの横軸の長さP、ただし\nを含んだ長さ。
int default_width = 0;// 横の長さの数値の方。一応初期設定ゼロ。

width = &default_width; // widthに番地を代入。

//入力数値でステージ選択 FINALSTAGENUMBERは選択できるステージの最大数
decide_stage_number = SelectNumber("ステージ", FINALSTAGENUMBER);

// ステージ数を渡して、マップデータ読み込み
// この関数からもってくるのは、選択できるくじの最大数
final_kuji_number = MapDataReading(decide_stage_number, mapdata, width);

// 文字列を画面に表示する文。
Update(mapdata);

//入力数値でくじ選択、関数そのものは、ステージ選択のものと同じ。
decide_kuji_number = SelectNumber("くじ", final_kuji_number);

// 設定されたくじ番号のところにPマークを入れる。
// この中で再表示もしたりしなかったり。
PMove(decide_kuji_number, mapdata, default_width);

return 0;
}[/c]

[c language="++"]// MapDataReading.cpp マップデータのファイルを読み込む文、引数はステージ番号、マップデータ用ポインタ。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int MapDataReading(int stage_number, char *mapp, int *map_width)
{
FILE *fp = NULL;
char str[64]; // ファイル読み込み1回分あたりの読み込み量
char textfile_name[20]; // 読み込みたいファイルの名前を入れる文字列
int final_kuji_number; // くじ番号の最大数
int char_length;

// 選択したステージの数字によって、mapdata数値.txtを読み込むための文字列作成
sprintf(textfile_name, "mapdata%d.txt", stage_number);

// textfile_nameのファイルが開いたかどうかの判定。読み込み用。
if((fp = fopen(textfile_name,"r")) == NULL){
printf("ファイルロードエラー\n");
exit(1);
}

// マップファイル1行目でくじの最大数の読み込み 
fgets(str, 64, fp);

// EOFの場合の処理のみ、他のエラー処理(数字じゃないとか、空欄とか)は後で考える。
if(!feof(fp)) {
final_kuji_number = atoi(str);
}

// ファイル2行目でマップの広さについて数を確保。ポインタ利用。
fgets(str, 64, fp);
char_length = strlen(str);
*map_width = char_length;

// ファイル2行目のとりこみ
for(int x=0; x < char_length; x++){
*mapp = str[x];
*mapp++;
}

// ファイル3行目からは、while文でマップデータを読み込み
// この方針だとEOFが配列に入ってからwhileを抜けることになる。
while(!feof(fp)) {
*mapp= fgetc(fp);
*mapp++;
}
// 読み込みファイルを閉じる
fclose(fp);

// Update()画面表示第1回目をここでやりたかったが、
// *mappをインクリメントをしている影響で、表示がヘンテコになるので却下。

return final_kuji_number; // くじの最大数を返す。
}[/c]

[c language="++"]// Update.cpp あみだくじゲームの画面遷移が目的のものです。。
#include <stdio.h>

int Update(char *mapp){

// 中身がEOFになる直前まで文字を表示。
while(!(*mapp == EOF)){
printf("%c", *mapp); //画面表示。今回はEOFの手前、要するにラスト行の"\n"まで表示。
*mapp++;
}

return 0;
}[/c]

[c language="++"]// PMove.cppはくじで選択したPを移動させるための文
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "amida.h"

// くじ番号は選択した番号、*mappはマップ文字列のP、map_widthはマップ1行ごとの長さ\n含む
int PMove(int kuji_number, char *mapp, int map_width){

char buffer = '\0'; // 文字入れ替え用のバッファー、
char kuji[3]; // くじの番号を文字に変えるための下準備

int start_x = 0; // Pの初期値設定用

// sprintfでくじの番号を文字化、kuji[0]=番号、kuji[1]='\0'
sprintf(kuji, "%d", kuji_number);

/* *mappの2行目で、kuji[0]の文字と同じものがあるかどうか調べる。
もし、同じものがあれば、その場所にPを置いて、元々あった文字をbufferに格納。
これはもしかしたら関数化するかも。
*/

do{
if (*((mapp+map_width)+start_x) == kuji[0]){
// ここで変換コマンド
buffer = (*(mapp+map_width)+start_x);
*((mapp+map_width)+start_x) = 'P';
kuji[0]= buffer;
break; // 変換したら抜ける
}
start_x++;
}while(start_x < map_width);

// while文でbreakしないで抜けた場合の異常終了処理・適当
if (start_x >= map_width) exit(2);

// 画面表示アップデート
Update(mapp);

/* ここからはPの動きの話。あみだなので、基本下へ行く。Pのマスの下にあるマスで考えられるのは、
 H:次は下に進むマス、R:次は右に行くマス、L:次は左へ行くマス。
  O:最終ハズレマス、W:最終当たりマスの5通りである。
ちなみに、*は行く可能性ゼロ。+は下のマスの可能性はないが、RとLが絡むときに関係してくる。

基本、下のマスの文字と'P'と文字の交換、bufferに入れていたものを交換前のPの位置に戻す作業
そして、今回、交換により取得した、下のマスだった文字によって、次の行動が決定するわけです。

Hを拾ってきた場合は、次も下のマスを見ることになる。
R、Lを拾ってきたら、次は右ないし左の+のマスを見る必要があるし、
Oならばあみだ失敗のアナウンス、Wならあみだ成功のアナウンスが必要となる。
*/
return 0;
}[/c]

 - C言語練習