C言語何でも質問掲示板


Total hit  今日  昨日  

必ずお読み下さい → 規約と注意事項  アンケートはこちら  エラーで投稿できない方はこちら  過去ログ検索はこちら

 
   画像のフェードについ ....   
     ・[53173] ookami 
     ・[53187] 深黒 
     ・[53190] ookami 
     ・[53197] Dixq (管理人) 
     ・[53237] 深黒 
     ・[53243] 深黒 
     ・[53245] ru 
     ・[53247] a 
     ・[53251] ookami 
     ・[53265] ねこ 
     ・[53267] 深黒 
   ブロック崩しを作りた ....   
     ・[53240] ru 
     ・[53241] softya 
     ・[53249] ハナブトオオトカゲ 
   質問です。   
     ・[53242] 匿名 
     ・[53248] yamataka 
   midファイルの音だけ鳴 ....   
     ・[53234] ookami 
     ・[53244] トロイカ 
   描画のサイズについて ....   
     ・[53229] シエル 
     ・[53232] たろう 
   簡単なサイコロの確率 ....   
     ・[53221] ドラ 
     ・[53223] ねこまねき 
   C言語でポーカーを作っ ....   
     ・[50668] ideyan 
     ・[50669] conio 
     ・[50676] box 
     ・[50677] ookami 
     ・[50678] たいちう 
     ・[50693] 南瓜 
     ・[50695] たいちう 
     ・[50697] 南瓜 
     ・[50728] ぽこ 
     ・[50742] たいちう 
     ・[50752] ookami 
     ・[50761] lbfuvab 
     ・[50822] ムンバ 
     ・[50833] box 
     ・[50841] 南瓜 
     ・[50845] 南瓜 
     ・[50848] たいちう 
     ・[50851] conio 
     ・[50852] 南瓜 
     ・[50853] conio 
     ・[50854] 南瓜 
     ・[50855] conio 
     ・[50856] 南瓜 
     ・[50857] conio 
     ・[50858] 南瓜 
     ・[50859] conio 
     ・[50872] 南瓜 
     ・[50914] ookami 
     ・[50915] たいちう 
     ・[50941] 南瓜 
     ・[50960] Ma 
     ・[50965] たいちう 
     ・[50970] 南瓜 
     ・[50971] たいちう 
     ・[50974] 南瓜 
     ・[50975] hoge 
     ・[50979] 南瓜 
     ・[50981] box 
     ・[50985] たいちう 
     ・[51041] 南瓜 
     ・[51076] たいちう 
     ・[51096] 南瓜 
     ・[51099] たいちう 
     ・[51110] 南瓜 
     ・[51111] conio 
     ・[51112] たいちう 
     ・[51215] 南瓜 
     ・[51231] たいちう 
     ・[51273] 南瓜 
     ・[51283] Ma 
     ・[51284] たいちう 
     ・[51316] 南瓜 
     ・[51317] たいちう 
     ・[51318] 南瓜 
     ・[51321] box 
     ・[51328] 南瓜 
     ・[51329] たいちう 
     ・[51331] Ma 
     ・[51332] 南瓜 
     ・[51333] たいちう 
     ・[51335] 南瓜 
     ・[51336] たいちう 
     ・[51412] 南瓜 
     ・[51418] たいちう 
     ・[51460] 南瓜 
     ・[51500] たいちう 
     ・[51501] box 
     ・[51542] 南瓜 
     ・[51548] たいちう 
     ・[51579] 南瓜 
     ・[51589] Ma 
     ・[51625] ムンバ 
     ・[51662] 南瓜 
     ・[51664] たいちう 
     ・[51789] 南瓜 
     ・[51806] Ma 
     ・[51815] たいちう 
     ・[51872] 南瓜 
     ・[51873] たいちう 
     ・[51901] 南瓜 
     ・[51911] たいちう 
     ・[51978] 南瓜 
     ・[51982] たいちう 
     ・[52003] 南瓜 
     ・[52006] たいちう 
     ・[52172] 南瓜 
     ・[52173] たいちう 
     ・[52177] 南瓜 
     ・[52183] たいちう 
     ・[52223] 南瓜 
     ・[52225] たいちう 
     ・[52227] 南瓜 
     ・[52228] たいちう 
     ・[52248] 南瓜 
     ・[52250] たいちう 
     ・[52254] 南瓜 
     ・[52256] たいちう 
     ・[52272] ookami 
     ・[52297] 南瓜 
     ・[52323] たいちう 
     ・[52360] 南瓜 
     ・[52368] たいちう 
     ・[52371] 南瓜 
     ・[52373] たいちう 
     ・[52500] 南瓜 
     ・[52504] たいちう 
     ・[52628] 南瓜 
     ・[52641] Ma 
     ・[52650] たいちう 
     ・[52751] 南瓜 
     ・[52752] たいちう 
     ・[52755] 南瓜 
     ・[52757] たいちう 
     ・[52772] 南瓜 
     ・[52956] 南瓜 
     ・[52986] ドラ 
     ・[53192] 南瓜 
     ・[53209] たいちう 
   斬られたときの振動の ....   
     ・[53167] Justy 
     ・[53181] ゆう 
     ・[53186] 組木紙織 
     ・[53205] ゆう 
     ・[53207] 組木紙織 
     ・[53208] 組木紙織 
     ・[531371275566684] ゆう 
   譜面データを読むとき ....   
     ・[53182] ookami 
     ・[53188] act 
     ・[53191] ookami 
     ・[53193] act 
     ・[53194] ookami 
     ・[53195] Dixq (管理人) 
     ・[53196] Dixq (管理人) 
     ・[53198] act 
     ・[53199] Dixq (管理人) 
     ・[53201] Libra 
     ・[53203] act 
   入力の処理でつまづい ....   
     ・[53163] Justy 
     ・[53202] オーシロ 
   変数の中身がおかしい   
     ・[53082] ぽこ 
     ・[53083] Justy 
     ・[53085] ひよこ 
     ・[53086] メタ 
     ・[53089] Justy 
     ・[53091] ひよこ 
     ・[53092] ひよこ 
     ・[53097] Justy 
     ・[53098] ひよこ 
     ・[53112] softya 
     ・[53122] ひよこ 
     ・[53138] たいちう 
     ・[53200] ひよこ 
   タイトル画面で一考   
     ・[53079] ookami 
     ・[53084] しろ 
     ・[53093] しろ 
     ・[53185] ookami 
   情報オリンピック予選 ....   
     ・[52664] toyo 
     ・[52665] たいちう 
     ・[52666] toyo 
     ・[52667] pon 
     ・[52668] pon 
     ・[52669] たいちう 
     ・[52685] pon 
     ・[52701] たいちう 
     ・[52787] pon 
     ・[52793] たいちう 
     ・[52796] pon 
     ・[52814] たいちう 
     ・[52908] pon 
     ・[52918] たいちう 
     ・[52970] pon 
     ・[52973] softya 
     ・[52989] たいちう 
     ・[53001] softya 
     ・[53005] たいちう 
     ・[53015] pon 
     ・[53033] たいちう 
     ・[53071] pon 
     ・[53094] たいちう 
     ・[53106] pon 
     ・[53113] たいちう 
     ・[53114] pon 
     ・[53116] たいちう 
     ・[53184] pon 
   C++のスコープについて ....   
     ・[53123] たかぎ 
     ・[53128] redhat98 
     ・[53136] たかぎ 
     ・[53171] redhat98 
     ・[53175] ぽこ 
     ・[53178] redhat98 
   整列関数で分からない ....   
     ・[53145] 先生さん 
     ・[53159] JJ 
     ・[53174] ドラ 
   c言語 リスト 配列   
     ・[53032] 組木紙織 
     ・[53034] asdf 
     ・[53037] 組木紙織 
     ・[53050] asdf 
     ・[53053] 組木紙織 
     ・[53055] asdf 
     ・[53057] 組木紙織 
     ・[53059] asdf 
     ・[53062] box 
     ・[53074] asdf 
     ・[53090] ドラ 
     ・[53095] asdf 
     ・[53100] 組木紙織 
     ・[53102] asdf 
     ・[53103] 組木紙織 
     ・[53105] asdf 
     ・[53109] 組木紙織 
     ・[53120] asdf 
     ・[53148] ドラ 
     ・[53151] asdf 
     ・[53166] 組木紙織 
     ・[53170] asdf 
   GetRand関数について   
     ・[53165] MNS 
     ・[53169] T.J 
   テキストファイルから ....   
     ・[53152] たかぎ 
     ・[53153] いむ 
     ・[53156] たかぎ 
     ・[53157] いむ 
     ・[53158] たかぎ 
     ・[53161] いむ 
   DXライブラリのメイン ....   
     ・[53129] Justy 
     ・[53135] たかぎ 
     ・[53139] ムンバ 
     ・[53146] たかぎ 
     ・[53160] ムンバ 
   跳ね返りができません ....   
     ・[53124] ru 
     ・[53127] Tatu 
     ・[53134] ハナブトオオトカゲ 
   図形の描画について   
     ・[53058] Justy 
     ・[53064] 夕暮 
     ・[53126] Libra 
   生年月日から(年齢) ....   
     ・[52826] ru 
     ・[52887] MK 
     ・[52925] たいちう 
     ・[52940] やんち 
     ・[53088] メタ 
     ・[53104] やんち 
     ・[53108] MK 
   描画輝度関数について   
     ・[53047] jay 
     ・[53099] papa 
   管理人さんへ 間違えた ....   
     ・[53067] Dixq (管理人) 
     ・[53087] ハナブトオオトカゲ 
   無題   
     ・[53073] box 
     ・[53075] Ryou 
     ・[53076] asdf 
     ・[53081] box 
     ・[530721276827459] sage 
     ・[530721276827547] sage 
   なぜこうなるのか   
     ・[53020] シエル 
     ・[53021] ハナブトオオトカゲ 
     ・[53028] メタ 
     ・[53029] シエル 
     ・[53031] メタ 
     ・[53068] Dixq (管理人) 

Name: 深黒  ..かけだし(1,102ポイント)   Date: 2010/05/31(月) 21:36   No:53172       
Title: 画像のフェードについて    
http://dixq.net/g/38.html
↑のページを参考にして、これを応用して画像を

黒→元画像
という風にフェードしながら表示できましたが、
白→元画像
という風に表示する事はできないでしょうか?


66ポイント を手に入れた。


Name: ookami  ..上級者(17,502ポイント)   Date: 2010/05/31(月) 21:46   No:53173     
Title: Re:画像のフェードについて    
SetDrawBrightでは元の画像より明るくすることはできないので、

SetDrawBlendMode(DX_BLENDMODE_NOBLEND,255);
DrawGraph(なにがし);
SetDrawBlendMode(DX_BLENDMODE_ALPHA,c);
DrawBox(0,0,640,480,GetColor(255,255,255),true);

とするのが良いと思います。


74ポイント を手に入れた。

Name: 深黒  ..かけだし(1,230ポイント)   Date: 2010/05/31(月) 23:01   No:53187     
Title: Re:画像のフェードについて    
返信ありがとうございます
おかげでやりたいことは出来るようになりましたが・・・

i=255;
while(i>0){
    i--;
    SetDrawBlendMode(DX_BLENDMODE_NOBLEND,255); 
    LoadGraphScreen(300,300, "使ってる画像" , TRUE );
    SetDrawBlendMode(DX_BLENDMODE_ALPHA,i); 
    DrawBox(300,300,410,436,GetColor(255,255,255),true);        
    ScreenFlip() ;
}
の処理の後、画面が真っ暗になってしまうのですが、どこかプログラムはおかしいでしょうか?


128ポイント を手に入れた。

Name: ookami  ..上級者(17,948ポイント)   Date: 2010/05/31(月) 23:11   No:53190     
Title: Re:画像のフェードについて    
ソースを見る限り問題はないので、ループの外で画面を真っ暗にしているのではないでしょうか?

ついでですが、LoadGraphScreenは毎回ディスクから読み込むので、ループの中で使用すると遅くなります。ループの前にLoadGraphしてループの中でDrawGraphするのが良いです。


125ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,194,987ポイント)   Date: 2010/05/31(月) 23:38   No:53197     
Title: Re:画像のフェードについて    
ループの中では必ずやるべき3大処理はきちんとやった方がいいですよ。

・画面の内容を消す
・メッセージ処理をする
・裏画面を反映する

書き方は上記リンク先の通りです。


81ポイント を手に入れた。

Name: 深黒  ..かけだし(1,257ポイント)   Date: 2010/06/01(火) 22:54   No:53237     
Title: Re:画像のフェードについて    
うーん、分からないです・・・
この画像のフェードの処理後、それ以降の動作をしなくなるようです・・・


27ポイント を手に入れた。

Name: 深黒  ..かけだし(1,505ポイント)   Date: 2010/06/02(水) 02:39   No:53243     
Title: Re:画像のフェードについて    
管理人さんの書き込みを意識するとこう言うことですかね・・・?

for(i=255;i>=0;i--){
    ClearDrawScreen();
    SetDrawScreen( DX_SCREEN_BACK ) ;
    SetDrawBlendMode(DX_BLENDMODE_NOBLEND,255); 
    DrawGraph(300,300, 画像 , TRUE );
    SetDrawBlendMode(DX_BLENDMODE_ALPHA,i); 
    DrawBox(300,300,410,436,GetColor(255,255,255),true);
    ScreenFlip() ;
}
whileをfor文にして、ClearDrawScreen();を足して、DrawGraphに変えただけですが・・・
なのでこの処理の後画面が真っ暗になります


248ポイント を手に入れた。

Name: ru  ..入門者(4,700ポイント)   Date: 2010/06/02(水) 03:14   No:53245     
Title: Re:画像のフェードについて    
#include "DxLib.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    ChangeWindowMode(TRUE);
    DxLib_Init();
    SetDrawScreen(DX_SCREEN_BACK);

    int cnt = 0;
    int GrHandle = LoadGraph("test.png");

    while(1)
    {
        // メッセージを処理する
        if(ProcessMessage() == -1 )
        {
            break;
        }
        if(CheckHitKey(KEY_INPUT_ESCAPE))
        {
            break;
        }
        // 画面の内容を消す
        ClearDrawScreen();

        DrawGraph(300, 300, GrHandle, FALSE);
        SetDrawBlendMode(DX_BLENDMODE_ALPHA, 255 - cnt % 255);
        DrawBox(300, 300, 410, 436, GetColor(255, 255, 255), TRUE);
        SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);

        cnt++;

        // 裏画面を反映する
        ScreenFlip();
    }

    DxLib_End();
}




2倍のポイントを手に入れた! 612ポイント を手に入れた。

Name: a  ..かけだし(1,336ポイント)   Date: 2010/06/02(水) 04:31   No:53247     
Title: Re:画像のフェードについて    
ruさんの回答を最近よく見かけますが、質問者さんに対して
もうちょっと"言葉"を書いて説明してあげたほうがいいですよ。
少しだけ私は不愉快に思いましたので。
説明の仕方が苦手だからという理由ならば何も言うことないですが。


107ポイント を手に入れた。

Name: ookami  ..上級者(18,250ポイント)   Date: 2010/06/02(水) 07:13   No:53251     
Title: Re:画像のフェードについて    
ループを抜けた後
SetDrawBlendMode(DX_BLENDMODE_NOBLEND,255);
とするとどうでしょうか?


23ポイント を手に入れた。

Name: ねこ  ..熟練のプログラマー(53,005ポイント)   Date: 2010/06/02(水) 12:32   No:53265     
Title: Re:画像のフェードについて    
<ruさんの回答を最近よく見かけますが、質問者さんに対して 
<もうちょっと"言葉"を書いて説明してあげたほうがいいですよ。 
<少しだけ私は不愉快に思いましたので。 
<説明の仕方が苦手だからという理由ならば何も言うことないですが。
そう思うなら補足レスしたら良いんじゃないでしょうか。
手間と時間をかけている回答者さんにROM専の人間がどうこう言うのもおかしな話だとROM専になった人間が言ってみます。


質問に関しては他の方もおっしゃってますが、フェード処理の外で何をしてるかですね。
問題が起こる部分だけを抜粋したWinMain関数の中を記述すると問題点が分かると思います。


204ポイント を手に入れた。

Name: 深黒  ..かけだし(1,593ポイント)   Date: 2010/06/02(水) 13:20   No:53267 解決!     
Title: Re:画像のフェードについて    
たくさんの方、返信ありがとうございました!!
SetDrawBlendMode(DX_BLENDMODE_NOBLEND,255);
と、ループの後に
SetDrawScreen( DX_SCREEN_FRONT ) ;が無かったことからエラーが出ていたようです・・・ 編集済み


2倍のポイントを手に入れた! 88ポイント を手に入れた。



Name: ハナブオオオトカゲ [URL]  ..かけだし(1,322ポイント)   Date: 2010/06/01(火) 22:55   No:53238       
Title: ブロック崩しを作りたい!    
#include "DxLib.h" 

typedef struct

    int x;
    int y;
    int dx;
    int dy;
    int r;
    int flag;
}ch_t; 
  
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(TRUE);
    DxLib_Init();
    SetDrawScreen(DX_SCREEN_BACK);

    ch_t ball;
    ball.x = 320;
    ball.y = 450;
    ball.dx = 0;
    ball.dy = 0;
    ball.r = 10;
    ball.flag = 0;

    int bx = 270;
    int by = 460;
    int blong=100;
    int color = GetColor(255, 255, 255);
    char key[256];
    int start = 0;
    int ballmax=0,wcount=0,scount=0; //scountはスペースを連打することでボールが変な動きをしないようにするため ballmaxはボール個数制限
    

    while(ProcessMessage() != -1)
    { 
        ClearDrawScreen();
        GetHitKeyStateAll(key);
    SetDrawBright( 255 , 255 , 255 );
    

    
        if(key[KEY_INPUT_ESCAPE])
        {
            break;
        }

        // 発射
        if(key[KEY_INPUT_SPACE]&&ballmax==0&&m==0)
        {
            ball.flag=1;
            ball.dx = 8;
            ball.dy = -8;
        scount=1;
        }
        // バー移動
        if(key[KEY_INPUT_RIGHT])
        {
            bx += 8;
        }
        if(key[KEY_INPUT_LEFT])
        {
            bx -= 8;
        }
        // バー移動範囲
        if(bx > 640-blong)
        {
            bx = 640-blong;
        
        }
        if(bx < 0)
        {
            bx = 0;
        
        }
    //特殊効果 Iキーでバーの長さを伸ばす
    if(key[KEY_INPUT_I]==1) blong=200;
    //再発射
    if(key[KEY_INPUT_R]==1&&ball.y>480&&ballmax<3){
        ball.flag=1;
            ball.dx = 8;
            ball.dy = -8;
        ball.x=bx+blong/2;
        ball.y=460;
        wcount=0;
        
            }
    //特殊効果 XとY同時押しでボール数リセット
    if(key[KEY_INPUT_X]==1&&key[KEY_INPUT_Y]==1){
        ballmax=0;
        SetDrawBright( 255 , 255 , 0 );
        } 
        // ボールの移動
        if(ball.flag==1)
        {
            // 移動距離計算
            ball.x += ball.dx;
            ball.y += ball.dy;
            // 移動範囲
            if(ball.x < 5 || ball.x > 640 - 5)
            {
                ball.dx *= -1;
            }
            if(ball.y < 0)
            {
                ball.dy *= -1;
            }
            if(by <= ball.y && by + 10 >= ball.y && bx <= ball.x && bx + blong >= ball.x)
            {
                ball.dy *= -1;
            }
        
        }
        if(ball.y>470&&wcount==0){ballmax+=1; wcount=1;}
        DrawBox(bx, by, bx + blong, by + 10, color, TRUE); // バー絵画
        DrawCircle(ball.x, ball.y, ball.r, color, TRUE); // ボール絵画

    DrawFormatString(0,0,color,"ボール残り%d",3-ballmax);//ボール残り数表示
    if(ballmax>0) DrawString(0,20,"Rキーで再発射",color);//再発射方法表示
        ScreenFlip();
    }

    DxLib_End();
    return 0;
}

                                         


こんな感じで、ボールの跳ね返りといくつかの裏ワザ(?)のようなものをつくりました。

これを利用して、ブロック崩しは作れますか?

多分、配列を利用してブロックを作るのでしょうが、詳しくどんな感じで作るのか教えてください。

ちなみに、DXライブラリ歴約1週間くらいでゲーム作成初級編のαブレンドのところ(最後の方)までできます。

もし、新しい知識がまだ必要なら何が必要か教えてください。

ちなみに、初級編の物理のところは、管理人さんもリアルな表現をしたいときに使うだけとのことと、僕が中2ということでやらなくてもいいとのことなので、やっていません。

お願いします。                     編集済み


1,322ポイント を手に入れた。


Name: ru  ..入門者(4,088ポイント)   Date: 2010/06/02(水) 00:22   No:53240     
Title: Re:ブロック崩しを作りたい!    
>これを利用して、ブロック崩しは作れますか?
作れる
>多分、配列を利用してブロックを作るのでしょうが、詳しくどんな感じで作るのか教えてください。
調べた?考えた?






94ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(173,336ポイント)   Date: 2010/06/02(水) 01:21   No:53241     
Title: Re:ブロック崩しを作りたい!    
こちらの段階的学習の何レベル目まで自分で作れますか?
http://wiki.game-develop.com/index.php?%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%2F%BD%E9%BF%B4%BC%D4%B8%FE%A4%B1%2F%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB%2F%C3%CA%B3%AC%C5%AA%B3%D8%BD%AC%2F%A5%D6%A5%ED%A5%C3%A5%AF%CA%F8%A4%B7%A4%F2%BA%EE%A4%EC


86ポイント を手に入れた。

Name: ハナブトオオトカゲ  ..かけだし(2,371ポイント)   Date: 2010/06/02(水) 05:53   No:53249 解決!     
Title: Re:ブロック崩しを作りたい!    
ありがとうございました。

次に何をしたらいいかわからなかったので質問しました。

ブロックを表示 → 当たり判定 → ブロックを消す → ゲームオーバーを作る → ゲームクリアを作る

でとりあえず自力でやってみます。

もし考えても出来なかったらまた質問させていただきますので、その時はよろしくお願いします。


63ポイント を手に入れた。



Name: yamataka  ..ぴよぴよ(445ポイント)   Date: 2010/06/01(火) 20:36   No:53233       
Title: 質問です。    
東方のゲーム(ダブルスポイラーまでの)で背景以外に3Dが使われている所ってありますか?

2倍のポイントを手に入れた! 68ポイント を手に入れた。


Name: 匿名  ..上級者(21,400ポイント)   Date: 2010/06/02(水) 01:34   No:53242     
Title: Re:質問です。    
背景、というと、
メイン画面のところのみを指してるんですよね?

見たところ、恐らくその部分のみでしょう。


40ポイント を落としてしまった。

Name: yamataka  ..ぴよぴよ(459ポイント)   Date: 2010/06/02(水) 05:36   No:53248 解決!     
Title: Re:質問です。    
はい、メイン画面です。

ありがとうございます。


14ポイント を手に入れた。



Name: トロイカ  ..ぴよぴよ(809ポイント)   Date: 2010/06/01(火) 18:19   No:53226       
Title: midファイルの音だけ鳴らない    
DXライブラリファイルにある「サンプルプログラム実行用フォルダ」を使って
ゲームプログラミングの館の入門サイトにてサンプルプログラムを実行しながら遊んでますが、
15. 音楽を流す。でつまっています。

PlaySound( "test.wav" , DX_PLAYTYPE_BACK ) ; //test.wavのバックグラウンド演奏
は音が鳴ります。
ところが
 PlayMusic( "test.mid" , DX_PLAYTYPE_BACK ) ; // test.midのバックグラウンド演奏
の音が鳴りません。

midファイル、wavファイルは当然同じフォルダに入っています。

ためしにmidファイルをwindows media playerで鳴らしてみましたが、
ちゃんと音は鳴ります。

virtual studio 2008にてプログラムを実行しています。

midファイルだけなぜ音が鳴らないのでしょうか?



276ポイント を手に入れた。


Name: ookami  ..上級者(18,227ポイント)   Date: 2010/06/01(火) 21:08   No:53234     
Title: Re:midファイルの音だけ鳴らない    
分かりませんが、mid音源の音量がゼロになっているってことはありませんか?

私の環境では、添付ファイルの「SWシンセサイザ」がそれにあたります。

Windows Media Player は、勝手にこの設定値を変更してくれちゃうために鳴っている可能性があります。


90ポイント を手に入れた。

Name: トロイカ  ..ぴよぴよ(837ポイント)   Date: 2010/06/02(水) 02:54   No:53244 解決!     
Title: Re:midファイルの音だけ鳴らない    
まさにご明察><;
音鳴りました。
おはずかしい・・
ありがとうございました。


28ポイント を手に入れた。



Name: たろう  ..上級者(21,450ポイント)   Date: 2010/06/01(火) 18:44   No:53227       
Title: 描画のサイズについて。    
DirectXで画像を出力しようとしたのですが、元のサイズではなく少し拡大された状態で出力されます。
元のサイズで出力したいのですが、どうすればよいでしょうか。
ソース載せます。
</pre>#include<windows.h>
#include<stdio.h>
#include <d3dx9.h>
#pragma comment( lib, "d3dx9.lib") 
#pragma comment( lib, "d3d9.lib" )
    LPD3DXSPRITE            g_pD3DXSprite = NULL;
    LPDIRECT3DTEXTURE9      g_pD3DTexture = NULL;
    char g_SpriteFileName[MAX_PATH] = "test.png";
    WIN32_FIND_DATA    FindFileData;
    BYTE* data; 
    HRESULT hr;
    LPDIRECT3D9    m_pD3D;
    IDirect3DDevice9* g_pD3DDevice=NULL;
    LPDIRECT3D9                g_pD3D            = NULL; // Direct3Dインターフェイス
    FILE *fp;
    D3DDISPLAYMODE dmode;
    D3DPRESENT_PARAMETERS    g_D3DPP;                // D3DDeviceの設定(現在)

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam)
{
    HRESULT hr = S_OK;

    switch(msg)
    {

    case WM_DESTROY:
        // ウインドウを閉じる
        PostQuitMessage(0);
        return 0;
    }
    // デフォルト処理
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInst,LPSTR lpCmdLine,int nShowCmd)
{


    WNDCLASSEX wc;
    HWND hWnd;

    wc.cbSize=sizeof(WNDCLASSEX);
    wc.style =0;
    wc.cbClsExtra=0;
    wc.cbWndExtra=32;
    wc.lpfnWndProc=MainWndProc;
    wc.hInstance =hInstance;
    wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wc.hIconSm =LoadIcon(NULL,IDI_WINLOGO);
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName=NULL;
    wc.lpszClassName="gamemain";


    if (!RegisterClassEx(&wc))
        return -1;
    hWnd = CreateWindow("gamemain", "ant",
        WS_OVERLAPPEDWINDOW,
            0, 0, 640, 480,
            NULL, NULL, hInstance, NULL);
    if(hWnd==NULL)
    {
        return -1;
    }
    ShowWindow(hWnd,nShowCmd);
    UpdateWindow(hWnd);
    
    D3DCAPS9 Caps; // 能力を受け取るD3DCAPS9構造体
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if (g_pD3D == NULL)
        return -1 ;

    hr = g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Caps);
    if (FAILED(hr))
    {


        hr = g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, &Caps);
        if (FAILED(hr) )
            return -1;
    }

    // 現在のディスプレイのフォーマットなどを取得しておく
    hr = g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dmode);
    if (FAILED(hr))
        return -1;
        ZeroMemory(&g_D3DPP, sizeof(g_D3DPP));
    g_D3DPP.BackBufferCount            = 1;
    g_D3DPP.SwapEffect                = D3DSWAPEFFECT_DISCARD;
    g_D3DPP.hDeviceWindow                = hWnd;
    g_D3DPP.Windowed                    = TRUE;
    g_D3DPP.PresentationInterval        = D3DPRESENT_INTERVAL_IMMEDIATE;

    hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
                        D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice);
    if (FAILED(hr))
    {
        hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
                        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice);
        if (FAILED(hr))
            return -1;
    }


// その他のフォーマットを調べる(なし)



 
    if((fp=fopen("test1.bmp","r+b"))==NULL)
    {
        return -1;
    }
    FindFirstFile("*.bmp",&FindFileData);
    data=(BYTE*)malloc((size_t)(FindFileData.nFileSizeLow));
    fread(data,FindFileData.nFileSizeLow,1,fp);
    
    fclose(fp);
    if( FAILED(D3DXCreateTextureFromFileInMemory(g_pD3DDevice,data,FindFileData.nFileSizeLow,&g_pD3DTexture)))
        return -1; 

       // スプライト生成
    if( FAILED(D3DXCreateSprite(g_pD3DDevice, &g_pD3DXSprite)))
    {
        return -1; 
    }

    MSG msg;
    do
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
             g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0.5f, 0 );

            if( SUCCEEDED( g_pD3DDevice->BeginScene() ) )
            {
                g_pD3DXSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DONOTSAVESTATE);
                g_pD3DXSprite->Draw(g_pD3DTexture,NULL,NULL,NULL,0xffffffff);
                g_pD3DXSprite->End();

                g_pD3DDevice->EndScene();
                g_pD3DDevice->Present(NULL,NULL,NULL,NULL);
            }
        }

    } while (msg.message != WM_QUIT);

    return 0;
}</pre>


1,272ポイント を手に入れた。


Name: シエル  ..ぴよぴよ(987ポイント)   Date: 2010/06/01(火) 18:58   No:53229     
Title: Re:描画のサイズについて。    
D3DXCreateTextureFromFileInMemoryではサイズが2のべき乗に調整されるので、
下記のD3DXCreateTextureFromFileInMemoryExを使って、直接画像サイズを
指定してください。
その際、FilterとMipFilterにはD3DX_FILTER_NONEを設定して下さい。
http://msdn.microsoft.com/ja-jp/library/cc372744.aspx


99ポイント を手に入れた。

