public cellvalueclass merge(cellvalueclass c2) { cellvalueclass cv = new cellvalueclass(); cv.useless = this.useless && c2.useless; foreach (string s in f.Keys) { cv.f[s] = this.f[s] + c2.f[s]; } return(cv); }
public int[] computermove(playerclass p, bool dodisplay, int depth, DateTime starttime) { //move[0] = x //move[1] = y //move[2] = threatlevel Random rnd = new Random(); if (boardcount() < 3) { return(randommove(p, 3)); } else if (boardcount() < 5) { return(randommove(p, 3)); } int[] move = randommove(p); //bool forced = false; if (depth > parent.maxdepth) { parent.memo("maxdepth"); return(move); } if (DateTime.Now - starttime > parent.timepermove) { parent.memo("timeout"); return(move); } for (int i = 0; i < board.size; i++) { for (int j = 0; j < board.size; j++) { if (b[i, j] == 0) { if (win(i, j, p.val)) { move[0] = i; move[1] = j; return(move); } } } } for (int i = 0; i < board.size; i++) { for (int j = 0; j < board.size; j++) { if (b[i, j] == 0) { if (win(i, j, -p.val)) { move[0] = i; move[1] = j; return(move); } } } } SortedDictionary <double, int[]> cvorder = new SortedDictionary <double, int[]>(); int maxprio = -1; int maxoff = -1; int maxdef = -1; double maxcv = -1; for (int i = 0; i < board.size; i++) { for (int j = 0; j < board.size; j++) { if (b[i, j] == 0) { cvx[i, j] = new cellvalueclass(); foreach (Tuple <int, int> uv in uvlist) { cvx[i, j] = cvx[i, j].merge(evaluateline(i, j, uv, p.val)); } cvx[i, j].f["density"] = (int)Math.Abs(getdensity(i, j, 2) - p.par.pp["optimaldensity"]); cvo[i, j] = new cellvalueclass(); foreach (Tuple <int, int> uv in uvlist) { cvo[i, j] = cvo[i, j].merge(evaluateline(i, j, uv, -p.val)); } cv[i, j] = cvx[i, j].totalvalue(p.par) + p.par.pp["oxratio"] * cvo[i, j].totalvalue(p.par) + p.par.pp["noise"] * rnd.NextDouble(); prio[i, j] = 2 * cvx[i, j].priority() + cvo[i, j].priority(); double ccvv = cv[i, j]; if (ccvv > 0.3) { while (cvorder.ContainsKey(ccvv)) { ccvv += 0.001; } int[] cvmv = new int[5] { i, j, 0, 0, 0 }; cvorder.Add(-ccvv, cvmv); } if (prio[i, j] > maxprio) { maxprio = prio[i, j]; maxcv = cv[i, j]; move[0] = i; move[1] = j; } else if (prio[i, j] == maxprio) { if (cv[i, j] > maxcv) { maxcv = cv[i, j]; move[0] = i; move[1] = j; } } if (cvx[i, j].priority() > maxoff) { maxoff = cvx[i, j].priority(); } if (cvo[i, j].priority() > maxdef) { maxdef = cvx[i, j].priority(); } } } } move[2] = maxprio; move[3] = maxoff; move[4] = maxdef; bool reachedlimit = false; bool win4found = false; bool win3found = false; if (move[2] < 1200) //search for VCF { playerclass other = p.otherplayer(); //for (int i = 0; i < board.size; i++) foreach (double ccvv in cvorder.Keys) { int i = cvorder[ccvv][0]; int j = cvorder[ccvv][1]; if (reachedlimit || win4found) { break; } //for (int j = 0; j < board.size; j++) { if (b[i, j] == 0) { if (cvx[i, j].f["fours"] > 0) { if (dodisplay) { parent.memo("Testing " + i + "," + j); } board testboard = this.copy(); testboard.smallsize(); testboard.b[i, j] = p.val; testboard.set(testboard.computermove(other, dodisplay, depth + 1, starttime), -p.val); if (dodisplay) { testboard.DisplayBoard(); } int[] nextmove = testboard.computermove(p, dodisplay, depth + 1, starttime); if (dodisplay) { parent.memo("nextmove[2] = " + nextmove[2]); } if (nextmove[3] >= 600) { move[0] = i; move[1] = j; move[2] = nextmove[2]; parent.memo("==== 4-win found! ===="); win4found = true; break; } else if (nextmove[2] < 0) { reachedlimit = true; break; } } } } } if (dodisplay) { this.DisplayBoard(); } } if (depth > parent.maxdepth) { parent.memo("maxdepth"); return(move); } if (DateTime.Now - starttime > parent.timepermove) { parent.memo("timeout"); return(move); } if (win4found) { parent.memo("win4found"); return(move); } if (move[2] < 10) //search for VCT { playerclass other = p.otherplayer(); //for (int i = 0; i < board.size; i++) //{ foreach (double ccvv in cvorder.Keys) { int i = cvorder[ccvv][0]; int j = cvorder[ccvv][1]; if (reachedlimit || win3found) { break; } //for (int j = 0; j < board.size; j++) { if (b[i, j] == 0) { if (cvx[i, j].f["threes"] > 0) { if (dodisplay) { parent.memo("Testing " + i + "," + j); } board testboard = this.copy(); testboard.smallsize(); testboard.b[i, j] = p.val; testboard.set(testboard.computermove(other, dodisplay, depth + 1, starttime), -p.val); if (dodisplay) { testboard.DisplayBoard(); } int[] nextmove = testboard.computermove(p, dodisplay, depth + 1, starttime); if (dodisplay) { parent.memo("nextmove[2] = " + nextmove[2]); } if (nextmove[3] >= 10) { move[0] = i; move[1] = j; move[2] = nextmove[2]; win3found = true; parent.memo("==== 3-win found! ===="); break; } else if (nextmove[2] < 0) { reachedlimit = true; break; } } } } } if (dodisplay) { this.DisplayBoard(); } } //parent.memo("Maxprio = " + maxprio); //parent.memo("Maxcv = " + maxcv); return(move); }
public cellvalueclass evaluateline(int x, int y, Tuple <int, int> uv, int m) { cellvalueclass cv = new cellvalueclass(); cv.f["free"] = freeline(x, y, uv, m); cv.f["xxx"] = xinfreeline(x, y, uv, m); if (cv.f["free"] < 5) { cv.useless = true; return(cv); } else if (cv.f["free"] == 5) { if (cv.f["xxx"] == 3) { cv.f["fours"] = 1; } else if (cv.f["xxx"] == 2) { cv.f["pot4"] = 1; } } else // 6+ cells free { string[] halflines = new string[2] { gethalfline(x, y, uv, m, 1), gethalfline(x, y, uv, m, -1) }; int cl = countline(x, y, uv, m); if (cl == 3) { int fb = freebeyond(x, y, uv, m); if (fb == 2) { cv.f["openfours"] = 1; } else if (fb == 1) { cv.f["fours"] = 1; } } else if (cl == 2) { int fb = freebeyond(x, y, uv, m); if (fb == 2) { //do x-x_x case here! for (int ihalf = 0; ihalf <= 1; ihalf++) { if (halflines[ihalf].StartsWith("x_x")) { cv.f["fours"]++; } else if (halflines[ihalf].StartsWith("xx_x")) { cv.f["fours"]++; } else if (halflines[ihalf].StartsWith("xx") && halflines[1 - ihalf].StartsWith("_x")) { cv.f["fours"]++; } } if (cv.f["fours"] == 0) { cv.f["threes"] = 1; } } else if (fb == 1) { cv.f["pot4"] = 1; } } else if (cv.f["xxx"] >= 1) { for (int ihalf = 0; ihalf <= 1; ihalf++) { if (halflines[ihalf].StartsWith("_xxx") && halflines[1 - ihalf].StartsWith("_")) { cv.f["fours"]++; } else if (halflines[ihalf].StartsWith("_xx_") && halflines[1 - ihalf].StartsWith("_")) { cv.f["threes"]++; } else if (halflines[ihalf].StartsWith("x_x_") && halflines[1 - ihalf].StartsWith("_")) { cv.f["threes"]++; } else if (halflines[ihalf].StartsWith("x_") && halflines[1 - ihalf].StartsWith("_")) { cv.f["twos"]++; } else if (halflines[ihalf].StartsWith("_x_") && halflines[1 - ihalf].StartsWith("_")) { cv.f["twos"]++; } else if (halflines[ihalf].StartsWith("x_") && halflines[1 - ihalf].StartsWith("_")) { cv.f["twos"]++; } else if (halflines[ihalf].StartsWith("__x_") && halflines[1 - ihalf].StartsWith("_")) { cv.f["twos"]++; } } } } return(cv); }