/* 探索(並列) */ private void queueSearchForParallel() { int searchSize = searchQueId.Count; int[] queIdArray = searchQueId.ToArray(); int[] searchField = new int[9] { MY_FIELD, NEIGHT1, NEIGHT2, NEIGHT3, NEIGHT4, NEIGHT5, NEIGHT6, NEIGHT7, NEIGHT8 }; int answerSize = 9999999; Object thisLock = new Object(); Parallel.For(0, searchSize, i => { /// Console.WriteLine(searchQueId.Count); int targetId = queIdArray[i]; /* キューからID取得 */ // string key; // key = dic.FirstOrDefault(x => x.Value.Equals(targetId)).Key; /* dicのValue(ID)よりFields(Key)を取得 */ // if (key != null) //{ // string strFields = key.ToString(); /* キーをStirngへ変換 */ if (storeDataDic.ContainsKey(targetId) == true) { StoreData tgtSD = storeDataDic[targetId]; AGI_CalcFields tgtAgiCF = new AGI_CalcFields(tgtSD.GetAgiCalcFields(), commonMap); /* stringからAGI_CalcFieldsを復元 */ for (int idKind = tgtSD.lastAttackStone + 1; idKind <= tgtSD.lastAttackStone + SEARCH_KIND_MAX; idKind++) /* SEARCH_KIND_MAX先分走査 */ { /* 石の決定 */ if (idKind < agi.GetAgiStoneList().GetListSize()) /* 石最大オーバー */ { bool setFlg = false; for (int kind = 0; kind < (int)Kinds.REV_R270; kind++) { if (agi.GetAgiStoneList().GetAgiStoneKindsList(idKind).GetAGIStones(kind) == null) /* 重複により削除された石 */ { continue; } int maxX = agi.GetAgiStoneList().GetAgiStoneKindsList(idKind).GetAGIStones(kind).GetXSize() - 2; int maxY = agi.GetAgiStoneList().GetAgiStoneKindsList(idKind).GetAGIStones(kind).GetYSize() - 2; int targetSize = Math.Max(maxX, maxY); if (targetSize >= 8) { targetSize = 8; } else if (targetSize <= 0) { targetSize = 0; } for (int idx = 0; idx < tgtAgiCF.GetAgiCalcFieldsSize(); idx++) /* 接地セル走査 */ { if ((tgtAgiCF.GetAgiCalcFieldNum(idx) == MY_FIELD) || /* 自フィールドまたは */ ((tgtAgiCF.GetAgiCalcFieldNum(idx) < 0) && (tgtAgiCF.GetAgiCalcFieldNum(idx) >= searchField[targetSize])) || /* 近傍以内または */ (((tgtAgiCF.GetAgiCalcFieldNum(idx) == WALL) || (tgtAgiCF.GetAgiCalcFieldNum(idx) == OBJECT)) && /* 壁または障害物であり、かつ */ ( ((tgtAgiCF.GetAgiCalcFieldNum(idx + 1) >= searchField[targetSize]) && (tgtAgiCF.GetAgiCalcFieldNum(idx + 1) < 0)) || /* 右隣りが近傍値 */ ((tgtAgiCF.GetAgiCalcFieldNum(idx + F_MAX_X) >= searchField[targetSize]) && (tgtAgiCF.GetAgiCalcFieldNum(idx + F_MAX_X) < 0)) ||/* 下隣が近傍値 */ ((tgtAgiCF.GetAgiCalcFieldNum(idx + (F_MAX_X + 1)) >= searchField[targetSize]) && (tgtAgiCF.GetAgiCalcFieldNum(idx + (F_MAX_X + 1)) < 0)) /* 右下が近傍値 */ ) ) ) { AGI_CalcFields resultF = placement(tgtAgiCF, idKind, kind, idx, true); /* 配置確認 */ if (resultF == null) /* 配置失敗 */ { continue; } else { int retId = storeFieldsForParallel(resultF, tgtSD.ID, idKind, kind, idx, tgtAgiCF, EVAL_C); if (retId == -1) /* 書き込み失敗 */ { continue; } else { setFlg = true; if (resultF.GetAgiCalcEmptySize() != 0) { nextQueId.Enqueue(retId); } else { lock (thisLock) { StoreData tmp; if (saveStoreDataDic.ContainsKey(retId) == true) { tmp = new StoreData(saveStoreDataDic[retId], commonMap); if (answerId.ContainsKey(retId) == true) { answerId[retId] = tmp; } else { answerId.Add(retId, tmp); } } else { nextQueId.Enqueue(retId); } } } } } } } } if (setFlg == false) { int retId = storeFieldsForParallelLast(tgtSD, idKind); nextQueId.Enqueue(retId); } } else { lock (thisLock) { if (answerSize < tgtSD.score) { if (answerId.ContainsKey(targetId) == false) { answerId.Add(targetId, tgtSD); } answerSize = tgtSD.score; } } } } } else { ; } }); foreach (var key in saveStoreDataDic.Keys) { if (storeDataDic.ContainsKey(key) == true) { if (saveStoreDataDic.ContainsKey(key) == true) { storeDataDic[key] = saveStoreDataDic[key]; } } else { if (saveStoreDataDic.ContainsKey(key) == true) { storeDataDic.Add(key, saveStoreDataDic[key]); } } } saveStoreDataDic.Clear(); searchQueId = new ConcurrentQueue<int>(); }
private string exchangeFieldsToString(AGI_CalcFields agicF) { string strRet = ""; for (int i = 0; i < agicF.GetAgiCalcFieldsSize(); i++) { strRet += agicF.GetAgiCalcFieldNum(i).ToString(); } return strRet; }
/* 石の配置 NG:null */ private AGI_CalcFields placement(AGI_CalcFields agicOrgF, int stoneId, int kinds, int placeIdx, bool connectCheck) { AGI_CalcFields retAgicF = new AGI_CalcFields(agicOrgF, commonMap); AGI_Stones setStone = new AGI_Stones(agi.GetAgiStoneList().GetAgiStoneKindsList(stoneId).GetAGIStones(kinds)); /* 石の加算処理 */ for (int i = 0; i < setStone.GetSize(); i++) { int idx = agiST2agiF(retAgicF.GetMaxX(), retAgicF.GetMaxY(), setStone.GetXSize(), setStone.GetYSize(), placeIdx, i); retAgicF.SetAgiCalcNum (idx, retAgicF.GetAgiCalcFieldNum(idx) + setStone.GetNum(i)); } /* 判定 */ bool connectFlg = false; /* 自陣と接続するか判定 */ for (int i = 0; i < retAgicF.GetAgiCalcFieldsSize(); i++) { int tmp = retAgicF.GetAgiCalcFieldNum(i); if ((tmp > 0) && ((tmp % 2) == 0)) { /* 正の偶数値があった場合、自・壁・障のいずれかと重なる */ return null; } if ((connectFlg == false) && (tmp == -6)) /* 近傍(-7) + 自陣(1) */ { connectFlg = true; } } if ((connectCheck == true) && (connectFlg != true)) { return null; } /* 加算前(石設置済み)に戻す */ retAgicF.GetReturnCalcFld(); return retAgicF; }
private void step1() { /* 初手処理 */ /* 石1~石(INIT_SEARCH_IDX)まで全探索 */ AGI_CalcFields calcF = new AGI_CalcFields(agi.GetAgiFields(), commonMap); storeRootFields(calcF); /* 親の登録 */ for (int id = 0; id < INIT_SEARCH_IDX; id++) { if(id > agi.GetAgiStoneList().GetListSize()) /* 石全体の数よりオーバーした場合 */ { break; } for (int idx = 0; idx < calcF.GetAgiCalcFieldsSize(); idx++) /* すべてのセルで確認 */ { for (int kind = 0; kind < (int)Kinds.REV_R270; kind++) /* すべての回転・反転で確認 */ { if (agi.GetAgiStoneList().GetAgiStoneKindsList(id).GetAGIStones(kind) == null) /* 重複により削除された石 */ { continue; } AGI_CalcFields resultF = placement(calcF, id, kind, idx, false); /* 配置確認 */ if (resultF == null) /* 配置失敗 */ { continue; } else { /* ROOT_ID = 0 */ if (storeFields(resultF, 0, id, kind, idx, calcF, EVAL_A) == -1) /* 書き込み失敗 */ { continue; } } } } } }