///////////////// MINIMAX //////////////// private tNodo minimax(tNodo nodo, int jugador) { int max, max_actual, jugada, mejorJugada = 0; tNodo intento; max = -1000; for (jugada = 0; jugada < N; ++jugada) { if (esValida(nodo, jugada)) { intento = aplicaJugada(nodo, jugador, jugada); max_actual = valorMin(intento); if (max_actual > max) { max = max_actual; mejorJugada = jugada; } } } //Colocamos la pieza en el tablero de Unity int i = mejorJugada / PlaceObjectOnGrid.Squares.GetLength(0); int j = mejorJugada % PlaceObjectOnGrid.Squares.GetLength(0); GameObject cruz = Instantiate(Cruz); cruz.transform.position = PlaceObjectOnGrid.Squares[i, j].obj.transform.position + new Vector3(0, 0.2f, 0); //Reproducimos un sonido indicando el principio del turno //de nuevo sonidoCorrecto.Play(); return(aplicaJugada(nodo, jugador, mejorJugada)); }
private tNodo aplicaJugada(tNodo t, int jugador, int jugada) { tNodo resultado = t.clone(); resultado.celdas[jugada] = jugador; resultado.vacias--; return(resultado); }
///////////////// FUNCIONES PUBLICAS //////////////// /*Se realiza el juego del TicTacToe entre el usuario y la maquina*/ public async void TicTacToe() { int jugador; int ganador; gameEnd = false; botonColocada = false; retiradaPieza = false; juego = crearNodo(tablero_inicial); grid.CambiarTexto("La IA juega con X \nUsted con O"); if (primero == 1) { jugador = -1; //Humano (O) - Min } else { jugador = 1; //IA (X) - Max } ganador = terminal(juego); //EJECUCION DEL JUEGO while (!gameEnd && juego.vacias > 0 && ganador == 0) { if (jugador == 1) { juego = minimax(juego, jugador); } else { //Esperará a que se termine de ejecutar //la jugada del adversario await jugadaAdversario(juego); } ganador = terminal(juego); jugador = opuesto(jugador); } if (gameEnd) { ganador = -2; } //RESULTADOS DEL JUEGO switch (ganador) { case 1: grid.CambiarTexto("Gana la IA"); break; case -1: grid.CambiarTexto("Gana el HUMANO"); break; case 0: grid.CambiarTexto("Empate"); break; } }
public tNodo clone() { tNodo res = new tNodo(); res.vacias = vacias; for (int i = 0; i < N; ++i) { res.celdas[i] = celdas[i]; } return(res); }
///////////////// FUNCIONES CLAVE MINIMAX //////////////// private static tNodo crearNodo(int[] tablero) { tNodo resultado = new tNodo(); for (int i = 0; i < N; ++i) { resultado.celdas[i] = tablero[i]; if (tablero[i] == 0) { resultado.vacias++; } } return(resultado); }
private async Task <tNodo> jugadaAdversario(tNodo t) { pieza = Instantiate(Circulo); //Esperamos hasta que el usuario haya colocado la pieza while (!botonColocada && !gameEnd) { if (!retiradaPieza) { if (pieza.transform.position.y <= 1) { Destroy(pieza); pieza = Instantiate(Circulo); } } else { //Se elimina la pieza de Unity retirarPieza(); //Se crea de nuevo la de Unity pieza = Instantiate(Circulo); retiradaPieza = false; } await Task.Yield(); } ; if (!gameEnd) { botonColocada = false; //Una vez colocada, actualizamos los valores del //tablero de la IA int i = pieza.GetComponent <DetectCollision>().squareCell.i; int j = pieza.GetComponent <DetectCollision>().squareCell.j; int jugada = i * PlaceObjectOnGrid.Squares.GetLength(0) + j; juego = aplicaJugada(t, -1, jugada); } return(juego); }
private static int terminal(tNodo juego) { int i = 0; int res = 0; while (res == 0 && i < 8) { if (juego.celdas[opciones_victoria[i, 0]] != 0 && juego.celdas[opciones_victoria[i, 0]] == juego.celdas[opciones_victoria[i, 1]] && juego.celdas[opciones_victoria[i, 1]] == juego.celdas[opciones_victoria[i, 2]]) { res = juego.celdas[opciones_victoria[i, 2]]; } i++; } return(res); }
private int valorMax(tNodo nodo) { int valor_max, jugada, jugador = 1, ganador; ganador = terminal(nodo); if (ganador == 0 && nodo.vacias > 0) { valor_max = -1000; for (jugada = 0; jugada < N; jugada++) { if (esValida(nodo, jugada)) { valor_max = Math.Max(valor_max, valorMin(aplicaJugada(nodo, jugador, jugada))); } } ganador = valor_max; } return(ganador); }
private int valorMin(tNodo nodo) { int valor_min, jugada, jugador = -1, ganador; ganador = terminal(nodo); if (ganador == 0 && nodo.vacias > 0) { valor_min = +1000; for (jugada = 0; jugada < N; ++jugada) { if (esValida(nodo, jugada)) { valor_min = Math.Min(valor_min, valorMax(aplicaJugada(nodo, jugador, jugada))); } } ganador = valor_min; } return(ganador); }
private bool esValida(tNodo actual, int jugada) { return(jugada >= 0 && jugada <= 9 && actual.celdas[jugada] == 0); }