public Te fromjoseki(Kyokumenn k, int tesu) { //tesuには実際の手数が渡されるが、定跡データは0手目から始まるので1ずらしておく tesu = tesu - 1; //定跡にあった候補手を入れる List <Te> teList = new List <Te>(); //定跡で進めた局面を作り、渡された局面と比較する Kyokumenn josekiKyokumenn = new Kyokumenn(); for (int i = 0; i < numJoseki; i++) { //平手で初期化 josekiKyokumenn.BanShokika(); for (int j = 0; j < tesu; j++) { if (josekiData [i][j * 2] == (byte)0 || josekiData [i][j * 2] == (byte)0xff) { break; } Te te = josekiByteToTe(josekiData [i][j * 2], josekiData [i][j * 2 + 1], josekiKyokumenn); josekiKyokumenn.Move(te); josekiKyokumenn.turn += 1; } //局面が一致するか if (josekiKyokumenn.equals(k)) { if (josekiData [i][tesu * 2] == (byte)0 || josekiData [i][tesu * 2] == (byte)0xff) { continue; } //候補手を生成 Te te = josekiByteToTe(josekiData[i][tesu * 2], josekiData[i][tesu * 2 + 1], k); teList.Add(te); } } if (teList.Count == 0) { //候補手がない場合 /* * if(child != null){ * //子定跡がある時は、その結果を返す * return child.fromjoseki(k,tesu); * } */ //候補手がなかったのでnullを返す return(null); } else { //候補手の中からランダム //候補手がない場合 return(teList[UnityEngine.Random.Range(0, teList.Count)]); } }
// float countTime; /* * public void Update () { * countTime += Time.deltaTime; * Debug.Log ("(●・▽・●)"); * } */ private int NegaMax(ref Te t, Kyokumenn k, int alpha, int beta, int depth, int depthMax) { int value = new int(); //深さが最大に達していたら評価値を返して終了 if (depth >= depthMax) { leaf++; value = k.evaluate(); //先手ならプラス、後手でマイナスの値を返す if (k.turn % 2 == 1) { return(value); } else { return(-value); } } node++; //現在の局面での合法手を生成 var teList = new List <Te>(); teList = k.GenerateLegalMoves(); value = -100000000; for (int i = 0; i < teList.Count; i++) { Te te = teList [i]; //その手で一手進めた局面を作る // KyokumennArray nextKyokumenn = k.DeepCopyKyokumenn (); k.Move(te.DeepCopy()); k.turn += 1; Te tempTe = new Te(); int eval = -NegaMax(ref tempTe, k, -beta, -alpha, depth + 1, depthMax); k.Back(te.DeepCopy()); k.turn -= 1; //大きかったら if (eval > value) { value = eval; //αの値も更新 if (eval > alpha) { alpha = eval; } //最善手を更新 best [depth, depth] = te; t.koma = te.koma; t.from = te.from; t.to = te.to; t.promote = te.promote; t.capture = k.banKoma [te.to]; for (int j = depth + 1; j < depthMax; j++) { best [depth, j] = best [depth + 1, j]; } //βカットの条件を満たしていたらループ終了 if (eval >= beta) { break; } } } return(value); }