ページ 11

グラフィックハンドルが勝手に書き換えられてしまいます

Posted: 2012年8月30日(木) 19:13
by 新米
directxでマインスイーパーを作っているのですが
マスを開けていくと途中で急にマスが消えてしまいます。

原因を調べるとマスの画像を読み込んだimage[15]のグラフィックハンドルが書き換わってしまっています。
自分の環境ではimage[0]は134479876から134479856になっていました。

しかし、自分ではimageの数値を変更する様なプログラムは書いていないので
なぜ書き換わってしまうのかまったく分かりません。

どこが悪いのでしょうか。

コード:

#include "DxLib.h"
#include <stdio.h>
#include "key.h"

int math[20][15];
int image[15];

// 初期化をする
void field_initialize(int tall,int wade,int bomb){
	if(LoadDivGraph("image/math.png",15,5,3,25,25,image)!=0)exit(1);
	
	for(int i=0;i<15;i++){
		for(int j=0;j<20;j++)math[j][i]=10;
	}
}

void field_set(int w,int t){
	int i,r,rt,rw;

	i=0;
	while(i<50){
		r=GetRand(299);
		rt=r/20;
		rw=r%20;
		if((rt==t && (rw==w || rw==w-1 || rw==w+1))||(rt==t-1 && (rw==w || rw==w-1 || rw==w+1))||(rt==t+1 && (rw==w || rw==w-1 || rw==w+1)))continue;
		if(math[rw][rt]==19)continue;
		else math[rw][rt]+=9;
		i++;
	}

	for(i=0;i<15;i++){
		for(int j=0;j<20;j++)
			if(math[j][i]==10)math[j][i]+=bomb_ckeck(j,i);
	}
}

// 計算する
void field_update(int w,int t,int a){

	if(a==0){
		if(math[w][t]>=10)math[w][t]-=10;
		if(math[w][t]==0)field_zero(w,t);
	}
}

void field_zero(int w,int t){
	if(t>0){
		if(w>0)if(math[w-1][t-1]>=10){
			math[w-1][t-1]-=10;
			if(math[w-1][t-1]==0)field_zero(w-1,t-1);
		}
		if(math[w][t-1]>=10){
			math[w][t-1]-=10;
			if(math[w][t-1]==0)field_zero(w,t-1);
		}
		if(w<29)if(math[w+1][t-1]>=10){
			math[w+1][t-1]-=10;
			if(math[w+1][t-1]==0)field_zero(w+1,t-1);
		}
	}

	if(w>0)if(math[w-1][t]>=10){
		math[w-1][t]-=10;
		if(math[w-1][t]==0)field_zero(w-1,t);
	}
	if(w<29)if(math[w+1][t]>=10){
		math[w+1][t]-=10;
		if(math[w+1][t]==0)field_zero(w+1,t);
	}

	if(t<14){
		if(w>0)if(math[w-1][t+1]>=10){
			math[w-1][t+1]-=10;
			if(math[w-1][t+1]==0)field_zero(w-1,t+1);
		}
		if(math[w][t+1]>=10){
			math[w][t+1]-=10;
			if(math[w][t+1]==0)field_zero(w,t+1);
		}
		if(w<29)if(math[w+1][t+1]>=10){
			math[w+1][t+1]-=10;
			if(math[w+1][t+1]==0)field_zero(w+1,t+1);
		}
	}
}

// 描画する
void field_draw(int x,int y){
	int i,j;

	for(i=0;i<15;i++){
		for(j=0;j<20;j++){
			if(math[j][i]<10)DrawGraph(j*25+70,i*25+70,image[math[j][i]],TRUE);
			if(math[j][i]>=10)DrawGraph(j*25+70,i*25+70,image[10],TRUE);
			DrawFormatString(j*25+70,i*25+70,GetColor(0,0,0),"%d",math[j][i]);
		}
	}

	for(i=0;i<15;i++){
		DrawGraph(i*25+120,25,image[i],TRUE);
	}
	DrawFormatString(120,5,GetColor(0,0,0),"%d",image[0]);

	if(x>70 && x<570 && y>70 && y<445){
		SetDrawBlendMode(DX_BLENDMODE_ADD,125);
		DrawGraph(((x-70)/25)*25+70,((y-70)/25)*25+70,image[10],TRUE);
		SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
	}
}

