ショッピングモール  Personal Health / Stress ( Aromatherapy )


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.4955

五目並べのプログラムです…
投稿者---山田(2005/11/27 07:44:12)


前回のみなさんからご教授いただいたことを参考に
プログラムを直してみました。
結果、満足した結果を得られました。
が、問題というか、疑問が1つ生じました。
碁盤の目を表すためにme[][]という配列を用いたのですが、
最初にこれを定義するときのサイズについてわからなくなりました。
プログラム自体はme[81][81]で定義すると、
満足する結果が得られるのですが、
何故でしょうか?
私としては、アスキーコードでoが111ですので、
111でないとまずい気がしたのですが…
私は初心者ですので、
なるべく詳しく教えていただけるとありがたいです。
よろしくお願いいたします。
OSはWindowsXPでコンパイラはC Pad for Borland C++です。

#include<stdio.h>
#include<string.h>

main()
{
    char input[4];
    int me[81][81];                       /*ここです!!*/
    char a, b;
    
    printf("   a b c d e f g h i j k l m n o\n");               
    for(a='A';a<='O';a++)
    {
        printf(" %c", a);
        for(b='a';b<='o';b++)
        {
            me[a][b] = 0;
            if(me[a][b]==0)
            printf(" +");
        }
        printf("\n");
    }
    
    while(1)
    {
    label1:
        printf("先攻の番です。何行目の何列目に置きますか??\n");
        fgets(input, 4, stdin);
        
        if(me[input[0]][input[1]]==1 || me[input[0]][input[1]]==2
                 || input[0]<65 || input[0]>79 || input[1]<97 || input[1]>111 || input[2]!=10)
        {
            printf("不正な入力です。\n");
            goto label1;
        }
         
        me[input[0]][input[1]] = 1;
        printf("   a b c d e f g h i j k l m n o\n");
        for(a='A';a<='O';a++)
        {
            printf(" %c", a);
            for(b='a';b<='o';b++)
            {
                if(me[a][b]==0)
                    {printf(" +");}
                if(me[a][b]==1)
                    {printf(" @");}
                if(me[a][b]==2)
                    {printf(" O");}
            }
            printf("\n");
        }
    label2:
        printf("後攻の番です。何行目の何列目に置きますか??\n");
        fgets(input, 4, stdin);
        
        if(me[input[0]][input[1]]==1 || me[input[0]][input[1]]==2
                 || input[0]<65 || input[0]>79 || input[1]<97 || input[1]>111 || input[2]!=10)
        {
            printf("不正な入力です。\n");
            goto label2;
        }
          
        me[input[0]][input[1]] = 2;
        printf("   a b c d e f g h i j k l m n o\n");
        for(a='A';a<='O';a++)
        {
            printf(" %c", a);
            for(b='a';b<='o';b++)
            {
                if(me[a][b]==0)
                    {printf(" +");}
                if(me[a][b]==1)
                    {printf(" @");}
                if(me[a][b]==2)
                    {printf(" O");}
            }
            printf("\n");
        }
    }
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:五目並べのプログラムです… 4956 επιστημη 2005/11/27 10:54:25


No.4956

Re:五目並べのプログラムです…
投稿者---επιστημη(2005/11/27 10:54:25)


>プログラム自体はme[81][81]で定義すると、
>満足する結果が得られるのですが、
>何故でしょうか?

…てゆーか、碁盤のタテ×ヨコはいくつです?
'a'〜'o'で指定できるのなら me[15][15]で十分ではないかと。



この投稿にコメントする

削除パスワード

No.4957

Re:五目並べのプログラムです…
投稿者---RAPT(2005/11/27 11:08:15)


別スレッドの続きなら、関係を明示してください。
いきにり新スレッドで説明もなく開始されたら、意味不明です。

No.4944 プログラムの間違いを指摘していただけないでしょうか…

プログラム自体はme[81][81]で定義すると、 満足する結果が得られるのですが、 何故でしょうか?
何が問題なのでしょうか。 まず、前提条件と自分の考えを説明してください。 結果だけ示されても、答えようがありません。



この投稿にコメントする

削除パスワード

No.4958

Re:五目並べのプログラムです…
投稿者---山田(2005/11/27 11:49:54)


>'a'〜'o'で指定できるのなら me[15][15]で十分ではないかと。

縦×横は、おっしゃる通り15×15です。
ですが、me[15][15]では動作しませんでした。


>まず、前提条件と自分の考えを説明してください。
結果だけ示されても、答えようがありません。

申し訳ないですが、前提条件という意味を理解できません。
すみません。でも、私なりに状況を説明させていただきます。

まず碁盤の目を表示させるために配列(me[][])を用いようと思いました。
次に、fgets()で取り込んだ英語(AaやGeなど)を
アスキーコードの数でそのままme[][]に代入しようと思いました。
ですから、me[][]の最初の[]にはアスキーコードでOである97まで、
2つめの[]には、oである111まで用意しなければならないと
思ったのですが、
実際は81にしてあげると、問題なく動くのです。
(80だとできませんでした。)
理由を知りたいので教えていただけると嬉しいです。
私なりに状況を説明したつもりですが、
至らない点は教えていただけるとありがたいです。
よろしくお願いします。


この投稿にコメントする

削除パスワード

No.4959

Re:五目並べのプログラムです…
投稿者---まきじ(2005/11/27 12:00:38)


>me[][]の最初の[]にはアスキーコードでOである97まで、
>2つめの[]には、oである111まで用意しなければならないと
>思ったのですが、

[][]内に記述するのは、行と列の数なので
a から o を数えると 15 個だから
me[15][15] とするのが自然かと。

81 は実際のオセロの基盤が 9x9 の 81 マスからきたのでは?
なので me[9][9] とも考えられます。


この投稿にコメントする

削除パスワード

No.4961

Re:五目並べのプログラムです…
投稿者---山田(2005/11/27 12:07:38)


>[][]内に記述するのは、行と列の数なので
>a から o を数えると 15 個だから
>me[15][15] とするのが自然かと。
>
>81 は実際のオセロの基盤が 9x9 の 81 マスからきたのでは?
>なので me[9][9] とも考えられます。

81以下の数では、上手く動作しませんでした。
私も15が自然かと思うのですが、使いたい配列の場所が、
me[65][79]〜me[97][111]なのです。



この投稿にコメントする

削除パスワード

No.4964

Re:五目並べのプログラムです…
投稿者---まきじ(2005/11/27 12:10:41)


>私も15が自然かと思うのですが、使いたい配列の場所が、
>me[65][79]〜me[97][111]なのです。

a から o や A から O を 0 から 14 に対応する様に
うまく式を書いてやればできます。


この投稿にコメントする

削除パスワード

No.4965

Re:五目並べのプログラムです…
投稿者---山田(2005/11/27 12:11:56)


PARTさんの書き込みをサーバーエラーで見れないので、
もう一度書き込んでもらえますか??
よろしくお願いします。。


この投稿にコメントする

削除パスワード

No.4963

Re:五目並べのプログラムです…
投稿者---RAPT(2005/11/27 12:10:36)


実際は81にしてあげると、問題なく動くのです。 (80だとできませんでした。)
単に「たまたま動作している」だけにすぎません。 VC++6で試しに、me[1][1]; と宣言してみたところ、 問題なく動いているように見えました。 ところが、実際にアクセス違反なので、どこかのメモリを破壊している はずです。それが今回はたまたま露見しなかっただけでしょう。 アスキーコードそのままを保存するなら、 me[80][112]; と宣言しないとまずいでしょう。 ただ、これだと無駄な領域が多過ぎなので、既に他の方がご指摘している ように、バッファを最小にして、添え字を工夫することが推奨されます。



この投稿にコメントする

削除パスワード

No.4966

Re:五目並べのプログラムです…
投稿者---山田(2005/11/27 12:16:07)


みなさんありがとうございました。
では、プログラムを改良して、
無駄な領域をなくしたいと思います。
重複してしまいますが、
みなさんありがとうございました。



この投稿にコメントする

削除パスワード

No.4967

Re:五目並べのプログラムです…
投稿者---RAPT(2005/11/27 12:16:35)


if(me[input[0]][input[1]]==1 || me[input[0]][input[1]]==2 || input[0]<65 || input[0]>79 || input[1]<97 || input[1]>111 || input[2]!=10) { printf("不正な入力です。\n"); goto label1; }
これですが、判定順を考慮しないとアクセス違反になります。 先に input[0], input[1] の範囲を限定してから、me[x][y] の値を 確認するように変更する必要があります。



この投稿にコメントする

削除パスワード

No.4973

Re:五目並べのプログラムです…
投稿者---山田(2005/11/27 17:11:55)


</blockquote>
これですが、判定順を考慮しないとアクセス違反になります。
先に input[0], input[1] の範囲を限定してから、me[x][y] の値を
確認するように変更する必要があります。
</pre>

なるほど。大変勉強になります。至らないことばかりなので、
またご指摘していただけると嬉しいです。
ありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity