リバーシで8方向の処理をまとめる&置ける場所の表示

スポンサーリンク
スポンサーリンク


いろんなサイトを参考にしつつ、なんとなく頭の中にはできてきたので、サクサクいくかなぁと思ったらそんなことはなく、やたら手間取ってやっとできた。なんか色々あったけど全部は覚えてないのでさらっと書いとく。

スポンサーリンク

8方向の処理をまとめる

CheckFlip**()を分割する

石を置けるかどうかの処理とそれを元に引っ繰り返す処理が一緒になっているので、それを分けた。

checkCanFlip()

public void checkCanFlip(TextView tv){
    int di;
    int taptag = Integer.parseInt(tv.getTag().toString());
    TextView ttv;
    int StoneColor;

    for(int d = 0 ; d <= 7 ; d++){
        di = MoveQuantity[d];

        for(int c = 1 ; c <= 8 ; c ++) {
            ttv = parentView.findViewWithTag(String.format("%02d",taptag + (c * di)));

            if(ttv == null) {
                canFlip[d] = false;
                break;
            }

            if (!existStone(ttv)) {
                canFlip[d] = false;
                break;
            }

            StoneColor = getStoneColor(ttv);

            if (PlayerTurn == StoneColor && StoneCount[d] < 1) {
                canFlip[d] = false;
                break;
            }

            if (PlayerTurn != StoneColor) {
                StoneCount[d]++;
                continue ;
            }

            if (PlayerTurn == StoneColor) {
                canFlip[d] = true;
                break;
            }
        }
    }
}
オセロプログラム ~7行のC言語で書くコンピュータ対局~
SyntaxHighlighter.defaults = false; SyntaxHighlight

こちらのサイトがすごく参考になった。ここまできれいには書けないけど、8方向の移動量を配列で持っておくっていうのがすごい。かっこいい。

  • MoveQuantity[]→方向ごとの移動量
  • StoneCount[]→方向ごとのひっくり返せる石の数
  • canFlip[]→方向ごとにひっくり返せるならtrue

としてばーっと8方向チェックする。上記3つはメンバ変数なので次の引っ繰り返す処理でも使える。

上端に来た時、getTag()すると”01″のはずが”1″になったりとint型にした弊害が出たのでString.formatで0埋めした。使い方がよく分かんなかった、特に引数が。のでコピペ。でも怒られる。怒られる内容がよくわかってなかったり。

for文も1方向ずつのコードからほぼ流用できたけど、return, break, continueの使い方がこんがらがり、1回1回ステップインしながら置き換えて確かめていった。大変だった。。。

引っ繰り返す処理を作る

public void FlipStone(TextView tv){
    int di;
    int taptag = Integer.parseInt(tv.getTag().toString());
    TextView ttv;

    for(int d = 0 ; d <= 7 ; d++) {
        di = MoveQuantity[d];

        if(canFlip[d]){
            setStoneToCell(tv);

            for(int c = 1 ; c <= StoneCount[d] ; c++){
                ttv = parentView.findViewWithTag(String.format("%02d",taptag + (c * di)));
                setStoneToCell(ttv);
            }
        }
    }

    canFlip = new boolean[]{false, false, false, false, false, false, false, false};
    StoneCount = new int[]{0,0,0,0,0,0,0,0};
}

上で使った3つの変数を元に、石をひっくり返していく。実際for文で回したり、使ってる変数は同じなんだけど、ここを分けとかないと次の置き石の表示でcheckcanflipを使い回せないと思ったので。最初、処理の最後で配列を初期化してなくて、置くごとにえらい場所に置き石可能の表示が出てた。

スポンサーリンク

置ける場所の表示

この前作ったCellArrayを使ってマスを全部検査していく。思ったんだけど、別にCellArray作んなくても、findViewWithTagで回しても別に良かったんじゃ…。どっちのが楽なんだろ。ていうか最初にちゃんと方針を決めて自分に分かりやすいように作っていってないのが悪いんだろうな。やっぱりあれが必要、とか、これいらなかった、とかが多いので、自分でも把握ができなくなってしまいます。

scanBoard()

この名前の関数はTextView達を配列にぶっこむ関数だったけど、そっちはmakeCellArrayに名前変えて、こっちでこの名前を利用することにした。

public void scanBoard(){

    for(TextView[] cc : CellArray){
        for(TextView c : cc) {
            if(existStone(c)){

            }else{
                checkCanFlip(c);

                for (boolean b : canFlip) {
                    if (b) {
                        c.setText("*");
                        break;
                    } else {
                        c.setText("");
                    }
                }
                canFlip = new boolean[]{false, false, false, false, false, false, false, false};
                StoneCount = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
            }
        }
    }
}

ここに来るまでが長かった。これ作ってる間に、checkcanflipの不具合が見つかったりして、どっちがダメなのか分かんなくなった。置ける場所には「*」を表示することにした。

その前は

c.setBackgroundColor(Color.rgb(150, 255, 170));

こんな感じで色を付けようとしていたんだけど、色を付けると枠線が消えた。

こんな。

枠線はもう完全に理解しないでコピペしてきてるので、直し方も分からず。調べる気も起きず。なので「*」にした。それによって(“”)で判定していた部分、existStone()とか、に支障が出たので、「*」の場合も空白扱いにするようにコード変えた。これは3ヶ所ぐらいだったので助かった。

ここまで

書いた以外にも細かい所でいっぱい引っかかってるんだけど、書くのがめんどい。

あ、あとforとかifがなんだか深くなってしまうな。解消したいけど、そこまで頭が回らない…。

置き石可能かの表示ができたので、こっから「そこには置けません」のトーストと、パス機能に広げられるんじゃないかなと思ってる。やっぱり頭の中で考えるのと、実際書くんじゃ大違いだなぁ。頑張っていっぱい考えたけど、思い通りに動かないこと山の如し、先が思いやられるぞ。でもやっぱ完成させたい気持ちのほうがあるかな。うまくいくといいなぁ。

参考

Java:ゼロ埋め、半角スペース埋めする方法 | 覚え書き.com
Javaで数値のゼロ埋め、文字列の半角スペース埋めをする方法
配列 | Java入門
変数は1つの値を保存するのに使用されますが、配列は同じ用途で利用する複数の値を格納しておく時に使用されます。例えば10個の値を保存する場合、変数を使う場合は変数が10個必要ですが、配列では10個の要素を持つ1つの配列に値を保存します。また繰り返し処理を使って順に値を取り出すといったことができます。ここではJavaにおけ...
背景色の設定 - TextViewクラス - Androidプログラミング入門 | JavaDrive
背景色の設定

コメント

タイトルとURLをコピーしました