Name: たろう  ..上級者(21,467ポイント)   Date: 2010/06/01(火) 19:56   No:53232 解決!     
Title: Re:描画のサイズについて。    
おかげで表示できるようになりました。ありがとうございました!

17ポイント を手に入れた。



Name: ねこまねき  ..ぴよぴよ(18ポイント)   Date: 2010/06/01(火) 15:57   No:53215       
Title: 簡単なサイコロの確率計算    
初めて投稿させていただきます。
下記のプログラムをDXを使って書いてみたのですが
どうしても、数字が重なって表示されてしまいます。
原因がわからないので質問させていだきました。
質問の仕方もこれでいいのか自信がないレベルなのですが
よろしくお願いします。

OS:WindowsXP HomeEdition  
VisualC++2008ExpressEdition 

#include "DxLib.h"
 
char Key[256];
 

        int MouseInput,White,saikoro,i;
        int    kaku[5],saiko[5];
        int sousu,gyou=15;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理



        SetMouseDispFlag( TRUE ) ;
        SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定
        MouseInput = GetMouseInput() ;
        White   = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
 


/////////////////////////////////////////////////////////////////

        while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] && (MouseInput & MOUSE_INPUT_RIGHT ) == 0){
              //↑メッセージ処理         ↑画面をクリア           ↑キーボード入力状態取得      ↑ESCが押されていない


            // マウスの入力を得る
            MouseInput = GetMouseInput() ;

            saikoro=GetRand(6)+1;
            
            sousu++;//サイコロの振った回数


            for(i=0;i<6;i++){
                if(saikoro==i+1){saiko[i]++;}
                kaku[i]=saiko[i]/sousu;//
            }
            
            /////////////


            DrawString(0,0, "右クリックで終わります6", White);//文字列表示
            DrawFormatString(50, 50, White , "サイコロの出た数字%d(1から6まで)", saikoro);//文字列表示
            for( int me = 1; me < 7; me ++ ){          
                DrawFormatString(50, gyou*me+65, White , "%dが出た回数%d回", me,saiko[me-1]);//文字列表示
                DrawFormatString(200, gyou*me+65, White , "統計%d%", kaku[me-1]);//文字列表示
            }        
            DrawFormatString(50,gyou*8+65 , White , "サイコロを振った回数%d", sousu);//文字列表示
            
             ScreenFlip();//裏画面を表画面に反映

        }
 
        DxLib_End();
        return 0;
編集済み


18ポイント を手に入れた。


Name: ドラ  ..初心者(5,867ポイント)   Date: 2010/06/01(火) 17:39   No:53221     
Title: Re:簡単なサイコロの確率計算    
>どうしても、数字が重なって表示されてしまいます。
数字が重なるとか言う前に、バグっていますよ?

>int    kaku[5],saiko[5]; 
配列の要素数が足りません。

>saikoro=GetRand(6)+1; 
個人的にとても気持ち悪いのですが、DXライブラリのGetRand()は
GetRand(6)だと、0〜6の値を返して来ます。
と言う事でここもおかしいですね。

>kaku[i]=saiko[i]/sousu;
確率を%単位で出したいなら先に100倍しておかないとダメですね。
 


152ポイント を手に入れた。

Name: ねこまねき  ..ぴよぴよ(61ポイント)   Date: 2010/06/01(火) 17:52   No:53223     
Title: Re:簡単なサイコロの確率計算    
相談して良かったです。
初心者なので、質問するのも緊張しました。
助かりました、ありがとうございました。


> >どうしても、数字が重なって表示されてしまいます。
> 数字が重なるとか言う前に、バグっていますよ?

> >int    kaku[5],saiko[5]; 
> 配列の要素数が足りません。

> >saikoro=GetRand(6)+1; 
> 個人的にとても気持ち悪いのですが、DXライブラリのGetRand()は
> GetRand(6)だと、0〜6の値を返して来ます。
> と言う事でここもおかしいですね。

> >kaku[i]=saiko[i]/sousu;
> 確率を%単位で出したいなら先に100倍しておかないとダメですね。
>  




43ポイント を手に入れた。



Name: 南瓜  ..初心者(5,734ポイント)   Date: 2010/04/15(木) 00:23   No:50666       
Title: C言語でポーカーを作っているんですが その2    
一応、解決!を押してしまったので続きを新たに立てました
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main (void) {
    char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
    int i;
    int n_hand[5];/*5枚の数字の手札*/
    
    srand(time(NULL));
    printf("[ポーカー]\n");
    printf("あなたの手札は\n");
    
    for(i = 0; i < 5; i++) {/* 五枚のカードをrandで決定 */ 
        n_hand[i]= rand() % 13 + 1;/*数字を出す*/
    }
    for(i = 0; i < 5;  i++) {
        printf("%s ",  n_hand[5]);/* 五枚のカードを表示 */ 
    }
    
    printf("\n");
    return 0;
}

これを実行すると何回やってもA A A A Aしか実行されません
恐らく最初のfor文の所がおかしいと思うんですが、どうでしょうか?
(やっぱり配列の所の書き方が悪いんだと思うんですが)


367ポイント を手に入れた。


Name: ideyan  ..入門者(3,913ポイント)   Date: 2010/04/15(木) 00:40   No:50668     
Title: Re:C言語でポーカーを作っているんですが その2    
>printf("%s ",  n_hand[5]);/* 五枚のカードを表示 */ 

iが関係なくなっている上に配列の添字の範囲をオーバーしています。
(int n_hand[5];なら添字は0〜4ですよね?)


75ポイント を手に入れた。

Name: conio  ..比類無きプログラマー(84,368ポイント)   Date: 2010/04/15(木) 00:41   No:50669     
Title: Re:C言語でポーカーを作っているんですが その2    
以前も指摘されていましたが、要素が5の配列の添え字の範囲は
0〜4までです。 5はありません。

------------------------------------------------------------
    for(i = 0; i < 5;  i++) {
        printf("%s ",  n_hand[5]);/* 五枚のカードを表示 */ 
    }
------------------------------------------------------------
それとこのfor文ですが、
5回 n_hand[5]の値を表示しているだけなので当然 値は変わりません。


あとint型の値を表示したいのであれば、printf関数で指定するのは%dです。
%sではありません。

【追記】
もしかすると、
-------------------------------------
5つの値を表示したい場合は、n_hand[5]
2つの値を表示したい場合は、n_hand[2]
-------------------------------------
と指定すればよい、というイメージを持ってますか?

それは間違いです。

ゲームを作成する前に、基本の構文や配列の使い方などを
入門書などで確認するべきだと思います。 編集済み


225ポイント を手に入れた。

Name: box  ..ハッカー(152,046ポイント)   Date: 2010/04/15(木) 10:01   No:50676     
Title: Re:C言語でポーカーを作っているんですが その2    
最終的に出力したいのは、"A"〜"K"、つまり、number[0]〜number[12]の
いずれかですよね?
どれを出力したいか、つまり、number[]の添字の値が
n_hand[]に入ることになります。
number[n_hand[i]]
という書き方です。

rand()の値を13で割った後、1を足しているのは余分です。
なぜなら、rand() % 13 の結果は0〜12のいずれかであり、
それに1を加えると1〜13のいずれかとなり、number[]の定義範囲を
超えてしまう場合があります(13のとき)。

"A"が[0]、"K"が[12]という風に、手札の数字と配列添字の値が
1つずれているのがいやであれば、
rand() % 13 + 1
はそのままにしておいて、number[]の先頭(number[0])に
ダミーの要素を加えるとよいでしょう。
そうすると、配列定義はnumber[14]で、手札として使う範囲は
number[1]〜number[13]となり、手札の数字と添字の値が一致して
わかりやすくなるでしょう。


2倍のポイントを手に入れた! 520ポイント を手に入れた。

Name: ookami  ..入門者(3,119ポイント)   Date: 2010/04/15(木) 10:19   No:50677     
Title: Re:C言語でポーカーを作っているんですが その2    
横から失礼します。

南瓜さんの理解度を知りたいのですが、以下のソースコードを読んで(実行せずに)、どのような出力になるか予想してみてもらえますか?
まずは int 配列に絞ってます。

■例1
int arr[3];
arr[0]=100;
arr[1]=101;
arr[2]=102;
printf("%d ",arr[0]);
printf("%d ",arr[1]);
printf("%d ",arr[2]);

■例2
int arr[3];
arr[0]=10;
arr[1]=11;
arr[2]=12;
i=1;
printf("%d ",arr[i]);

■例3
int i;
for(i=0;i<3;i++) {
   printf("%d ",i);
}

■例4
int i;
for(i=0;i<3;i++) {
   printf("%d ",arr[i]);
}


237ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(72,092ポイント)   Date: 2010/04/15(木) 10:20   No:50678     
Title: Re:C言語でポーカーを作っているんですが その2    
【一応前スレ】
http://www.play21.jp/board/formz.cgi?action=res&resno=50232&page=&id=dixq&rln=50642


> 【追記】
> もしかすると、
> -------------------------------------
> 5つの値を表示したい場合は、n_hand[5]
> 2つの値を表示したい場合は、n_hand[2]
> -------------------------------------
> と指定すればよい、というイメージを持ってますか?

> それは間違いです。

> ゲームを作成する前に、基本の構文や配列の使い方などを
> 入門書などで確認するべきだと思います。

そうなんですよね。
配列の使い方について、No.50638よりも後退してしまってます。


61ポイント を落としてしまった。

Name: 南瓜  ..初心者(5,962ポイント)   Date: 2010/04/15(木) 18:11   No:50693     
Title: Re:C言語でポーカーを作っているんですが その2    
何度も同じ指摘すみませんm(_ _)m
n_hand[5]でn_hand[1]なら値は0、h_hand[2]なら値は1、……n_hand[5]なら値は4ってことですよね?
なのにfor(i = 0; i < 5;  i++)でi < 5と書いているのが間違っていると
> printf("%s ",  n_hand[5]);
の部分のn_hand[5]にしていた理由は、[i]にしていると
コンパイルして実行するとずっとBus Errorが出るので,
Bus Errorの出ない[5]にしてました
原因はint型なのにずっと%sにしてたのが原因だと指摘され気づきました

次に、ookamiさんの
例1がint arr[3]; で箱を3つ用意して、arr[0]=100; arr[1]=101; arr[2]=102;と 宣言されているので
100,101,102と出力されると思います
例2が例1同じようになっていますが、i=1と宣言されているので
11が出力されると思います
例3は0から3未満まで増え続けるので
0,1,2と出力されると思います
例4は例3と同じようにarr[0],arr[1],arr[2]と出力されると思います


228ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(72,935ポイント)   Date: 2010/04/15(木) 18:23   No:50695     
Title: Re:C言語でポーカーを作っているんですが その2    
> n_hand[5]で n_hand[1]なら値は0、h_hand[2]なら値は1、……n_hand[5]なら値は4ってことですよね?

何を言っているのか判りません。


> なのにfor(i = 0; i < 5;  i++)でi < 5と書いているのが間違っていると 

i < 5 は間違いではないですよ。


> コンパイルして実行するとずっと Bus Errorが出るので,
> Bus Errorの出ない[5]にしてました

原因を確かめずにその場しのぎで直すのはよくないことです。


もう一度書きますが、前スレのNo.50638を参考にして、No.50666を直してみてください。


90ポイント を手に入れた。

Name: 南瓜  ..初心者(6,222ポイント)   Date: 2010/04/15(木) 19:06   No:50697     
Title: Re:C言語でポーカーを作っているんですが その2    
boxさんの指摘は、後回しにして先にたいちうさんの指摘から直します
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main (void) {
    char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/

    int i;
    int n_hand[5];/*5枚の数字の手札*/

    srand(time(NULL));
    printf("[ポーカー]\n");
    printf("あなたの手札は\n");
    
    for(i = 0; i < 5; i++) {/* 五枚のカードをrandで決定 */ 
        n_hand[i]= rand() % 13 + 1;/*数字を出す*/

    }
    for(i = 0; i < 5;  i++) {
        printf("%d ",  n_hand[i]);/* 五枚のカードを表示 */ 
    }
    
    printf("\n");
    return 0;
}

No.50638を参考に書き直しました。実行しても問題なく?出力されました


260ポイント を手に入れた。

Name: ぽこ  ..初心者(8,335ポイント)   Date: 2010/04/16(金) 01:01   No:50728     
Title: Re:C言語でポーカーを作っているんですが その2    
んでは次に、No:50245でたいちうさんがおっしゃっていた仕様

>【新しい仕様】 
>1.forループでカードを配ります(randで数字とスートを決定するということ)。 
>2.5枚のカードを配り終えてから、その5枚のカードを表示します。 

の1.の部分をやり遂げてみては?
まだスートの決定をやっていませんよね?


106ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(72,948ポイント)   Date: 2010/04/16(金) 08:49   No:50742     
Title: Re:C言語でポーカーを作っているんですが その2    
スートを実装してもよいですし、
折角用意しているnumberの配列を使って、
AとかKとか表示できるようにしてもよいでしょう。

No.50676でBoxさんが書いていることを理解する必要があります。


13ポイント を手に入れた。

Name: ookami  ..入門者(3,594ポイント)   Date: 2010/04/16(金) 12:34   No:50752     
Title: Re:C言語でポーカーを作っているんですが その2    
おkです。

あと、

int arr[3];
arr[0]=100;
arr[1]=101;
arr[2]=102;
printf("%d ",arr[-1]); // @
printf("%d ",arr[3]); // A

@、Aのようにするとインデックスが範囲外なので、何が表示されるかは不定ですね。この点で、冒頭の、n_hand[5]が間違っているのはideyanさんもご指摘の通りです。

次は文字列と配列について。[1]〜[7]で出力される内容を予想してみてもらえますか?

char *st="A";
printf("%s ",st); // [1]

char *stArr[3]={"A","B","C"};
printf("%s ",stArr[0]); // [2]
printf("%s ",stArr[1]); // [3]
printf("%s ",stArr[2]); // [4]

int i,j;
i=1;
printf("%s ",stArr[i]); // [5]

int arr[3];
arr[0]=1;
arr[1]=2;
arr[2]=0;
i=arr[1];
printf("%d %s ",i,stArr[i]); // [6]

for(j=0;j<3;j++) {
    i=arr[j];
    printf("%d %s ",i,stArr[i]); // [7]
}


403ポイント を手に入れた。

Name: lbfuvab  ..プログラマー(25,476ポイント)   Date: 2010/04/16(金) 16:56   No:50761     
Title: Re:C言語でポーカーを作っているんですが その2    
キツイ言い方になりますが、一度入門書を読み直して配列を使った簡単なプログラムを組む事を勧めます。

どうも配列の取り扱いが慣れていない様に感じます。


61ポイント を手に入れた。

Name: ムンバ  ..プログラマー(33,166ポイント)   Date: 2010/04/18(日) 03:01   No:50822     
Title: Re:C言語でポーカーを作っているんですが その2    
こんばんはっ!

number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
(前後のソース等々、略させて頂きます。)

number[0] → A
number[1] → 2
number[2] → 3
number[3] → 4
number[4] → 5
number[5] → 6
number[6] → 7
number[7] → 8
number[8] → 9
number[9] → 10
number[10] → J
number[11] → Q
number[12] → K

です。

>何度も同じ指摘すみませんm(_ _)m 
>n_hand[5]でn_hand[1]なら値は0、h_hand[2]なら値は1、……n_hand[5]なら値は4ってことですよね?
  ↑これは一時、忘れて下さい。

n_hand[5] = {"A","2","3","Q","K"};/*カードの番号*/
だとしますと
カードは「"Aのカード","2のカード","3のカード","Qのカード","Kのカード"」
で、5枚のカードが用意されました。

n_hand[5] = {"A","2","3","Q","K"};/*カードの番号*/

で、この5枚のカードが、南瓜さんのソースで用意されたとします。
この5枚の用意されたカードを、何かの理由があって
南瓜さんが{"A","2","3","Q","K"}の値を呼び出したいとすると

"A" を呼び出したい時は n_hand[0](添え字 0 )
"2" を呼び出したい時は n_hand[1](添え字 1 )
"3" を呼び出したい時は n_hand[2](添え字 2 )
"Q" を呼び出したい時は n_hand[3](添え字 3 )
"K" を呼び出したい時は n_hand[4](添え字 4 )

誤字脱字があれば、ご容赦下さい。

ookamiさん(No:50752 )の、お答えが自分勝手に気になってます。^^;
南瓜さん!お時間あれば、もう一息お願いします。<(_ _)> 

---↓編集・追記---
boxさんへ(上から、すみません。<(_ _)>)
了解です。余計な事を書いてしまいました。
混乱してしまったら申し訳御座いません。 編集済み


655ポイント を手に入れた。

Name: box  ..ハッカー(152,177ポイント)   Date: 2010/04/18(日) 09:44   No:50833     
Title: Re:C言語でポーカーを作っているんですが その2    
> n_hand[5] = {"A","2","3","Q","K"};/*カードの番号*/

n_handは、乱数で定める1〜13の数値です。
上のように書いちゃうと、質問者さんがますます混乱しそうです。
って、もう見てないかもしれないけど。


36ポイント を手に入れた。

Name: 南瓜  ..初心者(6,411ポイント)   Date: 2010/04/18(日) 12:40   No:50841     
Title: Re:C言語でポーカーを作っているんですが その2    
ちょっと忙しかったので返信してなかったらこんなに返信が!
先にookamiさんから
[1]はAが出力されて、[2][3][4]はstArr[0][1][2]は順にA,B,Cが順に出力されると思います
[5]はi = 1なので、stArr[1]でBが出力されると思います
[6]はi = arr[1]なので、arr[1]と2が出力されると思います
[7]は1 arr[0]、2 arr[1]、0 arr[2]が順に出力されると思います
他の返信はまた後で返信します


189ポイント を手に入れた。

Name: 南瓜  ..初心者(6,896ポイント)   Date: 2010/04/18(日) 13:35   No:50845     
Title: Re:C言語でポーカーを作っているんですが その2    
boxさんの指摘にあったrandの所を修正しました
int main (void) {
    char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
    char *mark[4] = {"♥","♦","♠","♣"};/*カードのマーク*/

    int i;
    int n_hand[5];/*5枚の数字の手札*/
    int m_hand[5];/*5枚のマークの手札*/

    srand(time(NULL));
    printf("[ポーカー]\n");
    printf("あなたの手札は\n");
    
    for(i = 0; i < 5; i++) {/* 五枚のカードをrandで決定 */ 
        n_hand[i]= rand() % 13;/*数字を出す*/
        m_hand[i] = rand() % 4;/*マークを出す*/

    }
    for(i = 0; i < 5;  i++) {
        printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);/* 五枚のカードを表示 */ 
    }
    printf("\n");

これをコンパイルして実行するとマークと数字両方ともちゃんと出力されるようになりました
で、次の仕様の5枚再表示ですが、ただ単にprintf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);
を書き足してもsegmentation faultが出る事ので、調べたらstrcpy関数を使うのかな?と思ったんですが
「s2が指す文字列を、s1が指す配列にコピーする」とあるので、
markとnumber2つの配列をコピーできるかどうかわからず困っております


485ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(73,499ポイント)   Date: 2010/04/18(日) 13:49   No:50848     
Title: Re:C言語でポーカーを作っているんですが その2    
> で、次の仕様の5枚再表示ですが、ただ単にprintf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);
> を書き足してもsegmentation faultが出る事ので、調べたらstrcpy関数を使うのかな?と思ったんですが

配列のコピーは必要無いですよ。
どうやったのですか?
segmentation faultの原因を理解しないまま迷走しているように思われますが。


39ポイント を手に入れた。

Name: conio  ..比類無きプログラマー(86,438ポイント)   Date: 2010/04/18(日) 14:13   No:50851     
Title: Re:C言語でポーカーを作っているんですが その2    
>>printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]); を書き足しても
>>「s2が指す文字列を、s1が指す配列にコピーする」とあるので、 
>>markとnumber2つの配列をコピーできるかどうかわからず困っております

--------------------------------------------------------------------
mark[m_hand[i]]を1番目の"%s"にコピーして文字列を書き換える
number[n_hand[i]]を2番目"%s"にコピーして文字列を書き換える
--------------------------------------------------------------------
こんな風に、printf関数は文字や文字列をコピーして表示していると解釈しているのですか?
printf関数は表示するだけで、コピーなどは行っていません。

%sや%c、%dというのは ただの書式指定子であって、
その文字列自体が書き換わっている訳では無いです。

また、値などをコピーしたら画面に表示されるという仕様でもありません。
解釈を間違えています。






332ポイント を手に入れた。

Name: 南瓜  ..初心者(7,027ポイント)   Date: 2010/04/18(日) 14:17   No:50852     
Title: Re:C言語でポーカーを作っているんですが その2    
        for(i = 0; i < 5;  i++) {
        printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);/* 五枚のカードを表示 */ 
    }
        printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);
    printf("\n");

と単純に書き足しただけなのです^^;


131ポイント を手に入れた。

Name: conio  ..比類無きプログラマー(86,623ポイント)   Date: 2010/04/18(日) 14:26   No:50853     
Title: Re:C言語でポーカーを作っているんですが その2    
for文から抜けたときのiの値を確認してください。
-----------------------------------------------------------------------------------
for(i = 0; i < 5;  i++) {
    printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);/* 五枚のカードを表示 */ 
}
printf("iの値は%dです。"i);
//printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);
-----------------------------------------------------------------------------------
そして、もしその値を添え字に使ったらどうなるのか?
を考えてみてください。


 


185ポイント を手に入れた。

Name: 南瓜  ..初心者(7,062ポイント)   Date: 2010/04/18(日) 14:40   No:50854     
Title: Re:C言語でポーカーを作っているんですが その2    
mark[m_hand[i]],number[n_hand[i]]でiを使っているのに
for文を書かなかったらiのままで出力される訳が無い^^;
と言うことですね?


35ポイント を手に入れた。

Name: conio  ..比類無きプログラマー(87,335ポイント)   Date: 2010/04/18(日) 15:15   No:50855     
Title: Re:C言語でポーカーを作っているんですが その2    
>>mark[m_hand[i]],number[n_hand[i]]でiを使っているのに 
>>for文を書かなかったらiのままで出力される訳が無い^^; 
>>と言うことですね? 
全然違います。 何を言っているのか分かりません。


もう一度詳しく言いますが、
配列のm_handと、配列のn_handの添え字の範囲は何なのか、
そして、変数iの値は何になっているのか調べてください。

それと、南瓜さんが質問したsegmentation faultというのはセグメンテーション違反
不正な場所へアクセスしようとした際などに発生します。

再度言いますが、for文を抜けた後の iの値を添え字に使ったらどうなるのか?
それを考えてみてください。


2倍のポイントを手に入れた! 712ポイント を手に入れた。

Name: 南瓜  ..初心者(7,157ポイント)   Date: 2010/04/18(日) 15:57   No:50856     
Title: Re:C言語でポーカーを作っているんですが その2    
m_hand[5]の添字の範囲は0,1,2,3,4で、n_hand[5]の添字の範囲も0,1,2,3,4
変数iは、for文で0~4まで増やして各配列[i]に代入されていくと思います。
>for文を抜けた後の iの値を添え字に使ったらどうなるのか?
ここがいまいち判んないんですが、for文がないのでint iのままで
そのままだとmark[m_hand[i]]などは、表示されないんだと思いますが
正しいでしょうか?


95ポイント を手に入れた。

Name: conio  ..比類無きプログラマー(87,735ポイント)   Date: 2010/04/18(日) 16:08   No:50857     
Title: Re:C言語でポーカーを作っているんですが その2    
添え字の範囲は0〜4であってます。
そして、その範囲以外の値を設定してはいけない、という事もわかりますよね?
(分からない場合は、参考書などを見直してください)


>>ここがいまいち判んないんですが、for文がないのでint iのままで
for文にはよく変数としてiやjが使われますが、
iやjは別にfor文にしか使えないというものではありません。
よって、for文があるかないか、等は全く無関係です。

それと、main関数内で定義されている変数iは、main関数の最後まで有効です。
(main関数の中での有効範囲を明示的に設定しない限り)
最初にi = 10000;と代入したら、特に何もしない限り最後まで値は10000のままです。


で、さっきも書きましたが とりあえずfor文から抜けた時のiの値を
printf関数で表示してみてください。
iの値は0〜4の範囲に収まってますか?
----------------------------------------------------------------------------------- 
for(i = 0; i < 5;  i++) { 
    printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);/* 五枚のカードを表示 */  

printf("iの値は%dです。\n",i); //iの値を表示してみる。
//printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);  ←エラーの原因なのでコメントアウト。
----------------------------------------------------------------------------------- 編集済み


400ポイント を手に入れた。

Name: 南瓜  ..初心者(7,193ポイント)   Date: 2010/04/18(日) 16:34   No:50858     
Title: Re:C言語でポーカーを作っているんですが その2    
iの値は5であって、0~4に収まっていませんでした
いままで、何度も言われてる添字の範囲外の値が出力されていました


36ポイント を手に入れた。

Name: conio  ..比類無きプログラマー(87,867ポイント)   Date: 2010/04/18(日) 16:49   No:50859     
Title: Re:C言語でポーカーを作っているんですが その2    
そうです。
変数には 有効範囲があり、
その範囲の中では値を保ち続けているので(書き換えが起こらない場合)
使いまわしをする際には、再度適切な代入を行って下さい。

ついでに、2番目のfor文でエラーが発生しなかったのは、
値が5になったiに、0を代入する処理が行われているからです。
---------------------------------
for(i = 0; i < 5;  i++) { 
    //省略

for(i = 0; i < 5;  i++) { 
    //省略

--------------------------------- 編集済み


132ポイント を手に入れた。

Name: 南瓜  ..初心者(7,503ポイント)   Date: 2010/04/18(日) 21:19   No:50872     
Title: Re:C言語でポーカーを作っているんですが その2    
大変お待たせしました
    for(i = 0; i < 5;  i++) {
        printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);/* 五枚のカードを表示 */ 
    }
    printf("\n");
    printf("念のため、もう一度5枚をお見せます。\n");/*もう一度同じカードを表示*/
    for(i = 0; i < 5; i++) {
        printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);
    }
    printf("\n");

同じ所は省略しました。
これで、たいちうさんの仕様通りの結果が出力されました


2倍のポイントを手に入れた! 310ポイント を手に入れた。

Name: ookami  ..入門者(3,521ポイント)   Date: 2010/04/19(月) 08:46   No:50914     
Title: Re:C言語でポーカーを作っているんですが その2    
おっと... [6]以降が違いますね... ヒントをば。

(途中のみコピー) -- ここから
arr[0]=1; 
arr[1]=2; 
arr[2]=0; 
i=arr[1]; // ☆
printf("%d %s ",i,stArr[i]); // [6] 
-- ここまで

> [6]はi = arr[1]なので、arr[1]と2が出力されると思います 

では、☆の行を i=2; と読み替えるとどうですか?読み替えてもう一度[6]の回答を。


124ポイント を落としてしまった。

Name: たいちう  ..比類無きプログラマー(74,220ポイント)   Date: 2010/04/19(月) 09:31   No:50915     
Title: Re:C言語でポーカーを作っているんですが その2    
> これで、たいちうさんの仕様通りの結果が出力されました

お疲れ様です。
次のステップは、カードの交換と役の判定のどちらかです。
どっちからやりたいですか?

それと何度もプログラムを動かすうちに、
5枚の手札の中に数字もスートも同じカードが現れるはずです。
本来一組のトランプでは起こりえないことですので、
まずは重複をなくす処理を追加しますか?

3つのうちで簡単なのは重複の除去ですが、
南瓜さんの好きな順番に実装してよいです。
但し、1つずつ順番に、です。

どれか次に追加する機能を決めて、どのようにすれば実装できるか、
自分なりに考えてみてください。


101ポイント を手に入れた。

Name: 南瓜  ..初心者(7,594ポイント)   Date: 2010/04/19(月) 23:27   No:50941     
Title: Re:C言語でポーカーを作っているんですが その2    
では、重複の除去から行おうと思います
マーク4つと数字13で配列を作ったので、[4][13]の二次元配列を新たに作って
52個分の箱を用意して、doやwhile文を使って違うマーク、数字を引くまで
引き続ける というプログラムを書き足そうと思います。


91ポイント を手に入れた。

Name: Ma  ..比類無きプログラマー(89,410ポイント)   Date: 2010/04/20(火) 03:59   No:50960     
Title: Re:C言語でポーカーを作っているんですが その2    
>doやwhile文を使って違うマーク、数字を引くまで 
>引き続ける というプログラムを書き足そうと思います。

たまに思うのですが、この手法って間違っている気がするのですがどうでしょうか?
これだと、永遠に処理が終わらない確立がありますよね。数学的上ではありますが・・・。
まぁ、実際やると、普通そのようなことは起こらないですけど。(天文学的な可能性なので)

私はこのようなときは、最初っから手札にあるカードはランダムに選ぶときにの候補にならないような処理をしてます。
(*これは指摘ではなく、どちらかというと質問です。) 編集済み


1ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(74,015ポイント)   Date: 2010/04/20(火) 09:16   No:50965     
Title: Re:C言語でポーカーを作っているんですが その2    
> たまに思うのですが、この手法って間違っている気がするのですがどうでしょうか?

試行回数の期待値を考えてみてください。
5枚引くとして平均何回やりなおしがあるか?50枚引くとしたら?
期待値の数倍の処理時間でもクリティカルにならないならば、
必ずしも悪い方法ではないでしょう。

ただし擬似乱数のできが悪いなど無限ループに陥る可能性も確かにあります。
この可能性を無視できなかったり、やり直しが嫌ならば、
実際のトランプのように予め配列をシャッフルしておくのが良いでしょう。

http://ray.sakura.ne.jp/tips/shaffle.html

ちなみに私の場合だと、簡易的にはやり直しの方法で、
丁寧に作るときは配列のシャッフルです。
今回の場合だとstl::random_shuffleを使うでしょうね。


# もちろん南瓜さんは南瓜さんの方針で作ってもらってよいですよ。
# 後で気が向いたらこの部分だけ差し替えることもできます。


