
いろんなサイトを参考にしつつ、なんとなく頭の中にはできてきたので、サクサクいくかなぁと思ったらそんなことはなく、やたら手間取ってやっとできた。なんか色々あったけど全部は覚えてないのでさらっと書いとく。
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;
}
}
}
}
http://uguisu.skr.jp/othello/7gyou.html
こちらのサイトがすごく参考になった。ここまできれいには書けないけど、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がなんだか深くなってしまうな。解消したいけど、そこまで頭が回らない…。
置き石可能かの表示ができたので、こっから「そこには置けません」のトーストと、パス機能に広げられるんじゃないかなと思ってる。やっぱり頭の中で考えるのと、実際書くんじゃ大違いだなぁ。頑張っていっぱい考えたけど、思い通りに動かないこと山の如し、先が思いやられるぞ。でもやっぱ完成させたい気持ちのほうがあるかな。うまくいくといいなぁ。
参考
http://write-remember.com/program/java/format/