//KKKKKKKKKKKKKKKKKKKK public void InitBoad() //盤面の初期化:ゲーム開始時にする //盤面の初期化 // SGameLog = ""; { nPutHist = 0; //配置履歴の数(何手目か) Stone = new int[8, 8]; //配置石情報 StoneEdge = new bool[8, 8]; //境界情報(境界以外のマスだけ配置可能(挟んでひっくり返せる)か確かめれば良い for (int i1 = 0; i1 < putHist.Length; i1++) { putHist[i1] = new PutOperationCls(); } for (int i1 = 0; i1 < putList.Length; i1++) { putList[i1] = new PutOperationCls(); } ActiveFirstPlayer = true;//リバーシは黒先攻 Stone[3, 3] = White; Stone[4, 3] = Black; Stone[3, 4] = Black; Stone[4, 4] = White; EdgeCheck(3, 3, ref putHist[0]); EdgeCheck(4, 3, ref putHist[0]); EdgeCheck(3, 4, ref putHist[0]); EdgeCheck(4, 4, ref putHist[0]); putHist[0] = new PutOperationCls(); PutCheck();//この初期盤面に対して配置可能な箇所を調べる SPutLog = ""; }
//KKKKKKKKKKKKKKKKKKKK void EdgeCheckInverse(ref PutOperationCls aug) //一手戻したときの境界判定を一手ぶん戻す { int px, py; StoneEdge[aug.x, aug.y] = true;//一手戻したのだから、その座標は境界である for (int id = 0; id < 8; id++) { if (aug.edgeAdd[id])//着手時の追加境界情報を元に、境界情報を復元する { px = aug.x + DirX[id]; py = aug.y + DirY[id]; StoneEdge[px, py] = false;//その一手で境界になったのだから、境界ではなくなる } } }
//KKKKKKKKKKKKKKKKKKKK public void PutInverse(ref PutOperationCls aug) //AI内部盤面を一手分戻す { int p = aug.x + 8 * aug.y; nPutHist = aug.nPutHist - 1; Input[p] = 0; for (int id = 0; id < 8; id++) { for (int i1 = 1; i1 <= aug.reverseDirection[id]; i1++) { p = aug.x + i1 * DirX[id] + 8 * (aug.y + i1 * DirY[id]); Input[p] = -aug.Color; } } Input[64] = 0;//aug. nPutList; }
//KKKKKKKKKKKKKKKKKKKK //KKKKKKKKKKKKKKKKKKKK public void Put(ref PutOperationCls aug) //AIの内部盤面に着手する { int p = aug.x + 8 * aug.y; nPutHist = aug.nPutHist; Input[p] = aug.Color; for (int id = 0; id < 8; id++) { for (int i1 = 1; i1 <= aug.reverseDirection[id]; i1++) { p = aug.x + i1 * DirX[id] + 8 * (aug.y + i1 * DirY[id]); Input[p] = aug.Color; } } // Input[64] = 0;//aug. nPutList; }
//KKKKKKKKKKKKKKKKKKKK string AutoPutString(ref PutOperationCls aug) //配置履歴を出力する(SPutLogに) { string s; int tmp; if (aug.Color == 1) { s = "B"; } else { s = "W"; } tmp = aug.x + 1; s += tmp.ToString(); tmp = aug.y + 1; s += tmp.ToString() + ","; return(s); }
//KKKKKKKKKKKKKKKKKKKK bool PutCheckSub(ref PutOperationCls aug, ref int x, ref int y, int PutColor) //分割 //(x,y)地点が配置可能場所かどうか調べ、boolを返す //augに反点数を書き込んでおく { int px, py; //ポインタ bool f1 = false; for (int id = 0; id < 8; id++) //各方向に対して { aug.reverseDirection[id] = 0; //初期化 for (int ir = 1; ir < 10; ir++) //無限ループ回避 { px = x + ir * DirX[id]; py = y + ir * DirY[id]; if (!Inside(ref px, ref py)) //ポインタが盤面内かどうか { aug.reverseDirection[id] = 0; //ポインタが盤面外:挟めなかったとき break; } else { if (Stone[px, py] == -PutColor) //相手の石のとき { aug.reverseDirection[id]++; //カウンタ+1 } else if (Stone[px, py] == PutColor) //自分の石のとき { if (aug.reverseDirection[id] > 0) { f1 = true; //フラグセットし } break; //次の方向へ } else //空白のとき:挟めなかった時 { aug.reverseDirection[id] = 0; //一つも返せません break; //次の方向へ } } } } return(f1); //配置可能かどうか }
//KKKKKKKKKKKKKKKKKKKK void EdgeCheck(int x, int y, ref PutOperationCls aug) //新規エッジの確認 //配置候補を更新する { int px, py; aug.edgeAdd = new bool[8]; //初期化 ここに追加したエッジだけ格納 StoneEdge[x, y] = false; //この関数が走るのは、(x,y)に配置したとき for (int id = 0; id < 8; id++) { px = x + DirX[id]; py = y + DirY[id]; if (Inside(ref px, ref py)) { if (Stone[px, py] == 0 && StoneEdge[px, py] == false) //空白であり、まだエッジと登録されていない場合 { StoneEdge[px, py] = true; //エッジに登録 aug.edgeAdd[id] = true; //新規登録したことを登録 } } } }
//KKKKKKKKKKKKKKKKKKKK public void Put(ref PutOperationCls aug) //配置履歴クラスを引数に着手する //自動で、配置履歴を残す //変更される盤面は Stone[,], StoneEdge[,] { int px, py; Checked = false; //配置可能場所が変更になったことを表す aug.nPutHist = nPutHist; //何手目 putHist[nPutHist] = aug; //履歴を残す Stone[aug.x, aug.y] = aug.Color; //置いた場所 EdgeCheck(aug.x, aug.y, ref putHist[nPutHist]); //配置候補更新 for (int id = 0; id < 8; id++) { //各方向(id)に対して、石を反転させる for (int ir = 1; ir <= aug.reverseDirection[id]; ir++)//返せる枚数が繰り返しの上限となる { px = aug.x + ir * DirX[id]; py = aug.y + ir * DirY[id]; Stone[px, py] = aug.Color; } } nPutHist++; //履歴の数をインクリメント ChangeActivePlayer(); //自動交代 }