311ポイント を落としてしまった。

Name: 南瓜  ..初心者(7,874ポイント)   Date: 2010/04/20(火) 17:20   No:50970     
Title: Re:C言語でポーカーを作っているんですが その2    
以下のように書き足しました
int card[4][13];/*引いたカードかを記憶する(1なら使用、0なら未使用)*/
    
for(i = 0; i < 5; i++) {/* 五枚のカードをrandで決定 */ 
    do { /*別のカードを引くまで繰り返す*/
    n_hand[i]= rand() % 13;/*数字を出す*/
    m_hand[i] = rand() % 4;/*マークを出す*/
    } while (card[m_hand[i]][n_hand[i]] == 1);/*card[4][13]と同じなら1,違うなら0*/
    card[m_hand[i]][n_hand[i]] = 1;/*card[4][13]に引いた情報を記憶*/

1なら使用、0なら未使用の所がうまく書けてるか不安です
実行した限りでは、同じマーク、数字は出ませんでしたが

カードのシャッフル一つでも奥が深いんだなと感心しました。が、とりあえず今は
完成させてから、そのような細かい所をどうするかを考えようと思います


280ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(74,148ポイント)   Date: 2010/04/20(火) 18:30   No:50971     
Title: Re:C言語でポーカーを作っているんですが その2    
> 1なら使用、0なら未使用の所がうまく書けてるか不安です

配列cardの初期化を忘れてはいませんよね?
掲示された部分については間違いは見当たりません。

で、次は何を追加しますか?
手札の交換か、役の判定かのどっちかだと思いますが。


75ポイント を手に入れた。

Name: 南瓜  ..初心者(8,032ポイント)   Date: 2010/04/20(火) 20:07   No:50974     
Title: Re:C言語でポーカーを作っているんですが その2    
int型で宣言しただけで、初期化はしてませんでした
なのでint card[4][13]の部分を以下のように書き直しました
int main (void) {
    int card[4][13] = {{0}};/*引いたカードかを記憶する(1なら使用、0なら未使用)*/
    char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
    char *mark[4] = {"♥","♦","♠","♣"};/*カードのマーク*/

以下省略
これで、int card[4][13]は0で初期化されてますか?
書き方が正しかったら、次はカードの交換を行いたいです


158ポイント を手に入れた。

Name: hoge  ..入門者(4,188ポイント)   Date: 2010/04/20(火) 20:27   No:50975     
Title: Re:C言語でポーカーを作っているんですが その2    
>これで、int card[4] [13]は0で初期化されてますか? 

YES

でも俺なら
 int card[4][13] = {{0}};
こんな中途半端な描き方しないで
 int card[4][13] = {0};
こうする。

それと配列宣言で初期値を書くときは配列サイズは勝手にあわせてくれるので
  char *mark[] = {"♥","♦","♠","♣"};
これでいい。その方が間違えた値を入れてしまう心配がない。
ただし右辺がない場合は
 char *mark[4];
こうしないと、エラーになる。
 編集済み


184ポイント を手に入れた。

Name: 南瓜  ..初心者(8,195ポイント)   Date: 2010/04/20(火) 21:39   No:50979     
Title: Re:C言語でポーカーを作っているんですが その2    
確かに{{0}}より{0}の方がすっきりして見えますね
[]に値を入れない方法は、本にも書いてありました。
同じ結果になるのに書き方は、ほんといろいろあるんだなと
驚きます。どっちにするかは慣れなんだろうけど、最初は値を入れようと思います

5枚を表示→scanfで交換するカード(1〜5)を選択(これ辺をどう書くかがいまいち漠然としか思いつかない)
→選んだカードのみrandで選び直す→選んだカード、選ばなかったカード合わせて5枚を表示

交換しない場合はscanfで0を押す→そのまま再表示と言う流れでいこうかと思ってます


163ポイント を手に入れた。

Name: box  ..ハッカー(152,218ポイント)   Date: 2010/04/20(火) 22:07   No:50981     
Title: Re:C言語でポーカーを作っているんですが その2    
> どっちにするかは慣れなんだろうけど、最初は値を入れようと思います

配列の要素数なんてのはコンピューターに数えさせる、
という考え方もありかな、と思います。


41ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(74,284ポイント)   Date: 2010/04/20(火) 23:00   No:50985     
Title: Re:C言語でポーカーを作っているんですが その2    
> 5枚を表示→scanfで交換するカード(1〜5)を選択(これ辺をどう書くかがいまいち漠然としか思いつかない)

前スレでも書きましたが、
例えば次の様な入力方法はいかがですか?

0 : 交換なし
4 : 4枚目を交換
135 : 1枚目・3枚目・5枚目を交換
12345 : 全部交換 

ご検討ください。

# 前スレへのリンクが切れてしまっているので、一応貼りなおし。
http://www.play21.jp/board/formz.cgi?action=res&resno=50232&page=&lognum=155&id=dixq&rln=50642


136ポイント を手に入れた。

Name: 南瓜  ..初心者(8,415ポイント)   Date: 2010/04/21(水) 17:34   No:51041     
Title: Re:C言語でポーカーを作っているんですが その2    
int i, j; 新しく変数jを書き足して

printf("カードを交換する場合1~5を入力して下さい(0は交換しない) > ");
    scanf("%d", &j);
    while (getchar() != '\n') { }
    if(j != 0) 
    for(j = 0; j < 5; j++) {
        printf("%s - %s ", mark[m_hand[j]], number[n_hand[j]]);
    }
    if (j == 0) 
    printf("念のため、もう一度5枚をお見せます。\n");/*もう一度同じカードを表示*/
    for(i = 0; i < 5; i++) {
        printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);
    }

交換しない=0を選んだ時は、いいんですがそれ以外1~5を選んだとき
if(j != 0)以下をどう書けばいいのか判りません
この書き方だとまた5枚表示して、計10枚表示される書き方になると
思ってましたが、交換したい配列を選んで、そこだけrandで選び直す
書き方が思いつきません


220ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(75,428ポイント)   Date: 2010/04/22(木) 09:59   No:51076     
Title: Re:C言語でポーカーを作っているんですが その2    
今までのプログラムはしばらく忘れ、必ず新しいプログラムを作ってください。
(今までのプログラムを間違って消さないように!)
こんな入出力を作ってください。
カードの実体も交換も不要です。ユーザーインタフェースだけです。

【Step 1】
入力方法の説明 > 135
あなたの入力した数値は 135 でした。

【Step 2】
入力方法の説明 > 135
あなたの入力した数値は 135 でした。
1枚目のカードを交換します。
3枚目のカードを交換します。
5枚目のカードを交換します。

Step1はできますよね?
まずはそれをここに載せ、Step2の方法を考えてみてください。


214ポイント を手に入れた。

Name: 南瓜  ..初心者(8,657ポイント)   Date: 2010/04/22(木) 20:42   No:51096     
Title: Re:C言語でポーカーを作っているんですが その2    
おまたせしました
int main (void) {
    int i;
    
    printf("入力方法の説明 > ");
    scanf("%d", &i);
    printf("あなたの入力した数値は%dでした。\n", i);
    return 0;
}

変数を増やして表現する?
%d枚目のカードを交換します。, i
%d枚目のカードを交換します。, j
%d枚目のカードを交換します。, k
みたいに でもこのやり方だとものすごくまどろっこしいですよね


2倍のポイントを手に入れた! 242ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(75,606ポイント)   Date: 2010/04/22(木) 22:19   No:51099     
Title: Re:C言語でポーカーを作っているんですが その2    
> 変数を増やして表現する?
> %d枚目のカードを交換します。, i
> %d枚目のカードを交換します。, j
> %d枚目のカードを交換します。, k
> みたいに でもこのやり方だとものすごくまどろっこしいですよね

変数を増やして表現する、というのがどんな方法か判りませんが、
もっと良い方法が思いつかないなら仕方ないでしょう。
後でいくらでも改良することができますので、まずは動くものを作りましょう。
考えてみて下さい。


2倍のポイントを手に入れた! 178ポイント を手に入れた。

Name: 南瓜  ..初心者(8,839ポイント)   Date: 2010/04/23(金) 07:40   No:51110     
Title: Re:C言語でポーカーを作っているんですが その2    
変数を増やしても思った感じに成らなかったので
それっぽく動きそうなのにしました
int main (void) {
    int i, j;
    
    printf("入力方法の説明 > ");
    scanf("%d", &i);
    printf("あなたの入力した数値は%dでした。\n", i);
    for(j = 0; j < i; j++) {
        printf("%d枚目のカードを交換します。\n", i);
    }

欠点は、13入力すると13回処理を行うのと1 3とすると
スペースを認識せずに1として認識して処理をする所です


182ポイント を手に入れた。

Name: conio [URL]  ..比類無きプログラマー(88,594ポイント)   Date: 2010/04/23(金) 08:58   No:51111     
Title: Re:C言語でポーカーを作っているんですが その2    
--------------------------------------------------------
int main (void) {
    int i, j;
    
    printf("入力方法の説明 > ");
    scanf("%d", &i);
    printf("あなたの入力した数値は%dでした。\n", i);
    for(j = 0; j < i; j++) {
        printf("%d枚目のカードを交換します。\n", i);
    }
    return(0);
}
--------------------------------------------------------

これは、やり方がおかしいです。
35と入力したら
----------------------------
0枚目のカードを交換します。
1枚目のカードを交換します。
2枚目のカードを交換します。
3枚目のカードを交換します。

:

31枚目のカードを交換します。
32枚目のカードを交換します。
33枚目のカードを交換します。
34枚目のカードを交換します。
----------------------------
こんな風になってしまいます。


あと数字の間にスペースを空けて入力するのではなく、
135(ひゃくさんじゅうご)と入力したら
1(いち)と3(さん)と5(ご)と分離して読み込む方法を考えてみてください。

【追記】
混乱しそうなので追記。
ゲームの仕様を実装出来ればいいので、やり方は好きな方法を選んで下さい。 編集済み


395ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(75,674ポイント)   Date: 2010/04/23(金) 08:59   No:51112     
Title: Re:C言語でポーカーを作っているんですが その2    
> 欠点は、13入力すると13回処理を行うのと1 3とすると
> スペースを認識せずに1として認識して処理をする所です

そのようなプログラムを書いてしまったのだから当然です。

色々方法はありますが、入力を文字列として受け取ってみてください。
想定外の入力に対する処理も後回しにして、13という入力を
"13"という文字列として受け取って、Step 1を作れますか?
Step 2は?


68ポイント を手に入れた。

Name: 南瓜  ..初心者(8,972ポイント)   Date: 2010/04/25(日) 10:37   No:51215     
Title: Re:C言語でポーカーを作っているんですが その2    
遅くなりました
char change[] = "012345";
    
printf("入力方法の説明 > ");
scanf("%s", change);
while(getchar() != '\n') {}
printf("あなたの入力した数値は%sでした。\n", change);
printf("%s枚目のカードを交換します。\n", change);

こういうことでしょうか?


133ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(76,140ポイント)   Date: 2010/04/25(日) 13:43   No:51231     
Title: Re:C言語でポーカーを作っているんですが その2    
> こういうことでしょうか?

当然違います。
No:51076に書いた仕様を満たしていません。
"135"と入力すれば判るでしょう。

# 違うということは自分で気付けたと思うのですが。
# もしも気付いていたのならば、無駄なやり取りは避けましょう。
# 掲示板での一回のやり取りで数時間から数日かかる場合、
# 問題解決がその分遅れて損するのは誰ですか?
# もっと上手に掲示板と私を利用してください。


106ポイント を手に入れた。

Name: 南瓜  ..中級者(9,138ポイント)   Date: 2010/04/26(月) 21:47   No:51273     
Title: Re:C言語でポーカーを作っているんですが その2    
    char change[7] = "012345";
    
    printf("入力方法の説明 > ");
    scanf("%s", change);
    while(getchar() != '\n') {}
    printf("あなたの入力した数値は%sでした。\n", change);
    printf("%s枚目のカードを交換します。\n", change);

    return 0;

本で調べたり、ネットで調べましたが
どうしてもstep2の仕様ができません
どの知識を使えばいいのかもわからず
完全に手詰まりです


166ポイント を手に入れた。

Name: Ma  ..比類無きプログラマー(91,889ポイント)   Date: 2010/04/27(火) 08:29   No:51283     
Title: Re:C言語でポーカーを作っているんですが その2    
>たいちうさん
conio さんも言っているとおり、いっそのこともっとやさしい仕様にしてはいかがでしょうか。
桁でコントロールではなく、一回一回入力する方針でもいいんじゃないでしょうか?

目的にそぐわない方法でしたら無視してください。

*追記
彼の仕様を使いint型で読み込むなら、以下のようなアポローチが可能だと思います。

1桁目
change%10

2桁目
int temp = change - 1桁目
(temp%10)/10

....

や、
5桁目
change/10000

4桁目
(change%10000)/1000

...

などが思いつきます。*深く考えていないので穴だらけかも。
あと、当然想定外の値や文字が来た場合の判定もしなくてはなりません。 編集済み


124ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(76,665ポイント)   Date: 2010/04/27(火) 09:11   No:51284     
Title: Re:C言語でポーカーを作っているんですが その2    
それではもう少しヒントを。

【Step 2】
入力方法の説明 > 135
あなたの入力した文字列は 135 でした。
文字列の長さは 3 です。
1 文字目は 1 です。
2 文字目は 3 です。
3 文字目は 5 です。


> 桁でコントロールではなく、一回一回入力する方針でもいいんじゃないでしょうか?

それでもよいです。しかし複数回の入力を処理するほうが難しいと思ってのこの仕様です。


23ポイント を手に入れた。

Name: 南瓜  ..中級者(9,475ポイント)   Date: 2010/04/28(水) 17:19   No:51316     
Title: Re:C言語でポーカーを作っているんですが その2    
int i;
    char change[6] = "12345";
    char *p1;
    
    p1 = change;
    printf("入力方法の説明 > ");
    scanf("%s", change);
    while(getchar() != '\n') {}
    printf("あなたの入力した数値は%sでした。\n", change);
    printf("文字列の長さは%dです。\n", strlen(change));
    for(i = 1; i <= strlen(change); i++) {
            printf("%d文字目は%cです。\n", i, *p1+i-1);
    }

だいぶ言われた仕様に近づいたと思います
(0や6以上を打ち込んだ時の対処法はまだですが)
打ち込んだ回数ループする仕様は問題ないとおもうんですが、
「?文字目は?です」の所が123や345とかは、仕様通りになるのですが
(たまたまうまくいってるだけ?)135だと
1文字目は1、2文字目は2、3文字目は3のように出力されてしまいます
直す所は「*p1+i-1」の部分だと思うんですが、どのように直せばいいでしょうか?


337ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(77,531ポイント)   Date: 2010/04/28(水) 17:27   No:51317     
Title: Re:C言語でポーカーを作っているんですが その2    
for(i = 0; i < strlen(change); i++) {
    printf("%d文字目は%cです。\n", i + 1, change[i]);
}
これで行けるんじゃないかと。 p1は不要ですし、changeの初期値も不要です。 十分な領域が必要なだけなので、 char change[10]; とでもしておけばよいでしょう。 Step 3ですが、forループの中を次のように変えてください。
int n = ???;
printf("%d文字目は%dです。\n", i + 1, n);


131ポイント を手に入れた。

Name: 南瓜  ..中級者(9,570ポイント)   Date: 2010/04/28(水) 18:42   No:51318     
Title: Re:C言語でポーカーを作っているんですが その2    
指摘通り直したらうまくいきました
for(i = 0; i < strlen(change); i++) {
        int n = ???;
            printf("%d文字目は%dです。\n", i+1, n);
    }

ただ、step3のint n = ???;の意味がわかりません
というよりコンパイルできません
?は条件演算子を指しているんでしょうか?


95ポイント を手に入れた。

Name: box  ..ハッカー(152,378ポイント)   Date: 2010/04/28(水) 21:33   No:51321     
Title: Re:C言語でポーカーを作っているんですが その2    
> ?は条件演算子を指しているんでしょうか?

考えすぎ。
「何を書けばよいですか?」という問いかけです。


23ポイント を手に入れた。

Name: 南瓜  ..中級者(9,694ポイント)   Date: 2010/04/28(水) 23:06   No:51328     
Title: Re:C言語でポーカーを作っているんですが その2    
    for(i = 0; i < strlen(change); i++) {
        int n = change[i];
            printf("%d文字目は%cです。\n", i+1, n);
    }

step2と同様の結果が得られたんですが、これはたいちうさんの
意図する仕様になったでしょうか?
特に%dじゃなくて%cにしてしまった所が気にかかる…
でも%dじゃstep2と同様の結果が得られないし…


124ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(77,633ポイント)   Date: 2010/04/28(水) 23:42   No:51329     
Title: Re:C言語でポーカーを作っているんですが その2    
> step2と同様の結果が得られたんですが、これはたいちうさんの
> 意図する仕様になったでしょうか?
> 特に%dじゃなくて%cにしてしまった所が気にかかる…

%dで表示することが目的です。
なぜならば、入力を配列の添え字に変換する必要があるからです。

> でも%dじゃstep2と同様の結果が得られないし…

どんな結果になりましたか?
その結果は何を表していますか?
その結果をどのように加工したら望む結果が得られますか?


102ポイント を手に入れた。

Name: Ma  ..比類無きプログラマー(92,072ポイント)   Date: 2010/04/29(木) 01:37   No:51331     
Title: Re:C言語でポーカーを作っているんですが その2    
文字列 数字 変換
とかって検索。

atoi


15ポイント を手に入れた。

Name: 南瓜  ..中級者(9,774ポイント)   Date: 2010/04/29(木) 10:01   No:51332     
Title: Re:C言語でポーカーを作っているんですが その2    
int n = atoi(change);
printf("%d文字目は%dです。\n", i+1, n);

%dだと1が49と出力されていたので
調べた所ASCIIコードが関与してることが判ったので
文字列を10進法に替えるatoiを使いました
次のステップは123と入力すると123と返ってくるので
atoiを使ってstep2の仕様にするのでしょうか?


80ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(77,785ポイント)   Date: 2010/04/29(木) 10:56   No:51333     
Title: Re:C言語でポーカーを作っているんですが その2    
> atoiを使ってstep2の仕様にするのでしょうか?

私はatoiの使用はお勧めしません。
atoiは文字列を数値に変換する関数ですが、
今回は1文字ずつ処理した方が簡単なので、
文字から数値への変換が必要です。

'1'という文字はASCIIコードで49です。
'2'という文字はASCIIコードで50です。
...

nの求め方が判りませんか?


2倍のポイントを手に入れた! 152ポイント を手に入れた。

Name: 南瓜  ..中級者(9,828ポイント)   Date: 2010/04/29(木) 12:03   No:51335     
Title: Re:C言語でポーカーを作っているんですが その2    
        int n = change[i] - '0';
        printf("%d文字目は%dです。\n", i+1, n);

これでいいでしょうか?
これなら%dでもいままでと変わらずの結果になるので…


54ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(77,876ポイント)   Date: 2010/04/29(木) 12:15   No:51336     
Title: Re:C言語でポーカーを作っているんですが その2    
> これでいいでしょうか?

OKです。
そろそろポーカーに戻って、出来るところまで作ってください。


17ポイント を手に入れた。

Name: 南瓜  ..中級者(10,016ポイント)   Date: 2010/05/01(土) 18:04   No:51412     
Title: Re:C言語でポーカーを作っているんですが その2    
とりあえず、カード交換らしき所だけ書きました
38~45行目は、条件文のchange[i]の変数の所が書き方が
いけないと思うんですが、どのように書き換えればいいでしょうか?
(change[i]をjとかに替えたらちゃんとif文は機能しました。ただその後はエラーが出ましたが…)
46-53行目は、コンパイルできなかったため、考え方自体が根本から間違っているかまでは判りませんでした
(char型なのにint型に代入しようとするやり方がいけないのだとは思うのですが…
交換する時は、あのように一時的に他の変数に代入するのだと本に書いてあったのですが
ちゃんと理解してなかったのか?)


188ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(78,079ポイント)   Date: 2010/05/01(土) 21:59   No:51418     
Title: Re:C言語でポーカーを作っているんですが その2    
色々まずいですが、致命的なのは同じ指摘を何度も受けていることです。
forループの外にiがありますが、このiには何が代入されていると思いますか?

それと交換の部分ですが、複数枚交換するため、交換の処理は
複数回呼ばれなければいけません。
こんな感じに。
for(i = 0; i < strlen(change); i++) {
    int n = change[i] - '0';
    printf("%d枚目のカードを交換します。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]]);
    /* カード交換の処理 */
    printf("%d枚目のカードを交換しました。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]]);
}


179ポイント を手に入れた。

Name: 南瓜  ..中級者(10,126ポイント)   Date: 2010/05/02(日) 10:28   No:51460     
Title: Re:C言語でポーカーを作っているんですが その2    
前のfor文によりiには5が代入されているままだと思います
同じ指摘何度もされて申し訳ないです
本やサイトで勉強し直してるのですが中途半端な理解のままだと
痛感しています
本当にすみません


2倍のポイントを手に入れた! 110ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(78,912ポイント)   Date: 2010/05/02(日) 21:51   No:51500     
Title: Re:C言語でポーカーを作っているんですが その2    
謝ってもらう必要はないのですが、理解することを大切にしないと上達は望めません。
「この様な場合にはどうしたら良いか?」という質問に対しては、
答えるだけなら答えやすいのですが、それを延々と繰り返すことが上達につながるでしょうか?

1つ指摘を受けた時、それを適用してプログラムが動けばそれで良しとしていませんか?
言われるままに直す人と、何故駄目だったのかを理解して直す人は違います。
これを繰り返していけば、表面的には同じものが出来上がったとしても、
身に着く実力は比べ物にならないでしょう。
もしも指摘が理解できない場合は、入門書などを読み返さないといけません。
それでも理解できない場合は、再度質問しなければいけません。

前スレの最初のプログラムをスタートとして、
カードの交換と役の判定の完成をゴールと考えると、
今は大体半分くらいの完成度という印象です。
今まで言われるままに直していたのならば、同じだけの手間がかかりますが、
今までで理解が深まっているのならば、後半はもっと楽でしょう。

行き詰った場合、前スレとこのスレのどこかからヒントが得られる場合もあるでしょうから、
質問の回答を待つ間に全体を読み直すことも有効でしょう。
完成まで付き合うつもりですので、焦らず頑張ってください。


483ポイント を手に入れた。

Name: box  ..ハッカー(152,541ポイント)   Date: 2010/05/02(日) 22:16   No:51501     
Title: Re:C言語でポーカーを作っているんですが その2    
> 前のfor文によりiには5が代入されているままだと思います

そうなのかどうかは、当該のfor文を抜けた直後で
printf()してみるとすぐにわかりますね。

「〜だと思います」ではなくて、コードを書いて
自分で確認しましょう。


57ポイント を手に入れた。

Name: 南瓜  ..中級者(10,305ポイント)   Date: 2010/05/03(月) 16:20   No:51542     
Title: Re:C言語でポーカーを作っているんですが その2    
printfを使った所、iなら5、change[i]は?でした。
if文の条件式がうまくいかないのは初期化していないchange[i]を
書いていたから?変数を変えればうまくいく?
かといってscanfで入力した値を元にfor文に入る前にif文で判断させたい訳だし
changeを変えてしまったらfor文のchangeが機能しないし…
38~45行目のif文の所を修正するには、if,配列の他にどの辺の知識がいりますか?


179ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(78,924ポイント)   Date: 2010/05/03(月) 19:32   No:51548     
Title: Re:C言語でポーカーを作っているんですが その2    
> 38~45行目のif文の所を修正するには、if,配列の他にどの辺の知識がいりますか?

自分で考える力と、人からの指摘を理解する力。
if文をどのように修正したいのですか?


39ポイント を手に入れた。

Name: 南瓜  ..中級者(10,410ポイント)   Date: 2010/05/04(火) 08:57   No:51579     
Title: Re:C言語でポーカーを作っているんですが その2    
38~45行目のif文を前のscanfで入力した値を元に分岐させたいです
1~5なら交換する処理を、0なら交換しませんと処理、それ以外なら
もう一度値を入力するように促す処理です
特に判断する変数の所です
if(1 < ???) && (??? < 5)


105ポイント を手に入れた。

Name: Ma  ..比類無きプログラマー(93,298ポイント)   Date: 2010/05/04(火) 12:19   No:51589     
Title: Re:C言語でポーカーを作っているんですが その2    
    for(i = 0; i < strlen(change); i++) {
        int n = change[i] - '0';
        if ((1 <= n) && (n <= 5)) {
            printf("%d枚目のカードを交換します。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]] );
        }    
        else if(n == 0)
            printf("0なので交換しません。\n");
    }

これでどうですか?
あと、何が間違っていたのか指摘すれば、
change[i] を比較しているなら、int n = change[i] - '0';の教訓を忘れていませんか?
for文でチェックしないと、入力された文字数がいくつであっても対応することができないと思いませんか?

*注意:この方法では、毎カード 0 の可能性を比較しています。
もし、最初の一回だけでいいなら、

    if(change[0] == '0'){
        printf("0なので交換しません。\n");
    }
    else{
        for(i = 0; i < strlen(change); i++) {
            int n = change[i] - '0';
            printf("%d枚目のカードを交換します。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]] );
        }
    }

こちらのほうが好ましいかも。 編集済み


250ポイント を手に入れた。

Name: ムンバ  ..プログラマー(39,403ポイント)   Date: 2010/05/05(水) 01:59   No:51625     
Title: Re:C言語でポーカーを作っているんですが その2    
こんばんは?!

飛び込み、ごめんなさい。(謝
プログラミングは、相変わらず初心者です。

>>こちらのほうが好ましいかも。

 南瓜さんが、ポーカーを作る過程での質問ですので
 好ましいか好ましくないかは、南瓜さんが決める事だと思います。

勝手にずっと最初から、このスレを傍観させて頂いてます。
南瓜さんの自作のポーカー、完成できる事を祈ります。
余計なお世話かと思いますし、なんにもお役に立てませんが
南瓜さん、がんばってると思うんですよね。(間違ってたら、ごめんなさい。)

オリジナルのポーカーの完成、応援させて頂きます。
ぜひ、完成までがんばって下さいっ!
(この私のコメント、レス無し希望です。宜しくお願い致します。)


176ポイント を手に入れた。

Name: 南瓜  ..中級者(10,615ポイント)   Date: 2010/05/05(水) 21:50   No:51662     
Title: Re:C言語でポーカーを作っているんですが その2    
ookamiさん すみません 読み飛ばして返信に気づきませんでした
%dはarr[1]が出力がされて、%sはstArr[arr[1]]となってstArr[2]で正しいでしょうか?

確かに先にif文を書いてしまったら対応できませんよね
Maさんが案を提案してくれたので、0~5以外の数字を入力したとき
0~5を入力するまでループする機能を付けてから投稿しようとしたら
遅くなりました。しかしゴチャゴチャな出来になってしまって…

この仕様が特に問題なかったらカード交換に移りたいと思います
複数回呼び出すという事は
mark[m_hand[n-1]] = m_temp[n-1];
    m_temp[n-1] = c_m_hand[m_hand[n-1]];
    c_m_hand[m_hand[n-1]] = mark[m_hand[n-1]];

これを複数回実行すればいいということですか?


205ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(79,117ポイント)   Date: 2010/05/05(水) 22:17   No:51664     
Title: Re:C言語でポーカーを作っているんですが その2    
> これを複数回実行すればいいということですか?

実行時エラーになるでしょう。いや、処理系依存かな。
いずれにしても、やってみればうまくいかないことは判ります。
私個人の意見ですが、できればこのような質問は避けるべきです。
質問の仕方・掲示板の有効な使い方についても考えてみて下さい。


まだ躓いているようですので、少し簡単な仕様を考えてみました。

1.カードを5枚選択。
2.カードを5枚表示。
3."1"が入力されたものとする。(strcpy(change, "1"); と書く)
4.1枚目のカードを交換。
5.カードを5枚表示。(新しいカードと、元の4枚のカードが表示される)

カードの交換とは何を意味しているのか、考えてみて下さい。


139ポイント を手に入れた。

Name: 南瓜  ..中級者(10,453ポイント)   Date: 2010/05/08(土) 14:41   No:51789     
Title: Re:C言語でポーカーを作っているんですが その2    
しばらく、本やネットでstrcpyについて調べてたんですが
ファイルだと31~33の所の???の書き方が判りません

カードの交換は、値を交換すると言うこと?

strcpyは文字列をコピーしてもう一つの配列にコピーするのと
 
temp = x[i];
    x[i] = x[j];
    x[j] = temp;

のような値の交換って何が違うんですか?



162ポイント を落としてしまった。

Name: Ma  ..比類無きプログラマー(95,440ポイント)   Date: 2010/05/08(土) 20:15   No:51806     
Title: Re:C言語でポーカーを作っているんですが その2    
>カードの交換は、値を交換すると言うこと?
はい。

>何が違うんですか?
文字通り、コピー、と交換の違いです。

    x[i] = x[j];
これで、コピー。
片方、上書きされるほうのデータは消失します。


    temp = x[i];
    x[i] = x[j];
    x[j] = temp;

これで交換。
一時的に、上書きされるほうのデータを新しく作った変数でとっておくことでデータの消失を防ぎます。
もちろん、実際には strcpy の内部はこんなシンプルではないでしょうが。


206ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(79,842ポイント)   Date: 2010/05/08(土) 23:46   No:51815     
Title: Re:C言語でポーカーを作っているんですが その2    
本筋を見失っています。

私の仕様が要求しているのは、
「"1"が入力された時は、正しく動作する」という事です。
入力は、"1"だったり、"14"だったり、"12345"だったりしますので、
これらの全てに対応したプログラムが必要ですが、
初めの一歩として、"1"に対応させましょう、ということ。

毎回"1"を入力するのが面倒だろうから、changeに"1"を代入したら楽だよ、
という意味で、strcpyを提案しました。
strcpyを使ってカードを交換するわけではありません。
strcpyの使い方が判らないならば、毎回"1"を入力してください。


次に、Maさんの説明だと判りにくいのではないかと思うので、
私からも交換について説明します。

南瓜さんはソートのプログラムを作ったことがあるでしょうか?
ソートのプログラムの基本的な要素として、値の比較と値の「交換」があります。
この交換はしばしば次の様に書かれています。

> temp = x[i];
> x[i] = x[j];
> x[j] = temp;

カードの交換を実装しようという時に、「交換」の意味を深く考えずに
上述の「交換」を使おうという事が間違いです。
実際にトランプでポーカーをするときに、手札を一枚「交換」するということは、
手札のうちの一枚を場に移し、山から新しいカードを一枚引くことです。
実装すべきなのは、この動作です。
同じ「交換」でも、ソートのプログラムの「交換」とは全然似てないことが判るでしょう。


376ポイント を手に入れた。

Name: 南瓜  ..中級者(10,666ポイント)   Date: 2010/05/09(日) 23:43   No:51872     
Title: Re:C言語でポーカーを作っているんですが その2    
Maさん、説明ありがとうございます
ソートのプログラムは、本やネットで見ただけで、使えるかな?
と思っただけでそこまで考えてませんでした^^;
>手札のうちの一枚を場に移し、山から新しいカードを一枚引くことです。 
>実装すべきなのは、この動作です。 
ということは、step1としてはまた山札から引き直す処理を書き加えれば達成?
ただ、この書き方だと交換する枚数の位置を指示できないから
(5と入力すると5枚全て交換されてしまう…)
また新たな処理(int n = change[i] - '0'以降のやつ)を作る?
でも書き足したらうまくいかなかったので書き足す前のやつを載せました。

言葉が同じ交換でもその交換する手段は異なるんですね


213ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(79,878ポイント)   Date: 2010/05/10(月) 00:03   No:51873     
Title: Re:C言語でポーカーを作っているんですが その2    
> ただ、この書き方だと交換する枚数の位置を指示できないから
> (5と入力すると5枚全て交換されてしまう…)

forループを二重にしてはいけません。

> printf("%d枚目のカードを交換します。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]] );
>  /* カード交換の処理 */
> printf("%d枚目のカードを交換しました。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]]);

"/*カード交換の処理*/"と書かれている部分で、1枚だけ交換です。


36ポイント を手に入れた。

Name: 南瓜  ..中級者(10,768ポイント)   Date: 2010/05/10(月) 22:18   No:51901     
Title: Re:C言語でポーカーを作っているんですが その2    
とりあえずこれで”1”と入力すれば1枚だけ交換して
新しい1枚と元の4枚が表示されるようになりました。

forループを二重にしてはいけないのは
最初のforループの中で 次のforループが繰り返されて
しまうからですよね?


102ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(79,845ポイント)   Date: 2010/05/10(月) 23:50   No:51911     
Title: Re:C言語でポーカーを作っているんですが その2    
> forループを二重にしてはいけないのは
> 最初のforループの中で 次のforループが繰り返されて
> しまうからですよね?

その理由も十分ではありません。
結局のところ、二重にする必要がない、というのが理由です。


> とりあえずこれで”1”と入力すれば 1枚だけ交換して
> 新しい1枚と元の4枚が表示されるようになりました。

それでは、他の入力も試してください。
(何度も書いていますが、勝手に次のステップに進んでください)


63ポイント を手に入れた。

Name: 南瓜  ..中級者(10,638ポイント)   Date: 2010/05/12(水) 15:05   No:51978     
Title: Re:C言語でポーカーを作っているんですが その2    
No:51901の書き方だと
1から連番(123とか12345とか)で入力すれば無事交換できるのですが
2以降や135などの入力すると場所指定が出来ずに打ち込まれた数
135なら135枚目を交換するのではなく、123枚を交換してしまうのは
for文のstrlen(change)によると推測してるのですが、ここを変えてしまっては
元も子もないので、少しヒントを頂けないでしょうか?


130ポイント を落としてしまった。

Name: たいちう  ..比類無きプログラマー(80,262ポイント)   Date: 2010/05/12(水) 15:49   No:51982     
Title: Re:C言語でポーカーを作っているんですが その2    
for(i = 0; i < strlen(change); i++) {
    int n = change[i] - '0';
    if ((1 <= n) && (n <= 5)) {
        printf("%d枚目のカードを交換します。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]] );

        int index = n - 1;
        // i ではなくて、indexを使ってください。ここから
        do {
            n_hand[i]= rand() % 13;
            m_hand[i] = rand() % 4;
        } while (card[m_hand[i]][n_hand[i]] == 1);
        card[m_hand[i]][n_hand[i]] = 1;
        // ここまで。
        
        printf("%d枚目のカードを交換しました。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]]);
    } else if (n == 0) {
        printf("0なので交換しません。\n");
    }
}

i, n, indexがそれぞれ何を表すのか、正確に理解していないとプログラムは作れませんよ。
「正確に理解」という言葉の目安は、第三者に正確に説明できる程度、と考えてください。


357ポイント を手に入れた。

Name: 南瓜  ..中級者(10,845ポイント)   Date: 2010/05/12(水) 23:15   No:52003     
Title: Re:C言語でポーカーを作っているんですが その2    
変数iは0で初期化して、strlen(change)まで増加する
変数nはchange[i]-'0'により入力した文字を数値に変換し
ifが1<=n<=5のとき、交換する処理になる
nは打ち込んだ数字が表示され、
mark~、number~がn-1なのは、配列の添字が0から始まるから。
変数indexはn-1なのも、これも配列の添字が0から始まるから
n-1で、nはすでに数値変換しているから入力した数字から1引かれる事で
正しい配列の添字になっている。
最期にn=0なら交換しない処理をする
どうでしょうか?正しい説明になってますか?

もし、正しかったら残りは役を判断する所だと思うので
役を判断する処理として、64~65行目の書き方というより
考え方の方向性は正しいでしょうか?正しかった場合、これにあと何を書き足せば
処理がうまくいくのか、ご指摘お願いします。


207ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(80,453ポイント)   Date: 2010/05/12(水) 23:34   No:52006     
Title: Re:C言語でポーカーを作っているんですが その2    
> どうでしょうか?正しい説明になってますか?

間違ってはいないと思うけど、この説明からは
南瓜さんが正しく理解している、とまでは判断できません。
今までのやり取りを見ると特に。

「自分が理解している」と主張するためにも、
「自分の理解は正しい?」と質問するためにも、
国語の力が必要です。これももっと磨いてください。


> 役を判断する処理として、64~65 行目の書き方というより
> 考え方の方向性は正しいでしょうか?正しかった場合、これにあと何を書き足せば
> 処理がうまくいくのか、ご指摘お願いします。

方向性も何も、何か考えがあるようには見えません。
実際に配られたトランプを見て、フラッシュかどうか、
どのように判断していますか?
まずは、日本語で丁寧に書いてみましょう。

# 「交換」という言葉を深く考えなかった反省も生かして下さいね。


171ポイント を手に入れた。

Name: 南瓜  ..中級者(10,986ポイント)   Date: 2010/05/15(土) 23:52   No:52172     
Title: Re:C言語でポーカーを作っているんですが その2    
今フラッシュ、ストレートの役の判定を作っている途中で
フラッシュは、うまくいったんですがストレートで苦戦してます
(この書き方だとSegmentation faultが出るので、74~82行は/**/を
使ってます)
Segmentation faultが出るという事は、74~82行目の書き方が
悪いんでしょうが、何処がいけないんでしょうか?




141ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(80,647ポイント)   Date: 2010/05/16(日) 00:05   No:52173     
Title: Re:C言語でポーカーを作っているんですが その2    
> Segmentation fault が出るという事は、74~82行目の書き方が
> 悪いんでしょうが、何処がいけないんでしょうか?

実行時エラーの原因は、配列の範囲を超えているから。
配列のインデックスは、0〜4までです。

> int n_hand[5];/*5枚の数字の手札*/

それと、どうしてこのプログラムでストレートの
判定ができると考えているのですか?
この辺に南瓜さんの根本的な問題があると思います。

例によって第一段階の仕様はできるだけ簡単にしたいので、
キングとエースはつながっていなくても結構です。


99ポイント を手に入れた。

Name: 南瓜  ..中級者(11,057ポイント)   Date: 2010/05/16(日) 00:28   No:52177     
Title: Re:C言語でポーカーを作っているんですが その2    
int n_hand[5]で範囲指定してるのに、i+4や[12]は超えてしまう
またやってしまったorz

12345([i] [i+1]…)やA10JQK([0] [9]…)のストレートをどう表現すればいいかな
と思いあのような書き方をしました
あぁ…orz


71ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(80,737ポイント)   Date: 2010/05/16(日) 01:54   No:52183     
Title: Re:C言語でポーカーを作っているんですが その2    
> 12345([i] [i+1]…)やA10JQK([0] [9]…)のストレートを
> どう表現すればいいかなと思い

ここまでは良いのですが、

> あのような書き方をしました

どうしてそれであのような書き方になったのですか?
なんとなくで適当に書いているとしか思えないのですが。
これが一番の問題ですので、上達したいのならば
自分で自分を分析してください。


90ポイント を手に入れた。

Name: 南瓜  ..中級者(11,334ポイント)   Date: 2010/05/16(日) 23:30   No:52223     
Title: Re:C言語でポーカーを作っているんですが その2    
char *number[13]から13個の数字を宣言して、int n_hand[5]から5個の箱を用意する
number[n_hand[i]]は、5個の箱にランダムで選ばれた13個の数字を入れて出力するために必要な書き方
23456のストレートならn_hand[1]で2が選ばれて、n_hand[2]で3…と続き
 number[n_hand[1]],number[n_hand[2]]…number[n_hand[[5]]で23456と出力される
やっぱりストレートを判断するには、n_hand[i]が重要になる
しかし、number[n_hand[i]],number[n_hand[i+1]]…number[n_hand[i+4]]だと
Segmentation faultになってしまう

ストレートの判断でn_hand[i]は重要ではなく、別の判断基準が必要なのでしょうか?


277ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(80,869ポイント)   Date: 2010/05/16(日) 23:40   No:52225     
Title: Re:C言語でポーカーを作っているんですが その2    
for(i = 0; i < 5; i++) {/* 五枚のカードをrandで決定 */ 
    do { /*別のカードを引くまで繰り返す*/
        n_hand[i]= rand() % 13;/*数字を出す*/
        m_hand[i] = rand() % 4;/*マークを出す*/
    } while (card[m_hand[i]][n_hand[i]] == 1);/*card[4][13]と同じなら1,違うなら0*/
    card[m_hand[i]][n_hand[i]] = 1;/*card[4][13]に引いた情報を記憶*/
}


↑の部分をコメントアウトして、その代わりに、
23456のストレートをn_handとm_handにセットしましょう。

これをストレートと判定できますか?


132ポイント を手に入れた。

Name: 南瓜  ..中級者(11,410ポイント)   Date: 2010/05/17(月) 00:22   No:52227     
Title: Re:C言語でポーカーを作っているんですが その2    
判定できませんでした…
というより、何にでもストレートの判定が(そういう書き方だから当然なのだがorz)
m_handにも23456をセットする理由は、エラーを起こさせないため?


76ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(81,194ポイント)   Date: 2010/05/17(月) 00:41   No:52228     
Title: Re:C言語でポーカーを作っているんですが その2    
> 判定できませんでした…
> というより、何にでもストレートの判定が(そういう書き方だから当然なのだがorz)
> m_handにも23456をセットする理由は、エラーを起こさせないため?

違います。m_handにそんな数値をセットしてはいけません。こうしましょうか。
int m_hand[5] = { 0,1,2,3,3 };

m_hand(スート)とn_hand(数)の組み合わせで1枚のカードを表現しているので、
手札を決めるには、m_handにも値をセットしなくてはならないから書いたのであり、
m_handに23456をセットするようにとは書いていません。
m_handの取りうる値の範囲を考えれば当然です。

最終的には、どんな手札でもストレートの判定を正しくできるプログラムですが、
とりあえず23456をストレートと判定できるプログラムを作りましょう、ということ。

南瓜さんは、23456がどうしてストレートだと認識できるのですか?
その手順をできるだけ詳しく日本語で書いてください。
それをC言語に直したら完成です。


325ポイント を手に入れた。

Name: 南瓜  ..中級者(11,766ポイント)   Date: 2010/05/17(月) 20:52   No:52248     
Title: Re:C言語でポーカーを作っているんですが その2    
1)カードが5枚配られる→2)カードは32564だった→3)数字を確認→4)数字を順に並べ直す
→5)23456になった→6)ストレート

1はすでに出来ている。2,5は便宜的ではあるけどセットしてある。
3,4は書かなくてもいい所? 重要なのはやはり6か?

23457にセットしてもストレートと判定されてしまうので、
書き方云々より考え方が間違ってる?



2倍のポイントを手に入れた! 356ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(81,080ポイント)   Date: 2010/05/17(月) 20:58   No:52250     
Title: Re:C言語でポーカーを作っているんですが その2    
> if(n_hand[1] && n_hand[2] && n_hand[3] && n_hand[4] && n_hand[5]) {
>     flag_s = 1;
> }

まずい点は2つ。
1つめは、何度も指摘されている配列のindexの有効範囲。

2つめについてですが、このif文の条件を日本語で表してみて下さい。
そもそも何をやっているつもりなのですか?


>→5)23456になった→6)ストレート 
...
> 3,4は書かなくてもいい所? 重要なのはやはり6か?

これも何度か書いていますが、どうして23456をストレートと認識できるのですか?
ストレートの定義は?
それをC言語に翻訳できるレベルまで細かく日本語で表すと?


114ポイント を落としてしまった。

Name: 南瓜  ..中級者(12,207ポイント)   Date: 2010/05/17(月) 22:58   No:52254     
Title: Re:C言語でポーカーを作っているんですが その2    
int nは入力した文字の長さstrlen(change)を数値に変換したもの
int indexは変換した数値から1を引いたもので、有効範囲はint nが1〜5
の時に0<=index<=4

もしn_hand[1]かつn_hand[2]かつn_hand[3]かつn_hand[4]かつn_hand[5]なら
(もし23456なら)flag_sを1にしろ
(もちろん上記の書き方で23456は判断出来てませんが
number[n_hand[i]]、number[n_hand[i+1]]…の書き方が駄目なら他の書き方が思いつかない…)

ストレートは、値がi,i+1,i+2,i+3,i+4のようになっているから(最初に書いたような)
その方法で判断しようとしてました

5枚のカードの値がマークは関係なしに連続しているなら(23456とか)ストレートと認識できる

1枚目の数字2を記憶する→残りのカードから1枚目の記憶した数字の±1のカードがあるか
探す→1はなかったが3がある→では4があるか探す→4があった→5はあるか探す→5があった
→6があるか探す→6があった→5枚のカードのチェック終わり
→if(ストレートを判断する条件)ならばflag_sを1にしろ→flag_s=1ならprintf(ストレートを表示)


441ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(81,489ポイント)   Date: 2010/05/17(月) 23:39   No:52256     
Title: Re:C言語でポーカーを作っているんですが その2    
> (もちろん上記の書き方で23456 は判断出来てませんが
> number[n_hand[i]]、number[n_hand[i+1]]…の書き方が駄目なら他の書き方が思いつかない…)

適当に書いてもうまくいくわけがありません。
「適当」と「試行錯誤」は全く別物ですよ。


> 1枚目の数字2を記憶する→残りのカードから1枚目の記憶した数字の±1のカードがあるか
> 探す→1はなかったが3がある→では4があるか探す→4があった→5はあるか探す→5があった
> →6があるか探す→6があった→5枚のカードのチェック終わり
> →if(ストレートを判断する条件)ならばflag_sを1にしろ→flag_s=1ならprintf(ストレートを表示)

近づいてきました。しかし、今度は欲張りすぎです。
23456がストレートであることが判りさえすればよいので、
次の手順を考えて下さい。

1枚目の数字2を記憶する
→2枚目の数字が(2+1)であるか
→3枚目の数字が(2+2)であるか
→4枚目の数字が(2+3)であるか
→5枚目の数字が(2+4)であるか


159ポイント を手に入れた。

Name: ookami  ..上級者(15,924ポイント)   Date: 2010/05/18(火) 12:37   No:52272     
Title: Re:C言語でポーカーを作っているんですが その2    
南瓜さん すみません、51662で回答されていることに気づきませんでした。考え方は合っていますが、「出力結果」を聞いたので、その回答では間違いです。(そういう意味では、前の回答も間違いの部分はあったのですが...)

とはいえ、たいちうさんとのやり取りで、かなり先に進まれているようですので、私とのやり取りはいったん置いておきましょう。


126ポイント を手に入れた。

Name: 南瓜  ..中級者(12,321ポイント)   Date: 2010/05/18(火) 20:51   No:52297     
Title: Re:C言語でポーカーを作っているんですが その2    
ookamiさん、わかりました

一応、判断する時の形らしきものは出来たのですが
同じ23456でも並びが異なる23456(35462とか)は
ストレートと判断されない凡庸性なしの書き方になってしまいました…

数字の記憶とは、int n = 2;みたいな(数字を宣言する)認識よりも
言葉通りに数字を(新たな変数とかに)記憶させるという認識が正しいのでしょうか?


114ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(81,883ポイント)   Date: 2010/05/19(水) 00:24   No:52323     
Title: Re:C言語でポーカーを作っているんですが その2    
> 一応、判断する時の形らしきものは出来たのですが
> 同じ23456でも並びが異なる23456(35462とか)は
> ストレートと判断されない凡庸性なしの書き方になってしまいました…

まず凡庸と汎用の意味を辞書で調べましょう。これでは話が通じません。

35462への対応はもちろん考えていますが、これは次のステップです。
次のステップに進む前に、今のステップをもう少しきれいにしましょう。
判定にforループを使えませんか?


76ポイント を落としてしまった。

Name: 南瓜  ..中級者(12,310ポイント)   Date: 2010/05/19(水) 19:31   No:52360     
Title: Re:C言語でポーカーを作っているんですが その2    
国語力を鍛えねば(笑)…

11ポイント を落としてしまった。

Name: たいちう  ..比類無きプログラマー(81,991ポイント)   Date: 2010/05/19(水) 22:51   No:52368     
Title: Re:C言語でポーカーを作っているんですが その2    
> 国語力を鍛えねば(笑)…

笑いごとではなく、国語力はもちろん英語力も必要ですよ。
でも、その根底にあるのは論理的に思考する能力です。

で、添付されたプログラムは、ストレートを判定できるのですか?


49ポイント を手に入れた。

Name: 南瓜  ..中級者(12,353ポイント)   Date: 2010/05/19(水) 23:29   No:52371     
Title: Re:C言語でポーカーを作っているんですが その2    
あのままでは、判定できないのでこっちで出来るようにしました
判定基準はフラッシュと同じ仕組みです


43ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(81,972ポイント)   Date: 2010/05/20(木) 00:15   No:52373     
Title: Re:C言語でポーカーを作っているんですが その2    
次は、23456と34567のどちらでもストレートと判定できる
ようにしてください。


19ポイント を落としてしまった。

Name: 南瓜  ..中級者(12,416ポイント)   Date: 2010/05/22(土) 19:24   No:52500     
Title: Re:C言語でポーカーを作っているんですが その2    
お待たせしました
順番がバラバラ(35246とか)かエースをまたぐ(10JQKA)以外の
ストレートなら判断出来るようになりました


63ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(83,118ポイント)   Date: 2010/05/22(土) 19:42   No:52504     
Title: Re:C言語でポーカーを作っているんですが その2    
頑張ってますね。
次は35246を判定しましょう。
No:52248を読み返してください。


2倍のポイントを手に入れた! 64ポイント を手に入れた。

Name: 南瓜  ..中級者(12,314ポイント)   Date: 2010/05/23(日) 21:40   No:52628     
Title: Re:C言語でポーカーを作っているんですが その2    
ソートにも多くのやり方があり驚きましたが
今の自分でも理解できそうで、処理にも影響がでないであろう
バブルソートにしました。

順番がバラバラのパターンで、あとすることは
最小値をn_hand[i]の添字にどうすれば組み込めるか、
と考えていますが、解決するにはバブルソートを完全に
理解する必要があるのかな?

またゲーム作りでソートを利用する際、(ジャンルや規模によって違うでしょうが)
バブルソートはどこまで通用するものですか?


102ポイント を落としてしまった。

Name: Ma  ..ハッカー(100,987ポイント)   Date: 2010/05/23(日) 23:27   No:52641     
Title: Re:C言語でポーカーを作っているんですが その2    
シューティングで毎フレームソートするっていうんじゃないなら、O(n^2) のソートでさえもOKです。
あるいは、推定の起動する環境がめちゃくちゃ古いPCでない限り。
今回のような、たまにソートする必要があるだけなら、どんなソートでもあまり気にする必要はないとおもいます。
でもこだわるなら早く処理できるコードのほうが好ましいでしょうが。 編集済み


119ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(83,402ポイント)   Date: 2010/05/24(月) 08:58   No:52650     
Title: Re:C言語でポーカーを作っているんですが その2    
ソート前後でカードを表示してください。
正しくソートできていますか?


> と考えていますが、解決するにはバブルソートを完全に
> 理解する必要があるのかな?

ライブラリを利用することにすれば、ライブラリの利用方法のみ
知っておけば、中身を理解する必要は必ずしもありません。
当然ですが、自分のプログラムでライブラリをどのように使うかは
完全に理解しておく必要があります。

ポーカーの役判定のプログラムと比較すれば、
バブルソートの方がよほど簡単なので、
手を抜かないことをお勧めします。
難しいようならば、ソートするだけのプログラムを作ってはどうですか?


120ポイント を手に入れた。

Name: 南瓜  ..中級者(12,475ポイント)   Date: 2010/05/25(火) 14:51   No:52751     
Title: Re:C言語でポーカーを作っているんですが その2    
ソートの前後を表示させたんですが、正しく出来てると思います
表示上は…
49行目のストレートの判断方法のn_hand[i] == 1+i+k;
のn_hand[i]は、ソートされた後ではなくソート前の値を
参照してストレートを判断してるんだと判ったんですが
だったらn_hand[i]の添字に最小値を組み込むんじゃなくて
最小値自体を記憶させて、それを元に判定した方がいいのか?
書いてて分け判らなくなってきたな…


161ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(85,364ポイント)   Date: 2010/05/25(火) 15:00   No:52752     
Title: Re:C言語でポーカーを作っているんですが その2    
ソートの前後に↓を入れて確認してください。
for(i = 0; i < 5;  i++) {
    printf("%s - %s ", mark[m_hand[i]], number[n_hand[i]]);/* 五枚のカードを表示 */ 
}


58ポイント を手に入れた。

Name: 南瓜  ..中級者(12,516ポイント)   Date: 2010/05/25(火) 16:19   No:52755     
Title: Re:C言語でポーカーを作っているんですが その2    
確認した結果、ソートはうまくいってました
となると判断基準ですが、最小値の(位置?)判断の仕方がわかりません


41ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(85,403ポイント)   Date: 2010/05/25(火) 16:30   No:52757     
Title: Re:C言語でポーカーを作っているんですが その2    
> 確認した結果、ソートはうまくいってました 

ソートの前後に表示された結果をここに貼ってください。
何でしつこく確認を求めていると思いますか?


39ポイント を手に入れた。

Name: 南瓜  ..中級者(12,679ポイント)   Date: 2010/05/25(火) 19:37   No:52772     
Title: Re:C言語でポーカーを作っているんですが その2    
あなたの手札は
42531
♥ - 5 ♦ - 3 ♠ - 6 ♣ - 4 ♣ - 2 
12345
♥ - 2 ♦ - 3 ♠ - 4 ♣ - 5 ♣ - 6 
♥ - 2 ♦ - 3 ♠ - 4 ♣ - 5 ♣ - 6 
error
error
error
error
error
他の役

実はうまくいってなかったのか?


163ポイント を手に入れた。

Name: 南瓜  ..中級者(12,659ポイント)   Date: 2010/05/28(金) 20:07   No:52956     
Title: Re:C言語でポーカーを作っているんですが その2    
ソートの自力での解決が困難なため
ペア系の判定で出来る所までやりました


20ポイント を落としてしまった。

Name: ドラ  ..初心者(5,479ポイント)   Date: 2010/05/29(土) 06:20   No:52986     
Title: Re:C言語でポーカーを作っているんですが その2    
>ソートの自力での解決が困難なため 
ソートのロジックが間違っているのではなくn_hand配列のみソートしてしまったので、
n_hand配列とm_hand配列の同じ添字の要素には同一カードの数字とマークの情報が
分割して格納されているという大前提が崩れているのですよ。
そのため手札の表示でバグっているのですが、気付かないのですか?


>for(i = 0; i < 5; i++) {
>    if(n_hand[0] == n_hand[i]){
>        flag_p++;
>    }
>}
flag_p は n_hand[0]と同じ数字のカードを何枚持っているかでしょう?
この情報だけで役判定できますか?


>for(i = 0; i < 5; i++) {
>    if((n_hand[2] == n_hand[3]) || (n_hand[3] == n_hand[4])) {
>        flag_two++;
>    }
>}
for文内でiを使っていないのに5回繰り返す意味が分からない・・・


役判定は同じ数字のカードを何枚ずつ持っているかという情報を作ってから
やった方が簡単になると思いますがどうでしょうか?

後、処理を機能ごとに関数に切り分けていくという事を覚えた方がよさそうです。
 


409ポイント を手に入れた。

Name: 南瓜  ..中級者(12,994ポイント)   Date: 2010/05/31(月) 23:18   No:53192     
Title: Re:C言語でポーカーを作っているんですが その2    
言われて気づけば、マークがまったく変わってなかったorz
書き直したので、表示はまともになりました

ツーペアの所は意味が無い事に気づいて書き直したんですが、投稿したやつは
直す前の方でした

>役判定は同じ数字のカードを何枚ずつ持っているかという情報を作ってから

とは例えばフォーカードなら for文を書かないで
if(((n_hand[0]==n_hand[1])&&(n_hand[0]==n_hand[2])&&(n_hand[0]==n_hand[3]))||
        ((n_hand[1]==n_hand[2])&&(n_hand[1]==n_hand[3])&&(n_hand[1]==n_hand[4])))

という風に書けばいいんでしょうか?

ヘッダーファイルを使いこなせれば、すっきりして判りやすくなりますよね
役の判断が出来てからヘッダーファイルを使って分割しようと思います


335ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(89,515ポイント)   Date: 2010/06/01(火) 08:57   No:53209     
Title: Re:C言語でポーカーを作っているんですが その2    
> とは例えばフォーカードなら for 文を書かないで

例えば int buf[13]; という配列を用意して、
2, 3, 4, 4, 5 のワンペアの場合、

buf[1] = 1;
buf[2] = 1;
buf[3] = 2;
buf[4] = 1;
(後は全部0)

となるように数えておく、ということでしょう。
その後に判定です。
(フルハウスの判定は先にした後で、)2が1つみつかったらワンペア。


> ヘッダーファイルを使いこなせれば、すっきりして判りやすくなりますよね

まず使うべきなのは関数です。
ヘッダーファイルを使わなくても関数は使えます。


113ポイント を手に入れた。



Name: ゆう  ..かけだし(1,649ポイント)   Date: 2010/05/31(月) 07:58   No:53137       
Title: 斬られたときの振動の表現    
ドラクエ系のRPGの戦闘なんかでよくある
「斬られたときの振動」のようなエフェクトを作りたいと思っています。
モンスターがソード等でダメージを受けたときに、上下(もしくは左右)に一瞬揺れる表現です。
要は表示位置を調整してやればいいのだとは思うのですが、
具体的にどのように処理するといいのか考えがまとまりません。
何かいい方法、もしくはヒント等ありましたらお願いします。


136ポイント を手に入れた。


Name: Justy  ..伝説なるハッカー(537,879ポイント)   Date: 2010/05/31(月) 20:54   No:53167     
Title: Re:斬られたときの振動の表現    
 大きく分けると方法は2つあります。

1 全てのオブジェクトをオフセットで移動する

 丁度龍神録が採用している方式です。
 移動量を管理するクラスを作って、揺らしたい全てのオブジェクトの座標にこのクラスの x方向と y方向の
オフセット移動量を足します。

 龍神録では「ドンと揺れる」dn_t型がその移動量クラスとなっています。
 
龍神録プログラミングの館 22章
http://dixq.net/rp/22.html

 実際の使用例は

龍神録プログラミングの館 24章
http://dixq.net/rp/24.html
のソースの dn変数の使われ方を見て下さい。

 ボスの描画(graph_boss関数)や弾の描画(graph_bullet関数)で表示する座標に
dn.xや dn.yを足し込んでいます。

 この dn.xや dn.yは 22章の dn_calc関数内で、揺れていないときは 0、揺れるときは
毎フレームランダムな移動量になるよう管理されています。



2 全てを描画後最後に移動する

 1と同様揺れる移動量を管理するクラスを作ります。
 
 揺らしたいオブジェクトをバックバッファではなく、画面と同じ大きさのテクスチャにそのままの位置で
レンダリングしていきます。
 画面上のオブジェクト全てを揺らすなら、全てをここでレンダリングして下さい。

 これで揺らしたい絵が出来上がりましたので、レンダリング先をバックバッファに切り替え、
そのレンダリングしたテクスチャの表示位置(揺れないときは左上が [0, 0])を移動量クラスの
情報に沿って適切にずらして表示します。
 このあたりは1と同じですね。


 実際の処理は状況に合わせていろいろあるでしょうが、考え方としてはこんなところです。


716ポイント を手に入れた。

Name: ゆう  ..かけだし(1,988ポイント)   Date: 2010/05/31(月) 22:29   No:53181     
Title: Re:斬られたときの振動の表現    
丁寧な回答ありがとうございます。

私も、画面全体よりは個々のユニットを揺らす感じがほしいので、
1の個々の描画オフセット量をクラスか何かで管理する形になりそうです。
(2の、まとめて揺らすという手もあるんですね。とても参考になりました)

ただ、具体的なオフセット量の算出をどうしたらいいのかがよくわかりません。
もちろんここは、求める演出次第だとは思うのですが・・・。
龍神録ではランダムに揺らしてる感じになってるみたいですね。
私が想定しているのは、
・ランダムではなく一方向に揺れる(縦に揺れる感じ)
・最初が一番揺れが大きく、次第に小さくなって止まる
・揺れの一往復にかかる時間は、揺れ幅が違っていても常に(だいたい)一定
・数往復程度揺れて、最終的に止まるまでせいぜい1秒程度
という感じです。
イメージは大体あるのですが、それを実際うまくコードに起こせません。
もう少し悩んでみようと思います。


339ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(86,153ポイント)   Date: 2010/05/31(月) 22:56   No:53186     
Title: Re:斬られたときの振動の表現    
(3^(-t/100))*COS(t/50)*COS(t/1)
ただし、"^"は指数を意味する。

t=80ぐらいのときにほぼ0となる。数回振動しながら小さくなっていく関数です。

100や50や1の値を自分が欲しい動きになるように調節してあげてください。
エクセルでグラフ書いてあげると分かりやすいと思います。


//式を明確にするために括弧を追加 編集済み


2倍のポイントを手に入れた! 228ポイント を手に入れた。

Name: ゆう  ..かけだし(2,177ポイント)   Date: 2010/06/01(火) 03:18   No:53205     
Title: Re:斬られたときの振動の表現    
おお、ありがとうございます。
Excelでグラフにしてみたら、確かに私が求めていたものにかなり近いです。
それにしても難しい式ですね・・・理解しようとしてもちんぷんかんぷんです。
自分で思いつくのは不可能でしたね、これは・・・。

厚かましいお願いですが、もしわかったら教えていただきたいのですが、
↑の式は「-○〜○」の範囲で動きますが、
同じイメージで「0〜○」の範囲で動く式はどのようになるのでしょうか。


189ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(86,341ポイント)   Date: 2010/06/01(火) 06:54   No:53207     
Title: Re:斬られたときの振動の表現    

最大値は負の範囲にありますが、別にそのまま0以上の範囲で使ってくれてかまいませんよ。

こっちは使いやすいように係数の意味をきちんと与えたばーじょんです。
(2^(-t/D))*COS(t*B*(2*PI()))*COS(t*PI()/(C*2))*A
A:t=0のときの大きさ=最大値
B:振動数
C:値が0になるまでの時間
D:減少の仕方を表す。大きいと最初はなだらかに減少。
PI()は円周率を意味する。
"^"は指数を意味する。


188ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(86,390ポイント)   Date: 2010/06/01(火) 08:24   No:53208     
Title: Re:斬られたときの振動の表現    
質問の意味を勘違いしてていたかも。
こちらはどうですか。
(2^(-t/D))*COS(t*B*(2*PI()))*COS(t*PI()/(C*2))*COS(t*B*(2*PI()))*A
 編集済み


49ポイント を手に入れた。

Name: ゆう   Date: 2010/06/03(木) 21:04   No:531371275566684     
Title: Re:斬られたときの振動の表現    
返信が遅れて申し訳ありません。
係数の具体的な説明ありがとうございます。

新しくご提示いただいた式は、どうにも複雑すぎて理解不能でした。
(係数が具体的でなかったので、思ったようなグラフに出来ませんでした)

ただ揺らすだけなのでそれほど難しくないと思っていたのですが、
予想外に複雑になったりしますね。
教えていただいたことを参考に、やってみたいと思います。
ありがとうございました!




Name: act  ..ぴよぴよ(17ポイント)   Date: 2010/05/31(月) 22:21   No:53179       
Title: 譜面データを読むときに    
このサイトの太鼓の鉄人を参考にしながら太鼓の達人もどきを作ろうとしているのですが、譜面を追加するときに一曲ごとにフォルダを作ってその中に譜面のデータなどをいれるようにしたいのですが、このようにすると譜面のデータを読むときにどのようにパスを指定すればいいのかがわからないのですが、どうすれば上手くいくでしょうか。 編集済み

17ポイント を手に入れた。


Name: ookami  ..上級者(17,523ポイント)   Date: 2010/05/31(月) 22:39   No:53182     
Title: Re:譜面データを読むときに    
"フォルダ/ファイル名"のように、"/"などで区切る、ということではなくてですか?

21ポイント を手に入れた。

Name: act  ..ぴよぴよ(136ポイント)   Date: 2010/05/31(月) 23:01   No:53188     
Title: Re:譜面データを読むときに    
日本語おかしくてすいません。自分でもなんて言っていいかわからなくて…
曲ごとのフォルダの名前はプログラムを作った後に決めるわけじゃないですか、となるとそのフォルダの中のファイルにアクセスしたいときにどうすればアクセスできるかがわからなくて困っています。


119ポイント を手に入れた。

Name: ookami  ..上級者(18,132ポイント)   Date: 2010/05/31(月) 23:13   No:53191     
Title: Re:譜面データを読むときに    
むむむ... さっぱり分かりませんが、こういうことかな?
sprintf(fullpath,"%s/%s",folder,filename);

とりあえず、参考にされたページのURLと、作りかけのソースを貼ってみましょうか。


2倍のポイントを手に入れた! 184ポイント を手に入れた。

Name: act  ..ぴよぴよ(277ポイント)   Date: 2010/05/31(月) 23:24   No:53193     
Title: Re:譜面データを読むときに    
えーと、まだ頭の中で考えているだけでソースは書いていません(汗)
stepmaniaって言うゲームがあるじゃないですか。あれのように曲を追加できるようにしたいのですが、プログラムを作る段階ではどのようなフォルダ名になるかがわかりませんよね?なのでfopenで譜面を読むにしてもパスがわからず、開けないじゃないですか。この時どうすれば開けるかが知りたいのですが…


141ポイント を手に入れた。

Name: ookami  ..上級者(18,218ポイント)   Date: 2010/05/31(月) 23:31   No:53194     
Title: Re:譜面データを読むときに    
フォルダ内のファイルを検索して処理するということでしょうか?

    WIN32_FIND_DATA fd;
    HANDLE hFind;
    hFind = FindFirstFile(pattern,&fd);
    if(hFind==(HANDLE)-1) return;
    do{
        printf(fd.cFileName);
    }while(FindNextFile(hFind,&fd));
    FindClose(hFind);


86ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,194,885ポイント)   Date: 2010/05/31(月) 23:35   No:53195     
Title: Re:譜面データを読むときに    
そんな時は「FindFirstFile」でググってみるといいですよ。
http://www.google.co.jp/search?hl=ja&q=FindFirstFile&lr=lang_ja

リンク先を見ればフォルダ内のファイルのリストアップの仕方が書いてあります。


98ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,194,906ポイント)   Date: 2010/05/31(月) 23:35   No:53196     
Title: Re:譜面データを読むときに    
う、のんびり書いてたら被ってしまいました、すみません;

21ポイント を手に入れた。

Name: act  ..ぴよぴよ(345ポイント)   Date: 2010/05/31(月) 23:51   No:53198     
Title: Re:譜面データを読むときに    
win32という単語が出てくると言うことはwin32APIを使うということですよね。
私はwin32APIを勉強してきてないのですがこの処理をしたいとなるとやはり勉強してこなくてはいけないですよね…
Cの標準関数でなんとかならないものでしょうか?


68ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,195,192ポイント)   Date: 2010/05/31(月) 23:59   No:53199     
Title: Re:譜面データを読むときに    
そんなに抵抗すること無いと思いますが、どうでしょう?

ookamiさんのプログラムどこか解らないでしょうか?
解りやすく書かれていると思いますが。

fd.cFileNameがファイル名です。
ファイルが見つかる限りクルクルループを周ります。
後ろの3文字を見れば欲しいファイルかどうかがわかるでしょう。

私の書いたリンク先にあるプログラムを見ればif文ひとつでフォルダかどうか判断する方法も書いてあります。

Cの標準関数にはフォルダ内のフォルダやファイルを列挙する関数はありません。


205ポイント を手に入れた。

Name: Libra  ..上級者(20,562ポイント)   Date: 2010/06/01(火) 00:26   No:53201     
Title: Re:譜面データを読むときに    
以前(1年半くらい前?)
この掲示板に提示されたソースなら持ってます

#include <stdio.h>
#include <dirent.h>

int main(void)
{

        struct dirent* f;

        DIR* fd;

        fd = opendir(".");

        if (fd == NULL) {

            printf("open dir error\n");

            return 0;

        }

        while (f = readdir(fd)) {

            printf("%s\n", f->d_name);

        }

        closedir(fd);

        return 0;
}


WinAPI無しの方法ですね。 編集済み


131ポイント を手に入れた。

Name: act  ..ぴよぴよ(386ポイント)   Date: 2010/06/01(火) 01:07   No:53203 解決!     
Title: Re:譜面データを読むときに    
了解しました。
この方法を使えばなんとかなりそうなので少し勉強してきます。
夜遅くにどうもありがとうございました。


41ポイント を手に入れた。



Name: オーシロ  ..かけだし(1,171ポイント)   Date: 2010/05/31(月) 14:05   No:53141       
Title: 入力の処理でつまづいています    
始めまして、オーシロと申します。

入力関連の処理で楽をしてみようと、
必要なボタンの構造体を配列で用意して、
for文で1つずつ入力されているかどうかをチェックする処理を考えました。

それで私が書いたのが以下のようなソースです。

#include <DxLib.h>

//ボタンの数
#define BUTTON_NUM    8

//各ボタン
#define KEY_UP        0
#define KEY_DOWN    1
#define KEY_LEFT    2
#define KEY_RIGHT    3
#define KEY_BUTTON1    4
#define KEY_BUTTON2    5
#define KEY_BUTTON3    6
#define KEY_BUTTON4    7

//ボタンの構造体
typedef struct{
    int Handle;    //ボタンのビット
    int Time;    //ボタンが入力された時間
} button_data;

//入力の構造体
typedef struct{
    int PadInput;    //入力媒体のビット
    button_data Button[BUTTON_NUM];    //ボタンの数だけボタンの構造体
} input_data;

//グローバル宣言
input_data Input;

//入力の構造体の初期化
void InputInit(){
    //入力媒体のビットを入れる
    Input.PadInput = GetJoypadInputState(DX_INPUT_KEY_PAD1);
    //各ボタンのビットを入れる。後々にコンフィグで変更できるようにしたい
    Input.Button[KEY_UP].Handle = PAD_INPUT_UP;
    Input.Button[KEY_DOWN].Handle = PAD_INPUT_DOWN;
    Input.Button[KEY_LEFT].Handle = PAD_INPUT_LEFT;
    Input.Button[KEY_RIGHT].Handle = PAD_INPUT_RIGHT;
    Input.Button[KEY_BUTTON1].Handle = PAD_INPUT_A;
    Input.Button[KEY_BUTTON2].Handle = PAD_INPUT_B;
    Input.Button[KEY_BUTTON3].Handle = PAD_INPUT_X;
    Input.Button[KEY_BUTTON4].Handle = PAD_INPUT_Y;
    //それぞれの入力時間は最初はゼロ
    for(int i=0;i<BUTTON_NUM;i++){
        Input.Button[i].Time = 0;
    }
}

//入力されているかをチェックする関数
void InputCheck(){
    for(int i=0;i<BUTTON_NUM;i++){
        //各ボタンの入力状況をチェック
        if(Input.PadInput & Input.Button[i].Handle){
            //入力されていたらカウント
            Input.Button[i].Time++;
        }
        else{
            //入力されていなかったら0に戻す
            Input.Button[i].Time = 0;
        }
    }
}

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

    InputInit();
    while(ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0){
        ClearDrawScreen();
        InputCheck();

        for(int i=0;i<BUTTON_NUM;i++){
            DrawFormatString(0, 0 + i * 20, GetColor(255, 255, 255), "%3dは押されてから%5d回カウントされました", Input.Button[i].Handle, Input.Button[i].Time);
        }
        ScreenFlip();
    }

    DxLib_End();
    return 0;
}