// 終了処理をする
void field_finalize(){
    //特になし
}

int bomb_ckeck(int w,int t){
	int i=0;

	if(t>0){
		if(w>0)if(math[w-1][t-1]==19)i++;
		if(math[w][t-1]==19)i++;
		if(w<29)if(math[w+1][t-1]==19)i++;
	}

	if(w>0)if(math[w-1][t]==19)i++;
	if(w<29)if(math[w+1][t]==19)i++;

	if(t<14){
		if(w>0)if(math[w-1][t+1]==19)i++;
		if(math[w][t+1]==19)i++;
		if(w<29)if(math[w+1][t+1]==19)i++;
	}
	return i;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	SetBackgroundColor(0,150,0);
	ChangeWindowMode(TRUE);
	if(DxLib_Init()!=0) return -1;
	SetDrawScreen(DX_SCREEN_BACK);

	int x,y,mouse,a=-1;

	int tall=15,wade=20,bomb=50;

	field_initialize(tall,wade,bomb);

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && key_update()==0)
	{
		mouse=GetMouseInput();
		GetMousePoint(&x,&y);

		if(x>70 && x<570 && y>70 && y<445){
			if(mouse & MOUSE_INPUT_LEFT){
				if(a==-1){
					field_set((x-70)/25,(y-70)/25);
					a=0;
				}
				field_update((x-70)/25,(y-70)/25,a);
			}
		}
		field_draw(x,y);

		DrawFormatString(5,5,GetColor(255,255,255),"tall = %d",tall);
		DrawFormatString(5,20,GetColor(255,255,255),"wide = %d",wade);
		DrawFormatString(5,35,GetColor(255,255,255),"bomb = %d",bomb);
		

		if(key_get(KEY_INPUT_RETURN)==1)break;
	}

	DxLib_End();    // DXライブラリ終了処理
	return 0;
}

Re: グラフィックハンドルが勝手に書き換えられてしまいます

Posted: 2012年8月30日(木) 20:15
by softya(ソフト屋)
DirectXではなくDXライブラリですね。

ハンドルを書き換えられる原因は、たぶん変数名の付け方とかが悪いせいだと思います。
math[20][15];
と定義されてますが、2次元目は0から14までの添字のはずです。
ところがこの計算ですが
rt=r/20;
rw=r%20;
このrtを使うと
math[rw][rt]+=9;
2次元目は15までの範囲を超えると思います。
ですよね?

訂正。ここじゃなかったです。調査中。

ご自分でも縦横とか混乱しているのではないでしょうか?
自分で分りやすい縦横を表す英語は何でしょうか?
その名前を変数名にされたほうが良いと思います。

すいません。混練しましたが怪しいところを見つけました。
サイズ問題にはちがなかったですが。

field_zero関数ですがw<29と言うところをたくさん見つけました。
これ?w<19じゃないでしょうか? math[20][15];なんですよね?
と言うことで一番怪しい怪しい候補です。

こうすることをおすすめします。
#define WIDTH (20)
#define TXXXX (15) Tは意味が予想できません。
int math[WIDTH ][TXXXX ];
if(w<(WIDTH-1))if(math[w+1][t-1]>=10){

Re: グラフィックハンドルが勝手に書き換えられてしまいます

Posted: 2012年8月30日(木) 21:18
by 新米
解決しました!ありがとうございました!

やはりなんども使う値は定義したほうが良いんですね。
勉強になりました。

Re: グラフィックハンドルが勝手に書き換えられてしまいます

Posted: 2012年8月30日(木) 21:21
by softya(ソフト屋)
橙子ボタンの隣にある解決チェックのチェックと解決ソースコードの投稿をお願いしますね。
解決ソースコードの投稿はフォーラムルールとなっています。 http://dixq.net/board/board.html

Re: グラフィックハンドルが勝手に書き換えられてしまいます

Posted: 2012年8月30日(木) 23:33
by 新米
すみません。
以後気をつけます。

Re: グラフィックハンドルが勝手に書き換えられてしまいます

Posted: 2012年8月31日(金) 00:01
by nil
解決ソースコードの投稿をお願いします