そろそろあみだくじからの卒業間近? 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]
Pick Up
- 1
-
Macbook air Mid2012 のバッテリー交換を行おうとして右往左往したときのログ(前編)
やったときのログシリーズ、バッテリー交換編
- 2
-
Macbook Air Mid2012 のバッテリー交換をしたときのメモ(後編)
バッテリー交換後編。