これをコンパイルして実行してみたところ、なぜかボタンを押してもカウントされませんでした。
どこが駄目なのでしょうか?

OSはWindowsXP Professional SP3で、開発環境はMicrosoft Visual C++ 2008です。
Cに関する知識は基礎はある程度できるほうだと思います。


1,171ポイント を手に入れた。


Name: Justy  ..伝説なるハッカー(537,163ポイント)   Date: 2010/05/31(月) 20:19   No:53163     
Title: Re:入力の処理でつまづいています    
>どこが駄目なのでしょうか? 
 パッドの押下情報……Input.PadInputを毎フレーム更新して下さい。


2倍のポイントを手に入れた! 88ポイント を手に入れた。

Name: オーシロ  ..かけだし(1,184ポイント)   Date: 2010/06/01(火) 00:50   No:53202 解決!     
Title: Re:入力の処理でつまづいています    
> >どこが駄目なのでしょうか? 
>  パッドの押下情報……Input.PadInputを毎フレーム更新して下さい。

あっ…。
なんて情けないケアレスミス。すみません、ありがとうございました。


13ポイント を手に入れた。



Name: ひよこ  ..比類無きプログラマー(83,113ポイント)   Date: 2010/05/30(日) 16:10   No:53080       
Title: 変数の中身がおかしい    
いつもお世話になっています。
ちょっとしたソフトを作っているのですが
おかしな現象が起きています。
i=0;と代入したのにi=260;となってたり
i=sとしてiとsの値が違っていたりと何かが起きているのですが、
どうすればいいでしょうか?私自身もこういうことは初めてで困っています。
VC++2008EE Vistaです。よろしくお願いします。 


