public override int playI(QuatroField field, InterfaceNotifier notifier) { GameCoords click; while (true) { click = notifier.getClick(); if (click == null) Thread.Sleep(100); else break; } return click.column; }
public override int playI(QuatroField field, InterfaceNotifier notifier) { int play = rdm.Next(9); //Change the talk every time the monkey plays int choice = rdm.Next(3); switch(choice) { case 0: talk = "YOU ARE GONNA LOOSE!!!"; break; case 1: talk = "MuuhaAHahaham Noob!"; break; case 2: talk = "You are so bad! You Lost IT!!"; break; } //Notify visuals the talk has changed NotifyChanged(); return play; }
int winNext(int player, QuatroField field) { int count = 1; int play = -1; for (int y = 0; y < 7; y++) { for (int x = 0; x < 9; x++) { // para todas as jogadas verificar todas as possibilidades if (field[y, x] == player) { // horizontal -> if (x < 6) { for (int i = 1; i < 4; i++) if (field[y, x + i] == player) count++; else play = x + i; // checkar gaps e.g: 1011 if (count == 3 && field.head(play) == y) return play; else count = 1; } // horizontal <- // NOTA: Gaps horizontais ja foram chekados em cima. if (x > 2) { for (int i = 1; i < 3; i++) if (field[y, x - i] == player) count++; if (count == 3 && field.head(x - 3) == y) return x - 3; else count = 1; } // vertical if (y < 4) { for (int i = 1; i < 3; i++) if (field[y + i, x] == player) count++; if (count == 3 && field.head(x) == y + 3) return x; else count = 1; } // diagonal declive 1 -> if (x < 6 && y < 4) { int line = -10; for (int i = 1; i < 4; i++) if (field[y + i, x + i] == player) count++; else { play = x + i; // checkar gaps line = y + i; } if (count == 3 && field.head(play) == line) return play; else count = 1; } // diagonal declive 1 <- // NOTA: Gaps diagonais com declive 1 ja foram chekados em cima. if (x > 2 && y > 2) { for (int i = 1; i < 3; i++) if (field[y - i, x - i] == player) count++; if (count == 3 && field.head(x - 3) == y - 3) return x - 3; else count = 1; } // diagonal declive -1 -> if (x < 6 && y > 2) { int line = -10; for (int i = 1; i < 4; i++) if (field[y - i, x + i] == player) count++; else { play = x + i; // checkar gaps line = y - i; } if (count == 3 && field.head(play) == line) return play; else count = 1; } // diagonal declive -1 <- // NOTA: Gaps diagonais com declive -1 ja foram chekados em cima. if (x > 2 && y < 4) { for (int i = 1; i < 3; i++) if (field[y + i, x - i] == player) count++; if (count == 3 && field.head(x - 3) == y + 3) return x - 3; else count = 1; } } } } return -1; }
List<int> possibleMoves(QuatroField field) { List<int> plays = new List<int>(); for (int i = 0; i < 9; i++) { if (field.canPlay(i)) { plays.Add(i); } } return plays; }
public int nCaminhos(int playerToPlay, int columnToPlay, int playerToScan, QuatroField field) { field.forcePlay(columnToPlay, playerToPlay); int countCaminhos = 0; int count = 1; int column = -1; for (int y = 0; y < 7; y++) { for (int x = 0; x < 9; x++) { // para todas as jogadas verificar todas as possibilidades if (field[y, x] == playerToScan) { // horizontal -> if (x < 6) { for (int i = 1; i < 4; i++) if (field[y, x + i] == playerToScan) count++; else column = x + i; // checkar gaps e.g: 1011 if (count == 3 && field.head(column) == y && field[y, x + 1] == playerToScan) countCaminhos++; else count = 1; } // horizontal <- // NOTA: Gaps horizontais ja foram chekados em cima. if (x > 2) { column = x - 3; for (int i = 1; i < 3; i++) if (field[y, x - i] == playerToScan) count++; if (count == 3 && field.head(column) == y && field[y, x - 1] == playerToScan) countCaminhos++; else count = 1; } // vertical if (y < 4) { for (int i = 1; i < 3; i++) if (field[y + i, x] == playerToScan) count++; if (count == 3 && field.head(x) == y + 3 && field[y + 1, x] == playerToScan) countCaminhos++; else count = 1; } // diagonal declive 1 -> if (x < 6 && y < 4) { int line = -10; for (int i = 1; i < 4; i++) if (field[y + i, x + i] == playerToScan) count++; else { column = x + i; // checkar gaps line = y + i; } if (count == 3 && field.head(column) == line) countCaminhos++; else count = 1; } // diagonal declive 1 <- // NOTA: Gaps diagonais com declive 1 ja foram chekados em cima. if (x > 2 && y > 2) { column = x - 3; for (int i = 1; i < 3; i++) if (field[y - i, x - i] == playerToScan) count++; if (count == 3 && field.head(column) == y - 3 && field[y - 1, x - 1] == playerToScan) countCaminhos++; else count = 1; } // diagonal declive -1 -> if (x < 6 && y > 2) { int line = -10; for (int i = 1; i < 4; i++) if (field[y - i, x + i] == playerToScan) count++; else { column = x + i; // checkar gaps line = y - i; } if (count == 3 && field.head(column) == line) countCaminhos++; else count = 1; } // diagonal declive -1 <- // NOTA: Gaps diagonais com declive -1 ja foram chekados em cima. if (x > 2 && y < 4) { column = x - 3; for (int i = 1; i < 3; i++) if (field[y + i, x - i] == playerToScan) count++; if (count == 3 && field.head(column) == y + 3 && field[y + 1, x - 1] == playerToScan) countCaminhos++; else count = 1; } } } } field.undo(); return countCaminhos; }
bool isSafe(int play, int player, QuatroField field) { int count = 1; int column = -1; int nextline = field.head(play) + 1; for (int y = 0; y < 7; y++) { for (int x = 0; x < 9; x++) { // para todas as jogadas verificar todas as possibilidades if (field[y, x] == player) { // horizontal -> if (x < 6) { for (int i = 1; i < 4; i++) if (field[y, x + i] == player) count++; else column = x + i; // checkar gaps e.g: 1011 if (count == 3 && y == nextline && column == play) return false; else count = 1; } // horizontal <- // NOTA: Gaps horizontais ja foram chekados em cima. if (x > 2) { column = x - 3; for (int i = 1; i < 3; i++) if (field[y, x - i] == player) count++; if (count == 3 && y == nextline && column == play) return false; else count = 1; } // diagonal declive 1 -> if (x < 6 && y < 4) { int line = -10; for (int i = 1; i < 4; i++) if (field[y + i, x + i] == player) count++; else { column = x + i; // checkar gaps line = y + i; } if (count == 3 && line == nextline && column == play) return false; else count = 1; } // diagonal declive 1 <- // NOTA: Gaps diagonais com declive 1 ja foram chekados em cima. if (x > 2 && y > 2) { column = x - 3; for (int i = 1; i < 3; i++) if (field[y - i, x - i] == player) count++; if (count == 3 && y-3 == nextline && column == play) return false; else count = 1; } // diagonal declive -1 -> if (x < 6 && y > 2) { int line = -10; for (int i = 1; i < 4; i++) if (field[y - i, x + i] == player) count++; else { column = x + i; // checkar gaps line = y - i; } if (count == 3 && line == nextline && column == play) return false; else count = 1; } // diagonal declive -1 <- // NOTA: Gaps diagonais com declive -1 ja foram chekados em cima. if (x > 2 && y < 4) { column = x - 3; for (int i = 1; i < 3; i++) if (field[y + i, x - i] == player) count++; if (count == 3 && y+3 == nextline && column == play) return false; else count = 1; } } } } return true; }
public List<int> triar(List<int> possibleMoves, int myNumber, int opNumber, QuatroField field) { List<int> opWin = new List<int>(); List<int> meTwoWays = new List<int>(); List<int> opTwoWays = new List<int>(); List<int> opOneWay = new List<int>(); List<int> meOneWay = new List<int>(); List<int> opCanStop = new List<int>(); List<int> safe = new List<int>(); for (int i = 0; i < possibleMoves.Count; i++) { // selection logic if (!isSafe(possibleMoves[i], opNumber, field)) opWin.Add(possibleMoves[i]); else if (nCaminhos(myNumber, possibleMoves[i], myNumber, field) > 1) meTwoWays.Add(possibleMoves[i]); else if (nCaminhos(opNumber, possibleMoves[i], opNumber, field) > 1) opTwoWays.Add(possibleMoves[i]); else if (!isSafe(possibleMoves[i], myNumber, field)) opCanStop.Add(possibleMoves[i]); else if (nCaminhos(myNumber, possibleMoves[i], myNumber, field) > 0) meOneWay.Add(possibleMoves[i]); else if (nCaminhos(opNumber, possibleMoves[i], opNumber, field) > 0) opOneWay.Add(possibleMoves[i]); else safe.Add(possibleMoves[i]); } talk = "meTwoWays -> " + string.Join(", ", meTwoWays) + "\nopTwoWays -> " + string.Join(", ", opTwoWays) + "\nmeOneWay -> " + string.Join(", ", meOneWay) + "\nopOneWay -> " + string.Join(", ", opOneWay) + "\nsafe -> " + string.Join(", ", safe) + "\nopCanStop -> " + string.Join(", ", opCanStop) + "\nopWin -> " + string.Join(", ", opWin) + "\n"; if (meTwoWays.Count > 0) { talk += "Vou fazer dois caminhos."; NotifyChanged(); return meTwoWays; } else if (opTwoWays.Count > 0) { talk += "Podias fazer dois caminhos!"; NotifyChanged(); return opTwoWays; } else if (meOneWay.Count > 0) { talk += "Vou fazer um caminho"; NotifyChanged(); return meOneWay; } else if (opOneWay.Count > 0) { talk += "Podias fazer um caminho"; NotifyChanged(); return opOneWay; } else if (safe.Count > 0) { talk += "Safe Monkey Move"; NotifyChanged(); return safe; } else if (opCanStop.Count > 0) { talk += "Podes impedir-me :c"; NotifyChanged(); return opCanStop; } else { talk += "Ganhas-te"; NotifyChanged(); return opWin; } }
public override int playI(QuatroField field, InterfaceNotifier notifier) { int play; int myNumber = field.PlayerTurn; int opNumber = myNumber == 1 ? 2 : 1; play = winNext(myNumber, field); if (play != -1) { talk = "Eu vou ganhar na coluna " + play; NotifyChanged(); return play; } play = winNext(opNumber, field); if (play != -1) { talk = "Tu ias ganhar na coluna " + play; NotifyChanged(); return play; } List<int> moves = triar(possibleMoves(field), myNumber, opNumber, field); return moves[rdm.Next(moves.Count)]; }
private float valor(QuatroField field, int profundidadeActual) { float media = 0; float[] plays = new float[9]; float[] valoresNoFimDoAdversario = new float[9]; float advMean; int advCount; int count = 0; bool victoriaAdversaria = false; //int ope = operations; //operations++; // --------------- caso limite de profundidade --------------- if (profundidadeActual >= profundidade) return valorDeFundo; // --------------- calcular vitoria imediata --------------- for (int i = 0; i < 9; i++) { if (field.canPlay(i)) { field.play(i); if (field.PlayerWon) { field.undo(); return 1; } else field.undo(); } } // --------------- calculo geral ------------------------------ for (int i = 0; i < 9; i++) { if (field.canPlay(i)) { victoriaAdversaria = false; count++; field.play(i); //advCount = 0; //advMean = 0f; // --------------- calcular os valores consoante as jogadas adversarias --------------- for (int j = 0; j < 9; j++) { if (field.canPlay(j)) { //advCount++; field.play(j); if (field.PlayerWon) { victoriaAdversaria = true; field.undo(); break; } field.undo(); } } if (!victoriaAdversaria) { for (int j = 0; j < 9; j++) { if (field.canPlay(j)) { field.play(j); valoresNoFimDoAdversario[j] = valor(field, profundidadeActual + 1); //advMean += valoresNoFimDoAdversario[j]; //System.out.println(ope); field.undo(); } } //media += min(valoresNoFimDoAdversario)*0.5f + advMean/advCount; plays[i] = min(valoresNoFimDoAdversario); } else { //media += 0; //o jogador adversario conseguiu ganhar, SUCKER!!! plays[i] = 0; } field.undo(); } else plays[i] = -1; } //media = media / count; //return media; return max(plays); }
private int search(QuatroField field) { player_ = field.PlayerTurn; float[] jogadasAdversarias = new float[9]; bool victoriaAdversaria = false; float valorMaximo = 0; float random = (float)rdm.NextDouble(); int numeroMaximos = 0; operations = 0; for (int k = 0; k < jogadas.Length; k++) { jogadas[k] = -1; } for (int i = 0; i < 9; i++) { if (field.canPlay(i)) { field.play(i); if (field.PlayerWon) { field.undo(); jogadas[i] = 1; return i; } else field.undo(); } } for (int i = 0; i < 9; i++) { victoriaAdversaria = false; if (field.canPlay(i)) { field.play(i); for (int j = 0; j < 9; j++) { if (field.canPlay(j)) { field.play(j); if (field.PlayerWon) { jogadas[i] = -1; victoriaAdversaria = true; field.undo(); break; } field.undo(); } } if (!victoriaAdversaria) { for (int j = 0; j < 9; j++) { if (field.canPlay(j)) { field.play(j); jogadasAdversarias[j] = valor(field, 1); field.undo(); } } jogadas[i] = min(jogadasAdversarias); } field.undo(); } } numeroMaximos = 1; valorMaximo = jogadas[0]; for (int i = 1; i < 9; i++) { if (jogadas[i] >= valorMaximo && field.canPlay(i)) { if (jogadas[i] == valorMaximo) { numeroMaximos++; } else { numeroMaximos = 1; valorMaximo = jogadas[i]; } } } random = (random * numeroMaximos) + 1; numeroMaximos = 1; for (int i = 0; i < 9; i++) { if (jogadas[i] == valorMaximo && field.canPlay(i)) { if ((int)(random) == numeroMaximos) { return i; } else { numeroMaximos++; } } } return 0; }
public override int playI(QuatroField field, InterfaceNotifier notifier) { playing = true; lock(valuesLock) { for (int i = 0; i < values.Length; i++) values[i] = -1; } NotifyChanged(); int bestPlay = search(field); playing = false; lock(valuesLock) { for (int i = 0; i < values.Length; i++) values[i] = jogadas[i]; } NotifyChanged(); return bestPlay; }
public override void EndGame(QuatroField field) { talk = "I WOOOONNNN!!!!"; NotifyChanged(); }
public override int playI(QuatroField field, InterfaceNotifier notifier) { return rdm.Next(9); }