掲示板利用宣言

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

 私は

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

掲示板2

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

No.24791

オセロ
投稿者---NANA(2005/12/14 01:23:42)


私は今オセロを作っています。
それでどうもうまく反転のところができません。
実行するとおかしな文字がでるんです。
原因がわかるかたがいたらおしえてください。
ちなみに、下のソースはx = 4, y = 2, c = 1の時の反転の結果を見るため
に値が代入してあります。

#include<stdio.h>

/*----------------*
 Reversed function
*----------------*/
int reverse(int a[][8], int c, int x, int y, int dx, int dy)
{
    int i, temp;
    if(a[x][y] == c && i > 0){
        printf("1\n");
        return c;
    }
    else if(a[x][y] == 0 && i > 0){
        printf("2\n");
        return 0;
    }
    else if((0 < x && y >= 8) && i > 0){
        printf("3\n");
        return 0;
    }
    else if(a[x][y] == c && i < 0){
        printf("4\n");
        a[x][y] = -a[x][y];
        return c;
    }
    else if(a[x][y] != c && i < 0){
        printf("5\n");
        return 0;
    }
    else if(i > 0){
        printf("6\n");
        i = i * -1;
        reverse(a, c, x + dx, y + dy, dx, dy);
    }
}
/*----------------*
 Display of array 
*----------------*/
void displaymap(int a[][8])
{
    int i, j;
    for(i = 0; i < 8; i++){
        for(j = 0; j < 8; j++){
            if(a[i][j] == -1)
                a[i][j] = 'X';
            else if(a[i][j] == 1)
                a[i][j] = '0';
            else if(a[i][j] == 0)
                a[i][j] = '-';
        }
    }
    for(i = 0; i < 8; i++){
        for(j = 0; j < 8; j++){
            printf("%c",a[i][j]);
        }
        printf("\n");
    }
}