118ポイント を手に入れた。


Name: ぽこ  ..中級者(12,469ポイント)   Date: 2010/05/30(日) 16:27   No:53082     
Title: Re:変数の中身がおかしい    
一旦、「クリーン」を行ってリビルドしてみては?
それでダメな場合、*.pdbファイルを消去して、リビルドしてみてはどうでしょうか?


62ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(536,691ポイント)   Date: 2010/05/30(日) 16:27   No:53083     
Title: Re:変数の中身がおかしい    
 コンパイラの最適化はオフですか?

10ポイント を手に入れた。

Name: ひよこ  ..比類無きプログラマー(83,158ポイント)   Date: 2010/05/30(日) 16:41   No:53085     
Title: Re:変数の中身がおかしい    
ぽこさん、クリーンしてリビルドしてみましたが、できませんでした。
Justyさんコンパイラの最適化はオフですか?
>>プロジェクトのリンカの最適化はすべて既定値となっています。
一回再インストールしてみます。


45ポイント を手に入れた。

Name: メタ  ..かけだし(1,059ポイント)   Date: 2010/05/30(日) 16:43   No:53086     
Title: Re:変数の中身がおかしい    
ひょっとしたらグローバル変数が・・・


12ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(536,974ポイント)   Date: 2010/05/30(日) 16:59   No:53089     
Title: Re:変数の中身がおかしい    
>リンカの最適化
 どの設定を見ていますか?
 コンパイラ(構成プロパティ → C/C++ → 最適化)の方です。
 判らなければ、今構成は Debug/Releaseどっちになっていますか?


>リビルドしてみましたが、できませんでした。
 リビルド出来なかった、ということですか?
 リビルドに失敗しているとなるとソースと実行ファイル・デバッグ情報に食い違いが発生している
可能性が高いです。

 再インストールの前に、VisualC++を一旦全て終了し、ビルドの成果物(設定が標準なら
Debug/Releaseフォルダ)や ncbファイルを消して、プロジェクトを立ち上げて再度試してみてください。

 ファイル・フォルダが消せないようであれば、OSを再起動してから試して下さい。


283ポイント を手に入れた。

Name: ひよこ  ..比類無きプログラマー(83,416ポイント)   Date: 2010/05/30(日) 17:12   No:53091     
Title: Re:変数の中身がおかしい    
メタさん、グローバル変数がどうしたのでしょうか・・・。
Justyさん
>>もう再インストールしてしまいました。
>>けれど、今でもおかしな値になります。
リビルドしてみましたが、できませんでした。
>>すみません、言葉が足りませんでした。リビルドしてからもおかしな値が出たということです。
最適化は無効となっています。

今、これはと思うことがありました。
for(int i=0;i<MAX_PATH;i++)    
    fileName[i]=num;
問題のソースの前にこういう文があって問題の変数iの定義へ移動をしたら上のfor文のiを指したということは
原因かもしれないと思ったのですが、これが原因の場合どうすればいいでしょうか?


258ポイント を手に入れた。

Name: ひよこ  ..比類無きプログラマー(83,474ポイント)   Date: 2010/05/30(日) 17:17   No:53092     
Title: Re:変数の中身がおかしい    
今変数名を変えて試してみましたら、代入できました。
これはコンパイラのせいなのでしょうか?


2倍のポイントを手に入れた! 58ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(537,267ポイント)   Date: 2010/05/30(日) 17:44   No:53097     
Title: Re:変数の中身がおかしい    
>今変数名を変えて試してみましたら、代入できました。 
 多分ウインドウ上の値がおかしかっただけで、元々できていたと思いますよ。
 基本的にデバッガの値は「デバッガが認識している値」を表示しているだけで、
本当にその変数にその値が入っているかどうかまた別の話ですから。


>これはコンパイラのせいなのでしょうか?
 どちらかというとコーディングスタイルとデバッガの見方に問題があります。
 for文の中と外で同じ変数名(しかも短い)を宣言するというスタイルは言語的には問題ないですが、
お行儀がいいとはちょっと言えません。
 for文の中は iでいいとしても、外の方は何か適切な名前をつけた方がいいですね。

 次に見ているウインドウは多分「自動変数」ウインドウだと思いますが、
こちらは同じ関数内に同じ変数名が複数あるとウインドウ内の変数名の参照先がプログラムの実行に合わせて
変化してしまいます。

 そういう場合は「ローカル」ウインドウの方で確認して見て下さい。
 こちらを使うと、関数内で使われている全てのローカル変数がリストアップされます。 編集済み


293ポイント を手に入れた。

Name: ひよこ  ..比類無きプログラマー(83,577ポイント)   Date: 2010/05/30(日) 18:16   No:53098 解決!     
Title: Re:変数の中身がおかしい    
コーディングスタイルとデバッガの見方に問題があったのですか。
for文で使い回しをしようと思ったらこのようなコーディングになってしまいました。
これからは気をつけようと思います。
ローカルのウィンドウで確認してみましたがちゃんとi=0がありました。
皆様のおかげで解決できました。
ぽこさん、Justyさん、メタさんありがとうございました。


103ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(172,984ポイント)   Date: 2010/05/30(日) 21:25   No:53112     
Title: Re:変数の中身がおかしい    
一言付け加えるならリリースビルドでデバッグすると変数はまともな値を示しませので必ずデバッグビルドでデバッグしてください。リリスービルドの最適化されたものの動作がデバッガで追跡し切れないために起こる現象です。

86ポイント を手に入れた。

Name: ひよこ  ..比類無きプログラマー(83,643ポイント)   Date: 2010/05/30(日) 23:22   No:53122     
Title: Re:変数の中身がおかしい    
softyaさん補足ありがとうございます。
つまり、リリースビルドではデバッグをしないほうがいいということですね。
今回、変数が代入できない現象はデバッグビルドで起きました。
デバッガの使い方が悪かったのが原因でした。


66ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(89,402ポイント)   Date: 2010/05/31(月) 09:54   No:53138     
Title: Re:変数の中身がおかしい    
> つまり、リリースビルドではデバッグをしないほうがいいということですね。

デバッグ用のビルドとリリース用のビルドですので、当然そうなります。

しかし、リリース用のビルドの時にしか発生しないバグもありますので、
その場合は何らかの方法でリリースビルドでビルドした
プログラムをデバッグする必要があります。
デバッグビルドで発生するバグを全てつぶしてからの話ですけど。


52ポイント を手に入れた。

Name: ひよこ  ..比類無きプログラマー(83,663ポイント)   Date: 2010/06/01(火) 00:12   No:53200     
Title: Re:変数の中身がおかしい    
たいちうさん補足ありがとうございます。
リリースビルドのバグですか。
今回はデバッグビルドでデバッガの見方の間違いのせいでまだ良かったです。


20ポイント を手に入れた。



Name: しろ  ..初心者(6,418ポイント)   Date: 2010/05/30(日) 16:03   No:53077       
Title: タイトル画面で一考    
ちょこちょことDXライブラリについて勉強して、(おそらく)一番簡単(であろう)クイズゲームを作ってみることにしました。タイトル画面で選択肢を選ぶところで、下のようなプログラムを作成しました。

GAMESTARTの値の増減で選択肢を選ぶという流れなのですが、パソコンの処理速度のせいか、上下キーでGAMESTARTの値を変えると、いっきにGAMESTARTの値が2くらい増えたりして、うまくありません。

どんなテクニックを使えばうまくいくでしょうか?
最初は分岐をGAMESTART=1,3,5の値をとるとき、選択肢として処理をして、2,4の場合は自動的に1増やす、あるいは減らすというプログラムにしたのですが、これもいまいちな操作性で……

よろしくお願いいたします。


---------------

#include "DxLib.h"

int FontHandle[20];//FontHandle配列を宣言
char Key[256];//Key配列を宣言


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理

    int GAMESTART=1;
 
    SetGraphMode(1024,768,32) ;// 画面モードの変更
    

    

    FontHandle[0]= CreateFontToHandle("MS 明朝" , 30 , 2 , DX_FONTTYPE_NORMAL);//FontHandle[0]がフォントデータを取得
    FontHandle[1]= CreateFontToHandle("MS 明朝" , 20 , 2 , DX_FONTTYPE_NORMAL);//FontHandle[0]がフォントデータを取得



    
    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
              //↑メッセージ処理         ↑画面をクリア           ↑キーボード入力状態取得      ↑ESCが押されていない
            
        if(GAMESTART==1){

                DrawStringToHandle( 290 , 150 ,"(仮名前)クイズゲーム", GetColor(255,255,255) , FontHandle[0] ) ;
                DrawStringToHandle( 400 , 300 ,"ゲームを始める", GetColor(255,255,255) , FontHandle[1] ) ;
                DrawStringToHandle( 400 , 350 ,"記録を見る", GetColor(0,255,255) , FontHandle[1] ) ;
                DrawStringToHandle( 400 , 400 ,"ゲームを終わる", GetColor(0,255,255) , FontHandle[1] ) ;
                
                    if(Key[KEY_INPUT_DOWN]){
                        GAMESTART++;
                }
                    
                
                ScreenFlip();//裏画面を表画面に反映
        }
        

                if(GAMESTART==2){

                    DrawStringToHandle( 290 , 150 ,"(仮名前)クイズゲーム", GetColor(255,255,255) , FontHandle[0] ) ;
                    DrawStringToHandle( 400 , 300 ,"ゲームを始める", GetColor(0,255,255) , FontHandle[1] ) ;
                    DrawStringToHandle( 400 , 350 ,"記録を見る", GetColor(255,255,255) , FontHandle[1] ) ;
                    DrawStringToHandle( 400 , 400 ,"ゲームを終わる", GetColor(0,255,255) , FontHandle[1] ) ;

                    if(Key[KEY_INPUT_DOWN]){
                        GAMESTART++;
                }
                    if(Key[KEY_INPUT_UP]){
                        GAMESTART--;
                }

                    
                    ScreenFlip();//裏画面を表画面に反映

                }

                if(GAMESTART==3){

                    DrawStringToHandle( 290 , 150 ,"(仮名前)クイズゲーム", GetColor(255,255,255) , FontHandle[0] ) ;
                    DrawStringToHandle( 400 , 300 ,"ゲームを始める", GetColor(0,255,255) , FontHandle[1] ) ;
                    DrawStringToHandle( 400 , 350 ,"記録を見る", GetColor(0,255,255) , FontHandle[1] ) ;
                    DrawStringToHandle( 400 , 400 ,"ゲームを終わる", GetColor(255,255,255) , FontHandle[1] ) ;

                    if(Key[KEY_INPUT_UP]){
                        GAMESTART--;
                }
                    if(Key[KEY_INPUT_RETURN]){//Enterキーを押すとゲーム終了。
                    break;
                    }

                    ScreenFlip();//裏画面を表画面に反映

                }
                

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

    return 0 ;        // ソフトの終了

}

---------------------------------


1,072ポイント を手に入れた。


Name: ookami  ..上級者(17,428ポイント)   Date: 2010/05/30(日) 16:08   No:53079     
Title: Re:タイトル画面で一考    
プログラムを見ると、ボタンを押している間は毎フレームGAMESTARTを増減するようですね。
キーを押した最初の1フレームだけ増減するようにしてはいかがでしょうか。
http://dixq.net/g/41.html


90ポイント を手に入れた。

Name: しろ  ..初心者(6,452ポイント)   Date: 2010/05/30(日) 16:30   No:53084     
Title: Re:タイトル画面で一考    
なるほど、こんな便利な関数があったんですね。

どうもありがとうございます。 編集済み


34ポイント を手に入れた。

Name: しろ  ..初心者(7,182ポイント)   Date: 2010/05/30(日) 17:17   No:53093     
Title: Re:タイトル画面で一考    
すいません。以下のように書き換えました。(一部関数を追加しています。)

でも↑入力はうまくいきますが、↓入力はやはり同じ状況になってしまいます。

どこかまずい部分があるでしょうか?

----------------
#include "DxLib.h"

int FontHandle[20];//FontHandle配列を宣言
void Title_Quiz(int *pT);//Title_Quiz関数の宣言


int GetHitKeyStateAll_2(int Keys[]){
        char Key1[256];
        GetHitKeyStateAll(Key1);
        for(int i=0;i<256;i++){
                if(Key1[i]==1) 
                    Keys[i]++;
                else              
                    Keys[i]=0;
        }
        return 0;
}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理

    int GAMESTART=1;
    int Key[256];//Key配列を宣言

 
    SetGraphMode(1024,768,32) ;// 画面モードの変更
    

    

    FontHandle[0]= CreateFontToHandle("MS 明朝" , 30 , 2 , DX_FONTTYPE_NORMAL);//FontHandle[0]がフォントデータを取得
    FontHandle[1]= CreateFontToHandle("MS 明朝" , 20 , 2 , DX_FONTTYPE_NORMAL);//FontHandle[0]がフォントデータを取得



    
    while(ProcessMessage()==0 &&ClearDrawScreen()==0 && GetHitKeyStateAll_2( Key )==0 && Key[KEY_INPUT_ESCAPE]==0){
              //↑メッセージ処理         ↑画面をクリア           ↑キーボード入力状態取得          ↑ESCが押されていない
            
        if(GAMESTART==1){

            int Quiz[3]={255,0,0};

            Title_Quiz(Quiz);
                
                    if(Key[KEY_INPUT_DOWN]==1){
                        GAMESTART=2;
                }
                    
                
                ScreenFlip();//裏画面を表画面に反映
        }
            

                if(GAMESTART==2){

                    int Quiz[3]={0,255,0};

                    Title_Quiz(Quiz);

                    if(Key[KEY_INPUT_DOWN]==1){
                        GAMESTART=3;
                }
                    if(Key[KEY_INPUT_UP]==1){
                        GAMESTART=1;
                }

                    
                    ScreenFlip();//裏画面を表画面に反映

                }

                if(GAMESTART==3){

                    int Quiz[3]={0,0,255};

                    Title_Quiz(Quiz);

                    if(Key[KEY_INPUT_UP]==1){
                        GAMESTART=2;
                }
                
                    if(Key[KEY_INPUT_RETURN]==1){//Enterキーを押すとゲーム終了。
                    break;//whileから脱出
                    }

                    ScreenFlip();//裏画面を表画面に反映

                }
                

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

    return 0 ;        // ソフトの終了

}



void Title_Quiz(int *pT){            //Title_Quiz関数
    
    DrawStringToHandle( 290 , 150 ,"(仮名前)クイズゲーム", GetColor(255,255,255) , FontHandle[0] ) ;
    DrawStringToHandle( 400 , 300 ,"ゲームを始める", GetColor(pT[0],255,255) , FontHandle[1] ) ;
    DrawStringToHandle( 400 , 350 ,"記録を見る", GetColor(pT[1],255,255) , FontHandle[1] ) ;
    DrawStringToHandle( 400 , 400 ,"ゲームを終わる", GetColor(pT[2],255,255) , FontHandle[1] ) ;

}


730ポイント を手に入れた。

Name: ookami  ..上級者(17,697ポイント)   Date: 2010/05/31(月) 22:50   No:53185     
Title: Re:タイトル画面で一考    
if(GAMESTART==2){
    :
}
if(GAMESTART==3){
    :
}
if(GAMESTART==4){
    :
}
の、if を else if にしてはいかがでしょうか。

あとまぁ、書き方のスタイルは人それぞれなんでいいですが、whileループの中に複数ScreenFlipがあるのは違和感ありませんか?


48ポイント を手に入れた。



Name: pon  ..かけだし(1,503ポイント)   Date: 2010/05/24(月) 14:23   No:52662       
Title: 情報オリンピック予選過去問    
情報オリンピック2008-2009の予選の3番なのですが、
問題:http://www.ioi-jp.org/joi/2008/2009-yo-prob_and_sol/2009-yo-t3/2009-yo-t3.html

添付したようなプログラムを組みました。
かなり遅いので、解説を見ていると同じことをしている気がします。
何が問題でこんなに遅いのでしょうか。


119ポイント を手に入れた。


Name: toyo  ..熟練のプログラマー(46,305ポイント)   Date: 2010/05/24(月) 15:18   No:52664     
Title: Re:情報オリンピック予選過去問    
ループの一番中にある
for(int henkou=idou;henkou<idou+ren+1;henkou++){
    b[henkou]=b[henkou+ren+1];
}

で配列の内容を書き換えているのために処理に時間がかかるのでは
ループの中のインデントが深くなるほど処理に時間がかかるようになると思います
自分のパソコンの中を覗いたら昔書いたVisualC++2008のプロジェクトがあったのでアップしてみます
実際のゲームで画面を表示するなら配列の書き換えも必要になると思いますが計算をするだけなら移動処理はせずに数をカウントするだけでいいということです


209ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(84,618ポイント)   Date: 2010/05/24(月) 15:57   No:52665     
Title: Re:情報オリンピック予選過去問    
toyoさんに先を越されたけど、一応載せておきます。
アルゴリズムは一緒ですね。

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int data[10000];
int len;

int check(int index) {
    int lIndex = index;
    int rIndex = index + 1;
    int lLeft = index + 1;
    int rLeft = len - rIndex;

    for (;;) {
        int lCol = lIndex >= 0 ? data[lIndex] : 0;
        int lNum = 0;
        while (lIndex >= 0 && data[lIndex] == lCol) {
            lNum++;
            lIndex--;
        }

        int rCol = rIndex < len ? data[rIndex] : 0;
        int rNum = 0;
        while (rIndex < len && data[rIndex] == rCol) {
            rNum++;
            rIndex++;
        }

        if (lCol == rCol && lNum + rNum >= 4) {
            lLeft -= lNum;
            rLeft -= rNum;
        } else
            return lLeft + rLeft;
    }
}

void test(const string &fileName) {
    ifstream ifs(fileName.c_str());
    ifs >> len;
    for (int i = 0; i < len; i++) {
        int buf;
        ifs >> buf;
        data[i] = buf;
    }

    int min = len;
    for (int i = 0; i < len; i++) {
        for (int c = 1; c <= 3; c++) {
            if (data[i] == c) continue;
            if ((i > 0 && data[i - 1] == c) || (i < len - 1 && data[i + 1] == c)) {
                int c0 = data[i];
                data[i] = c;
                int left = check(i);
                if (min > left)
                    min = left;
                data[i] = c0;
            }
        }
    }
    cout << fileName << " : " << min << endl;
}

int main() {
    test("sample_1.txt");
    test("sample_2.txt");
    test("data_1.txt");
    test("data_2.txt");
    test("data_3.txt");
    test("data_4.txt");
    test("data_5.txt");

    return 0;
}


480ポイント を手に入れた。

Name: toyo  ..熟練のプログラマー(46,513ポイント)   Date: 2010/05/24(月) 16:17   No:52666     
Title: Re:情報オリンピック予選過去問    
このループの意図がわかりません
            for(int lop=1;lop>0;lop++){
                int idou;
                if(kesita>3){idou=kesita-3;}
                else{idou=0;}
                while(1){
//省略
                }//whileはここまで!!一回消す作業
                if(flag==0){
                    break;
                }
            }//一個変えたことによる連鎖計算終了

ループの中にflagを1にする文はありますが0にする文がありません
いったんflagが1になるとlopがオーバーフローして負になるまで繰り返してしまいます
無限ループでfor ( ; ; )やwhile(1)は見ますがfor(int lop=1;lop>0;lop++)のような書き方は変ですね


208ポイント を手に入れた。

Name: pon  ..かけだし(1,564ポイント)   Date: 2010/05/24(月) 16:18   No:52667     
Title: Re:情報オリンピック予選過去問    
配列を書き変えたのが良くなかったんですね
ありがとうございます

合格のボーダーの63点ギリギリしか取れなくて焦っています
何を勉強すればいいんでしょうか


61ポイント を手に入れた。

Name: pon  ..かけだし(1,635ポイント)   Date: 2010/05/24(月) 16:38   No:52668     
Title: Re:情報オリンピック予選過去問    
>>toyoさん
そうですね
flagの初期化の位置がおかしかったですね
flagの初期化の位置をちゃんとしてみたら、動作はかなり速くなったのですが、サンプル以外のinputに対して正確な答えを返しませんどうしてでしょう


71ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(84,932ポイント)   Date: 2010/05/24(月) 16:50   No:52669     
Title: Re:情報オリンピック予選過去問    
> 合格のボーダーの63点ギリギリしか取れなくて焦っています
> 何を勉強すればいいんでしょうか

・言語の知識
  間違っても足を引っ張ることのないようにしておきましょう。
  完璧に覚えなくても良いけど、過去問を解くのに必要な構文は
  最低限マスターしましょう。

・アルゴリズム
  アルゴリズムに精通していれば、問題を見た瞬間に
  役に立ちそうなアルゴリズムを思いつく可能性が上がります。
  良いプログラムを多く読んでおくことも大事。

・応用力
  初見の問題で短時間で効率の良いプログラムを作るには、
  応用力が最も必要です。
  言語の知識が完璧でも、アルゴリズム辞典を覚えていても、
  応用力が貧弱だと役に立ちません。
  言語やアルゴリズムの習得を通じて、多くのプログラムに触れ、
  多くのプログラムを書いて、応用力を養っていくのが唯一の方法だと思います。

言語とアルゴリズムは、努力次第で何とでもなりますが、
個人的には応用力はそうとは限らないと思います。
最初から応用が得意な人もいれば、努力しても応用力が身に付かない人もいます。
努力して応用力が強化される人もいるでしょうから、無駄な努力とは限りませんが。
量的な努力よりも工夫が重要だと思いますが、工夫できる人は既に応用力を
持っているともいえるし……
難しいところですね。

日本情報オリンピックだけをターゲットにした練習もあるとは思いますが、
それこそ不毛かもしれませんね。何を焦っているのか書いてもらえると、
もっとアドバイスできるかもしれませんが。


314ポイント を手に入れた。

Name: pon  ..かけだし(1,849ポイント)   Date: 2010/05/24(月) 21:28   No:52685     
Title: Re:情報オリンピック予選過去問    
・言語の知識
一応C++の本は読んでポインタやクラス以外は理解し覚えたつもりです(ポインタは一応意味は分かるのですが、何のために必要かが分かりません。クラスは意味がイマイチわかりませんでした。)

・アルゴリズム
これは全く知らないと言って過言でないかもしれません。
一応メモ化再帰やDPは分かりますが。

・応用力
それは自分ではよく分かりません。

自分は高2のため情報オリンピックを受けるのは最後のチャンスなので、とりあえず頑張りたいなと思っているのです。あと、単純にプログラミングができるようになりたいということです。

で、本題に戻るのですが、結局何が間違っているのでしょうか


214ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(85,083ポイント)   Date: 2010/05/25(火) 00:13   No:52701     
Title: Re:情報オリンピック予選過去問    
> ・アルゴリズム
> これは全く知らないと言って過言でないかもしれません。
> 一応メモ化再帰やDPは分かりますが。

まずはアルゴリズムを広く深く勉強することですね。
そして必要に応じて言語の知識を補強していきます。


> で、本題に戻るのですが、結局何が間違っているのでしょうか

まずtoyoさんに指摘された部分を直しましょう。
その後で考えても判らないならば、その時のプログラムを載せて下さい。
自分のプログラムを暫く忘れて、toyoさんや私のプログラムを解析するのも良いでしょう。


123ポイント を手に入れた。

Name: pon  ..かけだし(1,941ポイント)   Date: 2010/05/25(火) 22:11   No:52787     
Title: Re:情報オリンピック予選過去問    
toyoさんやたいちうさんのプログラムは分かりました。
結局は配列を並び変えていないことを除くと基本的には自分のと同じだと思うのですが、何故答えが間違えているのでしょうか


2倍のポイントを手に入れた! 92ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(85,957ポイント)   Date: 2010/05/25(火) 22:30   No:52793     
Title: Re:情報オリンピック予選過去問    
> toyoさんやたいちうさんのプログラムは分かりました。 

初心者のうちは、「アルゴリズムを理解する」ということは、
「何も見ないでも同じものが書ける」という意味と考えて下さい。
書けますか?


ponさんのプログラムをデバッグするのは骨なので(直すよりも1から書いた方が早いというケース)、
デバッグのヒントを。

n = 5;
a[] = { 1, 1, 2, 1, 1 };

という入力に対して、予想通りの答えを出せますか?

n = 7;
a[] = { 1, 2, 2, 3, 2, 2, 1 };
だったら?

デバッグするのに元の例題が難しいようだったら、適当な問題を入力することで
比較的簡単にデバッグできますよ。
それと、いちいち数値を入力するのは面倒ですし、間違う可能性も高いです。
ソースコードに書いてしまうか、問題ファイルを読み込むようにしましょう。


2倍のポイントを手に入れた! 554ポイント を手に入れた。

Name: pon  ..かけだし(1,967ポイント)   Date: 2010/05/25(火) 22:54   No:52796     
Title: Re:情報オリンピック予選過去問    
確かに、アルゴリズムとしては理解したつもりなのですが自分には実装できなさそうです…


