初めてのプログラミング

らんみゃ
記事: 2
登録日時: 9年前

初めてのプログラミング

投稿記事 by らんみゃ » 9年前

油分け算という数学の問題をご存知でしょうか?

油分け算とは、
5升の桶と3升の桶を使って4升を量るにはどうしたらいいか、などの問題です。

今私はこれのプログラムを書くことにチャレンジしていて、いくつか未解決の問題があって困っています。

質問掲示板を使わなかったのは、プログラムが長くて説明が大変になりそうなのでそのままプログラムを張ってしまおうと思ったからです。

まだメインの計算部分は完成していないので、ただビーカーの容量を設定シーンで決めて、計算シーンでマウスを使ってビーカーの位置をいじったり水の量を加算したりさせるだけです。

主な流れの例としては
1.ビーカーの容量を↑↓キーを使って選んで、エンターキーで決定。
2.ビーカーに表示された文字上でマウスを操作する
 右クリックで水を加える
 左クリックしながらでビーカーの移動
3.ここからはまだ未完ですが、水を移動させたりするつもりです。

未解決の部分
・ウィンドウのサイズが少し小さいので、大きくしたい。("無尽蔵"の画像が切れてしまう)
・ビーカーに入っている水の量に応じた描画をしたい。
 ↑例えばビーカー8dlに4dl入っている場合、水の描画は空ビーカーの半分に
・その他、プログラムが汚いので細かく添削していただけると助かります。

CODE:

#include"DxLib.h"
#include
#include

int Key[256]; //キーの数
int Rate[9]; //ビーカーの容量
int gpUpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
	GetHitKeyStateAll(tmpKey); // 全てのキーの入力状態を得る
	for (int i = 0; i");
		DrawFormatString(10, 420, Yellow, "使用するビーカーの容量を↓ボタンもしくは↑ボタンで指定して下さい。");
		DrawFormatString(10, 440, Yellow, "エンターキーで決定して下さい。");

		DrawRotaGraph(150, 200, 1.0, 0.0, Handle_B[RateNum1], TRUE); //B1の描画
		DrawFormatString(150, 200, Green, "%d dL", RateNum1); //B1の容量の表示

		DrawRotaGraph(450, 200, 1.0, 0.0, Handle_B[RateNum2], TRUE); //B2の描画
		DrawFormatString(450, 200, Green, "%d dL", RateNum2); //B2の容量の表示

		if (SelectNum == 0){ //B1選択
			if (Key[KEY_INPUT_DOWN] == 1){ //↓キーが押された瞬間
				RateNum1 = (RateNum1 + 9) % 10; //RateNumは9,18,27,,,となる。
			}
			if (Key[KEY_INPUT_UP] == 1){ // ↑キーが押された瞬間だけ処理
				RateNum1 = (RateNum1 + 1) % 10; //RateNumは1,2,3,,,となる。
			}
			if (Key[KEY_INPUT_RETURN] == 1){ //エンターキーが押された瞬間
				gpUpdateKey();
				SelectNum++; //選択番号の加算
			}
		}
		if (SelectNum == 1){ //B2選択
			if (Key[KEY_INPUT_DOWN] == 1){ //↓キーが押された瞬間
				RateNum2 = (RateNum2 + 9) % 10; //RateNumは9,18,27,,,となる。
			}
			if (Key[KEY_INPUT_UP] == 1){ // ↑キーが押された瞬間だけ処理
				RateNum2 = (RateNum2 + 1) % 10; //RateNumは1,2,3,,,となる。
			}
			if (Key[KEY_INPUT_RETURN] == 1){ //エンターキーが押された瞬間
				gpUpdateKey();
				SelectNum++; //選択番号の加算
			}
		}

		//ダブルエンターで設定画面を抜ける処理
		if (Key[KEY_INPUT_RETURN] == 1){ 
			gpUpdateKey();
			SelectNum++;
		}
		if (SelectNum == 3) break; //値の入力が終了
	}

	//計算シーン
	int B1_x = 100, B1_y = 150; //B1のxy座標
	int B2_x = 300, B2_y = 150; //B2のxy座標

	int W1_y = 8000, W2_y = 8000; //水のy座標

	int M_x, M_y; //マウスカーソルのxy座標

	int B1_V = 0, B2_V = 0; //B1,B2の容量

	int Button, ClickX, ClickY; //マウスのクリックされた値(左クリック),クリックされたときのxy座標

	int Handle_C; //空ビーカーの画像ハンドル
	Handle_C = LoadGraph("img/無尽蔵.png"); 

	int MouseDate = 0;
	int Finish = 0;

	SetMouseDispFlag(TRUE); //マウスを表示状態にする

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0){
		GetMousePoint(&M_x, &M_y); //マウスカーソルのxy座標の格納

		DrawRotaGraph(500, 350, 0.5, 0.0, Handle_C, TRUE); //無尽蔵の描画

		DrawRotaGraph(B1_x, B1_y, 0.8, 0.0, Handle_B[RateNum1], TRUE); //B1の描画
		DrawRotaGraph(B1_x, W1_y, 0.8, 0.0, Handle_W[RateNum1], TRUE); //水の描画
		DrawFormatString(B1_x, B1_y, Green, "%d dL", B1_V); //B1の容量の表示

		DrawRotaGraph(B2_x, B2_y, 0.8, 0.0, Handle_B[RateNum2], TRUE); //B2の描画
		DrawRotaGraph(B2_x, W2_y, 0.8, 0.0, Handle_W[RateNum2], TRUE); //水の描画
		DrawFormatString(B2_x, B2_y, Green, "%d dL", B2_V); //B2の容量の表示


		if (GetMouseInputLog(&Button, &ClickX, &ClickY, TRUE) == 0){ //右クリックされたときの処理(水を入れる)
			if ((Button & MOUSE_INPUT_RIGHT) != 0){ 
				if (M_x >= (B1_x - 10) && M_x = (B1_y - 10) && M_y = (B2_x - 10) && M_x = (B2_y - 10) && M_y = (B1_x - 40) && M_x = (B1_y - 15) && M_y = (B2_x - 40) && M_x = (B2_y - 15) && M_y = 10 && M_x = 450 && M_y <= 465){ 
				Finish = 50;
			}
		}

		if (Finish == 50)break; //終了処理

	}

	DxLib_End();
	return 0;
}
添付ファイル

