qsortの使い方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ららら

qsortの使い方

#1

投稿記事 by ららら » 9年前

とある場所で提示されていた問題なのですがその場では質問できそうでなかったので
こちらの掲示板で質問をさせていただきます

確か問題はLoadGraphScreen関数の入れ替えだったかな?
その関数をy座標を基準にqsortで入れ替えるといものでした

コード:

typedef struct{ 
int x;//x座標の値 
int y;//y座標の値 
char *name;//画像の名前 
}TEST; 

TEST base[2]; 
for( i=0; i<10; i++ ){ 
LoadGraphScreen( base[i].x , base[i]y ,*base[i].name , TRUE ) ; 
} 
といったのがヒントとして提示されていたのですがqsortの比較関数がつくれません
誰か詳しい方、教えていただけませんか? お願いします

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

Re: qsortの使い方

#2

投稿記事 by へろりくしょん » 9年前

だから、y を比較すればいいだけだと思いますが。

とりあえず、比較関数の中身は

int hikaku(const void *a, const void *b)
{
return ((TEST*)a)->y - ((TEST*)b)->y;
}

とでもすればいいかと。

アバター
みけCAT
記事: 6284
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: qsortの使い方

#3

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

とある場所ってどこですか?
y座標を基準にと言っても昇順ですか?降順ですか?その他ですか?
とりあえずy座標の昇順にソートするための関数です。

コード:

int comp(const void* x,const void* y) {
	TEST* xx=(TEST*)x;
	TEST* yy=(TEST*)y;
	if((xx->y)>(yy->y))return 1;
	if((xx->y)<(yy->y))return -1;
	return 0;
}
へろりん さんが書きました:だから、y を比較すればいいだけだと思いますが。

とりあえず、比較関数の中身は

int hikaku(const void *a, const void *b)
{
return ((TEST*)a)->y - ((TEST*)b)->y;
}

とでもすればいいかと。
これではいけません。
aのy座標とbのy座標の差が極端な場合、オーバーフローします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ららら

Re: qsortの使い方

#4

投稿記事 by ららら » 9年前

すいません qsort以前に比較の仕方が分かりませんでした
描画したい画像の数だけ構造体をつくるのでしょうか?

コード:

typedef struct{ 
int x;//x座標の値 
int y;//y座標の値 
char *name;//画像の名前 
}TEST; 
 
TEST base[2]; 
for( i=0; i<2; i++ ){ 
LoadGraphScreen( base[i].x , base[i]y ,*base[i].name , TRUE ) ; 
} 


typedef struct{ 
int a;//a座標の値 
int b;//b座標の値 
char *namae;//画像の名前 
}TEST2; 
 
TEST2 base[2]; 
for( i=0; i<2; i++ ){ 
LoadGraphScreen( base[i].a , base[i]b ,*base[i].namae , TRUE ) ; 
} 
すいません、、、 上のコードは正直、適当に書きました
二つのLoadGraphScreen関数をソートする為のコードを教えていただけませんか?
他のサイトを見ても分かりませんでした 形だけでもいいのでお願いします 

box
記事: 1747
登録日時: 9年前

Re: qsortの使い方

#5

投稿記事 by box » 9年前

ららら さんが書きました:二つのLoadGraphScreen関数をソートする為のコードを教えていただけませんか?
関数をソートする、というのがどういう行為を指しているのか、全くわかりません。
質問者さんの頭の中では、きちんとイメージできているんでしょうか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

しひ

Re: qsortの使い方

#6

投稿記事 by しひ » 9年前

コード:

typedef struct{ 
  int anko; 
}Taiyaki;
これは構造体の「定義」です。たい焼きで例えると、たい焼きの型です。

コード:

Taiyaki taro;
これは構造体の「宣言」です。たい焼きで例えると、たい焼きそのものです。

コード:

typedef struct{ 
  int anko; 
}Taiyaki;

Taiyaki taro;
Taiyaki jiro;
たい焼きを増やすためにわざわざ型を増やす必要はありません。たい焼きだけ増やして下さい。

コード:

焼く( taro );
便宜上、LoadGraphScreen()関数は焼く()関数と名付けます。

コード:

焼く( taro );
焼く( jiro );
たい焼きを2つ焼きたいときは、このように焼く関数を並べます。
焼く順番は上からになります。ソースコードにこのように書いた以上、順番を変えることはできません。
つまり、関数を入れ替えることはできません。実際にはできないこともないのですが、とりあえず今のあなたには無理です。

本題です。
焼く順番を変えたくとも関数は並び替えられません。では、どうするか。
たい焼きの方を並び替えれば焼く順番を変えることができます。

コード:

Taiyaki hako[2];
たい焼きを入れる配列を用意しました。これには2尾のたい焼きが入ります。

コード:

int i;
for( i = 0; i < 2; i++ )
{
  焼く( hako[i] );
}
繰り返し文と配列を使うことで、焼く関数1つでたい焼きを2尾焼くことができます。
この例の場合、箱0番に入っているたい焼き→箱1番に入っているたい焼き、の順番で焼きます。
箱0番に入っていたたい焼きと箱1番に入っていたたい焼きを入れ替えると、焼く順番も入れ替わります。
このたい焼きの入れ替えを行うのがqsort()関数です。

正直、とある場所にあったコードととある場所に書かれていたコメントが全てだと思います。
それらの意味が分かるようになるまで、ゲーム製作なんて窓から投げ捨ててC言語の勉強をすることをお勧めします。

box
記事: 1747
登録日時: 9年前

Re: qsortの使い方

#7

投稿記事 by box » 9年前

しひ さんが書きました:

コード:

typedef struct{ 
  int anko; 
}Taiyaki;
これは構造体の「定義」です。たい焼きで例えると、たい焼きの型です。
ひじょうにわかりやすい例えをされていると思います。
が、
しひ さんが書きました:

コード:

Taiyaki taro;
これは構造体の「宣言」です。たい焼きで例えると、たい焼きそのものです。
ここは、構造体の宣言ではなくって、先に定義してあった構造体(たい焼きの型)を使った変数(たい焼き)の定義であります。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

しひ

Re: qsortの使い方

#8

投稿記事 by しひ » 9年前

少し長い文書いただけですぐぼろが出る!
申し訳ないです。

ららら

Re: qsortの使い方

#9

投稿記事 by ららら » 9年前

qsortの勉強からやります

最後にひとつだけ質問させてください
あのようにqsortでやる方法と下のように

コード:

if(y<b)
LoadGraphScreen(x,y,aaa.png,TORE)
LoadGraphScreen(a,b,iii.png,TORE)
if(b>y)
LoadGraphScreen(a,b,iii.png,TPRE)
LoadGraphScreen(x,y,iii.png,TORE)
if文を使うのとどちらが高速なのでしょうか?
数学関数を使うと処理が遅くなると聞いたもんで・・・

しひ

Re: qsortの使い方

#10

投稿記事 by しひ » 9年前

そのたった6行のソースコードが既に危ういので、一度qsort関数の存在を忘れて基礎を固めて下さい。
速度の前に気にすべきことは山のようにあります。

それと、qsort関数は数学関数ではありません。

ららら

Re: qsortの使い方

#11

投稿記事 by ららら » 9年前

あ、あのですね・・・
じゃあ数学の勉強とif文の勉強からやります

ららら

Re: qsortの使い方

#12

投稿記事 by ららら » 9年前

う、今、気付いたのですが描画するものの数だけ構造体をつくるということが間違っていましたね
構造体は一つだけでいいはずです

アバター
bitter_fox
記事: 607
登録日時: 9年前
住所: 大阪府

Re: qsortの使い方

#13

投稿記事 by bitter_fox » 9年前

ららら さんが書きました:qsortの勉強からやります

最後にひとつだけ質問させてください
あのようにqsortでやる方法と下のように

コード:

if(y<b)
LoadGraphScreen(x,y,aaa.png,TORE)
LoadGraphScreen(a,b,iii.png,TORE)
if(b>y)
LoadGraphScreen(a,b,iii.png,TPRE)
LoadGraphScreen(x,y,iii.png,TORE)
if文を使うのとどちらが高速なのでしょうか?
数学関数を使うと処理が遅くなると聞いたもんで・・・
その程度の個数の判定であればわざわざqsortを引っ張り出すまでもないです。