nが小さな値に関しては正確な答えを出すのですが…(与えられたサンプルに対しても正確な値を返しました
答えが0になる場合はbugが起こっていたので、配列の最後に4という関係のない値を入れることで解決しました
しかし、問題のようなnが100になったりすると何故か変な答えを返します。
決してnを超えたりはしないのですが

ソースコードに書いてしまうのは確か(情報オリンピックでは)禁止されているはずです
問題ファイルを読み込む方法はたいちうさんのコードを見て初めて知りました…


26ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(86,041ポイント)   Date: 2010/05/26(水) 09:15   No:52814     
Title: Re:情報オリンピック予選過去問    
> 確かに、アルゴリズムとしては理解したつもりなのですが自分には実装できなさそうです…

あくまでも、つもりに過ぎなかったということです。

最近ブログで読んだことですが、私も昔から実践しています。
力が付きますよ。ご参考までに。
http://www.hyuki.com/d/201005.html#i20100521225000


84ポイント を手に入れた。

Name: pon  ..かけだし(1,991ポイント)   Date: 2010/05/27(木) 22:39   No:52908     
Title: Re:情報オリンピック予選過去問    
で、結局自分のプログラムは何が間違っていますか?

2倍のポイントを手に入れた! 24ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(86,745ポイント)   Date: 2010/05/28(金) 01:09   No:52918     
Title: Re:情報オリンピック予選過去問    
> 答えが0になる場合はbugが起こっていたので、配列の最後に4という関係のない値を入れることで解決しました
> しかし、問題のようなnが100になったりすると何故か変な答えを返します。

解決したというプログラムを載せて下さい。
No.52787のプログラムでは、↓の答えが-10002になってしまいます。

n = 5;
a[] = { 1, 1, 2, 1, 1 };


> で、結局自分のプログラムは何が間違っていますか?

おそらく考え方が間違っているのだと思いますが、
私にはプログラムからponさんの考え方が読み取れませんので、
私なりに直すと、やはりNo. 52665になってしまいます。

自分のプログラムの変数の意味とか、ループの意図とかうまく説明できますか?


2倍のポイントを手に入れた! 86ポイント を手に入れた。

Name: pon  ..かけだし(2,035ポイント)   Date: 2010/05/28(金) 22:45   No:52970     
Title: Re:情報オリンピック予選過去問    
改訂版です。
コメントを書く部分に書いてみました。何か間違っている部分があるでしょうか


2倍のポイントを手に入れた! 44ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(171,053ポイント)   Date: 2010/05/28(金) 23:11   No:52973     
Title: Re:情報オリンピック予選過去問    
>コメントを書く部分に書いてみました。何か間違っている部分があるでしょうか
と聞く前に。

たいちうさんの
n = 5;
a[] = { 1, 1, 2, 1, 1 }; 
を入れて試してみましたか?
答えが合いませんよね。

そもそも、プログラムをデバッガトレースしたり、中間状態をprintfしたりしてちゃんとデバッグしてますか?
理解度をアップしたいなら、まずそこから始めて見ませんか。


131ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(88,581ポイント)   Date: 2010/05/29(土) 09:06   No:52989     
Title: Re:情報オリンピック予選過去問    
n = 5;
int a[20000] = { 1, 1, 2, 1, 1 }; 
(0)

n = 12;
int a[20000] = { 3, 2, 1, 1, 2, 3, 2, 2, 2, 1, 1, 3 }; 
(3)

n = 12;
int a[20000] = { 3, 2, 1, 1, 2, 3, 2, 1, 3, 2, 1, 3 }; 
(12)

n = 100;
int a[20000] = {
    2, 3, 1, 2, 2, 2, 3, 2, 1, 3, 1, 1, 2, 3, 2, 3, 3, 3, 1, 1, 2, 3, 2, 2, 2,
    3, 1, 1, 1, 2, 1, 3, 3, 3, 2, 2, 2, 3, 3, 3, 2, 2, 2, 3, 3, 2, 1, 1, 2, 2,
    2, 3, 3, 2, 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, 2, 3, 1, 2, 1, 2, 1, 1, 2, 3, 2,
    1, 2, 2, 1, 2, 2, 3, 3, 2, 1, 2, 3, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1,
};
(77)

今ちょっと試してみると、n = 12までは正しい答えが出せますね。
で、100の時に間違っていると。
確かにこのような場合のデバッグは少し難易度が高いですね。
今からしばらく外出しますが、今日中にはできるでしょう。


softyaさん>

n = 5の場合は正しい答えが出ているようですよ。
softyaさんか私かどちらかが勘違いをしているみたいですので、
ご確認お願いします。私も帰宅後にもう一度確認します。


533ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(171,413ポイント)   Date: 2010/05/29(土) 17:06   No:53001     
Title: Re:情報オリンピック予選過去問    
>softyaさんか私かどちらかが勘違いをしているみたいですので、 

あぁ、すいません勘違いですね。
任意の場所の任意の色を1つだけ置き換えるってのを全ての場所で行った場合のシミュレートですね。
ただ、ponさんのも解答例と一致しませんので、まだ間違いがあります。
http://www.ioi-jp.org/joi/2008/2009-yo-prob_and_sol/


58ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(88,893ポイント)   Date: 2010/05/29(土) 18:43   No:53005     
Title: Re:情報オリンピック予選過去問    
n = 13;
int a[20000] = { 3, 1, 2, 3, 2, 2, 1, 1, 1, 3, 3, 3, 1 };

比較的短くて誤判定するパターンを見つけました。
それと、デバッグにはこのような工夫をしましょう。

void show(int *b, int len) {
    for (int i = 0; i < len; i++)
        printf("%d", b[i]);
    printf("\n");
}

これで直せるのではないかと思いますが、どうしてもわからなければ再度聞いてください。


2倍のポイントを手に入れた! 312ポイント を手に入れた。

Name: pon  ..かけだし(2,142ポイント)   Date: 2010/05/29(土) 21:48   No:53015     
Title: Re:情報オリンピック予選過去問    
解決しました。配列の書き変えがうまくいってませんでした。
(ちゃんと最後まで書きかえることが出来ていませんでした。

if(b[idou+2]==b[idou+3]){
    for(int ren=1;ren>0;ren++){
        if(b[idou+ren] != b[idou+ren+1]){
            nn -= ren+1;
            for(int henkou=idou;henkou<nn;henkou++){
                b[henkou]=b[henkou+ren+1];
            }
            flag=1;
            kesita=idou;
            break;
        }
    }
    break;
}

これで正確な値を出すことができました。ありがとうございます


107ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(89,124ポイント)   Date: 2010/05/29(土) 23:32   No:53033     
Title: Re:情報オリンピック予選過去問    
解決!マークをチェックしましょう。
その他気付いた点です。

・配列bを初期化する
・無意味なインクルードをやめる
・連続の判定を改善する

配列bの初期化は必須です。
連続の判定については、次の問題点があります。

・5連続以上を消すルールに変えた場合、if文が1つ深くなる。
・10連続以上を消すルールに変えた場合、目も当てられない。
・ルール変更がないとしても、改善すればプログラムの見通しが良くなり、
  バグも減ります。

それと既に直っているかもしれませんが、
配列を書き換えて短くなった部分には0を代入しておきましょう。


最後に、折角この問題に取り組んだのだから、私かtoyoさんのプログラムも
「理解」できるようになったほうが良いと思います。


231ポイント を手に入れた。

Name: pon  ..かけだし(2,275ポイント)   Date: 2010/05/30(日) 14:59   No:53071     
Title: Re:情報オリンピック予選過去問    
情報オリンピックは時間の制限が結構きついのでインクルードはCopy&Pasteした方が良いと言われました

bの初期化について
一番最初に書いたprogramの時からbの初期化はしているはずです

ルールを変えた場合について
書くのがめんどくさくなるということでしょうか?



133ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(89,285ポイント)   Date: 2010/05/30(日) 17:19   No:53094     
Title: Re:情報オリンピック予選過去問    
> 情報オリンピックは時間の制限が結構きついのでインクルードはCopy&Pasteした方が良いと言われました

私なら今のponさんには別のアドバイスをします。
必要なものだけコピペしましょう。何が必要か瞬時に判らないなら論外です。
「十分早い時間で解けるようになる」前に、
「時間をかけたら解けるようになる」事を目指すべきです。
小手先の技を意識する段階ではありません。

せめて掲示板で質問するときには削除しておいてください。


> bの初期化について
> 一番最初に書いたprogramの時からbの初期化はしているはずです
> ...
> int n;
> scanf("%d",&n);
> int a[10000]={0};
> int b[10000];
> int nn_min=n;
> for(int loop=0;loop<n;loop++){
>     scanf("%d",&a[loop]);
>     b[loop]=a[loop];
> }

例えば、n = 12の時に、b[20]は初期化されますか?


> ルールを変えた場合について
> 書くのがめんどくさくなるということでしょうか?

質問の意味が判りません。
↓に説明しているとおりです。

> 連続の判定については、次の問題点があります。

> ・5連続以上を消すルールに変えた場合、if文が1つ深くなる。
> ・10連続以上を消すルールに変えた場合、目も当てられない。
> ・ルール変更がないとしても、改善すればプログラムの見通しが良くなり、
>   バグも減ります。


125ポイント を手に入れた。

Name: pon  ..かけだし(2,343ポイント)   Date: 2010/05/30(日) 20:37   No:53106     
Title: Re:情報オリンピック予選過去問    
includeについて
分かりました

bの初期化について
b[10000]={0}
と最初に書くべきだということですか?

ルールを変えた問題について
10連続のときに目も当てられないのは何故ですか?


68ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(89,311ポイント)   Date: 2010/05/30(日) 21:52   No:53113     
Title: Re:情報オリンピック予選過去問    
> bの初期化について
> b[10000]={0}
> と最初に書くべきだということですか?

それも正解の1つです。


> ルールを変えた問題について
> 10連続のときに目も当てられないのは何故ですか?

判らないならば、そのようにルールを変更して書いてみて下さい。


26ポイント を手に入れた。

Name: pon  ..かけだし(2,342ポイント)   Date: 2010/05/30(日) 22:18   No:53114     
Title: Re:情報オリンピック予選過去問    
ルールを変更して書いてみたのですが、普通に動くのですが

1ポイント を落としてしまった。

Name: たいちう  ..比類無きプログラマー(89,350ポイント)   Date: 2010/05/30(日) 22:33   No:53116     
Title: Re:情報オリンピック予選過去問    
> ルールを変更して書いてみたのですが、普通に動くのですが

動作しないとは書いていません。目も当てられないと書いたのです。
それを貼ってみて下さい。


39ポイント を手に入れた。

Name: pon  ..かけだし(2,329ポイント)   Date: 2010/05/31(月) 22:49   No:53184     
Title: Re:情報オリンピック予選過去問    
これなのですが


13ポイント を落としてしまった。



Name: redhat98  ..ぴよぴよ(241ポイント)   Date: 2010/05/30(日) 22:58   No:53121       
Title: C++のスコープについて    
はじめまして、こんばんは
redhat98です

MacOSX, Qt4でC++のプログラミングをやっているのですが、変数のスコープについて疑問があります。
GUIを手書きで作っているのですが、

MainWindow::MainWindow(QWidget *parent)
    : QLabel(parent, Qt::Window)
{
    QPixmap m_Image; //ここでメモリーリークは発生しないのか?
    m_Image.load(":/test.png"); //画像の読み込み
    setPixmap(m_Image); //画像をウィジェットに設定する
}

setPixmap(m_Image);はvoid setPixmap ( const QPixmap & )と宣言されています。
void (const QPixmap)と宣言されていれば、
自動的にインスタンスをコピーしてくれるので大丈夫だと思いますが
QPixmap m_Image;のと私は宣言をしているのでメモリリークが発生しないのか疑問です。

この場合は、*.hに「QPixmap m_Image;」とか「QPixmap *m_Image;」と書くのが妥当なのでしょうか?


241ポイント を手に入れた。


Name: たかぎ [URL]  ..ハッカー(193,408ポイント)   Date: 2010/05/30(日) 23:23   No:53123     
Title: Re:C++のスコープについて    
> メモリリークが発生しないのか疑問です。

どのようにしてメモリリークが発生すると考えていますか?
ちなみに、値渡しの方がメモリリークの可能性は高くなると思います。スライシングという言葉を聞いたことがありませんか?


47ポイント を手に入れた。

Name: redhat98  ..ぴよぴよ(405ポイント)   Date: 2010/05/31(月) 00:38   No:53128     
Title: Re:C++のスコープについて    
>どのようにしてメモリリークが発生すると考えていますか?

QPixmap m_Image;はスタックに積まれるハズなので、
コンストラクタを終えた時点でメモリから削除されると思います。
そして、後でそこを参照するした場合に問題が発生すると考えています。

よく考えてみるとメモリリークというか、メモリの不正な領域の参照でしたね


164ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(193,572ポイント)   Date: 2010/05/31(月) 07:38   No:53136     
Title: Re:C++のスコープについて    
setPixmapの仕様次第ですね。

2倍のポイントを手に入れた! 18ポイント を手に入れた。

Name: redhat98  ..ぴよぴよ(512ポイント)   Date: 2010/05/31(月) 21:27   No:53171     
Title: Re:C++のスコープについて    
>setPixmapの仕様次第ですね。
なぜですか?
無条件でスタックからデータが降ろされるのではないんですか?

くだらない質問で申し訳ありませんが、
ポインタじゃないメンバ変数を初期化する時は
初期化子でするのがデフォルトなのでしょうか?

質問ばかりで申しわかりません。


107ポイント を手に入れた。

Name: ぽこ  ..中級者(12,541ポイント)   Date: 2010/05/31(月) 21:50   No:53175     
Title: Re:C++のスコープについて    
> >setPixmapの仕様次第ですね。
> なぜですか?
> 無条件でスタックからデータが降ろされるのではないんですか?

setPixmapの内部でQPixmapを複製しているかどうかが重要だと思いますよ。
複製していない場合→不正アクセスの可能性がある。
複製している場合→不正アクセスの可能性なし(まあ、実装次第でしょうが。。)。


72ポイント を手に入れた。

Name: redhat98  ..ぴよぴよ(530ポイント)   Date: 2010/05/31(月) 22:18   No:53178 解決!     
Title: Re:C++のスコープについて    
>setPixmapの内部で QPixmapを複製しているかどうかが重要だと思いますよ。 
ひとまず問題なく動いているので、そのまま使ってみることにします。
フレームワークなのでちゃんと、そこまで考えてくれているんじゃないかなと思います。

ありがとうございました。


18ポイント を手に入れた。



Name: JJ  ..ぴよぴよ(467ポイント)   Date: 2010/05/31(月) 16:32   No:53143       
Title: 整列関数で分からないところがあります    
『文字列の長さが同じとき,先頭から文字の大小を比較し,その文字が小さいほうが,
文字列として小さいとする.文字列の長さが同じで全ての文字が等しいとき,二つの文
字列は等しい.
文字の大小順序:
0 < 1 < ... < 9 < a < b < … < z < A< B < ... < Z
文字列大小例: "abc" < "abd", "ab" < "abc", "a" < "aaa"』という課題で下のような関数を作ったのですがうまくいきません。
どこがおかしいのか教えてください。


void bubble(char p[][NUM],int n){
    int i,j,k,m;
    int len[num];
    char temp[NUM];
for(i=0;i<n;i++){
    len[i]=strlen(p[i]);
   }
for(i=0;i<n-1;i++){
  for(j=0;j<n-i-1;j++){
     if(len[j]>len[j+1]){
         strcpy(temp,p[j]);
         strcpy(p[j],p[j+1]);
         strcpy(p[j+1],temp);
         m=len[j];
         len[j]=len[j+1];
         len[j+1]=m;
      }
   }
}
for(i=0;i<n;i++){
  for(j=n-1;j>i;j--){
     if(len[j]==len[j-1]){
        k=strcmp(p[j],p[j-1]);        
     if(k<0){
        strcpy(temp,p[j]);
        strcpy(p[j],p[j-1]);
        strcpy(p[j-1],temp);
       }
     }
   }
  }
 for(i=0;i<n;i++){
     printf(" %s\n",p[i]);
   }
  printf("\n");
}



458ポイント を手に入れた。


Name: 先生さん  ..ぴよぴよ(65ポイント)   Date: 2010/05/31(月) 17:20   No:53145     
Title: Re:整列関数で分からないところがあります    
問題がよくわかんないけど。
"c" < "aaa" なのかな。 そう想定して。

少なくともstrcmpの比較は文字コードを使って行われるので 'a' > 'A' がなりたってしまうので今回の問題には合わないかと。

ちなみに僕だったら、ハッシュのように文字列を数値化する関数を先に作ってしまうと思う。

long getNum(char* str){
    long retNum = 0;
    while(str != '\0'){
        retNum = retNum * 74 + *str-'0'; //TODO まだ'a' > 'A'は直ってないので直す必要がある。
        str++;
    }
    return retNum;
}

まわりくどいかな。


65ポイント を手に入れた。

Name: JJ  ..ぴよぴよ(62ポイント)   Date: 2010/05/31(月) 19:29   No:53159     
Title: Re:整列関数で分からないところがあります    
もっと簡単に「小文字<大文字」にすることはできませんか?

26ポイント を手に入れた。

Name: ドラ  ..初心者(5,715ポイント)   Date: 2010/05/31(月) 21:50   No:53174     
Title: Re:整列関数で分からないところがあります    
>もっと簡単に「小文字<大文字」にすることはできませんか?
文字がアルファベットだった場合、大文字と小文字を相互変換してから
大小比較するstrcmp相当の関数を自作したらどうでしょうか?

ASCIIコードなら大文字と小文字の相互変換はこのような感じでできます。

if (isalpha(ch)) ch ^= 0x20;



130ポイント を手に入れた。



Name: asdf  ..ぴよぴよ(737ポイント)   Date: 2010/05/29(土) 21:58   No:53019       
Title: c言語 リスト 配列    
整数値が入ったint型の配列 A[0], A[1], ... , A[N-1] が与えられたとき、次に示すようなリストを配列で構成せよ。

header → A[0] → A[1] → ... → A[N-1]

また、リストを操作する2つの関数を作成せよ。
(1)追加関数 n番目の後に新たなデータを追加する
(2)削除関数 n番目のデータを削除する

という問題なのですが、一体何をすればよいのか全然分かりません。リストを調べても、ポインタを用いたものしかなく、配列を使ったものが見つかりませんでした。

とりあえず自分で考えたのは、

まず、Aに適当な整数値を入れておき、(1)の追加関数は、n+1番目以降の要素を1つずつ後ろにずらしてから、n+1番目の要素にデータをセットする。(2)の削除関数は、n+1番目以降の要素を1つずつ前にずらす。

という感じです。このようなプログラムを組めばよいのでしょうか?しかし、→をどう表現したらよいか分かりません。また、このようなプログラムを組む場合、構造体、ポインタは使わなくてもよいのでしょうか?

よろしくお願いします。


430ポイント を落としてしまった。


Name: 組木紙織  ..比類無きプログラマー(82,896ポイント)   Date: 2010/05/29(土) 23:26   No:53032     
Title: Re:c言語 リスト 配列    
この場合の"リスト"ってどのような意味ですか?

>→をどう表現したらよいか分かりません。
右矢印の意味はどのように定義されてますか?
それに依存します。

>また、このようなプログラムを組む場合、構造体、ポインタは使わなくてもよいのでしょうか? 
状況によっては構造体や、(明示的に)ポインタを使わなくてもできます。

問題は出題者がどのような意図をもって問題を出したのかですね。
それが分からないと、できるかもしれないし、できないかもしれないとしか言いようがないです。


28ポイント を手に入れた。

Name: asdf  ..ぴよぴよ(706ポイント)   Date: 2010/05/29(土) 23:48   No:53034     
Title: Re:c言語 リスト 配列    
本当は、添付した図に示すようなリストを配列で構成せよ。という問題でした。

この図で、この場合の"リスト"がどのような意味かわかりますでしょうか?

意図は、おそらく次回から本格的なリストを勉強するから、まずは配列でやれということだと思います。


31ポイント を落としてしまった。

Name: 組木紙織  ..比類無きプログラマー(83,300ポイント)   Date: 2010/05/30(日) 00:23   No:53037     
Title: Re:c言語 リスト 配列    
>この図で、この場合の"リスト"がどのような意味かわかりますでしょうか? 
大体予想はつきますが、口頭か文章で説明があったはずなので、それを聞いています。


>意図は、おそらく次回から本格的なリストを勉強するから、まずは配列でやれということだと思います
なら配列にデータを入れて(1)と(2)の関数を用意してあげれば十分かな。
まだ良くどのような実装にすればよいかが分からないけど。(以下参照)


最初の文章から以下のような実装を思いつきました。
(1)配列に要素を入れて、直接外部から配列をインデックス順に操作することでリストの要件を満たす。
(2)配列に要素と次のインデックスを入れて、インデックスをたどりながらリストの操作をする。
(3)配列に要素を入れて、配列へのポインタを要素としたリンクリストを作って操作をする。
(4)複数の要素を入れた配列を要素に持つリンクリストを作る。

で、多分、返答から確実なところは出題者に聞かないと分かりませんが、
一番実装が楽な(1)何じゃないかと想像しました。


404ポイント を手に入れた。

Name: asdf  ..ぴよぴよ(800ポイント)   Date: 2010/05/30(日) 00:54   No:53050     
Title: Re:c言語 リスト 配列    
>大体予想はつきますが、口頭か文章で説明があったはずなので、それを聞いています。
(2)配列に要素と次のインデックスを入れて、インデックスをたどりながらリストの操作をする。
のようなプログラムだったと思います。また、ポインタは使わないと言っていました。

しかし、プログラムをどのように組めばよいか全然思いつきません。
どのようにすればよいのでしょうか?


94ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(83,567ポイント)   Date: 2010/05/30(日) 01:16   No:53053     
Title: Re:c言語 リスト 配列    
本来は動的配列を使わないといけないのですが、
組み方が分かるようにサンプル組んでみました。
(無意味に)少しだけ難読化かけてます。
適当にいじってください。


#include <stdio.h>
typedef struct Node
{
    int num;
    int next_index;

} Node;
int main(void)
{
    
    Node list[10];
    int i=0;
b:    list[i].num =i;
    list[i].next_index =i+1;
    if(++i<10)goto b;
a:    printf("num:%d\tnext_index:%d\n",list[i-10].num,list[i-10].next_index);
    i=list[i-10].next_index+10;
    if(i<20)goto a;
    return 0;
}


267ポイント を手に入れた。

Name: asdf  ..かけだし(1,024ポイント)   Date: 2010/05/30(日) 01:50   No:53055     
Title: Re:c言語 リスト 配列    
#include <stdio.h>
#include <stdlib.h>

#define N 5

struct List {
    int val;
    int next;
};


int main(void) {
    int i;
    struct List A[N];
    
    for (i=0; i<N; i++) {
            A[i].next = i+1;
            A[i].val = rand();
    }
    for (i=0; i<N; i++)
        printf("A[%d]: %d\tnext_index: %d\n", i, A[i].val, A[i].next);
    return 0; 
}

と同じですよね。

結局のところ、あの→やheaderはどうすればよいのでしょうか?
追加の場合、例えば n=2 とされた場合、値をとりあえずA[N-1]に格納しておき、A[1].next=N-1, 
A[N-1].next=2 とすればよいのでしょうか?



224ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(83,836ポイント)   Date: 2010/05/30(日) 02:11   No:53057     
Title: Re:c言語 リスト 配列    
表示部がちょっと違います。
forループで回さないでください。
するのなら以下のように。
i=0;
while(i<10)
{
 printf("num:%d\tnext_index:%d\n",list[i].num,list[i].next_index);
 i=list[i].next_index;
}

右矢印は次のノードを示しているものなので、next_indexの事を意味しています。
headerは最初のノードを指示しているものです。それに相当するものをサンプルには使っていません。

>追加の場合、例えば n=2 とされた場合、値をとりあえずA[N-1]に格納しておき、A[1].next=N-1,  
>A[N-1].next=2 とすればよいのでしょうか? 
やってみたらどうですか?



269ポイント を手に入れた。

Name: asdf  ..かけだし(1,468ポイント)   Date: 2010/05/30(日) 02:34   No:53059     
Title: Re:c言語 リスト 配列    
#include <stdio.h>
#include <stdlib.h>

#define N 5

struct List {
    int val;
    int next;
};

struct List header;

void Add(struct List A[]);

int main(void) {
    int i;
    struct List A[N];
    int count = 0;

    for (i=0; i<N-1; i++) {
            A[i].next = i+1;
            A[i].val = i;
    }
    header.val = -1;
    header.next = 0;
    A[N-1].val = -1;
    A[N-1].next = 0;
    i = 0;
    while (count < N-1) {
        printf("A[%d]: %d\n", i, A[i].val);
        i = A[i].next;
        count++;
    }

    Add(A);
    //Del(A);
    
    return 0;
}

void Add(struct List A[]) {
    int i, n, val;
    int count = 0;

    puts("リストのn番目の後に追加する");
    do {
        printf("n  : ");        scanf("%d", &n);
    } while (n < 0 && n >= N);
    printf("val: ");         scanf("%d", &val);

    A[N-1].val = val;
    A[N-1].next = n;

    if (n == 0)
        header.next = N-1;
    else
        A[n-1].next = N-1;

    i = header.next;
    while (count < N) {
        printf("A[%d]: %d\n", i, A[i].val);
        i = A[i].next;
        count++;
    }
}

        


とりあえず作ってみました。こんな感じでよいのでしょうか?

また、添付した図で、A[N-1]に斜線があるのですが、あれはどういう意味なんでしょうか?


444ポイント を手に入れた。

Name: box  ..ハッカー(154,192ポイント)   Date: 2010/05/30(日) 07:58   No:53062     
Title: Re:c言語 リスト 配列    
> また、添付した図で、A[N-1]に斜線があるのですが、あれはどういう意味なんでしょうか?

リストの終わりを示しています。
自己参照型構造体でいうと、

typedef struct CELL {
    int value;
    struct CELL *next;
} CELL;

のようなケースで、nextがNULLだってことです。


64ポイント を手に入れた。

Name: asdf  ..かけだし(1,510ポイント)   Date: 2010/05/30(日) 15:45   No:53074     
Title: Re:c言語 リスト 配列    
ありがとうございます。
ということは、あのプログラムは、A「N-1]を使っているのでおかしいのでしょうか?
しかし、これを使わなかったらどうすればよいのでしょうか?


42ポイント を手に入れた。

Name: ドラ  ..初心者(5,278ポイント)   Date: 2010/05/30(日) 17:02   No:53090     
Title: Re:c言語 リスト 配列    
>リストの終わり
配列の要素を指す添字として使わない数値を使いましょう。
-1とかでいいのではないですか?

それから、挿入するときにA[N-1]に決め打ちでデータを格納するのはおかしいす。
2回連続で挿入すると必ずデータを壊します。
配列の中で未使用の要素を探す必要があります。

後、配列ではn番目の要素はA[n-1]かもしれませんが、
連結リストとして扱っているのですからheaderから順番にたぐっていかなければ
n番目のデータが配列内のどこに存在するか分かりません。
 


201ポイント を落としてしまった。

Name: asdf  ..かけだし(1,576ポイント)   Date: 2010/05/30(日) 17:30   No:53095     
Title: Re:c言語 リスト 配列    
回答ありがとうございます。

>配列の中で未使用の要素を探す必要があります。
未使用の要素などあるのでしょうか?

あのプログラムでだめなら、もう何をすればよいのか全く分かりません・・・


54ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(84,513ポイント)   Date: 2010/05/30(日) 18:50   No:53100     
Title: Re:c言語 リスト 配列    
>あのプログラムでだめなら、もう何をすればよいのか全く分かりません・・・

どこまでが大丈夫で、どこからがだめか理解していますか?
それなしには改善は不可能です。
あと、リストの概念をしってますか?
授業で習ったと思われるので飛ばして実装についてだけ話していたのですが、理解できていないような感じ
を受けました。リストというものはどのようなものか把握しておいてください。

以下問題点
1:要素数が5までしか扱えない、リストは要素数は固定ではなく、理論上無限の要素数を扱える必要がある。
2:挿入時に配列の最後の要素に入れるようにしているが、
 一度削除が行われた後だと、配列の途中が空白になるときがある。
 その時は配列のあいてある部分に入れたほうが空間効率がよくなる。
3:表示時にリストの要素数をあらかじめ知っていないと表示出来ないようになっている。
  あらかじめ要素数を知らなくても表示可能にする方がリストとしては自然。
4:問題要件は入力配列の要素をリストの初期値に使うとしてあるのに初期化時の要素の内容が固定である。
5:リストはheaderさえ知っていればどのような操作も(基本的には)可能である構造であるのに、
 挿入関数にheader以外の部分を渡すようにしている。
番外編
コメントが一切存在しない

1は動的配列を扱う方法を知っていれば、実装してください。
知らない場合はそれなりに大き目の配列を用意してごまかしましょう。
2はドラさんが書いている前半部分と同じことを意味しています。
3はリストの最後の要素の中身を考えれば実装できます。
4は今はとりあえず無視で、後でいくらでも直せます。
5を直すのも後でいいです。先に2や3を直すべきかと。


677ポイント を手に入れた。

Name: asdf  ..かけだし(2,354ポイント)   Date: 2010/05/30(日) 19:12   No:53102     
Title: Re:c言語 リスト 配列    
とりあえず、追加するのはいくらでもできるようにはできました。(配列の要素数までですが)
と思っていたら、できませんでした。とりあえず、Add関数で、n=0のときだけはできました。
どこがおかしいでしょうか?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 5
#define M 1000

struct List {
    int val;
    int next;
};

struct List header;
int j = N;    //データ数

void Add(struct List A[]);
void Del(struct List A[]);

int main(void) {
    int i, k;
    struct List A[M];

    srand(time(NULL));

    for (i=0; i<N; i++) {
            A[i].next = i+1;
            A[i].val = rand();
    }
    A[N-1].next = -1;
    for (i=N; i<M; i++) {
        A[i].next = -1;
        A[i].val = -1;
    }
    header.val = -1;
    header.next = 0;

    puts("List");
    i = 0;
    while (i != -1) {
        printf("A[%d]: %d\n", i, A[i].val);
        i = A[i].next;
    }
    do {
        puts("データをどうしますか?(追加:0 削除:1 やめる場合:3)");
        scanf("%d", &k);
        switch (k) {
            case 0:        Add(A);    break;
            case 1:        Del(A);    break;
            default:    break;
        }
    } while (k == 0 || k == 1);
    
    return 0;
}

void Add(struct List A[]) {
    int i, n, val;

    puts("リストのn番目の後にデータを追加する");
    do {
        printf("n  : ");    scanf("%d", &n);
    } while (n < 0 || n > j);
    printf("val: ");         scanf("%d", &val);

    A[j].val = val;
    if (n == 0)
        A[j].next = header.next;
    else if (n != j)
        A[j].next = A[n-1].next;
    if (n == 0)
        header.next = j;
    else
        A[n-1].next = j;

    i = header.next;
    while (i != -1) {
        printf("A[%d]: %d\n", i, A[i].val);
        i = A[i].next;
    }
    j++;
}



また、
>問題要件は入力配列の要素をリストの初期値に使うとしてあるのに初期化時の要素の内容が固定である
これは、どういう意味でしょうか?

 編集済み


2倍のポイントを手に入れた! 778ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(84,793ポイント)   Date: 2010/05/30(日) 19:34   No:53103     
Title: Re:c言語 リスト 配列    
とりあえず、実行可能なプログラムをあげてもらいたいと思います。

>>問題要件は入力配列の要素をリストの初期値に使うとしてあるのに初期化時の要素の内容が固定である 
>これは、どういう意味でしょうか? 

最新のではランダムになっているようですが、そのような意味ではなく、
最初の問題文では配列Aを与え、その値を初期値としたリストをつくうようになっています。
そのためリストを作るときは、配列を用意し、その配列から値を引っ張ってリストを
作るようにすべきということです。

この挿入関数は必ず配列の最後の部分に値を入れますが、削除したら配列の間があくと思います。
あいた要素はそのままにして、配列の最後に値を入れたいと思いますか?


280ポイント を手に入れた。

Name: asdf  ..かけだし(2,407ポイント)   Date: 2010/05/30(日) 20:32   No:53105     
Title: Re:c言語 リスト 配列    
すみません。
>最新のではランダムになっているようですが、そのような意味ではなく、 
最初の問題文では配列Aを与え、その値を初期値としたリストをつくうようになっています。 
そのためリストを作るときは、配列を用意し、その配列から値を引っ張ってリストを 
作るようにすべきということです。

の意味がよく分からないです。値を引っ張るとはどういうことでしょうか?初めにrand()で値を入れている部分が不要ということでしょうか?できれば、例となるプログラムを呈示して欲しいです。


53ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(85,109ポイント)   Date: 2010/05/30(日) 20:56   No:53109     
Title: Re:c言語 リスト 配列    
いま、この課題の解答と書いていて、その一部の初期化関係部分を抜粋しました。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/*最後のノードを表すフラグ*/
#define END -1
/*使われていないノードを表すフラグ*/
#define NUL -2
/*入力データ配列の要素数*/
#define N    2
/*リスト配列の要素数*/
#define LIST_SIZE    100

struct List {
    int val;
    int next;
};

/*表示関数*/
void print(struct List list[LIST_SIZE]);
/*初期化関数*/
void initialize(int A[N]/*初期化用データ*/,struct List list[LIST_SIZE]/*リスト*/);
int main(void)
{
    struct List list[LIST_SIZE];
    int A[] ={1,2};
    initialize(A,list);
    print(list);


}

void initialize(int A[N],struct List list[LIST_SIZE])
{
    int i;
    assert(N<=LIST_SIZE);
    list[0].val =0;
    list[0].next =1;

    for(i=1;i<=N;++i)
    {
        list[i].val = A[i-1];
        list[i].next =i+1;
    }
    list[i-1].next =END;
    for(;i<LIST_SIZE;++i)
    {
        list[i].next =NUL;
    }
}


2倍のポイントを手に入れた! 316ポイント を手に入れた。

Name: asdf  ..入門者(3,348ポイント)   Date: 2010/05/30(日) 22:56   No:53120     
Title: Re:c言語 リスト 配列    
これは、要するにリストを表す配列とは別にint型の配列を定義しろというでしょうか。

とりあえず、追加の関数を作っていたのですが、どうにもうまくいきません。
最後と最初に挿入するのはできるのですが、他の場合ができません。
Add関数の
else if (n != j) {
        A[k].next = A[n-1].next;
        A[n-1].next = k;
}
のn-1の部分がおかしいのは分かるのですが、どうすればよいか分かりません。どうすればよいのでしょうか? 以下、ソースコードです。(削除の部分は無視してください)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 5
#define M 1000

struct List {
    int val;
    int next;
};

struct List header;
int j = N;    //最後尾データ

void Add(struct List A[]);
void Del(struct List A[]);

int main(void) {
    int i, k;
    struct List A[M];
    int b[N];

    srand(time(NULL));
    for (i=0; i<N; i++)
        b[i] = rand();
    for (i=0; i<N; i++) {
            A[i].next = i+1;
            A[i].val = b[i];
    }
    A[N-1].next = -1;
    for (i=N; i<M; i++) {
        A[i].next = -1;
        A[i].val = -1;
    }
    header.val = -1;
    header.next = 0;

    puts("List");
    i = 0;
    while (i != -1) {
        printf("A[%d]: %d\n", i, A[i].val);
        i = A[i].next;
    }
    do {
        puts("データをどうしますか?(追加:0 削除:1 やめる場合:3)");
        scanf("%d", &k);
        switch (k) {
            case 0:        Add(A);    break;
            case 1:        Del(A);    break;
            default:    break;
        }
    } while (k == 0 || k == 1);
    
    return 0;
}

void Add(struct List A[]) {
    int i, k, n, val;

    puts("リストのn番目の後にデータを追加する");
    do {
        printf("n  : ");    scanf("%d", &n);
    } while (n < 0 || n > j);
    printf("val: ");         scanf("%d", &val);

    for (k=0; k<=j; k++)
        if (A[k].val == -1) {
            A[k].val = val;
            break;
        }
    
    if (n == 0) {
        A[k].next = header.next;
        header.next = k;
    }
    else if (n != j) {
        A[k].next = A[n-1].next;
        A[n-1].next = k;
    }
    else {
        A[k].next = -1;
        A[n-1].next = k;
    }

    i = header.next;
    while (i != -1) {
        printf("A[%d]: %d\n", i, A[i].val);
        i = A[i].next;
    }
        j++;
}


941ポイント を手に入れた。

Name: ドラ  ..初心者(5,585ポイント)   Date: 2010/05/31(月) 17:41   No:53148     
Title: Re:c言語 リスト 配列    
Add関数内で「リストのn番目の要素の添字」を求める処理が存在していません。
headerから始まってn回たぐっていかないとリストのn番目の要素の添字は分かりません。

>if (n == 0) {
>    A[k].next = header.next;
>    header.next = k;
>}
>else if (n != j) {
>    A[k].next = A[n-1].next;
>    A[n-1].next = k;
>}
>else {
>    A[k].next = -1;
>    A[n-1].next = k;
>}
つまり↑の部分が間違っていて、↓こんな感じです。


if (n == 0) {
    A[k].next = header.next;
    header.next = k;
}
else {
    int nth_index; // リストのn番目の要素の添字
    
    nth_index = header.next;
    for (i = 1; i < n; ++i) {
        nth_index = A[nth_index].next;
    }
    
    A[k].next = A[nth_index].next;
    A[nth_index].next = k;
}
 


307ポイント を手に入れた。

Name: asdf  ..入門者(3,446ポイント)   Date: 2010/05/31(月) 18:35   No:53151 解決!     
Title: Re:c言語 リスト 配列    
回答ありがとうございます。質問してからもずっと考えていて、ドラさんと一緒の方法を思いつき、なんとかできました。

作れたので、これで解決ということにします。組木紙織さん、どうもありがとうございました。




98ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(85,925ポイント)   Date: 2010/05/31(月) 20:51   No:53166     
Title: Re:c言語 リスト 配列    
>作れたので、これで解決ということにします。
お疲れさまでした。
以下のコードは私が作ったものです。
処理が分かりやすいように素直に作ったつもりです。
自分が作ったのと比較して見てください。


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/*最後のノードを表すフラグ*/
#define END -1
/*使われていないノードを表すフラグ*/
#define NUL -2
/*入力データ配列の要素数*/
#define N    2
/*リスト配列の要素数*/
#define LIST_SIZE    100

struct Node {
    int val;
    int next;
};

/*挿入関数*/
void incert(int number/*挿入する位置*/,int data/*挿入するデータ*/,struct Node list[LIST_SIZE]/*リストのデータ配列の最初の要素*/);
/*消去関数*/
void erease(int number/*削除するノードの位置*/,struct Node list[LIST_SIZE]/*リストのデータ配列の最初の要素*/);
/*表示関数*/
void print(struct Node list[LIST_SIZE]);
/*初期化関数*/
void initialize(int A[N]/*初期化用データ*/,struct Node list[LIST_SIZE]/*リスト*/);
int main(void)
{
    struct Node list[LIST_SIZE];
    int A[] ={1,2};
    initialize(A,list);
    print(list);
    printf("ccccccccccccccccccccc\n");
    incert(1,3,list);
    print(list);
    printf("ccccccccccccccccccccc\n");
    erease(1,list);
    print(list);
    return 0;
}

void initialize(int A[N],struct Node list[LIST_SIZE])
{
    int i;
    assert(N<=LIST_SIZE);
/*    list[0]はheader*/
    list[0].val =0;
    list[0].next =1;

/*配列からリストの構築*/
    for(i=1;i<=N;++i)
    {
        list[i].val = A[i-1];
        list[i].next =i+1;
    }
    list[i-1].next =END;
/*使われていない部分のデータをNULで埋める*/
    for(;i<LIST_SIZE;++i)
    {
        list[i].next =NUL;
    }
}

void print(struct Node list[LIST_SIZE])
{
    int next =list[0].next;
    while(next!=END)
    {
        printf("A[%d]: %d\n", next, list[next].val);
        next =list[next].next;
    }
}

void incert(int number,int data,struct Node list[LIST_SIZE])
{
    int i,next;
    /*あいている配列の要素を探す*/
    for(i=0;i<LIST_SIZE;++i)
    {
        if(list[i].next == NUL)break;
    }
    
    if(i>=LIST_SIZE)
    {
        printf("err/n");
        exit(1);
    }
    assert(i<LIST_SIZE);

    /*挿入場所を探す*/
    next = 0;
    while(number>0)
    {
        next =list[next].next;
        --number;
        if(next==END)
        {
            printf("err\n");
            exit(1);
        }
    }
    /*挿入*/
    list[i].val = data;
    list[i].next = list[next].next;
    list[next].next = i;
}

void erease(int number,struct Node list[LIST_SIZE])
{
    int next=0,buf;
    /*削除場所を探す*/
    while(number>0)
    {
        if(list[next].next==END)
        {
            printf("err\n");
            exit(1);
        }
        next =list[next].next;
        --number;

    }
    if(list[next].next==END)
    {
        printf("err\n");
        exit(1);
    }
    /*削除*/
    buf = list[list[next].next].next;
    list[list[next].next].next =NUL;
    list[next].next =buf;
}


816ポイント を手に入れた。

Name: asdf  ..入門者(3,483ポイント)   Date: 2010/05/31(月) 21:09   No:53170 解決!     
Title: Re:c言語 リスト 配列    
組木紙織さん、わざわざありがとうございます。

参考にさせて頂きます。



37ポイント を手に入れた。



Name: T.J  ..ぴよぴよ(229ポイント)   Date: 2010/05/31(月) 20:22   No:53164       
Title: GetRand関数について    
GetRand関数で0〜10など、0〜ではなく、10〜20など、最小の数字を変更することはできますか?
よくわからなくて困っているので教えてください。お願いします


79ポイント を手に入れた。


Name: MNS  ..プログラマー(34,857ポイント)   Date: 2010/05/31(月) 20:29   No:53165     
Title: Re:GetRand関数について    
通常、10〜20の数字を得たいときは、
0〜10の乱数を取得した後、それに10を加えます。


27ポイント を手に入れた。

Name: T.J  ..ぴよぴよ(262ポイント)   Date: 2010/05/31(月) 21:05   No:53169 解決!     
Title: Re:GetRand関数について    
>MNSさん
なるほど、そんな簡単なことでよかったんですか。逆に気付きませんでした(笑)
有難うございました!


33ポイント を手に入れた。



Name: いむ  ..ぴよぴよ(240ポイント)   Date: 2010/05/31(月) 18:25   No:53150       
Title: テキストファイルからの読み込みについて    
今回で2度目の投稿となるのですが、どうしても
わからなかったところがあるので質問させていただきます。

以下のようなテキストファイルからデータを読み込んでいき、
ファイルの終わり(EOF)がくるまでループさせるということを
やっています。

テキストファイルの中身

25 2 3
4 5 6
7 8
[EOF]

ソースファイルの一部

    while (!feof(fp)) {

        fscanf(fp,"%d",&value);
        printf("%d\n",value);
    }

25
2
3
4
5
6
7
8

という結果が出てほしいのですが、実際は
最後の8が2回表示されてしまいます。
[EOF]の位置が下の場合にはちゃんと表示されるのですが、
今回のような場合にでもしっかりと表示されるような方法はありますか?

25 2 3
4 5 6
7 8[EOF]



240ポイント を手に入れた。


Name: たかぎ [URL]  ..ハッカー(193,769ポイント)   Date: 2010/05/31(月) 18:46   No:53152     
Title: Re:テキストファイルからの読み込みについて    
fscanfの返却値をちゃんと確認しましょう。


22ポイント を手に入れた。

Name: いむ  ..ぴよぴよ(355ポイント)   Date: 2010/05/31(月) 18:54   No:53153     
Title: Re:テキストファイルからの読み込みについて    
>たかぎさん
お早い返信ありがとうございます。
以下のようにしてみたところ、自分の望むような
結果が表示されたのですがこれでいいのでしょうか?

    while (!feof(fp)) {

        if ((fscanf(fp,"%d",&value))==-1) break;
        printf("%d\n",value);
    }


115ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(193,888ポイント)   Date: 2010/05/31(月) 19:11   No:53156     
Title: Re:テキストファイルからの読み込みについて    
↓のほうがよいのでは?

if ((fscanf(fp,"%d",&value)) < 1) break;



45ポイント を手に入れた。

Name: いむ  ..ぴよぴよ(403ポイント)   Date: 2010/05/31(月) 19:17   No:53157     
Title: Re:テキストファイルからの読み込みについて    
>たかぎさん

理解力がなくて申し訳ないのですが、
どうしてそのような判定式になるのでしょうか?


48ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(193,902ポイント)   Date: 2010/05/31(月) 19:24   No:53158     
Title: Re:テキストファイルからの読み込みについて    
fscanfの仕様を調べてみてください。


14ポイント を手に入れた。

Name: いむ  ..ぴよぴよ(483ポイント)   Date: 2010/05/31(月) 19:34   No:53161     
Title: Re:テキストファイルからの読み込みについて    
>たかぎさん

fscanfはデータの読み取りに成功した個数を
返すので、戻り値が1より小さいという式を用いたということで
いいでしょうか?


2倍のポイントを手に入れた! 80ポイント を手に入れた。



Name: ムンバ  ..熟練のプログラマー(54,147ポイント)   Date: 2010/05/31(月) 00:31   No:53125       
Title: DXライブラリのメイン関数につきまして(雑談です)    
と、Visual C++ 2010 Expressにつきまして(これも雑談で、すみません。)
タイトル画面が長くなっちゃうと思ったので、こうしました。^^;

こんばんは。
いつもお世話になります。

今回は、DXライブラリのメイン関数についての質問なのですが・・・

実は、昨日から本家の掲示板で直接、お聞きしようと何度も思っていたのですが
一度も質問などした事は無いですし、先ほど覗いて見たら
私のハンドルネーム(ムンバ)と似た様な名前の方が、ご質問されていたので
あちらで質問しにくくなってしまいました。
ですので、雑談という事で宜しくお願い致します。(_ _)

こちら(Dixqさんのサイト内)のサンプルソースや
DXライブラリ本家のサンプルソースのDXライブラリでのメイン関数は

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )

と、なっていますが今、勉強してる本のDXライブラリのメイン関数は

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC)

と、なっています。
この様に(この本のメイン関数の様に)省略?しても
こちらのサイト内や本家のサンプルソースは、実行できました。

OS:Win7 Pro(32bit) ---編集追加部位---
環境:VC++2008(SP1)

私が購入した本の記述では
「HINSTANCE や LPSTR は、マイクロソフトが定義した型名です。
本書ではここ以外では登場しないので、正確に入力
していれば特に気にする必要はありません。」
と、なってます。


質問1
 http://www.microsoft.com/japan/msdn/vstudio/express/default.aspx
 のページの、左下の方

 Visual C++ 2010 Express
 ↑こちらをDLして使用した場合、30日〜90日無料で、91日目からは有料になるのでしょうか?
 それとも今、私が使ってるVC++2008の様に、ライセンスを取得すれば
 91日目からも、無料で継続使用できるものなのでしょうか?

質問2(.cpp)
 DXライブラリのメイン関数は
 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
 か
 int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC)
 か
 今後(今の所)、どちらで記述していけば間違いが無いのでしょうか?
 PCの環境によって使い分けた方が良いのでしょうか?

質問3(Visual C++ 2010 Express が、無償だと仮定しての質問です。)
    有償でしたら、質問3は無視して下さい。)

 質問3-1
  Visual C++ 2010 Express にバージョンアップした理由を、お聞きしたいです。
 質問3-2
  Visual C++ 2010 Express にバージョンアップしなかった理由を、お聞きしたいです。


相変わらず、ごめんなさい。寝てしまいます。(謝
寝るぎりぎりまで調べた結果の質問です。
またまた訳の解らない質問をしている様でしたら、ご迷惑をお掛け致します。
お時間のある方、お手数ですが、ご指導・ご指摘の程、宜しくお願い致します。

おやすみなさい。すみません。(_ _) 編集済み


524ポイント を手に入れた。


Name: Justy  ..伝説なるハッカー(537,075ポイント)   Date: 2010/05/31(月) 01:13   No:53129     
Title: Re:DXライブラリのメイン関数につきまして(雑談です)    
>質問1 
 2008と同じだと思いますよ。
 無料の登録だけすればそのまま無料。


>質問2(.cpp) 
 ただの変数名の違いしかないので、使い分ける必要もなく別にどっちでもいいです。お好みで。
 でもよく見かけるのは上の方ですし、変数名として意味がわかりやすいのも上ですね。

 ただ普通の Windowsプログラムならともかく DXライブラリの場合4つの引数とも
どうせ使わないので
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 
でいいかも。


>質問3-2
 メモリと HDDを食いつぶしそうだから、というのもありますが、仕事でも使う予定ないですし
2008の時に発売直後に買って痛い目みてるんで様子見 or SP1待ちです。


192ポイント を落としてしまった。

Name: たかぎ [URL]  ..ハッカー(193,554ポイント)   Date: 2010/05/31(月) 07:35   No:53135     
Title: Re:DXライブラリのメイン関数につきまして(雑談です)    
雑談ということなので...

DXライブラリはWinMainから始めるようになっていますが、次のようにmainから始めるようにしておけばもっと取っ付き易くなるのに、と考えることがあります。

#include <windows.h>
#include <stdlib.h>
extern int main(int, char*[]);
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 
{
    return main(__argc, __argv);
}

注) Cでないとコンパイルできません。


146ポイント を手に入れた。

Name: ムンバ  ..熟練のプログラマー(54,507ポイント)   Date: 2010/05/31(月) 10:30   No:53139 解決!     
Title: Re:DXライブラリのメイン関数につきまして(雑談です)    
おはようございます!

Justyさん、たかぎさん、早速のご解説どうもありがとうございます。

<<Justyさん
 新しいもの好きですので、無料だったらと思ったのですが
 おっしゃる様に私も「様子見orSP1」待ちにしときます。(笑
 
 4つの引数とも使われて無いんですか?
 知りませんでした〜!^^;
 しばらく? int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
 でやってみます。見易いですし。
 ありがとうございました。

<<たかぎさん
 了解しました!
 ソースありがとうございます。
 そういう書き方もできるんですね。試してみたいと思います。
 どうもありがとうございました。

勉強になりました。
また何かあれば、宜しくお願い致します。
失礼します。


360ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(193,595ポイント)   Date: 2010/05/31(月) 17:25   No:53146     
Title: Re:DXライブラリのメイン関数につきまして(雑談です)    
> そういう書き方もできるんですね。試してみたいと思います。

いや、DXライブラリ自体がそういう作りになっていれば、という妄想です。


23ポイント を手に入れた。

Name: ムンバ  ..熟練のプログラマー(54,553ポイント)   Date: 2010/05/31(月) 19:32   No:53160 解決!     
Title: Re:DXライブラリのメイン関数につきまして(雑談です)    
わざわざ、すみません。
相変わらず、勘違い多くて。^^;
ありがとうございました。

---↓追加---
もし、まだ見ていたら、たかぎさん・・・。

#include <windows.h> 
#include <stdlib.h> 
extern int main(int, char*[]); 
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)  

    return main(__argc, __argv); 
}

の方が、私の様な、ぴよぴよのプログラマーには
とっつきにくいっすよ。(涙

って事で、また何かありましたら宜しくお願い致します。ε=ε=┏( ∩_∩)┛ 編集済み


46ポイント を手に入れた。



Name: ハナブトオオトカゲ  ..かけだし(2,265ポイント)   Date: 2010/05/30(日) 22:37   No:53117       
Title: 跳ね返りができません。    
#include "DxLib.h"

typedef struct{
        int x,y,z,img,flag,down,up;
}ch_t;
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
        if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
 
     ch_t ball;//構造体ball
    ball.x=320;
    ball.y=450;
    ball.z=10;
    ball.up=0;
    ball.down=0;
     int bx=270;//bx:バーのX座標
    int bcolor; bcolor=GetColor(255,255,255);//バーの色の設定
    char key[256];
    SetDrawScreen( DX_SCREEN_BACK ) ;
    int start=0;//発射確認
    while(1){
        if(ProcessMessage()==-1) break;
        ClearDrawScreen();
        GetHitKeyStateAll(key);
        if(key[KEY_INPUT_SPACE]==1){
            ball.flag=1;
            } 
        if(key[KEY_INPUT_RIGHT]==1){ bx+=5; if(ball.flag==0) ball.x+=5;};//右キーでバーを右に+ボール操作
        if(key[KEY_INPUT_LEFT]==1){ bx-=5; if(ball.flag==0) ball.x-=5;}//左キーでバーを左に+ボール操作
        if(bx>540){ bx=540; if(ball.flag==0) ball.x=590;}
        if(bx<0){ bx=0;if(ball.flag==0) ball.x=50;}
        if(ball.flag==1){
            if(ball.x==0&&ball.down==1&&ball.y>=5){
                ball.x+=5;
                ball.y-=5;
                ball.up=0;
                ball.down=1;
                }
                
            if(ball.x==640&&ball.down==0&&ball.y>=5){
                ball.x-=5;
                ball.y-=5;
                ball.up=1;
                ball.down=0;
                }
            if(ball.y<5&&ball.up==1){
                ball.x-=5;
                ball.y+=5;
                ball.up=1;
                ball.down=0;
            }
            else {
                ball.x+=5;
                ball.y-=5;
                ball.up=1;
                ball.down=0;
                }
            }
        DrawBox(bx,460,bx+100,470,bcolor,TRUE);
        DrawCircle(ball.x,ball.y,ball.z,bcolor,TRUE);
        ScreenFlip();
         } 
        DxLib_End() ;           // DXライブラリ使用の終了処理
        return 0 ;              // ソフトの終了
}

スペースでボール発射
ball.upはボールが上へ向かっている状態
ball.downはボールが下へ向かっている状態です。

どうしたらいいか教えてください。


744ポイント を手に入れた。


Name: ru  ..入門者(3,994ポイント)   Date: 2010/05/31(月) 00:02   No:53124     
Title: Re:跳ね返りができません。    
見辛い
#include "DxLib.h" 

typedef struct
{ 
    int x;
    int y;
    int dx;
    int dy;
    int r;
    int flag;
}ch_t; 
  
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(TRUE);
    DxLib_Init();
    SetDrawScreen(DX_SCREEN_BACK);

    ch_t ball;
    ball.x = 320;
    ball.y = 450;
    ball.dx = 0;
    ball.dy = 0;
    ball.r = 10;
    ball.flag = 0;

    int bx = 270;
    int by = 460;
    int color = GetColor(255, 255, 255);
    char key[256];
    int start = 0;

    while(ProcessMessage() != -1)
    { 
        ClearDrawScreen();
        GetHitKeyStateAll(key);

        if(key[KEY_INPUT_ESCAPE])
        {
            break;
        }

        // 発射
        if(key[KEY_INPUT_SPACE])
        {
            ball.flag=1;
            ball.dx = 5;
            ball.dy = -5;
        }
        // バー移動
        if(key[KEY_INPUT_RIGHT])
        {
            bx += 5;
        }
        if(key[KEY_INPUT_LEFT])
        {
            bx -= 5;
        }
        // バー移動範囲
        if(bx > 540)
        {
            bx = 540;
        }
        if(bx < 0)
        {
            bx = 0;
        }
        // ボール
        if(ball.flag)
        {
            // 移動計算
            ball.x += ball.dx;
            ball.y += ball.dy;
            // 移動範囲
            if(ball.x < 5 || ball.x > 640 - 5)
            {
                ball.dx *= -1;
            }
            if(ball.y < 0)
            {
                ball.dy *= -1;
            }
            if(by <= ball.y && by + 10 >= ball.y && bx <= ball.x && bx + 100 >= ball.x)
            {
                ball.dy *= -1;
            }
        }

        DrawBox(bx, by, bx + 100, by + 10, color, TRUE); // バー
        DrawCircle(ball.x, ball.y, ball.r, color, TRUE); // ボール

        ScreenFlip();
    }

    DxLib_End();
    return 0;
}



266ポイント を手に入れた。

Name: Tatu  ..プログラマー(35,724ポイント)   Date: 2010/05/31(月) 00:38   No:53127     
Title: Re:跳ね返りができません。    
跳ね返りがうまくいかないと書かれていますが
ボールが何にもぶつかっていない状態では右上にしか
動かないようになっているみたいです。

そこで、ボールの構造体にx方向の速度、y方向の速度(または、速さと移動方向)
の変数を追加して、ボールの座標に速度を足して移動させるようにしたらどうでしょうか。

跳ね返りはボールが壁やバーにめり込み続けるような状態だったら速度を変更する
というようにすればよいでしょう。

あと、ブロック崩しのプログラムであるならば始めにそう書いておいた方がよいですよ。


208ポイント を手に入れた。

Name: ハナブトオオトカゲ  ..かけだし(2,308ポイント)   Date: 2010/05/31(月) 06:01   No:53134 解決!     
Title: Re:跳ね返りができません。    
速度の変数で移動すればいいのですね。

ありがとうございました。

ブロックなしのブロック崩しというのは書き忘れていました。

すみませんでした。


43ポイント を手に入れた。



Name: Libra  ..上級者(20,416ポイント)   Date: 2010/05/30(日) 00:07   No:53035       
Title: 図形の描画について    
DXライブラリを用いた時の処理です

質問
1:DXライブラリの楕円の描画で、添付図のように角度を変えて描画する事は可能でしょうか?
2:DXライブラリではどのような方法で円を描いているのでしょうか?
3:DXライブラリの図形描画のうち、円の描画だけ、引数のFillFlagに
デフォルト引数が設定されているのは何故でしょうか?



1に関して:描画が可能、という事であれば実装手順の方向性を教えていただきたいです。

2に関して:DirectXを用いてポリゴンで円や楕円を描いた時は、
中心から半径分だけの距離が離れた座標点(float型x、y)を中心から等角度で一定個数求め、
プリミティブの設定をトライアングルファンにして描画という方法で実装したのですが、
半径が10を下回ると歪な形になってしまいました。DXライブラリでは点を描画して円を作っている
という方法なのでしょうか?DXライブラリのソース読んでもわかりませんでした・・・。

3に関して:DxLib.hのプロトタイプ宣言を見たら、図形描画の円だけ
デフォルト引数が設定されていたので気になりました。


@DXライブラリのVerが3になって、かなりライブラリの内容が変化したと思いました。


496ポイント を手に入れた。


Name: Justy  ..伝説なるハッカー(536,681ポイント)   Date: 2010/05/30(日) 02:15   No:53058     
Title: Re:図形の描画について    
>1:DXライブラリの楕円の描画で、添付図のように角度を変えて描画する事は可能でしょうか? 
 DrawOval関数ですか?
 この関数を使わないで、ということであればいろいろやりようはありますが、
使ってということであれば残念ですが、この関数単体で回転させることはできません。
 しかし、この関数を使って楕円を(バックバッファではなく)テクスチャにレンダリングして楕円を書いた後
そのテクスチャを回転させて表示すれば、一応可能です。


>2:DXライブラリではどのような方法で円を描いているのでしょうか?
>点を描画して円を作っているという方法なのでしょうか
 細かいアルゴリズムはソースを見ながらデバッガで追うといいと思いますが、
計算で楕円になるよう FillFlagが偽ならポイントリストで、真ならラインリストを使って
描いているようです。

 単純にトライアングルファン方式と比べると、精度は高いものの楕円が大きいと何度も描きにいきますので、
それなりに負荷がありますね。


>3:DXライブラリの図形描画のうち、円の描画だけ、引数のFillFlagに 
>デフォルト引数が設定されているのは何故でしょうか? 
 特にその関数だけデフォルト引数にした方がいい理由もないので、
作者に訊かないとわかりません。


332ポイント を手に入れた。

Name: 夕暮  ..ぴよぴよ(119ポイント)   Date: 2010/05/30(日) 08:09   No:53064     
Title: Re:図形の描画について    
>3:DXライブラリの図形描画のうち、円の描画だけ、引数のFillFlagに  
>デフォルト引数が設定されているのは何故でしょうか? 

前に作者に似たような質問をしたのですが
バグではないのですがDXライブラリでは
初期の引数を設定してたりしなかったりと色々と調整してきたらしいです。
これはDXライブラリを作ってきた名残で残っているみたいです。
作者も気がついてはないと思いますので本家で指摘されてはどうでしょうか?


119ポイント を手に入れた。

Name: Libra  ..上級者(20,431ポイント)   Date: 2010/05/31(月) 00:37   No:53126 解決!     
Title: Re:図形の描画について    
返信ありがとうございます。

Justyさん
レンダリングして画像に変換して表示すればいいのですね。
もう少しソースの方を読み進めて理解していきたいと思います。

夕暮さん
今サークルで使う予定のDXライブラリの資料を作っているのですが、
図形描画の部分で、デフォルト引数が設定されていた為気になった次第です


15ポイント を手に入れた。



Name: MK  ..ぴよぴよ(429ポイント)   Date: 2010/05/26(水) 10:33   No:52817       
Title: 生年月日から(年齢)、(曜日)を出力    
今、生年月日から年齢と曜日を出すプログラムを作成していますが年齢は表示できるのですが曜日を出力のやり方が分かりません。
文字なので「%c」だと思って試すと「@」になってしまいます。
曜日の計算式は聞きましたが、それが何曜日になるのかが分からないのでご教授いただけないでしょうか

#define    _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Leap_Year(int);
int    Last_Day(int yy,int mm);
int Day_of_the_Week(int yy,int mm,int dd);
int main(void){
    int Today=20100401;
    int yy,mm,dd,Birth,nen;
    int Ld[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    
    do{
        printf("生年=");
        rewind(stdin);
        scanf("%d",&yy);
    }while(yy<1 || yy>(Today/10000));
    
    do{
        printf("生月=");
        rewind(stdin);
        scanf("%d",&mm);
    }while(mm<1 || mm>12);
    if(Leap_Year(yy)==1)    Ld[2]=29;
    else                    Ld[2]=28;

    do{
        printf("生日=");
        rewind(stdin);
        scanf("%d",&dd);
    }while(dd<1 || dd>Ld[mm]);
    
    Birth=yy*10000+mm*100+dd;
    nen=(Today-Birth)/10000;
    printf("年齢=%d\n",nen);
    printf("曜日=%c\n",Day_of_the_Week);
    rewind(stdin);
    getchar();
    return 0;
}
int Day_of_the_Week(int yy,int mm,int dd)
{
    if(mm<3)    {yy--;    mm+=10;}
    else        {mm-=2;}
    
    return((yy+(yy/4)-(yy/100)+(yy/400)+(13*mm+34)/5+dd)%7);
}
int    Leap_Year(int);
int    Last_Day(int yy,int mm)
{
    if(mm==2)    return(28+Leap_Year(yy));
    else        return((mm<8)?    30+mm%2:31-mm%2);
}
int Leap_Year(int yy)
{
    if((yy%4)!=0)    return(0);
    if((yy%100)!=0)    return(1);
    if((yy%400)!=0)    return(0);
    return(1);
}


429ポイント を手に入れた。


Name: ru  ..入門者(2,612ポイント)   Date: 2010/05/26(水) 13:17   No:52826     
Title: Re:生年月日から(年齢)、(曜日)を出力    
printf("曜日=%c\n",Day_of_the_Week); 
int Day_of_the_Week(int yy,int mm,int dd);


42ポイント を手に入れた。

Name: MK  ..ぴよぴよ(442ポイント)   Date: 2010/05/27(木) 19:01   No:52887 解決!     
Title: Re:生年月日から(年齢)、(曜日)を出力    
ありがとうございます


13ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(86,926ポイント)   Date: 2010/05/28(金) 10:58   No:52925     
Title: Re:生年月日から(年齢)、(曜日)を出力    
何故か解決したらしいけど気持ち悪いのでコメント。

> printf("曜日=%c\n",Day_of_the_Week);

この書き方では関数Day_of_the_Weekは呼ばれません。
関数のアドレスを取得し、それを文字として出力しようとしています。
正しく呼び出して表示するためには、まず次のように書きましょう。
戻り値は整数ですので、printfの書式指定は%dです。

printf("曜日=%d\n", Day_of_the_Week(yy, mm, dd));

次にこの戻り値は整数で、0が日曜日、1が月曜日、、、という意味です。
曜日に変換する標準関数はないので、次のような方法があります。
今度は文字列を表示しているので、%sです。

const char str[][7] = { "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" };
int dow = Day_of_the_Week(yy, mm, dd);
printf("曜日=%s\n", str[dow]);


181ポイント を手に入れた。

Name: やんち [URL]  ..かけだし(1,154ポイント)   Date: 2010/05/28(金) 14:47   No:52940     
Title: Re:生年月日から(年齢)、(曜日)を出力    
蛇足ですが、一週間の曜日を表示するサンプルプログラムを作って見ました。

----------------------------------------------------------------------
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

/**
 * ロケールの設定。
 */
void mysetlocale()
{
    int category;
    char *locale;
    
    category = LC_ALL;
    locale = "japanese";
    setlocale(category, locale);
}

/**
 * 一週間の曜日を表示。
 */
void print_wdays()
{
    struct tm date;
    char string[256];
    size_t maxsize;
    char *format;
    const int sunday = 0;
    const int saturday = 6;
    
    memset(&date, 0, sizeof(date));
    for (date.tm_wday = sunday; date.tm_wday <= saturday; date.tm_wday++)
    {
        maxsize = 255;
        format = "%A";
        strftime(string, maxsize, format, &date);
        printf("%s\n", string);
    }
}

/**
 * メイン関数。
 * @param[in] argc argv の数
 * @param[in] argv コマンドライン引数
 */
int main(int argc, char *argv[])
{
    mysetlocale();
    print_wdays();
    
    return 0;
}


129ポイント を手に入れた。

Name: メタ  ..かけだし(1,139ポイント)   Date: 2010/05/30(日) 16:52   No:53088     
Title: Re:生年月日から(年齢)、(曜日)を出力    
横槍ですが
>Title: Re:生年月日から(年齢)、(曜日)を出力     
>    蛇足ですが、一週間の曜日を表示するサンプルプログラムを作って見ました。
>やんちさん

エラーが出ました。。


80ポイント を手に入れた。

Name: やんち [URL]  ..かけだし(1,287ポイント)   Date: 2010/05/30(日) 19:37   No:53104     
Title: Re:生年月日から(年齢)、(曜日)を出力    
>横槍ですが
>>Title: Re:生年月日から(年齢)、(曜日)を出力     
>>    蛇足ですが、一週間の曜日を表示するサンプルプログラムを作って見ました。
>>やんちさん

> エラーが出ました。。

画像が潰れてて見難いですが、

Win32アプリケーションとかで、プロジェクト作ってませんか?
コンソールアプリケーションですよ。


133ポイント を手に入れた。

Name: MK  ..ぴよぴよ(456ポイント)   Date: 2010/05/30(日) 20:52   No:53108 解決!     
Title: Re:生年月日から(年齢)、(曜日)を出力    
皆さんありがとうございました^^

14ポイント を手に入れた。



Name: papa  ..ぴよぴよ(483ポイント)   Date: 2010/05/30(日) 00:28   No:53040       
Title: 描画輝度関数について    
はじめまして。初めて質問させていただきます。
私は現在ゲームプログラミングの館の入門編を順に進めております。
入門編の第9節の「輝度をセットする」で使用したSetDrawBright関数について教えていただきたいです。

SetDrawBright  ( 255 , 255 , 255 ) ;               //元の明るさにセット
LoadGraphScreen(   0 ,   0 , "graph/char.png" , TRUE ) ;//画像を表示。
       
SetDrawBright  ( 255 ,   0 ,   0 ) ;               //赤以外の明るさを0にセット
LoadGraphScreen( 200 ,   0 , "graph/char.png" , TRUE ) ;//画像を表示。
        
SetDrawBright  ( 128 , 128 , 128 ) ;               //明るさを半分にセット
LoadGraphScreen( 400 ,   0 , "graph/char.png" , TRUE ) ;//画像を表示。

サンプルプログラムは↑のようになっていましたが、SetDrawBright は次の行で挿入される図の輝度を
調整する関数と理解してよいのでしょうか?

また、第8節の「時間を取得する」のサンプルプログラムのfor文には{}は不要なのでしょうか?

開発環境はゲームプログラミングの館の解説どおりのものを使用しております。
初心者の初歩的な質問に答えるのも億劫だと思いますが、ご教授お願いいたします。


483ポイント を手に入れた。


Name: jay  ..上級者(16,554ポイント)   Date: 2010/05/30(日) 00:46   No:53047     
Title: Re:描画輝度関数について    
SetDrawBright関数とは、簡単に説明するならば
”次にSetDrawBright関数で輝度を調整するまでの画像全ての輝度を調整する関数”です。
つまり同じ輝度で画像を何度も描画するときは、わざわざ何度も調整しなくてもいいということです。
逆に言うと一度でも宣言してしまうと、もう一度宣言し直すまで輝度はずっと同じですから注意してください。


ちなみに
SetDrawBright  ( 255 ,   0 ,   0 ) ;  
にそれぞれに設定されている値は左から’R’’G’’B’
つまり”レッド””グリーン””ブルー”と光の三原色の強さを表しています。
それぞれの光の強さを調整するものだと思って下さい。
最大値は”255”、最小値は”0”です


for文に関してですが、
通常for文は”{}”でくくられた部分だけを繰り返します。
しかし”{}”は省くこともできます。
”{}”を省いた場合はfor文の次の文だけを、今回の場合は

for(i=0;i<100000;i++)                   //10万回a++;を実行
a++;

なのでa++を100000回繰り返すことになります。
これを”{}”をつけて下のように書いた場合、結果は全く同じになります。

for(i=0;i<100000;i++)//10万回a++;を実行
{
a++;
}


”{}”を省いた場合は”for文”の次の一文だけを繰り返すので注意して下さい。 編集済み


581ポイント を落としてしまった。

Name: papa  ..ぴよぴよ(534ポイント)   Date: 2010/05/30(日) 18:31   No:53099 解決!     
Title: Re:描画輝度関数について    
早速のご回答ありがとうございます。
jayさんのご解説で理解することができました。
これで安心して次の節に進むことができそうです。

お世話になりました。


51ポイント を手に入れた。



Name: ハナブトオオトカゲ [URL]  ..かけだし(1,502ポイント)   Date: 2010/05/30(日) 09:30   No:53066       
Title: 管理人さんへ 間違えたリンクがあります。    
http://dixq.net/g/30.html の物理入門ページへのリンクが、物理入門ページにいくのではなく、もう一度そのページを読み込むようになっています。

つまり、http://dixq.net/g/57.htmlへのリンクになっていません。

あと、僕は中2なのですが、物理について詳しくやっていません。

http://dixq.net/g/57.htmlでゆっくり理解し、ジャンプなどがしっかりできるようになってから次に進むべきでしょうか?


137ポイント を手に入れた。


Name: Dixq (管理人) [URL]  ..ウィザード(1,194,447ポイント)   Date: 2010/05/30(日) 11:33   No:53067     
Title: Re:管理人さんへ 間違えたリンクがあります。    
ありがとうございます。リンクミスですね。修正しました。ご報告ありがとうございます。

物理については知らなくても全く問題無いですよ。
ゲーム中キャラクタがジャンプするような動作や投げたボールの軌跡をリアルに表現したい時にしか使いません。

DXライブラリは特別何かを学ぶことなく基本的な関数に使い方を知ればもうすでにゲームが作れてしまうので、
一通り関数の使い方を確認したらゲームを作る作業にうつって大丈夫だと思いますよ。


189ポイント を手に入れた。

Name: ハナブトオオトカゲ [URL]  ..かけだし(1,521ポイント)   Date: 2010/05/30(日) 16:50   No:53087 解決!     
Title: Re:管理人さんへ 間違えたリンクがあります。    
ありがとうございました。
とりあえず、物理のところは飛ばして次に進みます。


19ポイント を手に入れた。



Name: Ryou  ..ぴよぴよ(115ポイント)   Date: 2010/05/30(日) 15:02   No:53072       
Title: 無題    
『バブルの整列関数に必要な関数を付加し,任意個(<100)の正数(0以上100以下)を対象とするバブルの3種の整列プログラムを完成せよ.
整列処理中に交換、並べ替えが起きた場合,交換や並べ替えがおきた要素を文字*で,そうでない要素を文字.で表した文字列を出力せよ.整列対象のデータ(配列)内で,データで移動しているものが*となる』

という課題で、下のようなプログラムでいけると分ったのですが、
「for(k=0;k<n;printf(%s,k==j-1||k==j?*:.);k++);」
では何が起こっているのか分かりません

もっと簡単なプログラムでかけるのなら教えてください



#include <stdio.h>

int BubSort(int x[ ], int n);
void ShowData(int x[ ], int n);
int main(void);

#define NUM_DATA 10
int x[ ] = {9,8,7,6,5,4,3,2,1,0};



int BubSort(int x[ ], int n)
{
int i, j, temp;
int k;

for (i = 0; i < n - 1; i++) {
for (j = n - 1; j > i; j--) {
if (x[j - 1] > x[j]) {
temp = x[j];
x[j] = x[j - 1];
x[j - 1]= temp;


for(k=0;k<n;printf(%s,k==j-1||k==j?*:.);k++);
printf(\n);



}
}
}
}


void ShowData(int x[ ], int n)
{
int i;

for (i = 0; i < n ; i++)
printf(%d, x[i]);
}

int main(void)
{

printf(BeforeSort:\n);
ShowData(x, NUM_DATA);
printf(\n\n);

BubSort(x, NUM_DATA);


printf(\n\nAfterSort:\n);
ShowData(x, NUM_DATA);
printf(\n);
return 0;
}



115ポイント を手に入れた。


Name: box  ..ハッカー(154,319ポイント)   Date: 2010/05/30(日) 15:42   No:53073     
Title: Re:無題    
コンパイルエラーが出ないソースを載せてください。

24ポイント を手に入れた。

Name: Ryou  ..ぴよぴよ(477ポイント)   Date: 2010/05/30(日) 15:47   No:53075     
Title: Re:無題    
#include <stdio.h>

int BubSort(int x[ ], int n);
void ShowData(int x[ ], int n);
int main(void);

#define NUM_DATA 10
int x[ ] = {9,8,7,6,5,4,3,2,1,0};



int BubSort(int x[ ], int n)
{
int i, j, temp,k;

for (i = 0; i < n - 1; i++) {
for (j = n - 1; j > i; j--) {
if (x[j - 1] > x[j]) {
temp = x[j];
x[j] = x[j - 1];
x[j - 1]= temp;


for(k=0;k<n;printf("%s",k==j-1||k==j?"*":"."),k++);
printf("\n");



}
}
}
}


void ShowData(int x[ ], int n)
{
int i;

for (i = 0; i < n ; i++)
printf("%d", x[i]);
}

int main(void)
{

printf("ソート前:");
ShowData(x, NUM_DATA);
printf("\n\n");

BubSort(x, NUM_DATA);


printf("\n\nソート後:");
ShowData(x, NUM_DATA);
printf("\n");
return 0;
}



でコンパイルエラーはでないです。


362ポイント を手に入れた。

Name: asdf  ..かけだし(1,522ポイント)   Date: 2010/05/30(日) 15:53   No:53076     
Title: Re:無題    
BubSort関数がおかしいです。

12ポイント を手に入れた。

Name: box  ..ハッカー(154,333ポイント)   Date: 2010/05/30(日) 16:27   No:53081     
Title: Re:無題    
> for(k=0;k<n;printf("%s",k==j-1||k==j?"*":"."),k++);

三項演算子 ?: についてご存じでなければ、調べてみてください。
if文で置き換えられます。


BubSort関数の戻り値がint型になっていますが、
どこかで使っているわけではないのでvoidでよいのではないでしょうか。


14ポイント を手に入れた。

Name: sage   Date: 2010/06/18(金) 11:17   No:530721276827459     
Title: Re:無題    
t

Name: sage   Date: 2010/06/18(金) 11:19   No:530721276827547     
Title: Re:無題    
テスト



Name: ハナブトオオトカゲ [URL]  ..かけだし(1,268ポイント)   Date: 2010/05/29(土) 21:42   No:53013       
Title: なぜこうなるのか    
シューティングの基本の、

else if( Key[ KEY_INPUT_RETURN ]  == 1 ){//5カウント以上たっていたら
                        counter=0;                       //カウンターを戻す
                        for(i=0;i<10;i++){             
                                if(tama[i].flag==0){     //発射していない玉を探し、
                                        tama[i].flag=1;  //発射フラグを立てる
                                        break;
                                }
                        }
                }
                for(i=0;i<10;i++){
                        if(tama[i].flag==1){              //発射している玉なら
                                tama[i].y-=8;             //座標を8減らす
                                DrawGraph( tama[i].x , tama[i].y , image[1] , TRUE );//玉を描画
                                if(tama[i].y < -32){      //もし画面外まで来たら
                                        tama[i].y=480;    //初期値に戻し、
                                        tama[i].flag=0;   //発射フラグを戻す
                                }
                        }
                }


についてなのですが、これで、エンターが1回押されただけでtama[0〜9]のflagがすべて1になってしまいそうなのですが、なぜ1つ1つ弾を打つことができるのでしょうか?

全部が発射フラグになっていたら全部が一気に飛びそうですが・・・。 編集済み


164ポイント を手に入れた。


Name: シエル  ..ぴよぴよ(874ポイント)   Date: 2010/05/29(土) 22:08   No:53020     
Title: Re:なぜこうなるのか    
ひとつフラグを立てる毎に、breakで抜けてるから。


5ポイント を手に入れた。

Name: ハナブトオオトカゲ [URL]  ..かけだし(1,365ポイント)   Date: 2010/05/29(土) 22:18   No:53021 解決!     
Title: Re:なぜこうなるのか    
あっ

whileで戻ってきたらまた0からやり直しだ・・・と思っていたら、wlileで戻ってきたときにはまだ画面上で上に動いている途中だから、i=0は飛ばされてi=1に行くというわけですね・・・!!!

ものすごくすっきりしました。


97ポイント を手に入れた。

Name: メタ  ..ぴよぴよ(960ポイント)   Date: 2010/05/29(土) 23:10   No:53028     
Title: Re:なぜこうなるのか    
質問者ではないのですが、breakすると、
       if(tama[i].flag==0){     //発射していない玉を探し、 
       tama[i].flag=1;  //発射フラグを立てる 
       break; 
}
から抜けるのでしょうか?
それとも、その前のforやelse ifからも抜けて、main関数からも抜けるのでしょうか?

何言ってるんだこいつ・・・と思うかもしれませんが、お願いします。


151ポイント を手に入れた。

Name: シエル  ..ぴよぴよ(888ポイント)   Date: 2010/05/29(土) 23:12   No:53029     
Title: Re:なぜこうなるのか    
for(i=0;i<10;i++)からだけ抜ける。

14ポイント を手に入れた。

Name: メタ  ..かけだし(1,022ポイント)   Date: 2010/05/29(土) 23:18   No:53031     
Title: Re:なぜこうなるのか    
なるほど!ありがとうございます!そうすると理解できました!
ハナブトオオトカゲさんの発言はちょっとまだ理解できませんが。。


62ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,194,787ポイント)   Date: 2010/05/30(日) 12:05   No:53068     
Title: Re:なぜこうなるのか    
ではちょっと詳しく説明してみます。


全てのデータは0で初期化してあるとし、
フラグは

tama[0].flag=1;
tama[1].flag=1;
tama[3].flag=1;

であるとしましょう。


数が少ない要素から登録を行いますが、画面から外に出るとフラグをオフにするので、
時間がたつと、数が少ないものからオフになります。
従って上記のように穴があるような状態になる場合があります。

01: while(1){
02:     if(counter<5){                           //前にエンターを押してから5カウント未満なら
03:            counter++;                        //カウントアップ
04:     }
05:     else if( Key[ KEY_INPUT_RETURN ]  == 1 ){//5カウント以上たっていたら
06:         counter=0;                           //カウンターを戻す
07:         for(i=0;i<10;i++){             
08:             if(tama[i].flag==0){             //発射していない玉を探し、
09:                 tama[i].flag=1;              //発射フラグを立てる
10:                 break;                       //for文から処理を抜ける
11:             }
12:         }
13:     }
14: }

まず5カウント以上押しっぱなしになるまでは2行目のifに入ります。
5カウント以上たてば5行目のelse ifの方に入ります。
counter=0;にして、
7行目でtamaのフラグが0の物を探します。

8行目でまず、i=0において、tama[i]・・つまりtama[0].flagが0かどうかを調べます。
しかし今、このフラグ1なので、そのまま7行目のi++が行われてi=1になります。
tama[1].flagを調べますが、これも1なので、戻ってi++が行われます。
tama[2].flagを調べるとこれが0なので、if文の中、9行目に入ります。
10行目でbreakします。
するとこのbreakは12行目のカッコから外にでます。
そのまま13行目へ差し掛かり、1行目に戻るという事です。


340ポイント を手に入れた。




 
[ 1 , ... ]
 
 
管理者画面   RSS   + Powered By 21style +