[拡張子 zip は無効化されているため、表示できません]


derok
記事: 51
登録日時: 12年前

Re: 初めてのプログラミング

投稿記事 by derok » 9年前

とりあえずHandle_BとHandle_Wの要素数が足りてませんね。
他は気づいたら追記します。

らんみゃ
記事: 2
登録日時: 9年前

Re: 初めてのプログラミング

投稿記事 by らんみゃ » 9年前

本当ですね。ありがとうございます。
配列ってサイズ以上のものがあったら新しく作ってくれるんですね。
Handle_B[10] Handle_W[10]
と直しておきます。

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: 初めてのプログラミング

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

らんみゃ さんが書きました:配列ってサイズ以上のものがあったら新しく作ってくれるんですね。
JavaScriptなど作ってくれる言語もありますが、C++では作ってくれず、範囲外にアクセスしたら未定義動作になります。

derok
記事: 51
登録日時: 12年前

Re: 初めてのプログラミング

投稿記事 by derok » 9年前

らんみゃ さんが書きました: 配列ってサイズ以上のものがあったら新しく作ってくれるんですね。
作っていません
偶然動いているだけです。
古い環境だと動きませんが、

CODE:

#include 
#include 
int main(){
    std::array ary={1,2,3,4,5};//int ary[10]相当
    int array_0=ary.at(4);//ary[4]相当
    ary.at(4)=8;
	for(int i=0;i<ary.size();i++){//ary.size()で配列の長さ取得
		printf("%d_",ary.at(i));
    }
}
となるstd::arrayを使えば範囲外アクセスを検知できます。