int main()
{
    int i, j;
    int x = 4, y = 2, c = 1, dx, dy;
    
    /* ------------------- ---*
     The array is initialized 
    *------------------------*/
    int a[8][8] = {{0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0},
                    {0,0,0,1,-1,0,0,0},
                    {0,0,0,-1,1,0,0,0},
                    {0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0}};
    displaymap(a);
    c = a[x][y];
    for(i = -1; i < 2; i++){
        for(j = -1; j < 2; j++){
            dx = i;
            dy = j;
            //printf("pattern = %d %d\n", dx, dy);
            reverse(a, c, x + dx, y + dy, dx, dy);
        }
    }
    printf("\n\n");
    displaymap(a);
    return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:オセロ 24792 wiz 2005/12/14 01:43:19
<子記事> Re:オセロ 24802 shu 2005/12/14 13:45:55
<子記事> Re:オセロ 24821 まきじ 2005/12/15 05:15:54


No.24792

Re:オセロ
投稿者---wiz(2005/12/14 01:43:19)


ぱっとみですが

int i, temp;
if(a[x][y] == c && i > 0){
以降でiを比較n使用していますがiは初期化されていないため、
中身が不定です。



この投稿にコメントする

削除パスワード

No.24793

オセロ
投稿者---NANA(2005/12/14 01:47:15)


>ぱっとみですが
>
>int i, temp;
>if(a[x][y] == c && i > 0){
>以降でiを比較n使用していますがiは初期化されていないため、
>中身が不定です。

再帰なんで、初期化しちゃうとif文がうまくいかないんです。
どうすればいいんでしょうか?


この投稿にコメントする

削除パスワード

No.24794

Re:オセロ
投稿者---まきじ(2005/12/14 01:50:29)


>再帰なんで、初期化しちゃうとif文がうまくいかないんです。
>どうすればいいんでしょうか?

static 指定すれば関数が最初に呼び出された時一度だけ初期化されます。


この投稿にコメントする

削除パスワード

No.24795

オセロ
投稿者---NANA(2005/12/14 01:54:51)


>>再帰なんで、初期化しちゃうとif文がうまくいかないんです。
>>どうすればいいんでしょうか?
>
>static 指定すれば関数が最初に呼び出された時一度だけ初期化されます。


実行してみましたが、まだうまくいかないみたいです。
他におかしいところがあるのでしょうか?


この投稿にコメントする

削除パスワード

No.24801

Re:オセロ
投稿者---円零(2005/12/14 13:01:40)


ソースコードを眺めても何をやりたいのか私にはイマイチわかりかねるのですが…

とりあえず初期化でも代入でもかまいませんから、
reverse()のローカル変数iに何か有効な値を与えないといけないんじゃないでしょうか。

文字が変わるのは、単に-1を掛けたものが表示されてるだけです。
0x2d * -1 = 0xd3、ですね。


この投稿にコメントする

削除パスワード

No.24802

Re:オセロ
投稿者---shu(2005/12/14 13:45:55)


main()の

c = a[x][y];

の部分は、

a[x][y] = c;

じゃあなかろうか?

reverse()も大事でしょうが、その前に正しく駒を置くための関数を作ってみることをすすめます。
直接的ではないですが、reverse()を作るにあたっての参考にもなると思うので……



この投稿にコメントする

削除パスワード

No.24805

オセロ
投稿者---NANA(2005/12/14 18:39:03)


どうすればいいんでしょ。


この投稿にコメントする

削除パスワード

No.24806

Re:オセロ
投稿者---気分屋(2005/12/14 19:00:08)


コーティン的なアドバイスとして

★1:初期化時に配列に0,1,-1のデータを入れているのに、displaymap関数で値を変える必要はないのでは?
    int i, j;
    for(i = 0; i < 8; i++){
        for(j = 0; j < 8; j++){
            if(a[i][j] == -1)
                printf( "X" );
            else if(a[i][j] == 1)
                printf( "0" );
            else
                printf( "-" );
        }
    }
と値で表示を指定するほうが良いでしょう。

★2:二次元配列の持ち方を8×8から10×10に変更し、周りに壁の値を入れておく。
私なら
-1:壁
 0:なにもない
 1:黒
 2:白
と値を決め

    int a[10][10] = 
    {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
        -1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
        -1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
        -1,  0,  0,  0,  1,  2,  0,  0,  0, -1,
        -1,  0,  0,  0,  2,  1,  0,  0,  0, -1,
        -1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
        -1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
        -1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    };

上記のように初期化しますね。

壁の値があらかじめ決まっていれば、再帰の
プログラムが組みやすくなるでしょう。




この投稿にコメントする

削除パスワード

No.24810

文字列比較
投稿者---NANA(2005/12/14 22:10:07)


なるほど。参考になりました。
でも今回はこれでつくらなきゃいけないんです。
買った本の問題なんですが、解答がないというすばらしさ(-ω-)/
で、とりあえず
ox
xo

のとき
x = 4 y = 2 c = 1 を代入して

o
oo
xo

としたいんですね。
でもうまくいかないんです。


この投稿にコメントする

削除パスワード

No.24821

Re:オセロ
投稿者---まきじ(2005/12/15 05:15:54)


完璧ではないですが、せっかく作ったので載せときます。(自己満足です。)

/*
compiler : gcc 3.4.2 (mingw-special)
option : -std=iso9899:1999 -pedantic -O2 -Wall
*/

#define Y 8
#define X 8

#include <stdio.h>

/* -1: 空 0:黒(先攻) 1:白 */

int brd[Y][X] ={{-1,-1,-1,-1,-1,-1,-1,-1},
                {-1,-1,-1,-1,-1,-1,-1,-1},
                {-1,-1,-1,-1,-1,-1,-1,-1},
                {-1,-1,-1, 1, 0,-1,-1,-1},
                {-1,-1,-1, 0, 1,-1,-1,-1},
                {-1,-1,-1,-1,-1,-1,-1,-1},
                {-1,-1,-1,-1,-1,-1,-1,-1},
                {-1,-1,-1,-1,-1,-1,-1,-1}
                };

int reverse(int y, int x, int k, int c){
    
    int ret = k;
    
    if(y < 0 || y >= Y || x < 0 || x >= X || brd[y][x] == -1) return -1;
    
    if(brd[y][x] != k){
        /*
            1: 左下 2: 下 3: 右下 4: 左 6: 右 7: 左上 8: 上 9: 右上
        */
        if(c == 1){
            if((ret = reverse(y + 1, x - 1, k, c)) == k) brd[y][x] = ret;
        }else if(c == 2){
            if((ret = reverse(y + 1, x, k, c)) == k) brd[y][x] = ret;
        }else if(c == 3){
            if((ret = reverse(y + 1, x + 1, k, c)) == k) brd[y][x] = ret;
        }else if(c == 4){
            if((ret = reverse(y, x - 1, k, c)) == k) brd[y][x] = ret;
        }else if(c == 6){
            if((ret = reverse(y, x + 1, k, c)) == k) brd[y][x] = ret;
        }else if(c == 7){
            if((ret  = reverse(y - 1, x - 1, k, c)) == k) brd[y][x] = ret;
        }else if(c == 8){
            if((ret = reverse(y - 1, x, k, c)) == k) brd[y][x] = ret;
        }else if(c == 9){
            if((ret = reverse(y - 1, x + 1, k, c)) == k) brd[y][x] = ret;
        }
    }
    
    return ret;
}

int checkbrd(void){

    for(int y = 0; y < Y; y++){
        for(int x = 0; x < X; x++){
            if(brd[y][x] == -1) return 1;
        }
    }
    
    return 0;
}

void printbrd(void){

    printf("%3c %2d %2d %2d %2d %2d %2d %2d %2d\n",' ',1,2,3,4,5,6,7,8);
    for(int y = 0; y < Y; y++){
        printf("%3d ",y+1);
        for(int x = 0; x < X; x++){
            if(brd[y][x] != -1) printf("%3s",brd[y][x] ? "○" : "●");
            else printf("%3s","×");
        }
        putchar('\n');
    }
}

int main(void){

    int x, y, k = 0;
    int flg;
    do{
        flg = 0;
        printbrd();
        printf("(%3s)縦(y) 横(x)(1-8):", k ? "○" : "●");
        scanf("%d%d%*c",&y,&x);
        y--;
        x--;
        if(brd[y][x] == -1){
            
            if(brd[y - 1][x - 1] != k && reverse(y - 1, x - 1, k, 7) == k) flg = 1;
            if(brd[y - 1][x] != k && reverse(y - 1, x, k, 8) == k) flg = 1;
            if(brd[y - 1][x + 1] != k && reverse(y - 1, x + 1, k, 9) == k) flg = 1;
            if(brd[y][x - 1] != k && reverse(y, x - 1, k, 4) == k) flg = 1;
            if(brd[y][x + 1] != k && reverse(y, x + 1, k, 6) == k) flg = 1;
            if(brd[y + 1][x - 1] != k && reverse(y + 1, x - 1, k, 1) == k) flg = 1;
            if(brd[y + 1][x] != k && reverse(y + 1, x, k, 2) == k) flg = 1;
            if(brd[y + 1][x + 1] != k && reverse(y + 1, x + 1, k, 3) == k) flg = 1;
            
            if(flg) brd[y][x] = k;
            else continue;
            
        }else continue;
        k = !k;
    }while(checkbrd());
}



この投稿にコメントする

削除パスワード

No.24854

オセロ
投稿者---NANA(2005/12/18 00:47:57)


まきじ様参考にさせていただきました。
なんとかこないだの悩んでいたところは解決できたのですが、
XO
OX
を
 O
OO
XO

にできるようになりました。



つぎはこの問題で躓きました。
なんどもすみません。
前回言っている意味がわからないとの事でしたので私の問いている問題を挙げておきます。

==============================================================
前問いでつくったreverse()において、配列a[][]の要素を反転した回数gを求めることができるようにこの関数を書き換えると同時に、リバースゲームのルールを以下のようにしたとき、このリバースゲームを完成させよ。このとき、関数reverse()の戻り値の定義を変更してはならない。プログラムでは、駒の置く位置は標準入力によるものとし、先手('0')と後手('X')の駒数を表示できるものとする。この駒数は反転した回数gを利用して求めること。また、ルールにより配置できない場所を指定した場合は"NO!"の出力し、再入力が可能となるようにすること。

ルール
先手と後手は交互に駒を配置する(完了)

既に駒が配置されているところには配置できない(完了)

不正な入力があった場合はもう一度入力を求める

ある駒を配置したとき、その駒とほかの自分の駒にはさまれる、たて、よこななめの戦場に配置される駒を自分の駒と置き換える(わかんない)

相手の駒を置き換えることができない場所へは配置できない(わかんない)

駒が置けなくなったら終了。勝者をはんていして結果を出力
====================================================================

現在のソース

#include<stdio.h>
#define white -1
#define black 1
int reverse(int a[][8], int c, int x, int y, int dx, int dy)
{
  static int I = 1;
  if(I > 0 && ( x < 0 && 8 <= y))
    return 0;
  else if(a[x][y] == 0 && I > 0)
    return 0;
  else if(a[x][y] == c && I > 0)
    return c;
  else if(I > 0){
    I = -1;
    reverse(a, c, x + dx, y + dy, dx, dy);
  }
  else if(a[x][y] == c && I < 0){
    a[x-dx][y-dy] = -a[x-dx][y-dy];
    I = 1;
    return c;
  }
  else if(I < 0){
    I = 1;
    return 0;
  }
}



void displaymap(int a[][8])
{
  int i, j;
  for(i = 0; i < 8; i++){
    for(j = 0; j < 8; j++){
      if(a[j][i] == -1)
    printf("X");
      if(a[j][i] == 0)
     printf("-");
      if(a[j][i] == 1)
    printf("0");
    }
    printf("\n");
  }
}
      

int main()
{
  int turn;
  int x = 4, y = 2, c = white, i, j, dx, dy;
  int a[8][8] = {{0,0,0,0,0,0,0,0},
         {0,0,0,0,0,0,0,0},
         {0,0,0,0,0,0,0,0},
         {0,0,0,1,-1,0,0,0},
         {0,0,0,-1,1,0,0,0},
         {0,0,0,0,0,0,0,0},
         {0,0,0,0,0,0,0,0},
         {0,0,0,0,0,0,0,0}};
  
  displaymap(a);
  for(turn = 0; turn < 65; turn++){
    if(c == white)
      printf("0 x y>");
    if(c == black)
      printf("X x y>");
    c = -c;
    scanf("%d%d", &x, &y);
    if(a[x][y] == -1 || a[x][y] == 1){
      printf("Cant' put it here\n");
      turn--;
    }
    else{
      a[x][y] = c;
      for(j = -1; j < 2; j++){
    for(i = -1; i < 2; i++){
      dx = i;
      dy = j;
      //printf("test: %d%d\n", i, j);
      reverse(a, c, x + dx, y + dy, dx, dy);
    }
      }
    }
    printf("\n");
    displaymap(a);
  }
  return 0;
}





この投稿にコメントする

削除パスワード

No.24857

Re:オセロ
投稿者---まきじ(2005/12/18 02:33:17)


>ある駒を配置したとき、その駒とほかの自分の駒にはさまれる、たて、よこななめの戦場に配置される駒を自分の駒と置き換える(わかんない)

自分の駒にブチ当たるまで、その列や行を見ていき
自分の駒にブチ当たれば、自分の駒に置き換える。
一揆にやろうとせずに、一方向をやってみれば如何ですか?

例えば、int array[]={0,0,0,0,0,1,0,0,0,0} の様な配列用意して
array[2] に 1 を代入すれば array[3] array[4] が 1 になる様な
プログラムを作ってみるとか。

ができれば

int array[]={0,1,0,0,0,0,0,0,1,0} の様にして
array[5] に 1 を代入すれば
array[2] から array[4] と array[6] から array[7] が 1 に
なる様にしてみる。

array に 1 が無かったらどうなるか?とか考えてみてください。


この投稿にコメントする

削除パスワード

No.24858

文字列比較
投稿者---NANA(2005/12/18 02:48:04)


なるほど。
今友達に言われたんですが、みなさん私迷惑ですか?

友達がそんなの一個ずつ教えてもらってたら迷惑だぞ。だれかに答えを掲示してもらってそれをみて自分で考えてわからなかったら質問するみたい中たちにしろよ(-ω-)/っていわれたんですが


この投稿にコメントする

削除パスワード

No.24859

オセロ
投稿者---NANA(2005/12/18 02:55:31)


あとなぜか勝手に題名が文字列比較になるのはなぜ?
コメントでやってるのにー?


この投稿にコメントする

削除パスワード

No.24861

Re:オセロ
投稿者---RAPT(2005/12/18 03:33:43)


>あとなぜか勝手に題名が文字列比較になるのはなぜ?
>コメントでやってるのにー?
変なブラウザか変なツールでも使っているんじゃない?

普通に「この投稿にコメントする」のリンクをクリックすると、
題名は「Re:オセロ」となるはずなのですが、NANAさんの投稿している
レスには、「Re:」がないので。



この投稿にコメントする

削除パスワード

No.24862

Re:文字列比較
投稿者---RAPT(2005/12/18 03:39:18)


> 友達がそんなの一個ずつ教えてもらってたら迷惑だぞ。
> だれかに答えを掲示してもらってそれをみて自分で考えてわからなかったら
> 質問するみたい中たちにしろよ(-ω-)/っていわれたんですが
それはそれで問題が。

「答え教えて」だと「課題の丸投げ」とみなされ、ここの掲示板利用規約に
違反しますし、大抵の場所では、課題の丸投げは嫌われます。

NANAさんの場合、まとめて一気に全部やろうとするから、ややこしくなって
いるので、やりたい処理をかみ砕いて、段階を踏んでコードを組み上げて
いけば良いとおもいます。



この投稿にコメントする

削除パスワード

No.24865

Re:文字列比較
投稿者---まきじ(2005/12/18 15:02:43)


>だれかに答えを掲示してもらってそれをみて自分で考えてわからなかったら質問するみたい中たちにしろよ

私のプログラムは勝敗判定以外はできてるはずなので
友達に言われた様に参考にして考えてください。

「参考にする」には、まずプログラム理解しないと参考にならないと思いますよ。


この投稿にコメントする

削除パスワード

No.24864

Re:オセロ
投稿者---shu(2005/12/18 12:07:34)


>なんとかこないだの悩んでいたところは解決できたのですが、

本当に解決できていますか?
まきじさん作のプログラムが動いたので解決にしていないでしょうか?

>まきじ様参考にさせていただきました。

で終わっているような感じですが、まだまだまだまだ参考にできるところがある。

>つぎはこの問題で躓きました。

前の段階がしっかりしてないから躓く。


……質問を繰り返すと流れが解かり難くなるので、質問する度に頭から通して読みかえして欲しい。


この投稿にコメントする

削除パスワード

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