ですが、キャラクターなどが100体(もしくは不定数体)居てそれぞれについてY座標の小さいものから描画しようとした場合はどうでしょう?
この場合は、qsortで構造体変数ごとY座標で並び替えて、それから順番に描画する方がスマートです。
(泥臭くするなら『最低Y座標を求めてその最低Y座標と同じキャラクタを描画、次に最低Y座標より大きいY座標の中で最低の物を見つけて、それを新しい最低Y座標として繰り返す』という方法で出来ますがこれだと二重ループになったりで非常に面倒くさいです。)

[hr]
蛇足ながら、そのコードの問題点を指摘しますと、
1.if構文に恐らく分岐・実行が望まれる文が二つあるのに{}がない
2.文の末尾に;がない
3.TPRE及びTOREはTRUEの誤りではないでしょうか
4.bとyが同じ値の時が考慮されていない

[hr]
ららら さんが書きました: じゃあ数学の勉強とif文の勉強からやります
数学の勉強は関係ないというか本末転倒ではないでしょうか?

ららら

Re: qsortの使い方

#14

投稿記事 by ららら » 9年前

foxさん、わざわざ書き込んでくださってありがとうございました
できるようになるまで繰り返してやってみます

lib

Re: qsortの使い方

#15

投稿記事 by lib » 9年前

あのねぇ、y座標を基準に並び替えたいんだよねぇ?
だったらy座標以外配列をつくらなくてもいいんじゃない?
それと描画したい絵の数だけ構造体をつくらなくてもいいよね?
なんで画像表示のところがポインタなの?
いくつもおかしいところあるんじゃないの?

ららら

Re: qsortの使い方

#16

投稿記事 by ららら » 9年前

う、ごめんなさい
自分でも努力します・・・
あと画像表示に使うのは文字列なのでポインタを使うのではないでしょうか?
よく分かりませんが・・・
それと自分も間違っていたかもしれませんが構造体はひとつでいいのですよね?
qsortは同じ構造体じゃないとソートできないような気もしますし・・・
よく分かりませんが・・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#17

投稿記事 by softya(ソフト屋) » 9年前

>>libさん

副管理人をさせていただいているsoftya(ソフト屋)です。
言葉遣いは丁寧にお願できますでしょうか。
ここのスローガンとして「アットホームで温かい」を目指しております。
http://dixq.net/board/board.html

>>らららさん

LoadGraphScreen()はファイルを読み込んで表示する命令ですので凄く遅くゲーム中に使うのは実は向いていません。
普通はLoadGraph()とDrawGraph()でロードと描画のタイミングを分けて使います。
なので、実際に表示にはDrawGraph()を使いますのでファイル名ではなくLoadGraph()の戻り値のグラフィックのハンドルを使います。
LoadGraph()は遅いので毎回表示ループが通らない別の場所で行うわけです。

それとqsort()以前に別のソート方法を学んだほうが良いかも知れません。
qsort()は、相当件数が多くないと高速に動作しないので別のソート方法のほうが有利な場合もあります。
まず、基本的なソートを学んでみましょう。サイトをご紹介します。

「アルゴリズムとデータ構造編 トップページ」
http://www.geocities.jp/ky_webid/algorithm/index.html
「アルゴリズム入門」
http://www5c.biglobe.ne.jp/~ecb/algorit ... thm00.html

>それと自分も間違っていたかもしれませんが構造体はひとつでいいのですよね?

この件は、らららさんが何件のキャラクタをy座標順に並べたいかによりますし、そもそもキャラクタを管理する構造体を利用する方法もあります。
あとポインタを理解いていればポインタリストだけでソートすることも出来ます。
なので、らららさんが理解しているレベルと想定しているプログラムの構造を出来るだけ明かしてもらえば適切なアドバイスが可能になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#18

投稿記事 by ららら » 9年前

ソフト屋さん、ありがとうございます
(クイックソートのほかにもソート方があったのですね 一度、目を通してみます)
わたしのレベルはざっとCの入門を見ただけで自分の考えたプログラムをつくったことはありません

コード:


#include "DxLib.h"

int comp( const void *c1, const void *c2){
          test test3 = *(test *)c1;
          test test4 = *(test *)c2;

          int tmp1 = test3.y;   
          int tmp2 = test4.y;

          return tmp1 - tmp2;
}

// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{          
        ChangeWindowMode( TRUE ) ;

	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}
         
        typedef struct{
	int y;
	}test;	
	
	test test2[2] = {
	{40},
            {41}
	};
	
	LoadGraphScreen( 20 , test2[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
	LoadGraphScreen( -20 , test2[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
	
	qsort(base,2,sozeof(test),comp)
	
	// 絵を打つ

	WaitKey() ;				// キー入力待ち

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;				// ソフトの終了 
}

とあるサイトを参考にわたしなりに考えてみたのですがどこが原因でエラーがでるのか分かりません
よろしければ教えてください

ららら

Re: qsortの使い方

#19

投稿記事 by ららら » 9年前

すいません、
baseはtest2に置き換えてください

ららら

Re: qsortの使い方

#20

投稿記事 by ららら » 9年前

一部、修正しましたがまだ動きません・・・

コード:

#include "DxLib.h"

        typedef struct{
	int y;
	}test;

int comp( const void *c1, const void *c2){
          test test2 = *(test *)c1;
          test test3 = *(test *)c2;

          int tmp1 = test2.y;   
          int tmp2 = test3.y;

          return tmp1 - tmp2;
}

// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{          
        ChangeWindowMode( TRUE ) ;

	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}
         
        typedef struct{
	int y;
	}test;
	                          
	int x = 20;
	
	
	test test1[2] = {
	{40},
        {41}
	};
	
	LoadGraphScreen( x , test1[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
	LoadGraphScreen( -20 , test1[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
	
	qsort(test1,2,sozeof(test),comp)
	
	// 絵を打つ

	WaitKey() ;				// キー入力待ち

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;				// ソフトの終了 
}


アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#21

投稿記事 by softya(ソフト屋) » 9年前

少なくとも、そのプログラムはコンパイルが通りません。
エラーメッセージ読み方は慣れたらわかりますので、まずエラーを理解することから始めてください。
何行目にどんなエラーが出ていますか?

[追記]
ソースコードを見る限り、C言語の次の部分が理解出来ていない可能性があります。
・宣言・変数のスコープ
・ポインタ
・配列の添字の範囲
・一部の演算子

あとプログラムの流れそのものを理解出来ていないと思います。
折角ソートしてもその値を使っていませんし、キャラクタの並びをy座標順にソートをしたかったのでは?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#22

投稿記事 by ららら » 9年前

ひとつ気付きましたがcomp関数は一番、下にもっていきました

エラーはひとつひとつ潰していきましたが
あと、ひとつというところで行き詰りました
「宣言の構文エラー」とはどういう意味でしょう?

それとqsortを使うとはどのようなことでしょうか?
comp関数の中身から間違っていますか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#23

投稿記事 by softya(ソフト屋) » 9年前

>「宣言の構文エラー」とはどういう意味でしょう?

その書かれている通りの意味なのですが、ソースコードを見ないとなんとも言えません。

>それとqsortを使うとはどのようなことでしょうか?
>comp関数の中身から間違っていますか?

qsort前に表示しているのは意味有りませんし、プログラム的に移動機能がない状況でキャラクタでソートする意味はまったくありません。
comp関数自体の中身はは冗長ですが合っています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#24

投稿記事 by ららら » 9年前

将来は動く画像をソートしたいのですが
今はまだ勉強中ということで静止画をソートしています
エラーは全て潰したのですが

コード:


#include "DxLib.h"

             typedef struct{
	int y;
	}test;

int comp( const void *c1, const void *c2);

// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{          
        ChangeWindowMode( TRUE ) ;

	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}
	
	
	test test1[2] = {
	{40},
             {41}
	};
	
	qsort(test1,2,sizeof(test),comp);
        
	LoadGraphScreen( 20 , test1[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
	LoadGraphScreen( 20 , test1[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
	
	
	// 絵を打つ

	WaitKey() ;				// キー入力待ち

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;				// ソフトの終了 
}

int comp( const void *c1, const void *c2){
          test test2 = *(test *)c1;
          test test3 = *(test *)c2;

          int tmp1 = test2.y;   
          int tmp2 = test3.y;

          return tmp1 - tmp2;
}
なぜか画像がソートされません
どこかおかしいところはありますか?

アバター
a5ua
記事: 199
登録日時: 9年前

Re: qsortの使い方

#25

投稿記事 by a5ua » 9年前

こちらで、LoadGraphScreenとLoadGraphの違いを理解した上で読んでください。
http://dixq.net/g/01_03.html
http://dixq.net/g/01_04.html

ゲームを作るうえで、LoadGraphScreenという関数を使うことはほぼありません。
なので、私もLoadGraphを使って説明します。


まず、以下のプログラムは理解できますか?
このプログラムが理解できないと話を進められないので、理解できないところがあれば言ってください。

戦闘機が、座標(0, 0)に、インベーダーが座標(50, 50)に描画されるはずです。
そして、ららら さんがやりたいことは、“プログラム実行中”に表示される画像を入れ替えることです。

コード:

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{          
	ChangeWindowMode(TRUE) ;
	
	if( DxLib_Init() == -1 ) {
		return -1;
	}

	int handle[2];
	
	handle[0] = LoadGraph("イラスト/戦闘機.bmp");
	handle[1] = LoadGraph("イラスト/インベーダー.bmp");

	for (int i = 0; i < 2; ++i) {
		DrawGraph(50 * i, 50 * i, handle[i], TRUE);
	}
	
	WaitKey();
	
	DxLib_End() ;
	
	return 0;
}

ららら

Re: qsortの使い方

#26

投稿記事 by ららら » 9年前

アドバイスありがとうございます 大変、嬉しいです
LoadGraphScreen描画関数のことですがテスト用なので簡単な方を選択して使っていました
コードが理解できるかの件ですがそれぐらいであれば理解できます
それと初心者なので分かりませんがi<2ではなくi<1ではないでしょうか? 分かりませんが・・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#27

投稿記事 by softya(ソフト屋) » 9年前

配列の添字の理解があやしいと思います。
LoadGraphScreen( 20 , test1[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
LoadGraphScreen( 20 , test1[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
は明らかに間違っています。何処が問題か分かりますか?

ららら さんが書きました:れと初心者なので分かりませんがi<2ではなくi<1ではないでしょうか? 分かりませんが・・・
i<1だと問題があります。
これはforループの基本動作の理解の問題ですので良く考えてみてください。

[追記]
らららさんの書いたコードだと表示座標は小さいものから大きな順にならびますが、画像は描画順番を入れ替えることはありませんが理解されていますか?

それとa5uaさんの書いたコードの handle[1] ってなんでしょうか?
出来るだけ正確にお答えください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#28

投稿記事 by ららら » 9年前

すいません 色々おかしいこと言ってました for文のことも狂ったようなこと言っていました
それと配列は0から始まるんでしたっけ じっと見つめていたら思い出しました

ごめんなさい 描画順が入れ替わらないことは理解していませんでした
どこをどう変えればいいのでしょう? 
構造体と関連付けをすることが鍵なのかなぁ~と思っていますがよく分かりません

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#29

投稿記事 by softya(ソフト屋) » 9年前

もうひとつの質問に答えていただいて良いですか?

[追記]
描画順番は先に書いたものから表示上は下になります。後で書いたものが上に重なると言うことですね。
なので、らららさんはy座標が大きいものから先に書きたいのか、小さいものから先に書きたいのか明確に出来ますでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#30

投稿記事 by ららら » 9年前

私はy座標が大きいものから描画したいです
並び替えは昇順でいいです・・・よね

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#31

投稿記事 by softya(ソフト屋) » 9年前

ららら さんが書きました:私はy座標が大きいものから描画したいです
並び替えは昇順でいいです・・・よね
そうすると、yが大きい物を下に描画ですがよろしいですね?

それと、らららさんが書いた下記の配列は、どの様に並び直るか書いてもらって良いですか?

コード:

    test test1[2] = {
    {40},
             {41}
    };
test1[0].yはxx
test1[1].yはxx
とお書きください。
それとa5uaさんの書いたコードの handle[1] ってなんでしょうか?
出来るだけ正確にお答えください。
もうひとつの質問に答えていただいて良いですか?
こちらの回答もお願いします。
意味もなく聞いているのではなくて全て理由があって質問しています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
a5ua
記事: 199
登録日時: 9年前

Re: qsortの使い方

#32

投稿記事 by a5ua » 9年前

次は、構造体を使った処理を考えましょう。
以下のプログラムでわからないところがあれば言ってください。

コード:

#include "DxLib.h"

// 位置と画像をまとめた構造体を定義
typedef struct
{
	int x:
	int y;
	int image;
} TEST;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{          
	ChangeWindowMode(TRUE) ;

	if( DxLib_Init() == -1 ) {
	    return -1;
	}

	// 要素数2個の配列
	TEST test[2];

	/* 配列のそれぞれの要素に値を設定する */
	
	test[0].x = 60;
	test[0].y = 50;
	test[0].image = LoadGraph("イラスト/戦闘機.bmp");

	test[1].x = 50;
	test[1].y = 60;
	test[1].image = LoadGraph("イラスト/インベーダー.bmp");
	
	/* 配列の要素を先頭から順に描画する */
	
	for (int i = 0; i < 2; ++i) {
	    DrawGraph(test[i].x, test[i].y, test[i].image, TRUE);
	}

	WaitKey();

	DxLib_End() ;
    
    return 0;
}
このプログラムの場合、test[0].image→test[1].imageの順番で描画されます。
そういうプログラムを書いたのだから、その順番をプログラム実行中に変更することは出来ません。

ですから、プログラム実行中に描画順を並び替えるには、

test[0] の中身:{60, 50, 戦闘機.bmpへの画像ハンドル}
test[1] の中身:{50, 60, インベーダー.bmpへの画像ハンドル}

となっているところを、

test[0] の中身:{50, 60, インベーダー.bmpへの画像ハンドル}
test[1] の中身:{60, 50, 戦闘機.bmpへの画像ハンドル}

という具合に、testという配列の要素を並び替えなければいけません。
いいですか?プログラム上で描画命令の順番を入れ替えるのではなく、
プログラム実行中に描画する要素を入れ替えるのです。
これを行うために、ソートという処理が必要になります。

ここまでは、理解できましたか?

ららら

Re: qsortの使い方

#33

投稿記事 by ららら » 9年前

>>それと、らららさんが書いた下記の配列は、どの様に並び直るか書いてもらって良いですか?
昇順ですから40→41と直ると思います

>>それとa5uaさんの書いたコードの handle[1] ってなんでしょうか?
イラスト/インベーダーが入っているint型の変数だと思います

ららら

Re: qsortの使い方

#34

投稿記事 by ららら » 9年前

a5uaさんの言っていること理解できました
関数を入れ替えるという表現が間違っていました すいません

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#35

投稿記事 by softya(ソフト屋) » 9年前

ららら さんが書きました:a5uaさんの言っていること理解できました
関数を入れ替えるという表現が間違っていました すいません
今までの私の話やa5uaさんの話が理解できたのでしたら、コードを書いてみてください。
分からないところがあったら聞いてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#36

投稿記事 by ららら » 9年前

一応、見よう見まねでやってみました
違っていましたら指摘してください

コード:


#include "DxLib.h"

        typedef struct{
	int x;
	int y;
	char *image;
	}test;

int comp( const void *c1, const void *c2);

// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{          
        ChangeWindowMode( TRUE ) ;

	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}
	
	
	test test1[2] = {
	{20,40,"イラスト/戦闘機.bmp"},
             {20,40,"イラスト/インベーダー.bmp"}
	};
	
	for (int i = 0; i < 2; i++) {
        LoadGraphScreen( test1[i].x , test1[i].y , test1[i].image , TRUE ) ;
        };
	
	qsort(test1,2,sizeof(test),comp);
	
	// 絵を打つ

	WaitKey() ;				// キー入力待ち

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;				// ソフトの終了 
}

int comp( const void *c1, const void *c2){
          test test2 = *(test *)c1;
          test test3 = *(test *)c2;

          int tmp1 = test2.y;   
          int tmp2 = test3.y;

          return tmp1 - tmp2;
}
ごめんなさい、メモリーに読み込むことは理解できていますが
今回はロードグラフスクリーンでやらせてもらいました

ららら

Re: qsortの使い方

#37

投稿記事 by ららら » 9年前

うーん・・・
いまコンパイルしましたがソートしてくれませんね・・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#38

投稿記事 by softya(ソフト屋) » 9年前

まず、問題点1。
y座標が同じなので意味が無いです。

問題点2。
softya(ソフト屋) さんが書きました:
ららら さんが書きました:私はy座標が大きいものから描画したいです
並び替えは昇順でいいです・・・よね
そうすると、yが大きい物を下に描画ですがよろしいですね?
この内容とコードで矛盾しているのですが分かりますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#39

投稿記事 by ららら » 9年前

数学座標とC座標がごちゃになっていたので言っていることがおかしかったです 反省します

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#40

投稿記事 by softya(ソフト屋) » 9年前

ららら さんが書きました:数学座標とC座標がごちゃになっていたので言っていることがおかしかったです 反省します
そうですね。
画面座標は上は小さく下は大きな値になります。(Cには座標系という定義はありません。これはDXライブラリが左上を(0,0)と定義しているからくる仕様です)
これは最初はよく間違えますので注意してください。特に画面が擬似3Dだったり本当の3Dだと凄まじく混乱します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#41

投稿記事 by ららら » 9年前

この2つの問題点を解決すれば正常にソートできると思いますでしょうか?

ららら

Re: qsortの使い方

#42

投稿記事 by ららら » 9年前

いえ、実はさっきから数をいじっているのですが
画像の表示順が変わらないのでどこか間違いがあるかなと思いまして・・・

アバター
a5ua
記事: 199
登録日時: 9年前

Re: qsortの使い方

#43

投稿記事 by a5ua » 9年前

LoadGraphScreenを呼び出して時点で、画像は描画されているので、
そのあとに、qsortを呼び出しても意味がありません。

プログラムは書いた順に実行されますから、
ソートして描画しなければ、値を初期化した後
・ソート
・描画
の順でプログラムを書かなければいけません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#44

投稿記事 by softya(ソフト屋) » 9年前

a5ua さんが書きました:LoadGraphScreenを呼び出して時点で、画像は描画されているので、
そのあとに、qsortを呼び出しても意味がありません。

プログラムは書いた順に実行されますから、
ソートして描画しなければ、値を初期化した後
・ソート
・描画
の順でプログラムを書かなければいけません。
一度説明したので、理解したと思って見逃していました。
らららさん、もう一度良く考えてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ららら

Re: qsortの使い方

#45

投稿記事 by ららら » 9年前

あわわわわ
たった今、自分には無謀だろうなと思っていたソートができました
信じられない・・・  あとはwhile(1)でゲーム用に改造すればいいんですよね  
これも一重に先輩方のおかげです  分かるまで何度も教授してくださったことに感謝します
私も先輩方のようになれるようにがんばります ありがとうございました

ららら

Re: qsortの使い方

#46

投稿記事 by ららら » 9年前

私の様な人がいるかもしれないのでソースを貼っておきます(綺麗ではないです)
なお降順になるよう修正をするのはまだしてません

コード:


#include "DxLib.h"

        typedef struct{
	int x;
	int y;
	char *image;
	}test;

int comp( const void *c1, const void *c2);

// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{          
        ChangeWindowMode( TRUE ) ;

	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}
	
	
	test test1[2] = {
	{20,41,"イラスト/戦闘機.bmp"},
        {-20,40,"イラスト/インベーダー.bmp"}
	};
	
	qsort(test1,2,sizeof(test),comp);
	
	for (int i = 0; i < 2; i++) {
        LoadGraphScreen( test1[i].x , test1[i].y , test1[i].image , TRUE ) ;
        };
	
	
	// 絵を打つ

	WaitKey() ;				// キー入力待ち

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;				// ソフトの終了 
}

int comp( const void *c1, const void *c2){
          test test2 = *(test *)c1;
          test test3 = *(test *)c2;

          int tmp1 = test2.y;   
          int tmp2 = test3.y;

          return tmp1 - tmp2;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: qsortの使い方

#47

投稿記事 by softya(ソフト屋) » 9年前

いえ、これで合ってますよ。
yの小さいほうが画面の奥になるのではありませんか?

あと、一度書きましたが件数次第ではqsortを使わないほうが速いこともあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る