public Position(Position p) { whiteDiscs = p.whiteDiscs; blackDiscs = p.blackDiscs; height = new int[7]; for (int i = 0; i <= 6; i++) { height[i] = p.height[i]; } toMove = p.toMove; }
public abstract int returnMove(Position p);
/* * nur in Situationen anwendbar, in denen niemand gewonnen hat und kein unentschieden vorliegt */ private int evaluate(Position p, bool recognized) { if (recognized) { counterrecognized += 1; } else { counterevaluated += 1; } //Threats ermitteln getthreats(p, Position.WHITE); getthreats(p, Position.BLACK); //Array initialisieren int[] height = new int[7]; int totalheight = 0; for (int i = 0; i < 7; i++) { height[i] = 6; for (int j = 0; j < 6; j++) { if (blackthreats[i][j] || whitethreats[i][j]) { height[i] = p.height[i]; totalheight += height[i]; goto outer; } } totalheight += 6; outer: ; } if (totalheight == 42) { return 0; } //Gewinner feststellen, falls auf restlichem Brett nichts passiert bool toMove = (totalheight % 2 == 0) ? Position.WHITE : Position.BLACK; bool winner; bool found = true; while (found) { found = false; //eigenen Threat besetzen for (int i = 0; i < 7; i++) { if (height[i] < 6 && (toMove == Position.WHITE ? whitethreats[i][height[i]] : blackthreats[i][height[i]])) { winner = toMove; if (recognized) { return (p.toMove == winner) ? (699 - totalheight) : (-699 + totalheight); } else { return (p.toMove == winner) ? (458 + p.numberOfDiscs()) : (-458 - p.numberOfDiscs()); } } } //gegnerischen Threat besetzen for (int i = 0; i < 7; i++) { if (height[i] < 6 && (toMove == Position.WHITE ? blackthreats[i][height[i]] : whitethreats[i][height[i]])) { height[i] += 1; toMove = !toMove; found = true; //UPGRADE_NOTE: Die continue-Anweisung mit Bezeichnung wurde in eine goto-Anweisung geändert. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1015'" goto outer1; } } //unkritisches Feld besetzen for (int i = 0; i < 7; i++) { if ((height[i] == 5) || (height[i] < 5 && !blackthreats[i][height[i] + 1] && !whitethreats[i][height[i] + 1])) { height[i] += 1; toMove = !toMove; found = true; //UPGRADE_NOTE: Die continue-Anweisung mit Bezeichnung wurde in eine goto-Anweisung geändert. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1015'" goto outer1; } } //unter eigene Drohung ziehen, ungerade Anzahl freier Felder for (int i = 0; i < 7; i++) { if (height[i] < 5 && (toMove == Position.WHITE ? !blackthreats[i][height[i] + 1] : !whitethreats[i][height[i] + 1]) && ((6 - height[i]) % 2 == 1)) { height[i] += 1; toMove = !toMove; found = true; //UPGRADE_NOTE: Die continue-Anweisung mit Bezeichnung wurde in eine goto-Anweisung geändert. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1015'" goto outer1; } } //unter eigene Drohung ziehen, gerade Anzahl freier Felder for (int i = 0; i < 7; i++) { if (height[i] < 5 && (toMove == Position.WHITE ? !blackthreats[i][height[i] + 1] : !whitethreats[i][height[i] + 1])) { height[i] += 1; toMove = !toMove; found = true; //UPGRADE_NOTE: Die continue-Anweisung mit Bezeichnung wurde in eine goto-Anweisung geändert. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1015'" goto outer1; } } //unter gegnerische Drohung ziehen for (int i = 0; i < 7; i++) { if (height[i] < 5) { height[i] += 1; toMove = !toMove; found = true; //UPGRADE_NOTE: Die continue-Anweisung mit Bezeichnung wurde in eine goto-Anweisung geändert. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1015'" goto outer1; } } goto outer1_brk; outer1: ; } outer1_brk: ; return 0; }
/* * Sortiert Züge nach Feldgewichten und nach dem besten Zug aus den Hash Tables */ private void sort(int[] z, Position p) { for (int i = 0; i < z[7]; i++) { tableValues[i] = table[z[i]]; //Feldgewichtung auswählen } int swap; for (int i = z[7] - 2; i >= 0; i--) { for (int j = 0; j <= i; j++) { if (table[z[j + 1]] > table[z[j]]) { swap = z[j + 1]; z[j + 1] = z[j]; z[j] = swap; swap = tableValues[j + 1]; tableValues[j + 1] = tableValues[j]; tableValues[j] = swap; } } } if (bestMove != -1) { for (int i = 0; i < z[7]; i++) { if (z[i] == bestMove) { if (i < 1) { break; } for (int j = i; i > 0; i--) { z[i] = z[i - 1]; } z[0] = bestMove; break; } } } }
public virtual int AlphaBeta(Position p, int depth, int alpha, int beta, double extension, MoveList pv, long Zkey, int move) { if (nodecount[1] + nodecount[0] > NODELIMIT) //wenn Knotenlimit überschritten, gehe zu Exception { throw new TooManyNodesException(); } if (depth < maxDepth) { maxDepth = depth; } p.makeMove(move); nodecount[0] += 1; int hashflag = HASHALPHA; //letzte Bits des Keys in Index umwandeln int index = (int)Zkey & (HASHSIZE - 1); //Hash Tables hvalue = -1; bestMove = -1; newbeta = beta; newalpha = alpha; if (HashTable2[index].key == Zkey) { if (HashTable2[index].depth >= (depth + extension)) { if (HashTable2[index].flag == HASHEXACT) { hvalue = HashTable2[index].value_Renamed; } if (HashTable2[index].flag == HASHALPHA && HashTable2[index].value_Renamed <= alpha) { hvalue = alpha; } if (HashTable2[index].flag == HASHALPHA && HashTable2[index].value_Renamed < beta) { newbeta = HashTable2[index].value_Renamed; } if (HashTable2[index].flag == HASHBETA && HashTable2[index].value_Renamed >= beta) { hvalue = beta; } if (HashTable2[index].flag == HASHBETA && HashTable2[index].value_Renamed > alpha) { newalpha = HashTable2[index].value_Renamed; } } bestMove = HashTable2[index].move; } if (HashTable1[index].key == Zkey) { if (HashTable1[index].depth >= (depth + extension)) { if (HashTable1[index].flag == HASHEXACT) { hvalue = HashTable1[index].value_Renamed; } if (HashTable1[index].flag == HASHALPHA && HashTable1[index].value_Renamed <= alpha) { hvalue = alpha; } if (HashTable1[index].flag == HASHALPHA && HashTable1[index].value_Renamed < beta) { newbeta = HashTable1[index].value_Renamed; } if (HashTable1[index].flag == HASHBETA && HashTable1[index].value_Renamed >= beta) { hvalue = beta; } if (HashTable1[index].flag == HASHBETA && HashTable1[index].value_Renamed > alpha) { newalpha = HashTable1[index].value_Renamed; } } bestMove = HashTable1[index].move; } if (HashTable3[index].key == Zkey) { hvalue = HashTable3[index].value_Renamed; } beta = newbeta; alpha = newalpha; if (hvalue != -1) { pv.length = 0; return hvalue; } MoveList mypv = new MoveList(); //entschiedene Positionen if (p.isWon(!p.toMove, move)) { pv.length = 0; addHashEntries(Zkey, index, depth + extension, -1000 + p.numberOfDiscs(), HASHEXACT, -1); return -1000 + p.numberOfDiscs(); } if (p.Draw) { pv.length = 0; addHashEntries(Zkey, index, depth + extension, 0, HASHEXACT, -1); return 0; } //Eröffnungsbuchzugriff if (opening) { if (p.numberOfDiscs() <= 8) { value_Renamed = searchBook(p); if (value_Renamed != -1) { pv.length = 0; addHashEntries(Zkey, index, depth + extension, value_Renamed, HASHEXACT, -1); return value_Renamed; } } } //Interior Node Recognition firstFreeColumn = -1; secondFreeColumn = -1; freeColumns = 0; for (int i = 0; i < 7; i++) { if (p.height[i] != 6) { freeColumns += 1; if (freeColumns == 3) break; if (freeColumns == 1) firstFreeColumn = i; if (freeColumns == 2) secondFreeColumn = i; } } //Wenn nur mehr wenige Spalten frei sind (Ende des Spieles) if (freeColumns == 1 || (freeColumns == 2 && (secondFreeColumn - firstFreeColumn >= 4))) { if (acuteThreat(p, p.toMove) == -1 && acuteThreat(p, !p.toMove) == -1) { value_Renamed = evaluate(p, true); pv.length = 0; addHashEntries(Zkey, index, depth + extension, value_Renamed, HASHEXACT, -1); return value_Renamed; } } if (depth <= (0 - extension)) { int akut2 = acuteThreat(p, p.toMove); if (akut2 != -1) { pv.length = 0; addHashEntries(Zkey, index, depth + extension, 1000 - p.numberOfDiscs() - 1, HASHEXACT, -1); return 1000 - p.numberOfDiscs() - 1; } int akut = acuteThreat(p, !p.toMove); if (akut == -1) { pv.length = 0; int val = evaluate(p, false); addHashEntries(Zkey, index, depth + extension, val, HASHEXACT, -1); return val; } extension += 2; Zkey = Zkey ^ (p.toMove ? zobristKeys[akut][0] : zobristKeys[akut][1]); int value_Renamed = -AlphaBeta(p, depth - 1, -beta, -alpha, extension, mypv, Zkey, akut); p.undoMove(akut); Zkey = Zkey ^ (p.toMove ? zobristKeys[akut][0] : zobristKeys[akut][1]); if (value_Renamed >= beta) { addHashEntries(Zkey, index, depth + extension - 2, beta, HASHBETA, -1); return beta; } if (value_Renamed > alpha) { hashflag = HASHEXACT; alpha = value_Renamed; pv.First = new MoveListElement(akut); if (mypv.length != 0) { pv.Rest = mypv; } pv.length = mypv.length + 1; } addHashEntries(Zkey, index, depth + extension - 2, alpha, hashflag, -1); return alpha; } int[] moves = generateMoves(p, searchDepth - depth); sort(moves, p); //Sortiert Züge nach Feldgewichten und nach dem besten Zug aus den Hash Tables //Suchvertiefung for (int i = 0; i < moves[7]; i++) { Zkey = Zkey ^ (p.toMove ? zobristKeys[moves[i]][0] : zobristKeys[moves[i]][1]); value_Renamed = -AlphaBeta(p, depth - 1, -beta, -alpha, extension, mypv, Zkey, moves[i]); p.undoMove(moves[i]); Zkey = Zkey ^ (p.toMove ? zobristKeys[moves[i]][0] : zobristKeys[moves[i]][1]); if (value_Renamed >= beta) { addHashEntries(Zkey, index, depth + extension, value_Renamed, HASHBETA, moves[i]); return beta; } if (value_Renamed > alpha) { hashflag = HASHEXACT; alpha = value_Renamed; pv.First = new MoveListElement(moves[i]); if (mypv.length != 0) { pv.Rest = mypv; } pv.length = mypv.length + 1; } } addHashEntries(Zkey, index, depth + extension, alpha, hashflag, (hashflag == HASHEXACT ? pv.pop() : -1)); return alpha; }
/* * Für den initialen Aufruf von AlphaBeta gibt es eine spezielle Funktion. * a) Hier wird kein Wert aus den Hash Tables, aus dem Eröffnungsbuch oder aus einer Form von Evaluation übernommen, * da man sonst 0 Level im Suchbaum und demzufolge keine PV, also auch keinen besten Zug erhält. * b) Hier muß nicht auf gewonnene oder unentschiedene Positionen getestet werden, da playGame() solche Stellungen abfängt. * c) Hier wird kein Zug-Argument übergeben. Diese Methode stellt stets den Wurzelknoten dar. */ public virtual int StartAlphaBeta(Position p, int depth, int alpha, int beta, double extension, MoveList pv, long Zkey) { nodecount[0] += 1; int hashflag = HASHALPHA; //letzte Bits des Keys in Index umwandeln int index = (int)Zkey & (HASHSIZE - 1); //Hashtables zugriff bestMove = -1; if (HashTable1[index].key == Zkey) //HashTable 1 suchen { bestMove = HashTable1[index].move; } if (HashTable2[index].key == Zkey) //in HashTable 2 suchen { bestMove = HashTable2[index].move; } MoveList mypv = new MoveList(); int[] moves = generateMoves(p, searchDepth - depth); //mögliche Züge generieren sort(moves, p); //Sortiert Züge nach Feldgewichten und nach dem besten Zug aus den Hash Tables for (int i = 0; i < moves[7]; i++) //moves[7] = Anzahl der möglichen Züge { Zkey = Zkey ^ (p.toMove == Position.WHITE ? zobristKeys[moves[i]][0] : zobristKeys[moves[i]][1]); value_Renamed = -AlphaBeta(p, depth - 1, -beta, -alpha, extension, mypv, Zkey, moves[i]); p.undoMove(moves[i]); Zkey = Zkey ^ (p.toMove == Position.WHITE ? zobristKeys[moves[i]][0] : zobristKeys[moves[i]][1]); if (value_Renamed >= beta) { addHashEntries(Zkey, index, depth + extension, value_Renamed, HASHBETA, moves[i]); return beta; } if (value_Renamed > alpha) { hashflag = HASHEXACT; alpha = value_Renamed; pv.First = new MoveListElement(moves[i]); if (mypv.length != 0) { pv.Rest = mypv; } pv.length = mypv.length + 1; } } addHashEntries(Zkey, index, depth + extension, alpha, hashflag, (hashflag == HASHEXACT ? pv.pop() : -1)); return alpha; }
/* * * Hauptmethode des Computerspielers, die eine Position annimmt und einen Zug zurückgibt. * Sie kapselt den Alpha-Beta-Algorithmus. */ public override int returnMove(Position arg) { //Spielfeld übernehmen Position p = new Position(arg); //Startwerte für das Iterative Deepening nodecount[1] = savedSum; int lastRoundMove = -1; int lastRoundValue = -1000; int bestFoundValue = 0; // Bewertung des besten Zuges searchDepth = 1; //aktuelle Suchtiefe int alpha = -10000; int beta = 10000; MoveList pv = new MoveList(); bool repeated = false; //Zobrist-Key erstellen long Zkey = 0; for (int i = 0; i < 42; i++) { if ((p.whiteDiscs & (0x0000000000400000L << i)) == (0x0000000000400000L << i)) { Zkey = Zkey ^ zobristKeys[i][0]; //^ = XOR } else if ((p.blackDiscs & (0x0000000000400000L << i)) == (0x0000000000400000L << i)) { Zkey = Zkey ^ zobristKeys[i][1]; } } //Löschen der HashTables 1 und 2. for (int i = 0; i < HASHSIZE; i++) { HashTable1[i].clear(); HashTable2[i].clear(); } //feststellen, ob man sich noch in der Eröffnung befindet if (bookEnabled && p.numberOfDiscs() < 8) { opening = true; } else { opening = false; } //Iterative-Deepening-Schleife while (!(searchDepth > (42 - p.numberOfDiscs()))) { repeated = false; nodecount[0] = 0; maxDepth = 100; counterrecognized = 0; counterevaluated = 0; counterhash1 = 0; counterhash2 = 0; counterhash3 = 0; pv = new MoveList(); //Zugliste long startTime = 0; long duration = 0; try { //Aspiration Search verlangt ggf. mehrere Anläufe while (true) { startTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; bestFoundValue = StartAlphaBeta(p, searchDepth, alpha, beta, 0, pv, Zkey); //Aufruf des eigentlichen Algorithmusses duration = repeated ? duration + (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - startTime : (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - startTime; //Start Aspiration Windows if (bestFoundValue <= alpha && !repeated) //erweitern des Suchfenster nach unten { repeated = true; alpha = -10000; beta = bestFoundValue + 2; continue; } if (bestFoundValue >= beta && !repeated) //erweitern des Suchfensters nach oben { repeated = true; beta = 10000; alpha = bestFoundValue - 2; continue; } if (repeated && (bestFoundValue <= alpha || bestFoundValue >= beta)) //setzen des Suchfensters auf Startwerte { alpha = -10000; beta = 10000; continue; } if (bestFoundValue == 0) //Unentschieden oder Ungeklärte Situation { alpha = bestFoundValue - 2; beta = bestFoundValue + 2; } if (bestFoundValue > 0 && bestFoundValue < 600) //alles offen { alpha = bestFoundValue; beta = bestFoundValue + 2; } if (bestFoundValue < 0 && bestFoundValue > -600) //alles offen für anderen Spieler { alpha = bestFoundValue - 2; beta = bestFoundValue; } if (bestFoundValue > 600) //sicher gewonnen { alpha = bestFoundValue - 1; beta = bestFoundValue + 1; } if (bestFoundValue < -600) //sicher gewonnen für anderen Spieler { alpha = bestFoundValue - 1; beta = bestFoundValue + 1; } //Ende Aspiration Windows break; } } catch (TooManyNodesException) //max. Anzahl von Knoten überschritten { duration = repeated ? duration + (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - startTime : (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - startTime; totalDuration = totalDuration + duration; nodecount[2] = nodecount[2] + nodecount[0]; nodecount[1] = nodecount[1] + nodecount[0]; return lastRoundMove; } lastRoundMove = pv.pop(); lastRoundValue = bestFoundValue; totalDuration = totalDuration + duration; nodecount[2] = nodecount[2] + nodecount[0]; nodecount[1] = nodecount[1] + nodecount[0]; int overwritten1 = 0; int overwritten2 = 0; int overwritten3 = 0; for (int i = 0; i < HASHSIZE; i++) { if (HashTable1[i].depth != -1) { counterhash1 += 1; overwritten1 += HashTable1[i].overwritten; } if (HashTable2[i].depth != -1) { counterhash2 += 1; overwritten2 += HashTable2[i].overwritten; } if (HashTable3[i].depth != -1) { counterhash3 += 1; overwritten3 += HashTable3[i].overwritten; } } if (bestFoundValue > 900 || bestFoundValue < -900) { break; } searchDepth += 1; } if (bestFoundValue < -900) { if (!opening) { return lastRoundMove; } else { //Wenn man in der Eröffnung in einer verlorenen Position ist, löscht man die Hash Tables und sucht ohne Eröffnungsbuch von vorne. bookEnabled = false; savedSum = nodecount[1]; for (int i = 0; i < HASHSIZE; i++) { HashTable3[i].clear(); } int result = returnMove(p); for (int i = 0; i < HASHSIZE; i++) { HashTable3[i].clear(); } savedSum = 0; bookEnabled = true; return result; } } else { return lastRoundMove; } }
/* * Sucht eine Stellung im Eröffnungsbuch. Dazu muß die Position ggf. gespiegelt und erneut gesucht werden. * Wenn die Stellung nicht gefunden wird, wird -1 zurückgegeben. */ public virtual int searchBook(Position p) { #region Zusammenbau des Spielfeldes in einen String von links nach rechts System.String s = new System.Text.StringBuilder().ToString(); for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 5; j++) { if ((p.whiteDiscs & (0x0000000000400000L << (j * 7 + i))) == (0x0000000000400000L << (j * 7 + i))) { s = System.String.Concat(s, "x"); } else if ((p.blackDiscs & (0x0000000000400000L << (j * 7 + i))) == (0x0000000000400000L << (j * 7 + i))) { s = System.String.Concat(s, "o"); } else { s = System.String.Concat(s, "b"); } s = System.String.Concat(s, ","); } } #endregion int result = binarySearch(s); //String suchen im Eröffnungsbuch (wenn nicht gefunden wird -1 zurückgegeben) if (result != -1) { return result; } #region Zusammenbau des Spielfeldes in einen String von rechts nach links s = new System.Text.StringBuilder().ToString(); for (int i = 6; i >= 0; i--) { for (int j = 0; j <= 5; j++) { if ((p.whiteDiscs & (0x0000000000400000L << (j * 7 + i))) == (0x0000000000400000L << (j * 7 + i))) { s = System.String.Concat(s, "x"); } else if ((p.blackDiscs & (0x0000000000400000L << (j * 7 + i))) == (0x0000000000400000L << (j * 7 + i))) { s = System.String.Concat(s, "o"); } else { s = System.String.Concat(s, "b"); } s = System.String.Concat(s, ","); } } #endregion return binarySearch(s); //String suchen im Eröffnungsbuch (wenn nicht gefunden wird -1 zurückgegeben) }
/* * Erzeugt alle Züge, es sei denn, einer der Spieler hat eine akute Drohung - dann nur einen Zug */ private int[] generateMoves(Position p, int depth) { int b = acuteThreat(p, p.toMove); //prüft, ob eine akute Drohung vorhanden ist (-1 = keine Drohung) if (b != -1) { moves[depth][7] = 1; moves[depth][0] = b; return moves[depth]; } int a = acuteThreat(p, !p.toMove); if (a != -1) { moves[depth][7] = 1; moves[depth][0] = a; return moves[depth]; } int size = 0; if (p.height[0] < 6) { moves[depth][size] = p.height[0] * 7 + 0; size += 1; } if (p.height[1] < 6) { moves[depth][size] = p.height[1] * 7 + 1; size += 1; } if (p.height[2] < 6) { moves[depth][size] = p.height[2] * 7 + 2; size += 1; } if (p.height[3] < 6) { moves[depth][size] = p.height[3] * 7 + 3; size += 1; } if (p.height[4] < 6) { moves[depth][size] = p.height[4] * 7 + 4; size += 1; } if (p.height[5] < 6) { moves[depth][size] = p.height[5] * 7 + 5; size += 1; } if (p.height[6] < 6) { moves[depth][size] = p.height[6] * 7 + 6; size += 1; } moves[depth][7] = size; return moves[depth]; }
/* * Stellt die aktuellen Drohungen von s in p fest und speichert sie in dem jeweiligen Threats-Array */ private void getthreats(Position p, bool s) { ulong x = (ulong)(s == Position.WHITE ? p.whiteDiscs : p.blackDiscs); bool[][] threats = (s == Position.WHITE ? whitethreats : blackthreats); #region Spalte 1 switch (p.height[0]) { case 0: if ((x & 0x0000000003800000L) == 0x0000000003800000L) threats[0][0] = true; else if ((x & 0x0000404040000000L) == 0x0000404040000000L) threats[0][0] = true; else threats[0][0] = false; goto case 1; case 1: if ((x & 0x00000001C0000000L) == 0x00000001C0000000L) threats[0][1] = true; else if ((x & 0x0020202000000000L) == 0x0020202000000000L) threats[0][1] = true; else threats[0][1] = false; goto case 2; case 2: if ((x & 0x000000E000000000L) == 0x000000E000000000L) threats[0][2] = true; else if ((x & 0x1010100000000000L) == 0x1010100000000000L) threats[0][2] = true; else threats[0][2] = false; goto case 3; case 3: if ((x & 0x0000700000000000L) == 0x0000700000000000L) threats[0][3] = true; else if ((x & 0x0000002082000000L) == 0x0000002082000000L) threats[0][3] = true; else if ((x & 0x0000001020400000L) == 0x0000001020400000L) threats[0][3] = true; else threats[0][3] = false; goto case 4; case 4: if ((x & 0x0038000000000000L) == 0x0038000000000000L) threats[0][4] = true; else if ((x & 0x0000104100000000L) == 0x0000104100000000L) threats[0][4] = true; else if ((x & 0x0000081020000000L) == 0x0000081020000000L) threats[0][4] = true; else threats[0][4] = false; goto case 5; case 5: if ((x & 0x1C00000000000000L) == 0x1C00000000000000L) threats[0][5] = true; else if ((x & 0x0008208000000000L) == 0x0008208000000000L) threats[0][5] = true; else if ((x & 0x0004081000000000L) == 0x0004081000000000L) threats[0][5] = true; else threats[0][5] = false; goto default; default: break; } #endregion #region Spalte 2 switch (p.height[1]) { case 0: if ((x & 0x0000000003400000L) == 0x0000000003400000L) threats[1][0] = true; else if ((x & 0x0000000007000000L) == 0x0000000007000000L) threats[1][0] = true; else if ((x & 0x0000808080000000L) == 0x0000808080000000L) threats[1][0] = true; else threats[1][0] = false; goto case 1; case 1: if ((x & 0x00000001A0000000L) == 0x00000001A0000000L) threats[1][1] = true; else if ((x & 0x0000000380000000L) == 0x0000000380000000L) threats[1][1] = true; else if ((x & 0x0000404000400000L) == 0x0000404000400000L) threats[1][1] = true; else if ((x & 0x0040404000000000L) == 0x0040404000000000L) threats[1][1] = true; else threats[1][1] = false; goto case 2; case 2: if ((x & 0x000000D000000000L) == 0x000000D000000000L) threats[1][2] = true; else if ((x & 0x000001C000000000L) == 0x000001C000000000L) threats[1][2] = true; else if ((x & 0x0020200020000000L) == 0x0020200020000000L) threats[1][2] = true; else if ((x & 0x2020200000000000L) == 0x2020200000000000L) threats[1][2] = true; else if ((x & 0x0000080082000000L) == 0x0000080082000000L) threats[1][2] = true; else threats[1][2] = false; goto case 3; case 3: if ((x & 0x0000680000000000L) == 0x0000680000000000L) threats[1][3] = true; else if ((x & 0x0000E00000000000L) == 0x0000E00000000000L) threats[1][3] = true; else if ((x & 0x0000004104000000L) == 0x0000004104000000L) threats[1][3] = true; else if ((x & 0x0004004100000000L) == 0x0004004100000000L) threats[1][3] = true; else if ((x & 0x1010001000000000L) == 0x1010001000000000L) threats[1][3] = true; else if ((x & 0x0000002040800000L) == 0x0000002040800000L) threats[1][3] = true; else threats[1][3] = false; goto case 4; case 4: if ((x & 0x0034000000000000L) == 0x0034000000000000L) threats[1][4] = true; else if ((x & 0x0070000000000000L) == 0x0070000000000000L) threats[1][4] = true; else if ((x & 0x0000208200000000L) == 0x0000208200000000L) threats[1][4] = true; else if ((x & 0x0200208000000000L) == 0x0200208000000000L) threats[1][4] = true; else if ((x & 0x0000102040000000L) == 0x0000102040000000L) threats[1][4] = true; else threats[1][4] = false; goto case 5; case 5: if ((x & 0x1A00000000000000L) == 0x1A00000000000000L) threats[1][5] = true; else if ((x & 0x3800000000000000L) == 0x3800000000000000L) threats[1][5] = true; else if ((x & 0x0010410000000000L) == 0x0010410000000000L) threats[1][5] = true; else if ((x & 0x0008102000000000L) == 0x0008102000000000L) threats[1][5] = true; else threats[1][5] = false; goto default; default: break; } #endregion #region Spalte 3 switch (p.height[2]) { case 0: if ((x & 0x0000000002C00000L) == 0x0000000002C00000L) threats[2][0] = true; else if ((x & 0x0000000006800000L) == 0x0000000006800000L) threats[2][0] = true; else if ((x & 0x000000000E000000L) == 0x000000000E000000L) threats[2][0] = true; else if ((x & 0x0001010100000000L) == 0x0001010100000000L) threats[2][0] = true; else threats[2][0] = false; goto case 1; case 1: if ((x & 0x0000000160000000L) == 0x0000000160000000L) threats[2][1] = true; else if ((x & 0x0000000340000000L) == 0x0000000340000000L) threats[2][1] = true; else if ((x & 0x0000000700000000L) == 0x0000000700000000L) threats[2][1] = true; else if ((x & 0x0000082002000000L) == 0x0000082002000000L) threats[2][1] = true; else if ((x & 0x0000808000800000L) == 0x0000808000800000L) threats[2][1] = true; else if ((x & 0x0080808000000000L) == 0x0080808000000000L) threats[2][1] = true; else threats[2][1] = false; goto case 2; case 2: if ((x & 0x000000B000000000L) == 0x000000B000000000L) threats[2][2] = true; else if ((x & 0x000001A000000000L) == 0x000001A000000000L) threats[2][2] = true; else if ((x & 0x0000038000000000L) == 0x0000038000000000L) threats[2][2] = true; else if ((x & 0x0000400040400000L) == 0x0000400040400000L) threats[2][2] = true; else if ((x & 0x0040400040000000L) == 0x0040400040000000L) threats[2][2] = true; else if ((x & 0x4040400000000000L) == 0x4040400000000000L) threats[2][2] = true; else if ((x & 0x0000100104000000L) == 0x0000100104000000L) threats[2][2] = true; else if ((x & 0x0004100100000000L) == 0x0004100100000000L) threats[2][2] = true; else threats[2][2] = false; goto case 3; case 3: if ((x & 0x0000580000000000L) == 0x0000580000000000L) threats[2][3] = true; else if ((x & 0x0000D00000000000L) == 0x0000D00000000000L) threats[2][3] = true; else if ((x & 0x0001C00000000000L) == 0x0001C00000000000L) threats[2][3] = true; else if ((x & 0x0020002020000000L) == 0x0020002020000000L) threats[2][3] = true; else if ((x & 0x2020002000000000L) == 0x2020002000000000L) threats[2][3] = true; else if ((x & 0x0000008208000000L) == 0x0000008208000000L) threats[2][3] = true; else if ((x & 0x0008008200000000L) == 0x0008008200000000L) threats[2][3] = true; else if ((x & 0x0208008000000000L) == 0x0208008000000000L) threats[2][3] = true; else if ((x & 0x0000004081000000L) == 0x0000004081000000L) threats[2][3] = true; else threats[2][3] = false; goto case 4; case 4: if ((x & 0x002C000000000000L) == 0x002C000000000000L) threats[2][4] = true; else if ((x & 0x0068000000000000L) == 0x0068000000000000L) threats[2][4] = true; else if ((x & 0x00E0000000000000L) == 0x00E0000000000000L) threats[2][4] = true; else if ((x & 0x0000410400000000L) == 0x0000410400000000L) threats[2][4] = true; else if ((x & 0x0400410000000000L) == 0x0400410000000000L) threats[2][4] = true; else if ((x & 0x1000101000000000L) == 0x1000101000000000L) threats[2][4] = true; else if ((x & 0x0000204080000000L) == 0x0000204080000000L) threats[2][4] = true; else threats[2][4] = false; goto case 5; case 5: if ((x & 0x1600000000000000L) == 0x1600000000000000L) threats[2][5] = true; else if ((x & 0x3400000000000000L) == 0x3400000000000000L) threats[2][5] = true; else if ((x & 0x7000000000000000L) == 0x7000000000000000L) threats[2][5] = true; else if ((x & 0x0020820000000000L) == 0x0020820000000000L) threats[2][5] = true; else if ((x & 0x0010204000000000L) == 0x0010204000000000L) threats[2][5] = true; else threats[2][5] = false; goto default; default: break; } #endregion #region Spalte 4 switch (p.height[3]) { case 0: if ((x & 0x0000000001C00000L) == 0x0000000001C00000L) threats[3][0] = true; else if ((x & 0x0000000005800000L) == 0x0000000005800000L) threats[3][0] = true; else if ((x & 0x000000000D000000L) == 0x000000000D000000L) threats[3][0] = true; else if ((x & 0x000000001C000000L) == 0x000000001C000000L) threats[3][0] = true; else if ((x & 0x0000082080000000L) == 0x0000082080000000L) threats[3][0] = true; else if ((x & 0x0002020200000000L) == 0x0002020200000000L) threats[3][0] = true; else threats[3][0] = false; goto case 1; case 1: if ((x & 0x00000000E0000000L) == 0x00000000E0000000L) threats[3][1] = true; else if ((x & 0x00000002C0000000L) == 0x00000002C0000000L) threats[3][1] = true; else if ((x & 0x0000000680000000L) == 0x0000000680000000L) threats[3][1] = true; else if ((x & 0x0000000E00000000L) == 0x0000000E00000000L) threats[3][1] = true; else if ((x & 0x0000104004000000L) == 0x0000104004000000L) threats[3][1] = true; else if ((x & 0x0004104000000000L) == 0x0004104000000000L) threats[3][1] = true; else if ((x & 0x0001010001000000L) == 0x0001010001000000L) threats[3][1] = true; else if ((x & 0x0101010000000000L) == 0x0101010000000000L) threats[3][1] = true; else threats[3][1] = false; goto case 2; case 2: if ((x & 0x0000007000000000L) == 0x0000007000000000L) threats[3][2] = true; else if ((x & 0x0000016000000000L) == 0x0000016000000000L) threats[3][2] = true; else if ((x & 0x0000034000000000L) == 0x0000034000000000L) threats[3][2] = true; else if ((x & 0x0000070000000000L) == 0x0000070000000000L) threats[3][2] = true; else if ((x & 0x0000800080800000L) == 0x0000800080800000L) threats[3][2] = true; else if ((x & 0x0080800080000000L) == 0x0080800080000000L) threats[3][2] = true; else { if ((x & 0x8080800000000000L) == 0x8080800000000000L) threats[3][2] = true; else if ((x & 0x0000200208000000L) == 0x0000200208000000L) threats[3][2] = true; else if ((x & 0x0008200200000000L) == 0x0008200200000000L) threats[3][2] = true; else if ((x & 0x0208200000000000L) == 0x0208200000000000L) threats[3][2] = true; else threats[3][2] = false; } goto case 3; case 3: if ((x & 0x0000380000000000L) == 0x0000380000000000L) threats[3][3] = true; else if ((x & 0x0000B00000000000L) == 0x0000B00000000000L) threats[3][3] = true; else if ((x & 0x0001A00000000000L) == 0x0001A00000000000L) threats[3][3] = true; else if ((x & 0x0003800000000000L) == 0x0003800000000000L) threats[3][3] = true; else if ((x & 0x0000004040400000L) == 0x0000004040400000L) threats[3][3] = true; else if ((x & 0x0040004040000000L) == 0x0040004040000000L) threats[3][3] = true; else if ((x & 0x4040004000000000L) == 0x4040004000000000L) threats[3][3] = true; else if ((x & 0x0000010410000000L) == 0x0000010410000000L) threats[3][3] = true; else if ((x & 0x0010010400000000L) == 0x0010010400000000L) threats[3][3] = true; else if ((x & 0x0410010000000000L) == 0x0410010000000000L) threats[3][3] = true; else if ((x & 0x0000008102000000L) == 0x0000008102000000L) threats[3][3] = true; else threats[3][3] = false; goto case 4; case 4: if ((x & 0x001C000000000000L) == 0x001C000000000000L) threats[3][4] = true; else if ((x & 0x0058000000000000L) == 0x0058000000000000L) threats[3][4] = true; else if ((x & 0x00D0000000000000L) == 0x00D0000000000000L) threats[3][4] = true; else if ((x & 0x01C0000000000000L) == 0x01C0000000000000L) threats[3][4] = true; else if ((x & 0x0000202020000000L) == 0x0000202020000000L) threats[3][4] = true; else if ((x & 0x2000202000000000L) == 0x2000202000000000L) threats[3][4] = true; else if ((x & 0x0000820800000000L) == 0x0000820800000000L) threats[3][4] = true; else { if ((x & 0x0800820000000000L) == 0x0800820000000000L) threats[3][4] = true; else if ((x & 0x0000408100000000L) == 0x0000408100000000L) threats[3][4] = true; else threats[3][4] = false; } goto case 5; case 5: if ((x & 0x0E00000000000000L) == 0x0E00000000000000L) threats[3][5] = true; else if ((x & 0x2C00000000000000L) == 0x2C00000000000000L) threats[3][5] = true; else if ((x & 0x6800000000000000L) == 0x6800000000000000L) threats[3][5] = true; else { if ((x & 0xE000000000000000L) == 0xE000000000000000L) threats[3][5] = true; else if ((x & 0x0010101000000000L) == 0x0010101000000000L) threats[3][5] = true; else if ((x & 0x0041040000000000L) == 0x0041040000000000L) threats[3][5] = true; else if ((x & 0x0020408000000000L) == 0x0020408000000000L) threats[3][5] = true; else threats[3][5] = false; } goto default; default: break; } #endregion #region Spalte 5 switch (p.height[4]) { case 0: if ((x & 0x0000000003800000L) == 0x0000000003800000L) threats[4][0] = true; else if ((x & 0x000000000B000000L) == 0x000000000B000000L) threats[4][0] = true; else if ((x & 0x000000001A000000L) == 0x000000001A000000L) threats[4][0] = true; else if ((x & 0x0000104100000000L) == 0x0000104100000000L) threats[4][0] = true; else threats[4][0] = false; goto case 1; case 1: if ((x & 0x00000001C0000000L) == 0x00000001C0000000L) threats[4][1] = true; else if ((x & 0x0000000580000000L) == 0x0000000580000000L) threats[4][1] = true; else if ((x & 0x0000000D00000000L) == 0x0000000D00000000L) threats[4][1] = true; else if ((x & 0x0002020002000000L) == 0x0002020002000000L) threats[4][1] = true; else if ((x & 0x0000208008000000L) == 0x0000208008000000L) threats[4][1] = true; else if ((x & 0x0008208000000000L) == 0x0008208000000000L) threats[4][1] = true; else threats[4][1] = false; goto case 2; case 2: if ((x & 0x000000E000000000L) == 0x000000E000000000L) threats[4][2] = true; else if ((x & 0x000002C000000000L) == 0x000002C000000000L) threats[4][2] = true; else if ((x & 0x0000068000000000L) == 0x0000068000000000L) threats[4][2] = true; else if ((x & 0x0001000101000000L) == 0x0001000101000000L) threats[4][2] = true; else if ((x & 0x0101000100000000L) == 0x0101000100000000L) threats[4][2] = true; else if ((x & 0x0000400410000000L) == 0x0000400410000000L) threats[4][2] = true; else if ((x & 0x0010400400000000L) == 0x0010400400000000L) threats[4][2] = true; else if ((x & 0x0410400000000000L) == 0x0410400000000000L) threats[4][2] = true; else threats[4][2] = false; goto case 3; case 3: if ((x & 0x0000700000000000L) == 0x0000700000000000L) threats[4][3] = true; else if ((x & 0x0001600000000000L) == 0x0001600000000000L) threats[4][3] = true; else if ((x & 0x0003400000000000L) == 0x0003400000000000L) threats[4][3] = true; else if ((x & 0x0000008080800000L) == 0x0000008080800000L) threats[4][3] = true; else if ((x & 0x0080008080000000L) == 0x0080008080000000L) threats[4][3] = true; else { if ((x & 0x8080008000000000L) == 0x8080008000000000L) threats[4][3] = true; else if ((x & 0x0020020800000000L) == 0x0020020800000000L) threats[4][3] = true; else { if ((x & 0x0820020000000000L) == 0x0820020000000000L) threats[4][3] = true; else if ((x & 0x0000010204000000L) == 0x0000010204000000L) threats[4][3] = true; else threats[4][3] = false; } } goto case 4; case 4: if ((x & 0x0038000000000000L) == 0x0038000000000000L) threats[4][4] = true; else if ((x & 0x00B0000000000000L) == 0x00B0000000000000L) threats[4][4] = true; else if ((x & 0x01A0000000000000L) == 0x01A0000000000000L) threats[4][4] = true; else if ((x & 0x0000404040000000L) == 0x0000404040000000L) threats[4][4] = true; else if ((x & 0x4000404000000000L) == 0x4000404000000000L) threats[4][4] = true; else if ((x & 0x1001040000000000L) == 0x1001040000000000L) threats[4][4] = true; else if ((x & 0x0000810200000000L) == 0x0000810200000000L) threats[4][4] = true; else threats[4][4] = false; goto case 5; case 5: if ((x & 0x1C00000000000000L) == 0x1C00000000000000L) threats[4][5] = true; else if ((x & 0x5800000000000000L) == 0x5800000000000000L) threats[4][5] = true; else { if ((x & 0xD000000000000000L) == 0xD000000000000000L) threats[4][5] = true; else if ((x & 0x0020202000000000L) == 0x0020202000000000L) threats[4][5] = true; else if ((x & 0x0040810000000000L) == 0x0040810000000000L) threats[4][5] = true; else threats[4][5] = false; } goto default; default: break; } #endregion #region Spalte 6 switch (p.height[5]) { case 0: if ((x & 0x0000000007000000L) == 0x0000000007000000L) threats[5][0] = true; else if ((x & 0x0000000016000000L) == 0x0000000016000000L) threats[5][0] = true; else if ((x & 0x0000208200000000L) == 0x0000208200000000L) threats[5][0] = true; else threats[5][0] = false; goto case 1; case 1: if ((x & 0x0000000380000000L) == 0x0000000380000000L) threats[5][1] = true; else if ((x & 0x0000000B00000000L) == 0x0000000B00000000L) threats[5][1] = true; else if ((x & 0x0000410010000000L) == 0x0000410010000000L) threats[5][1] = true; else if ((x & 0x0010410000000000L) == 0x0010410000000000L) threats[5][1] = true; else threats[5][1] = false; goto case 2; case 2: if ((x & 0x000001C000000000L) == 0x000001C000000000L) threats[5][2] = true; else if ((x & 0x0000058000000000L) == 0x0000058000000000L) threats[5][2] = true; else if ((x & 0x0002000202000000L) == 0x0002000202000000L) threats[5][2] = true; else if ((x & 0x0020800800000000L) == 0x0020800800000000L) threats[5][2] = true; else { if ((x & 0x0820800000000000L) == 0x0820800000000000L) threats[5][2] = true; else threats[5][2] = false; } goto case 3; case 3: if ((x & 0x0000E00000000000L) == 0x0000E00000000000L) threats[5][3] = true; else if ((x & 0x0002C00000000000L) == 0x0002C00000000000L) threats[5][3] = true; else if ((x & 0x0000010101000000L) == 0x0000010101000000L) threats[5][3] = true; else if ((x & 0x0100010100000000L) == 0x0100010100000000L) threats[5][3] = true; else if ((x & 0x1040040000000000L) == 0x1040040000000000L) threats[5][3] = true; else if ((x & 0x0000020408000000L) == 0x0000020408000000L) threats[5][3] = true; else threats[5][3] = false; goto case 4; case 4: if ((x & 0x0070000000000000L) == 0x0070000000000000L) threats[5][4] = true; else if ((x & 0x0160000000000000L) == 0x0160000000000000L) threats[5][4] = true; else if ((x & 0x0000808080000000L) == 0x0000808080000000L) threats[5][4] = true; else { if ((x & 0x8000808000000000L) == 0x8000808000000000L) threats[5][4] = true; else if ((x & 0x0001020400000000L) == 0x0001020400000000L) threats[5][4] = true; else threats[5][4] = false; } goto case 5; case 5: if ((x & 0x3800000000000000L) == 0x3800000000000000L) threats[5][5] = true; else { if ((x & 0xB000000000000000L) == 0xB000000000000000L) threats[5][5] = true; else if ((x & 0x0040404000000000L) == 0x0040404000000000L) threats[5][5] = true; else if ((x & 0x0081020000000000L) == 0x0081020000000000L) threats[5][5] = true; else threats[5][5] = false; } goto default; default: break; } #endregion #region Spalte 7 switch (p.height[6]) { case 0: if ((x & 0x000000000E000000L) == 0x000000000E000000L) threats[6][0] = true; else if ((x & 0x0000410400000000L) == 0x0000410400000000L) threats[6][0] = true; else threats[6][0] = false; goto case 1; case 1: if ((x & 0x0000000700000000L) == 0x0000000700000000L) threats[6][1] = true; else if ((x & 0x0020820000000000L) == 0x0020820000000000L) threats[6][1] = true; else threats[6][1] = false; goto case 2; case 2: if ((x & 0x0000038000000000L) == 0x0000038000000000L) threats[6][2] = true; else if ((x & 0x1041000000000000L) == 0x1041000000000000L) threats[6][2] = true; else threats[6][2] = false; goto case 3; case 3: if ((x & 0x0001C00000000000L) == 0x0001C00000000000L) threats[6][3] = true; else if ((x & 0x0000020202000000L) == 0x0000020202000000L) threats[6][3] = true; else if ((x & 0x0000040810000000L) == 0x0000040810000000L) threats[6][3] = true; else threats[6][3] = false; goto case 4; case 4: if ((x & 0x00E0000000000000L) == 0x00E0000000000000L) threats[6][4] = true; else if ((x & 0x0001010100000000L) == 0x0001010100000000L) threats[6][4] = true; else if ((x & 0x0002040800000000L) == 0x0002040800000000L) threats[6][4] = true; else threats[6][4] = false; goto case 5; case 5: if ((x & 0x7000000000000000L) == 0x7000000000000000L) threats[6][5] = true; else if ((x & 0x0080808000000000L) == 0x0080808000000000L) threats[6][5] = true; else if ((x & 0x0102040000000000L) == 0x0102040000000000L) threats[6][5] = true; else threats[6][5] = false; goto default; default: break; } #endregion for (int i = 0; i <= 6; i++) { for (int j = 0; j < p.height[i]; j++) { threats[i][j] = false; } } }
/* * Gibt -1 zurück, falls s keine akute Drohung in p hat, ansonsten die erste gefundene */ private int acuteThreat(Position p, bool s) { ulong x = (ulong)(s == Position.WHITE ? p.whiteDiscs : p.blackDiscs); #region Spalte 1 switch (p.height[0]) { case 0: if ((x & 0x0000000003800000L) == 0x0000000003800000L) return 0; if ((x & 0x0000404040000000L) == 0x0000404040000000L) return 0; break; case 1: if ((x & 0x00000001C0000000L) == 0x00000001C0000000L) return 7; if ((x & 0x0020202000000000L) == 0x0020202000000000L) return 7; break; case 2: if ((x & 0x000000E000000000L) == 0x000000E000000000L) return 14; if ((x & 0x1010100000000000L) == 0x1010100000000000L) return 14; break; case 3: if ((x & 0x0000700000000000L) == 0x0000700000000000L) return 21; if ((x & 0x0000002082000000L) == 0x0000002082000000L) return 21; if ((x & 0x0000001020400000L) == 0x0000001020400000L) return 21; break; case 4: if ((x & 0x0038000000000000L) == 0x0038000000000000L) return 28; if ((x & 0x0000104100000000L) == 0x0000104100000000L) return 28; if ((x & 0x0000081020000000L) == 0x0000081020000000L) return 28; break; case 5: if ((x & 0x1C00000000000000L) == 0x1C00000000000000L) return 35; if ((x & 0x0008208000000000L) == 0x0008208000000000L) return 35; if ((x & 0x0004081000000000L) == 0x0004081000000000L) return 35; break; default: break; } #endregion #region Spalte 2 switch (p.height[1]) { case 0: if ((x & 0x0000000003400000L) == 0x0000000003400000L) return 1; if ((x & 0x0000000007000000L) == 0x0000000007000000L) return 1; if ((x & 0x0000808080000000L) == 0x0000808080000000L) return 1; break; case 1: if ((x & 0x00000001A0000000L) == 0x00000001A0000000L) return 8; if ((x & 0x0000000380000000L) == 0x0000000380000000L) return 8; if ((x & 0x0000404000400000L) == 0x0000404000400000L) return 8; if ((x & 0x0040404000000000L) == 0x0040404000000000L) return 8; break; case 2: if ((x & 0x000000D000000000L) == 0x000000D000000000L) return 15; if ((x & 0x000001C000000000L) == 0x000001C000000000L) return 15; if ((x & 0x0020200020000000L) == 0x0020200020000000L) return 15; if ((x & 0x2020200000000000L) == 0x2020200000000000L) return 15; if ((x & 0x0000080082000000L) == 0x0000080082000000L) return 15; break; case 3: if ((x & 0x0000680000000000L) == 0x0000680000000000L) return 22; if ((x & 0x0000E00000000000L) == 0x0000E00000000000L) return 22; if ((x & 0x0000004104000000L) == 0x0000004104000000L) return 22; if ((x & 0x0004004100000000L) == 0x0004004100000000L) return 22; if ((x & 0x1010001000000000L) == 0x1010001000000000L) return 22; if ((x & 0x0000002040800000L) == 0x0000002040800000L) return 22; break; case 4: if ((x & 0x0034000000000000L) == 0x0034000000000000L) return 29; if ((x & 0x0070000000000000L) == 0x0070000000000000L) return 29; if ((x & 0x0000208200000000L) == 0x0000208200000000L) return 29; if ((x & 0x0200208000000000L) == 0x0200208000000000L) return 29; if ((x & 0x0000102040000000L) == 0x0000102040000000L) return 29; break; case 5: if ((x & 0x1A00000000000000L) == 0x1A00000000000000L) return 36; if ((x & 0x3800000000000000L) == 0x3800000000000000L) return 36; if ((x & 0x0010410000000000L) == 0x0010410000000000L) return 36; if ((x & 0x0008102000000000L) == 0x0008102000000000L) return 36; break; default: break; } #endregion #region Spalte 3 switch (p.height[2]) { case 0: if ((x & 0x0000000002C00000L) == 0x0000000002C00000L) return 2; if ((x & 0x0000000006800000L) == 0x0000000006800000L) return 2; if ((x & 0x000000000E000000L) == 0x000000000E000000L) return 2; if ((x & 0x0001010100000000L) == 0x0001010100000000L) return 2; break; case 1: if ((x & 0x0000000160000000L) == 0x0000000160000000L) return 9; if ((x & 0x0000000340000000L) == 0x0000000340000000L) return 9; if ((x & 0x0000000700000000L) == 0x0000000700000000L) return 9; if ((x & 0x0000082002000000L) == 0x0000082002000000L) return 9; if ((x & 0x0000808000800000L) == 0x0000808000800000L) return 9; if ((x & 0x0080808000000000L) == 0x0080808000000000L) return 9; break; case 2: if ((x & 0x000000B000000000L) == 0x000000B000000000L) return 16; if ((x & 0x000001A000000000L) == 0x000001A000000000L) return 16; if ((x & 0x0000038000000000L) == 0x0000038000000000L) return 16; if ((x & 0x0000400040400000L) == 0x0000400040400000L) return 16; if ((x & 0x0040400040000000L) == 0x0040400040000000L) return 16; if ((x & 0x4040400000000000L) == 0x4040400000000000L) return 16; if ((x & 0x0000100104000000L) == 0x0000100104000000L) return 16; if ((x & 0x0004100100000000L) == 0x0004100100000000L) return 16; break; case 3: if ((x & 0x0000580000000000L) == 0x0000580000000000L) return 23; if ((x & 0x0000D00000000000L) == 0x0000D00000000000L) return 23; if ((x & 0x0001C00000000000L) == 0x0001C00000000000L) return 23; if ((x & 0x0020002020000000L) == 0x0020002020000000L) return 23; if ((x & 0x2020002000000000L) == 0x2020002000000000L) return 23; if ((x & 0x0000008208000000L) == 0x0000008208000000L) return 23; if ((x & 0x0008008200000000L) == 0x0008008200000000L) return 23; if ((x & 0x0208008000000000L) == 0x0208008000000000L) return 23; if ((x & 0x0000004081000000L) == 0x0000004081000000L) return 23; break; case 4: if ((x & 0x002C000000000000L) == 0x002C000000000000L) return 30; if ((x & 0x0068000000000000L) == 0x0068000000000000L) return 30; if ((x & 0x00E0000000000000L) == 0x00E0000000000000L) return 30; if ((x & 0x0000410400000000L) == 0x0000410400000000L) return 30; if ((x & 0x0400410000000000L) == 0x0400410000000000L) return 30; if ((x & 0x1000101000000000L) == 0x1000101000000000L) return 30; if ((x & 0x0000204080000000L) == 0x0000204080000000L) return 30; break; case 5: if ((x & 0x1600000000000000L) == 0x1600000000000000L) return 37; if ((x & 0x3400000000000000L) == 0x3400000000000000L) return 37; if ((x & 0x7000000000000000L) == 0x7000000000000000L) return 37; if ((x & 0x0020820000000000L) == 0x0020820000000000L) return 37; if ((x & 0x0010204000000000L) == 0x0010204000000000L) return 37; break; default: break; } #endregion #region Spalte 4 switch (p.height[3]) { case 0: if ((x & 0x0000000001C00000L) == 0x0000000001C00000L) return 3; if ((x & 0x0000000005800000L) == 0x0000000005800000L) return 3; if ((x & 0x000000000D000000L) == 0x000000000D000000L) return 3; if ((x & 0x000000001C000000L) == 0x000000001C000000L) return 3; if ((x & 0x0000082080000000L) == 0x0000082080000000L) return 3; if ((x & 0x0002020200000000L) == 0x0002020200000000L) return 3; break; case 1: if ((x & 0x00000000E0000000L) == 0x00000000E0000000L) return 10; if ((x & 0x00000002C0000000L) == 0x00000002C0000000L) return 10; if ((x & 0x0000000680000000L) == 0x0000000680000000L) return 10; if ((x & 0x0000000E00000000L) == 0x0000000E00000000L) return 10; if ((x & 0x0000104004000000L) == 0x0000104004000000L) return 10; if ((x & 0x0004104000000000L) == 0x0004104000000000L) return 10; if ((x & 0x0001010001000000L) == 0x0001010001000000L) return 10; if ((x & 0x0101010000000000L) == 0x0101010000000000L) return 10; break; case 2: if ((x & 0x0000007000000000L) == 0x0000007000000000L) return 17; if ((x & 0x0000016000000000L) == 0x0000016000000000L) return 17; if ((x & 0x0000034000000000L) == 0x0000034000000000L) return 17; if ((x & 0x0000070000000000L) == 0x0000070000000000L) return 17; if ((x & 0x0000800080800000L) == 0x0000800080800000L) return 17; if ((x & 0x0080800080000000L) == 0x0080800080000000L) return 17; if ((x & 0x8080800000000000L) == 0x8080800000000000L) return 17; if ((x & 0x0000200208000000L) == 0x0000200208000000L) return 17; if ((x & 0x0008200200000000L) == 0x0008200200000000L) return 17; if ((x & 0x0208200000000000L) == 0x0208200000000000L) return 17; break; case 3: if ((x & 0x0000380000000000L) == 0x0000380000000000L) return 24; if ((x & 0x0000B00000000000L) == 0x0000B00000000000L) return 24; if ((x & 0x0001A00000000000L) == 0x0001A00000000000L) return 24; if ((x & 0x0003800000000000L) == 0x0003800000000000L) return 24; if ((x & 0x0000004040400000L) == 0x0000004040400000L) return 24; if ((x & 0x0040004040000000L) == 0x0040004040000000L) return 24; if ((x & 0x4040004000000000L) == 0x4040004000000000L) return 24; if ((x & 0x0000010410000000L) == 0x0000010410000000L) return 24; if ((x & 0x0010010400000000L) == 0x0010010400000000L) return 24; if ((x & 0x0410010000000000L) == 0x0410010000000000L) return 24; if ((x & 0x0000008102000000L) == 0x0000008102000000L) return 24; break; case 4: if ((x & 0x001C000000000000L) == 0x001C000000000000L) return 31; if ((x & 0x0058000000000000L) == 0x0058000000000000L) return 31; if ((x & 0x00D0000000000000L) == 0x00D0000000000000L) return 31; if ((x & 0x01C0000000000000L) == 0x01C0000000000000L) return 31; if ((x & 0x0000202020000000L) == 0x0000202020000000L) return 31; if ((x & 0x2000202000000000L) == 0x2000202000000000L) return 31; if ((x & 0x0000820800000000L) == 0x0000820800000000L) return 31; if ((x & 0x0800820000000000L) == 0x0800820000000000L) return 31; if ((x & 0x0000408100000000L) == 0x0000408100000000L) return 31; break; case 5: if ((x & 0x0E00000000000000L) == 0x0E00000000000000L) return 38; if ((x & 0x2C00000000000000L) == 0x2C00000000000000L) return 38; if ((x & 0x6800000000000000L) == 0x6800000000000000L) return 38; if ((x & 0xE000000000000000L) == 0xE000000000000000L) return 38; if ((x & 0x0010101000000000L) == 0x0010101000000000L) return 38; if ((x & 0x0041040000000000L) == 0x0041040000000000L) return 38; if ((x & 0x0020408000000000L) == 0x0020408000000000L) return 38; break; default: break; } #endregion #region Spalte 5 switch (p.height[4]) { case 0: if ((x & 0x0000000003800000L) == 0x0000000003800000L) return 4; if ((x & 0x000000000B000000L) == 0x000000000B000000L) return 4; if ((x & 0x000000001A000000L) == 0x000000001A000000L) return 4; if ((x & 0x0000104100000000L) == 0x0000104100000000L) return 4; break; case 1: if ((x & 0x00000001C0000000L) == 0x00000001C0000000L) return 11; if ((x & 0x0000000580000000L) == 0x0000000580000000L) return 11; if ((x & 0x0000000D00000000L) == 0x0000000D00000000L) return 11; if ((x & 0x0002020002000000L) == 0x0002020002000000L) return 11; if ((x & 0x0000208008000000L) == 0x0000208008000000L) return 11; if ((x & 0x0008208000000000L) == 0x0008208000000000L) return 11; break; case 2: if ((x & 0x000000E000000000L) == 0x000000E000000000L) return 18; if ((x & 0x000002C000000000L) == 0x000002C000000000L) return 18; if ((x & 0x0000068000000000L) == 0x0000068000000000L) return 18; if ((x & 0x0001000101000000L) == 0x0001000101000000L) return 18; if ((x & 0x0101000100000000L) == 0x0101000100000000L) return 18; if ((x & 0x0000400410000000L) == 0x0000400410000000L) return 18; if ((x & 0x0010400400000000L) == 0x0010400400000000L) return 18; if ((x & 0x0410400000000000L) == 0x0410400000000000L) return 18; break; case 3: if ((x & 0x0000700000000000L) == 0x0000700000000000L) return 25; if ((x & 0x0001600000000000L) == 0x0001600000000000L) return 25; if ((x & 0x0003400000000000L) == 0x0003400000000000L) return 25; if ((x & 0x0000008080800000L) == 0x0000008080800000L) return 25; if ((x & 0x0080008080000000L) == 0x0080008080000000L) return 25; if ((x & 0x8080008000000000L) == 0x8080008000000000L) return 25; if ((x & 0x0020020800000000L) == 0x0020020800000000L) return 25; if ((x & 0x0820020000000000L) == 0x0820020000000000L) return 25; if ((x & 0x0000010204000000L) == 0x0000010204000000L) return 25; break; case 4: if ((x & 0x0038000000000000L) == 0x0038000000000000L) return 32; if ((x & 0x00B0000000000000L) == 0x00B0000000000000L) return 32; if ((x & 0x01A0000000000000L) == 0x01A0000000000000L) return 32; if ((x & 0x0000404040000000L) == 0x0000404040000000L) return 32; if ((x & 0x4000404000000000L) == 0x4000404000000000L) return 32; if ((x & 0x1001040000000000L) == 0x1001040000000000L) return 32; if ((x & 0x0000810200000000L) == 0x0000810200000000L) return 32; break; case 5: if ((x & 0x1C00000000000000L) == 0x1C00000000000000L) return 39; if ((x & 0x5800000000000000L) == 0x5800000000000000L) return 39; if ((x & 0xD000000000000000L) == 0xD000000000000000L) return 39; if ((x & 0x0020202000000000L) == 0x0020202000000000L) return 39; if ((x & 0x0040810000000000L) == 0x0040810000000000L) return 39; break; default: break; } #endregion #region Spalte 6 switch (p.height[5]) { case 0: if ((x & 0x0000000007000000L) == 0x0000000007000000L) return 5; if ((x & 0x0000000016000000L) == 0x0000000016000000L) return 5; if ((x & 0x0000208200000000L) == 0x0000208200000000L) return 5; break; case 1: if ((x & 0x0000000380000000L) == 0x0000000380000000L) return 12; if ((x & 0x0000000B00000000L) == 0x0000000B00000000L) return 12; if ((x & 0x0000410010000000L) == 0x0000410010000000L) return 12; if ((x & 0x0010410000000000L) == 0x0010410000000000L) return 12; break; case 2: if ((x & 0x000001C000000000L) == 0x000001C000000000L) return 19; if ((x & 0x0000058000000000L) == 0x0000058000000000L) return 19; if ((x & 0x0002000202000000L) == 0x0002000202000000L) return 19; if ((x & 0x0020800800000000L) == 0x0020800800000000L) return 19; if ((x & 0x0820800000000000L) == 0x0820800000000000L) return 19; break; case 3: if ((x & 0x0000E00000000000L) == 0x0000E00000000000L) return 26; if ((x & 0x0002C00000000000L) == 0x0002C00000000000L) return 26; if ((x & 0x0000010101000000L) == 0x0000010101000000L) return 26; if ((x & 0x0100010100000000L) == 0x0100010100000000L) return 26; if ((x & 0x1040040000000000L) == 0x1040040000000000L) return 26; if ((x & 0x0000020408000000L) == 0x0000020408000000L) return 26; break; case 4: if ((x & 0x0070000000000000L) == 0x0070000000000000L) return 33; if ((x & 0x0160000000000000L) == 0x0160000000000000L) return 33; if ((x & 0x0000808080000000L) == 0x0000808080000000L) return 33; if ((x & 0x8000808000000000L) == 0x8000808000000000L) return 33; if ((x & 0x0001020400000000L) == 0x0001020400000000L) return 33; break; case 5: if ((x & 0x3800000000000000L) == 0x3800000000000000L) return 40; if ((x & 0xB000000000000000L) == 0xB000000000000000L) return 40; if ((x & 0x0040404000000000L) == 0x0040404000000000L) return 40; if ((x & 0x0081020000000000L) == 0x0081020000000000L) return 40; break; default: break; } #endregion #region Spalte 7 switch (p.height[6]) { case 0: if ((x & 0x000000000E000000L) == 0x000000000E000000L) return 6; if ((x & 0x0000410400000000L) == 0x0000410400000000L) return 6; break; case 1: if ((x & 0x0000000700000000L) == 0x0000000700000000L) return 13; if ((x & 0x0020820000000000L) == 0x0020820000000000L) return 13; break; case 2: if ((x & 0x0000038000000000L) == 0x0000038000000000L) return 20; if ((x & 0x1041000000000000L) == 0x1041000000000000L) return 20; break; case 3: if ((x & 0x0001C00000000000L) == 0x0001C00000000000L) return 27; if ((x & 0x0000020202000000L) == 0x0000020202000000L) return 27; if ((x & 0x0000040810000000L) == 0x0000040810000000L) return 27; break; case 4: if ((x & 0x00E0000000000000L) == 0x00E0000000000000L) return 34; if ((x & 0x0001010100000000L) == 0x0001010100000000L) return 34; if ((x & 0x0002040800000000L) == 0x0002040800000000L) return 34; break; case 5: if ((x & 0x7000000000000000L) == 0x7000000000000000L) return 41; if ((x & 0x0080808000000000L) == 0x0080808000000000L) return 41; if ((x & 0x0102040000000000L) == 0x0102040000000000L) return 41; break; default: break; } #endregion return -1; }
/// <summary> /// Start a new game /// </summary> /// <param name="mode"></param> public Connect4Game(GameSettings.GAMEMODE mode, int startingPlayer, GameSettings.DIFFICULTY difficulty, GameSettings settings) { startTime = DateTime.Now; RED_PLAYER = settings.RED_PLAYER; YELLOW_PLAYER = settings.YELLOW_PLAYER; COLUMNS = settings.COLUMNS; ROWS = settings.ROWS; this.aiStrength = difficulty; this.GameMode = mode; this.STARTING_PLAYER = startingPlayer; this.activePlayer = startingPlayer; map = new int[settings.COLUMNS, settings.ROWS]; switch (GameMode) { case (GameSettings.GAMEMODE.SinglePlayer): { position = new Position(); zuege = new MoveList(); comp = new ComputerPlayer(Position.WHITE, "Machine", true, difficulty); this.GameState = GameSettings.GAMESTATE.S_BeforeGame; break; } case (GameSettings.GAMEMODE.CPUvsCPU): { position = new Position(); zuege = new MoveList(); comp = new ComputerPlayer(Position.WHITE, "Machine1", true, difficulty); if (this.STARTING_PLAYER == RED_PLAYER) { this.GameState = GameSettings.GAMESTATE.S_WaitForCPU; this.HUMAN_PLAYER = RED_PLAYER; } else { this.GameState = GameSettings.GAMESTATE.S_WaitForCPU; this.HUMAN_PLAYER = YELLOW_PLAYER; } break; } case (GameSettings.GAMEMODE.LocalMultiPlayer): { position = new Position(); zuege = new MoveList(); this.GameState = GameSettings.GAMESTATE.S_BeforeGame; break; } case (GameSettings.GAMEMODE.NetworkGame): { position = new Position(); zuege = new MoveList(); /*string line = ""; using (StreamReader sr = new StreamReader("net.txt")) { string tmp; while ((tmp = sr.ReadLine()) != null) { line = tmp; } sr.Close(); } int port = Convert.ToInt32(line.Split(',')[0]); string ip = line.Split(',')[1]; if (Convert.ToInt32(line.Split(',')[2]) == 2) { netStartPlayer = 1; } else { netStartPlayer = 2; } NetGame = new Networking(port, ip);*/ this.GameState = GameSettings.GAMESTATE.S_WaitForConnection; break; } } }
// Free ressources public void Dispose() { position = null; comp = null; zuege = null; AIStarted = false; ClearGame(); }
/// <summary> /// Reset for a new game /// </summary> public void ClearGame() { for (int i = 0; i < COLUMNS; i++) { for (int j = 0; j < ROWS; j++) { Map[i,j] = 0; } } position = new Position(); turnCounter = 0; row = 0; turn = 0; won = 0; // Set the first player and the column the first stone is placed this.activePlayer = this.STARTING_PLAYER; this.SetNextPlayerStone(); }