elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: Guía actualizada para evitar que un ransomware ataque tu empresa


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... 251
101  Programación / Programación General / Re: Excel 2013 indicar celda "contigua" al 2ndo máximo valor, repetible. en: 26 Agosto 2025, 09:40 am
Mientras más automatizado mejor, hasta cierto punto, así que opto por la solución 2, no quiero ordenar la tabla cada vez que agregue datos, pero me diste una idea: ¿No se puede hacer un batch que busque los valores, o haga que Excel ordene esos valores de la tabla?
Doble clic es más fácil que seleccionar datos, hacer clic, esperar a que aparezca el menú...

No sabía eso de insertar una tabla en la tabla xD ¿seguro que no se ordenan automáticamente una vez lo indicas? En la imagen aparece una flechita hacia abajo.

No entiendo cómo funciona esto:
- La solución está en hacer una condición adicional para comprobar el orden de los apellidos dándoles valores igual que en el paso 1 pero sin sumarles el +1, y al final contar/sumar ambos números de orden para obtener un número de orden sin repeticiones

carlos | lópez | 2
maría | tórres | 3
carlos | flores | 1
Supongo que pones la fórmula más adelante.

Citar
- Su funcionamiento es sencillo, solo hay que despejar los valores repetidos y al resultante asignarle un número de orden, esta vez no sumaremos el +1 para que empiece en 0, al final se suma ese orden obtenido al número de orden del paso 1:
Idem...

Ya veo, pero ni idea cómo lo despejas.

No me funciona bien esto:
=CONTAR.SI($L$131:$L$137;">"&L132)+1

Decidí ampliar el rango, puse:
=CONTAR.SI($L$124:$L$137;">"&L125)+1

Pero supongo que no es el problema.

Te muestro:


La fila de Ataque tipo puñetazo es la 124.

Puse:
=CONTAR.SI($L$124:$L$137;">"&L125)+1
en la celda M124.
En la M125 la copié, quedó:
=CONTAR.SI($L$124:$L$137;">"&L126)+1
¿está bien que se cambie el 125?

Creo que había un error, cambié L125 por 124 y se arregló. Entiendo que la fórmula cuenta las veces que hay un valor mayor que el correspondiente a esa fila, no en la siguiente como estanba.

Ok.

¿Por qué se pone ">"&L124 en vez de >L124?

A ver, en el rango $L$124:$L$137 contar los valores si son >124. Luego sumar 1. No entiendo por qué las cosas raras...
CONTAR.SI(rango;condición para que se cuente)+1


Le pedí a GPT que explique la 2nda fórmula que pones:
(...)
CONTAR.SI.CONJUNTO($L$131:$L$137;L131;$B$131:$B$137;"<"&B131)
Aquí se manejan empates.
Cuenta cuántas filas tienen:
El mismo valor en L que L131 (empate en la métrica principal), y
Un valor en B estrictamente menor que B131.
Es decir, entre los empatados en L, cuenta cuántos “van antes” de L131 según un criterio secundario: B más pequeño.

No entiendo bien cómo es que hace eso...
CONTAR.SI.CONJUNTO(rango;valor;rango 2;condición a cumplir)
no lo capto...
La sintaxis de CONTAR.SI.CONJUNTO en español es:

CONTAR.SI.CONJUNTO(rango_criterios1; criterio1; [rango_criterios2; criterio2]; ...)

Cómo funciona:

rango_criterios1: el rango donde se evaluará el criterio1.
criterio1: la condición que deben cumplir las celdas de rango_criterios1 (puede ser un valor, una referencia, o una cadena con operadores como ">5", "<="&A1, etc.).
Puedes añadir más pares rango_criteriosN; criterioN. Excel solo contará la fila si TODAS las condiciones se cumplen simultáneamente (AND lógico, por filas).
No es “primero cuenta en el rango1 y luego en el rango2”. Más bien:

Recorre las filas en paralelo.
Para cada fila i, verifica: ¿la celda de rango_criterios1 cumple criterio1 Y la celda de rango_criterios2 cumple criterio2 Y ...?
Si sí, suma 1. Si no, no.

Aplicado a tu caso:
CONTAR.SI.CONJUNTO($L$131:$L$137; L131; $B$131:$B$137; "<"&B131)

rango_criterios1 = $L$131:$L$137
criterio1 = L131 (equivale a “igual a L131”)
rango_criterios2 = $B$131:$B$137
criterio2 = "<"&B131 (equivale a “estrictamente menor que B131”)
Cuenta cuántas filas, entre las 131–137, cumplen simultáneamente:

En la columna L: valor igual al de L131
Y en la columna B: valor menor que B131


Bien, pensé que CONJUNTO era como conjunto de datos, es más bien conjunto de condiciones que deben cumplirse.

Parece que funciona bien, pongo la tabla entera para descargar:
https://docs.google.com/spreadsheets/d/1xp_RAVCm3FwYSdTmqJWxRudvgQsqCrgQ/edit?usp=sharing&ouid=109273743447273895658&rtpof=true&sd=true

¿Podría ponerse que el 2ndo criterio en vez de orden alfabético sea órden de aparición? O sea, si está una fila antes, va antes.

Ahora no pero supongo que voy a leer más sobre fórmulas matriciales, por curiosidad.
102  Foros Generales / Foro Libre / Re: El okupa llamó a la Policía y nos echaron de nuestra casa por allanamiento de morada en: 24 Agosto 2025, 21:52 pm
Lo vi en varios videos de YT y no vi que en comentarios dijeran que es falso, salvo en un caso que decían que era en una ciudad y era en otra.
103  Programación / Programación General / Re: ¿Por qué el meteoro no va a donde le digo? en: 24 Agosto 2025, 06:02 am
Me lo dijeron:

Yo hacía:
DistanciaX = Meteor._x-400+Apuntando;

y lo correcto es:
DistanciaX = Apuntando+400-Meteor._x;

Solved  :D
104  Programación / Programación General / Excel 2013 indicar celda "contigua" al 2ndo máximo valor, repetible. en: 23 Agosto 2025, 03:50 am
Tengo unas celdas así:

y otras así:


Quiero que en las que puse 1ero aparezca, en una lo de fondo rojo que tenga mejor promedio, y en la otra lo de fondo rojo que tenga el 2ndo mejor promedio, pudiendo ser igual, o sea, el 2ndo máximo que encuentre.

Le dije a GPT el problema:
esto
=INDICE(B131:B138; COINCIDIR(MAX(L131:L138); L131:L138; 0))
y esto
=INDICE(B131:B138; COINCIDIR(K.ESIMO.MAYOR(L131:L138;2); L131:L138; 0))
me están dando el mismo resultado, no debería ¿qué pasa?

Vean que en la 1er imagen los resultados son los mismos, pero el 2ndo debería ser Patada agachado.

Citar
Hay dos escenarios típicos en los que ambas fórmulas pueden devolver lo mismo:

1) El 2.º mayor “con repetidos” es igual al máximo 
   - Si en L131:L138 hay al menos dos celdas con el valor máximo, entonces:
     - MAX(L131:L138) = 19 (por ejemplo)
     - K.ESIMO.MAYOR(L131:L138;2) también = 19
   - En ese caso, ambas COINCIDIR buscan 19 y, por diseño, COINCIDIR(...;0) devuelve la primera aparición del valor en el rango. Resultado: mismas filas, mismo INDICE.

2) Datos no numéricos/formato o espacios influyen en el cálculo 
   - Si hay textos que parecen números, errores, celdas vacías con espacios, etc., pueden afectar a K.ESIMO.MAYOR/ MAX o a COINCIDIR. Pero lo habitual es el caso 1.

Cómo obtener el “segundo mayor distinto” (sin repetir el máximo):
- Fórmula matricial en Excel 2013 (confirmar con Ctrl+Shift+Enter):
  =INDICE(B131:B138; COINCIDIR(MAX(SI(L131:L138<MAX(L131:L138); L131:L138)); L131:L138; 0))

- Alternativa separando el valor y luego buscando:
  1) En una celda auxiliar: =MAX(SI(L131:L138<MAX(L131:L138); L131:L138))  Confirmar con Ctrl+Shift+Enter.
  2) Luego: =INDICE(B131:B138; COINCIDIR(celda_aux; L131:L138; 0))

Si lo que quieres es “segundo con repetidos” pero devolver la segunda ocurrencia del mismo máximo, COINCIDIR por sí sola no devuelve la segunda coincidencia. Puedes usar una clave auxiliar (por ejemplo, agregar un pequeño ajuste por fila) o una fórmula que ubique la n‑ésima aparición. Por ejemplo, para devolver la fila de la 2.ª aparición del máximo:

- Fórmula matricial para la posición de la 2.ª coincidencia:
  =PESTAÑA(FILA(L131:L138)-MIN(FILA(L131:L138))+1; 2; SI(L131:L138=MAX(L131:L138); FILA(L131:L138)-MIN(FILA(L131:L138))+1))
  Luego úsala dentro de INDICE. Si prefieres, te la adapto completa a tu rango y separadores.

Creo que entiendo el problema "por diseño, COINCIDIR(...;0) devuelve la primera aparición del valor en el rango"
pero las soluciones me parecen bastante raras, aunque le pedí una más simple ¿se les ocurre?

Básicamente es:
- Buscar 2ndo máximo valor en un rango.
- Anotar en qué celda está.
- Restar columnas a esa posición.
105  Foros Generales / Foro Libre / Re: El okupa llamó a la Policía y nos echaron de nuestra casa por allanamiento de morada en: 23 Agosto 2025, 01:50 am
Pero nada tiene que ver con hackers....

Recientemente vi un video de una onlyfan que mató al novio. Parece que espiando los fiscales descubrieron que los padres de ella estaban intentando hackear la notebook o algo del asesinado para modificar los mensajes, pero como eso fue espionaje el juez no aprobó la prueba. En fin, es lo más parecido que se me viene a la mente a que hacer las cosas bien, sin hackear ni espiar, es recomendable, pero si los fiscales no hubieran espiado y el hackeo hubiera salido bien entonces la historia sería otra...

Por otro lado en YT hay un tío que postea videos donde supuestamente actúa como caza estafadores y se burla de ellos o similares. Yo no lo sé Rick...

Y por lo que tengo entendido hay muchos extrangeros ocupando ciudades enteras de Europa, así que está bravísimo el tema.
106  Programación / Programación General / Re: Ayuda en: 20 Agosto 2025, 18:10 pm
Más que un programador necesitas un hacker o experto en seguridad informática. Un programador es algo más general, como si dijeras médico general, no es experto en ojos, ni en pulmones, etc. Un programador, en general, tampoco es experto en averiguar direcciones de gente.
También podría ser un detective privado, él capaz que conoce a gente que sepa.

Pero dudo que te sirva de mucho conseguir su dirección...

Acude a la Policía Nacional o la Guardia Civil, si estás en España. O a la Policía de tu país.
Además, es gratis.
+1.
107  Foros Generales / Dudas Generales / ¿Cómo pedir a Youtube que no me recomiende un canal? en: 19 Agosto 2025, 16:00 pm
Estás viendo un video, quieres que no te aparezcan más de ese canal.

Si te aparecen en la lista de recomendados, puedes hacer clic en los 3 puntitos y poner la opción ahí.

¿Y si no te aparecen? ¿si sólo viste 1? No sé... Cuando te aparezcan de nuevo los bloqueas, tendrás que hacer una lista de los que quieres bloquear o memorizarlos, pero parece medio tedioso...

Otro método es que cuando vas a ver un video de un canal sospechosamente malo, lo abras en una nueva pestaña, así tienes en la otra el video en la lista y la opción de bloquearlo, pero esto tampoco está bueno, porque en mi caso se pone lento, y si pasa mucho tiempo la pestaña anterior se recarga, los recomendados cambian y ya no puedo bloquearlo. Además no todos los videos son sospechosamente malos, yo que sé, uno me dice "A sus 90 años, X revela lo que le pasó en..." y luego es el youtuber contando la biografía de esa persona, no habla la persona que crei que iba a hablar (parece) y tiene más relleno que Naruto, yo que iba a saber.

¿No se puede entrar al jodido canal y poner ahí no recomendarmelo? Que yo sepa no...

¿Habrá algún código que se le pueda enviar a YT? ¿algún javascript? ¿o sí hay una forma fácil de bloquear que no conozco?
108  Programación / Programación General / Re: ¿Error al convertir nùmero grande a binario? en: 19 Agosto 2025, 02:01 am
Flamer:
Hice lo que dijiste, puse
1111111011111110111111101111111011111110111111101111111000000000
y el resultado fue
18374403900871474688

pero al hacerlo aquí:
https://masterplc.com/calculadora/convertir-binario-a-decimal/
fue
18374403900871475000

Y GPT dijo
18,446,744,066,181,791,744

Yo no sé :xD


Ahora en un rato voy a hablar con él sobre el código que me dió porque no lo entendí. Luego actualizo.

Edit: Hablado hasta que me quedé sin puntos.

Resumen:
qué significa Saltar ceros líderes
Citar
Ignorar los 0s que están al inicio del binario

explica esto
  while (i < n && bin.charAt(i) == "0") { i++; }
  if (i >= n) return "0";

no sé si el while ha terminado, etc. Lo veo así:
while (i < n && bin.charAt(i) == "0") {
   i++;
}
if (i >= n) return "0";
y sigue ¿es así?

Citar

cambié los i por NroDeCaracteraMirar:
(código)
¿tengo que cambiar los siguientes i o son independientes? Este:
  for (; i < n; i++) {

Citar
Representan lo mismo, debes cambiarlos también

la variable n es el largo del binario, siempre?

Citar

var para qué es, qué diferencia hay entre definir una variable con var y sin var

Citar
En ActionScript (especialmente en Flash 5/ActionScript 1), var sirve para declarar variables con alcance local a la función o al clip donde se declaran. Si no usas var, la variable se crea de forma implícita en un ámbito más global, lo que puede provocar efectos secundarios.

Diferencias clave:

- Con var:
  - Crea una variable local al ámbito actual (normalmente la función).
  - Solo existe mientras se ejecuta esa función.
  - No “ensucia” el timeline/objeto global.
  - Mejor rendimiento y menos riesgos de colisiones de nombres.

- Sin var:
  - Crea o sobrescribe una propiedad en el objeto actual (this) o en el nivel global (_root en muchos casos).
  - Persiste después de terminar la función.
  - Puede pisar variables/propiedades existentes y causar bugs difíciles de rastrear.
  - En proyectos grandes, suele generar “fugas” de estado.

Buenas prácticas en Flash 5:
- Declara siempre tus variables con var dentro de funciones.
- Evita depender de variables implícitas globales.
- Usa nombres claros (como hiciste con LargoDelBinario) y mantén la consistencia.

No sabía o me había olvidado, a veces creaba variables y luego las eliminaba, de esta forma se eliminan solas.

cómo este if no tiene el { ?
  if (NroDeCaracteraMirar >= LargoDelBinario) return "0";
normalmente se pone
si (condición) {
   efecto

Citar
En muchos lenguajes (incluido ActionScript/javascript), si el if controla una sola sentencia, puedes omitir las llaves. Estas dos formas son equivalentes:

- Forma compacta en una sola línea:
  if (condicion) return "0";

- Forma “normal” con llaves:
  if (condicion) {
    return "0";
  }

- Forma sin llaves pero en varias líneas (no recomendada por claridad):
  if (condicion)
    return "0";

Recomendación:
- Usa llaves siempre, incluso para una única sentencia, por legibilidad y para evitar errores al agregar otra línea después. Por ejemplo, este cambio accidental introduce un bug si no hay llaves:

  if (condicion)
    hacerAlgo();
    hacerOtraCosa(); // se ejecutará siempre, no está dentro del if

Con llaves, eso no pasa.

¿es posible que NroDeCaracteraMirar quede mayor que LargoDelBinario?
  // Ignorar ceros al inicio del binario:
  var NroDeCaracteraMirar = 0;
  var LargoDelBinario = bin.length;
  // Para eso mira caracteres desde la izquierda hasta que no haya caracteres o hasta que no sea 0:
  while (NroDeCaracteraMirar < LargoDelBinario && bin.charAt(NroDeCaracteraMirar) == "0") {
    NroDeCaracteraMirar++;
  }
  if (NroDeCaracteraMirar >= LargoDelBinario) {
   return "0";
  }

el incremento de NroDeCaracteraMirar ocurre sólo si es menor que LargoDelBinario, por lo que en cierto punto quedará igual y luego ya no aumentará, por lo tanto NroDeCaracteraMirar nunca será mayor que LargoDelBinario ¿correcto?

Citar
Sí.

Código más claro (aún falta aclararlo más):
Código
  1. // Convierte un string binario (p.ej. "1101") a string decimal exacto (p.ej. "13")
  2. // No usa Number para representar el valor completo, solo dígitos individuales.
  3. function binToDecString(bin) {
  4.  // Ignorar ceros al inicio del binario:
  5.  var NroDeCaracteraMirar = 0;
  6.  var LargoDelBinario = bin.length;
  7.  // Para eso mira caracteres desde la izquierda hasta que no haya caracteres o hasta que no sea 0:
  8.  while (NroDeCaracteraMirar < LargoDelBinario && bin.charAt(NroDeCaracteraMirar) == "0") {
  9.    NroDeCaracteraMirar++;
  10.  }
  11.  // Si miró todos los caracteres:
  12.  if (NroDeCaracteraMirar == LargoDelBinario) {
  13. return "0";
  14.  }
  15.  
  16.  // digits almacena el número decimal en dígitos base 10, LSB primero (digits[0] es las unidades)
  17.  var digits = [0];
  18.  
  19.  // Recorremos desde el primer '1' encontrado
  20.  for (; NroDeCaracteraMirar < LargoDelBinario; NroDeCaracteraMirar++) {
  21.    var c = bin.charAt(NroDeCaracteraMirar);
  22.    if (c != "0" && c != "1") {
  23.      continue; // o maneja error si prefieres
  24.    }
  25.  
  26.    // decimal *= 2
  27.    var carry = 0;
  28.    var j;
  29.    for (j = 0; j < digits.length; j++) {
  30.      var x = digits[j] * 2 + carry;
  31.      digits[j] = x % 10;
  32.      carry = Math.floor(x / 10);
  33.    }
  34.    while (carry > 0) {
  35.      digits[digits.length] = carry % 10;
  36.      carry = Math.floor(carry / 10);
  37.    }
  38.  
  39.    // decimal += bit
  40.    if (c == "1") {
  41.      var k = 0;
  42.      var add = 1;
  43.      while (add > 0) {
  44.        if (k >= digits.length) digits[digits.length] = 0;
  45.        var y = digits[k] + add;
  46.        digits[k] = y % 10;
  47.        add = Math.floor(y / 10);
  48.        k++;
  49.      }
  50.    }
  51.  }
  52.  
  53.  // Construir string (invertir los dígitos)
  54.  var s = "";
  55.  for (var t = digits.length - 1; t >= 0; t--) {
  56.    s += digits[t];
  57.  }
  58.  return s;
  59. }

EdePC te respondo otro día porque por hoy este tema me cansó/aburrió, pero a simple vista, sí, voy a tener que poner que el programa opere así, pero eso es un problema a resolver más adelante.
109  Programación / Programación General / Posible aporte: Código para jugar bien Signos en línea, aún no probado. en: 18 Agosto 2025, 04:17 am
Se refiere al 3 en raya pero con la configuración que se ponga: En vez de 3 puede ser otro número y en vez de un tablero de 3*3 puede ser otro número independiente del anterior. Lo pensé para tableros cuadrados, pero quizá funcione para rectangulares. De momento está configurado para revisar sólo rayas horizontales, pero basta quitar un par de rayas // para que revise todas las posibilidades, es sólo que para pruebas me pareció mejor así.
Aún no lo probé, acabo de terminarlo, llevo bastante tiempo con esto... Disfrútenlo, analícenlo si quieren a ver qué tal:
Código
  1. // Signos en línea en tableros cuadrados:
  2. // Este programa tiene básicamente 3 etapas,
  3. // que se pueden resumir así:
  4. // Nota: La situación inicial, en que hay 0 signos colocados,
  5. // estará guardada en la lista nro 0.      
  6. // 1:
  7. // Probar acciones en cada situación de la lista nro 0,
  8. // guardando en una nueva lista las nuevas situaciones (que no...
  9. // sean victoria ni empate). Repetir con cada nueva lista hasta...
  10. // la que tenga situaciones en que sólo 1 acción es posible
  11. // (por ejemplo en el 3 en línea es la 8).
  12. // 2:
  13. // Probar acciones en cada situación de la última lista,
  14. // guardando datos sobre las consecuencias (victoria o empate)
  15. // de realizar la única acción posible.
  16. // 3:
  17. // En las situaciones no resueltas, empezando por las...
  18. // penúltimas listas, probar las acciones.
  19. // Guardar cuántas acciones causan victoria de uno, de otro y...
  20. // de empate. Averiguar la mejor acción en cada situación,
  21. // basado en el mejor resultado seguro que causa (asumiendo...
  22. // que el rival juega bien), y en 2nda instancia el más probable
  23. // (asumiendo que el rival juegue al azar).
  24. // Repetir hasta resolver la lista 0.
  25. JuntosRequeridos = 2;
  26. CasillerosPorFila = 2;
  27. // Contando desde 0:
  28. MaxColumna = CasillerosPorFila-1;
  29. Casilleros = CasillerosPorFila*CasillerosPorFila;
  30. // Están numerados así:
  31. // 0 1
  32. // 2 3
  33. MaxCasillero = Casilleros-1;
  34. // En las listas L_SaE se irán poniendo las situaciones a...
  35. // experimentar que tengan _ signos colocados.
  36. // En la lista 0 se agregará una situación:
  37. L0SaE1 = [];
  38. // A continuación se especifica cual, agregando v
  39. // (que significa vacío) en lo que serían los casilleros,
  40. // los elementos del array:
  41. ValoraAgregar = -1;
  42. do {
  43. ValoraAgregar++;
  44. L0SaE1.push("v");
  45. } while (ValoraAgregar < MaxCasillero);
  46. delete ValoraAgregar;
  47. // Los datos de las situaciones no están en las listas,
  48. // se crean aparte. Con esta variable se evita repetidamente...
  49. // convertir en texto y concatenar:
  50. S_ = "S"+(L0SaE1.join(""));
  51. // Datos de la situación:
  52. // Usada para fácilmente saber de qué signo es turno:
  53. set (S_+"Turno", "X");
  54. // En otros casos usada para evitar probar acciones...
  55. // innecesarias y con LastAPosible para saber si sólo queda 1:
  56. set (S_+"FirstAPosible", 0);
  57. set (S_+"LastAPosible", MaxCasillero);
  58. NroDeListaRevisandose = -1;
  59. // Última lista que se revisará en la etapa 1:
  60. // LastListaDeEt1 = Casilleros;
  61. // /////////////////////////////////////////////
  62. // /////////////////  Etapa 1  /////////////////
  63. // /////////////////////////////////////////////
  64. // Consiste en llegar a nuevas situaciones y guardarlas,
  65. // si no son victoria. Termina antes de que pueda haber empates.
  66. //
  67. // Usada a continuación y durante la etapa 1 (Et1)...
  68. // cuando no hay más situaciones en la lista revisándose:
  69. function BuscarOtraListaEt1 () {
  70. trace("Ejecutando BuscarOtraListaEt1");
  71. NroDeListaRevisandose++;
  72. PrepararUsoDeLista();
  73. PrepararSaE();
  74. // Si las situaciones de la lista tienen más de 1 opción:
  75. if (NroDeListaRevisandose < MaxCasillero) {
  76. // Para evitar concatenar cosas al guardar datos de situaciones nuevas:
  77. NextL_SaE = "L"+(NroDeListaRevisandose+1)+"SaE";
  78. trace("NextL_SaE: "+NextL_SaE);
  79. // Usado en EvaluarConocimientoSobreSEt1 para...
  80. // nombrar las situaciones nuevas que se logren:
  81. SituacionesNuevas = 0;
  82. } else {
  83. trace( "La lista actual tiene situaciones de sólo 1 opción; inicia la etapa 2.");
  84. // Iniciar Etapa 2:
  85. gotoAndStop(3);
  86. }
  87. }
  88. BuscarOtraListaEt1();
  89. // Usada cuando se cambia de lista, en BuscarOtraListaEt1,
  90. // al comenzar Et2 y en Et3:
  91. function PrepararUsoDeLista () {
  92. trace("Ejecutando PrepararUsoDeLista");
  93. // Para evitar concatenar repetidamente:
  94. L_SaE = "L"+NroDeListaRevisandose+"SaE";
  95. trace("L_SaE: "+L_SaE);
  96. NroDeSExperimentandose = 1;
  97. // También para evitar concatenar repetidamente:
  98. // L_SaE_ = L_SaE+NroDeSExperimentandose;
  99. L_SaE_ = L_SaE+"1";
  100. trace("L_SaE_: "+L_SaE_);
  101. trace("Comienzan experimentos en una nueva lista, la "+NroDeListaRevisandose);
  102. }
  103. // Usada cuando se elige una SaE, en BuscarOtraListaEt1,
  104. // BuscarOtraSituacionEt1, BuscarOtraSituacionEt2 y PrepararSaEEt3:
  105. function PrepararSaE () {
  106. trace("Ejecutando PrepararSaE");
  107. trace("Se inician experimentos en otra situación de la lista, la nro "+NroDeSExperimentandose);
  108. SituacionBase = eval(L_SaE_).slice();
  109. S_ = "S"+(SituacionBase.join(""));
  110. Turno = eval(S_+"Turno");
  111. FirstActionPosible = eval(S_+"FirstAPosible");
  112. LastActionPosible = eval(S_+"LastAPosible");
  113. Action = FirstActionPosible;
  114. }
  115. // Usada en frame 2 (o etapa 1) repetidamente:
  116. function ResetearSituacionEt1 () {
  117. // Plantear situación porque puede modificarse pero...
  118. // podría requerirse su estado original luego:
  119. Situacion = SituacionBase.slice();
  120. trace("La situación experimentándose es "+Situacion);
  121. EvaluarAplicabilidadEt1();
  122. }
  123. // Usada luego de que cambia la SaE y/o la acción, en Et1:
  124. function EvaluarAplicabilidadEt1 () {
  125. trace("Ejecutando EvaluarAplicabilidadEt1");
  126. if (Situacion[Action] == "v") {
  127. trace("La acción "+Action+" es realizable.");
  128. AplicarAccionEt1();
  129. } else {
  130. trace("La acción "+Action+" no es realizable.");
  131. SinResetBuscarOtraAccionEt1();
  132. }
  133. }
  134. // Usada luego de EvaluarAplicabilidadEt1,
  135. // si una acción es realizable:
  136. function AplicarAccionEt1 () {
  137. trace("Ejecutando AplicarAccionEt1");
  138. Situacion[Action] = Turno;
  139. trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  140. // ¿Ganó?
  141. // Si no se detecta victoria vertical,
  142. // revisa de otros modos (ver las funciones Chequear):
  143. ChequearVertical();
  144. if (Win == "No") {
  145. EvaluarConocimientoSobreSEt1();
  146. }
  147. // ¿Queda alguna acción sin probar en la situación?
  148. BuscarOtraAccionEt1();
  149. }
  150. // Usada en EvaluarAplicabilidadEt1 cuando una acción no es...
  151. // realizable:
  152. function SinResetBuscarOtraAccionEt1 () {
  153. trace("Ejecutando SinResetBuscarOtraAccionEt1");
  154. if (Action < LastActionPosible) {
  155. // Si queda alguna acción sin probar...
  156. // en la situación, probarla:
  157. Action++;
  158. EvaluarAplicabilidadEt1();
  159. } else {
  160. trace("No hay más acciones realizables.");
  161. BuscarOtraSituacionEt1();
  162. }
  163. }
  164. // Usada luego de AplicarAccionEt1:
  165. function BuscarOtraAccionEt1 () {
  166. trace("Ejecutando BuscarOtraAccionEt1");
  167. if (Action < LastActionPosible) {
  168. // Si queda alguna acción sin probar...
  169. // en la situación, probarla:
  170. Action++;
  171. // Se ejecutará ResetearSituacionEt1.
  172. } else {
  173. trace("No hay más acciones realizables.");
  174. BuscarOtraSituacionEt1();
  175. }
  176. }
  177. // Usada en AplicarAccionEt1 cuando no hay victoria (ni empate,
  178. // aunque por ahora no ocurren):
  179. function EvaluarConocimientoSobreSEt1 () {
  180. trace("Ejecutando EvaluarConocimientoSobreSEt1");
  181. // Estas 3 variables son para evitar reconcatenar:
  182. SituacionJoined = Situacion.join("");
  183. NewS_ = "S"+SituacionJoined;
  184. NewS_BestAction = NewS_+"BestAction";
  185. // ¿Se ha llegado antes a la situación?
  186. if (eval(NewS_BestAction) == undefined) {
  187. // No, anotar que debe investigarse:
  188. SituacionesNuevas++;
  189. // Copiar array (porque no se puede normalmente):
  190. trace("Situación a copiar a "+NextL_SaE+SituacionesNuevas+" es "+Situacion);
  191. set (NextL_SaE+SituacionesNuevas, Situacion.slice());
  192. trace("Esa situación no está anotada; se anota como nro "+SituacionesNuevas);
  193. set(NewS_BestAction, "Desconocida");
  194. if (Turno == "X") {
  195. set (NewS_+"Turno", "0");
  196. } else {
  197. set (NewS_+"Turno", "X");
  198. }
  199. // Averiguar cual es su 1er acción posible:
  200. AccionRevisandose = -1;
  201. do {
  202. AccionRevisandose++;
  203. if (Situacion[AccionRevisandose] == "v") {
  204. set (NewS_+"FirstAPosible", AccionRevisandose);
  205. break;
  206. }
  207. } while (true);
  208. // Averiguar cual es su última acción posible:
  209. AccionRevisandose = Casilleros;
  210. do {
  211. AccionRevisandose--;
  212. if (Situacion[AccionRevisandose] == "v") {
  213. set (NewS_+"LastAPosible", AccionRevisandose);
  214. break;
  215. }
  216. } while (true);
  217. }
  218. }
  219. // Usada en BuscarOtraAccionEt1 cuando no hay más acciones posibles,
  220. // y en SinResetBuscarOtraAccionEt1:
  221. function BuscarOtraSituacionEt1 () {
  222. trace("Ejecutando BuscarOtraSituacionEt1");
  223. NroDeSExperimentandose++;
  224. if (eval(L_SaE+NroDeSExperimentandose) != undefined) {
  225. // Hay otra situación en la lista,
  226. // prepararse a usarla:
  227. L_SaE_ = L_SaE+NroDeSExperimentandose;
  228. PrepararSaE();
  229. } else {
  230. trace("No hay más situaciones a experimentar en la lista actual, se mirará otra.");
  231. BuscarOtraListaEt1();
  232. }
  233. }
  234. // /////////////////////////////////////////////
  235. // /////////////////  Etapa 2  /////////////////
  236. // /////////////////////////////////////////////
  237. // Consiste en guardar el resultado de las situaciones en que...
  238. // sólo 1 acción es posible. Puede ser victoria o empate.
  239. //
  240. // Usada en frame 3 (o etapa 2) repetidamente:
  241. function ResetearSituacionEt2 () {
  242. // Plantear situación porque puede modificarse pero...
  243. // podría requerirse su estado original luego:
  244. Situacion = SituacionBase.slice();
  245. trace("La situación experimentándose es "+Situacion);
  246. AplicarAccionEt2();
  247. }
  248. // Usada luego de ResetearSituacionEt2, parece innecesario que sea función:
  249. function AplicarAccionEt2 () {
  250. trace("Ejecutando AplicarAccionEt2");
  251. Situacion[Action] = Turno;
  252. trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  253. // ¿Ganó?
  254. // Si no se detecta victoria vertical,
  255. // revisa de otros modos (ver las funciones Chequear):
  256. ChequearVertical();
  257. set(S_+"BestAction", Action);
  258. if (Win == "Sí") {
  259. trace("Victoria conseguida, guardando datos.");
  260. if (Turno == "X") {
  261. // Estas son las chances de que gane...
  262. // X, 0 o que haya empate:
  263. set(S_+"VictoriasDeX", 1);
  264. set(S_+"VictoriasDe0", 0);
  265. set(S_+"ResultadoEsperado", "X");
  266. } else {
  267. set(S_+"VictoriasDeX", 0);
  268. set(S_+"VictoriasDe0", 1);
  269. set(S_+"ResultadoEsperado", "0");
  270. }
  271. set(S_+"DistanciaaGanar", 1);
  272. set(S_+"Empates", 0);
  273. } else {
  274. trace("Empate conseguido, guardando datos.");
  275. set(S_+"VictoriasDeX", 0);
  276. set(S_+"VictoriasDe0", 0);
  277. set(S_+"Empates", 1);
  278. set(S_+"ResultadoEsperado", "E");
  279. }
  280. // ¿Queda alguna situación en la lista experimentándose?
  281. BuscarOtraSituacionEt2();
  282. }
  283. // Usada luego de AplicarAccionEt2, parece innecesario que sea función:
  284. function BuscarOtraSituacionEt2 () {
  285. trace("Ejecutando BuscarOtraSituacionEt2");
  286. NroDeSExperimentandose++;
  287. if (eval(L_SaE+NroDeSExperimentandose) != undefined) {
  288. // Hay otra situación en la lista,
  289. // prepararse a usarla:
  290. L_SaE_ = L_SaE+NroDeSExperimentandose;
  291. PrepararSaE();
  292. } else {
  293. trace("No hay más situaciones a experimentar en la lista actual, inicia la etapa 3.");
  294. BuscarOtraListaEt3();
  295. gotoAndStop(4);
  296. }
  297. }
  298. // /////////////////////////////////////////////
  299. // /////////////////  Etapa 3  /////////////////
  300. // /////////////////////////////////////////////
  301. // Consiste en guardar los resultados de las acciones en...
  302. // situaciones en que más de 1 acción es posible.
  303. // Particularmente se guarda la mejor acción.
  304. // El resultado de las acciones puede ser victoria,
  305. // una situación con posibles resultados,
  306. // y en la penúltima lista una situación con un único posible...
  307. // resultado.
  308. //
  309. // Usada antes y durante esta etapa...
  310. // cuando no hay más situaciones en la lista revisándose:
  311. function BuscarOtraListaEt3 () {
  312. trace("Ejecutando BuscarOtraListaEt3");
  313. NroDeListaRevisandose--;
  314. if (NroDeListaRevisandose > -1) {
  315. // Si se halla una lista:
  316. PrepararUsoDeLista();
  317. PrepararSaEEt3();
  318. } else {
  319. trace("No hay más listas a revisar; programa terminado.");
  320. // En este frame nada hay, es sólo para mostrar el mensaje:
  321. gotoAndStop(5);
  322. }
  323. }
  324. // Casi como PrepararSaE. Usada cuando se elige una SaE,
  325. // en BuscarOtraListaEt3 y BuscarOtraSituacionEt3:
  326. function PrepararSaEEt3 () {
  327. trace("Ejecutando PrepararSaEEt3");
  328. PrepararSaE();
  329. // Para evitar evals y concatenaciones repetidamente:
  330. BestAction = "";
  331. VictoriasDeX = 0;
  332. VictoriasDe0 = 0;
  333. Empates = 0;
  334. // Establecer que hasta ahora los resultados hallados...
  335. // son peores que lo posible, para que se sustituyan por...
  336. // cualquier acción:
  337. if (Turno == "X") {
  338. // La E antes de Obtenido es Esperado:
  339. BestResultadoEObtenido = "0";
  340. } else {
  341. BestResultadoEObtenido = "X";
  342. }
  343. // Si 2 acciones causan victoria segura,
  344. // esto sirve para elegir la mejor de ellas:
  345. BestDistanciaaGanar = Casilleros;
  346. // Si 2 acciones causan empate seguro,
  347. // esto sirve para elegir la mejor de ellas:
  348. BestChanceDeGanarEnE = -1;
  349. BestChanceDeEmpatarEnE = -1;
  350. // Si 2 acciones causan derrota segura,
  351. // esto sirve para elegir la mejor de ellas:
  352. LowestChanceDePerderEnD = -1;
  353. BestChanceDeGanarEnD = -1;
  354. }
  355. // Usada en frame 4 (o etapa 3) repetidamente:
  356. function ResetearSituacionEt3 () {
  357. // Plantear situación porque puede modificarse pero...
  358. // podría requerirse su estado original luego:
  359. Situacion = SituacionBase.slice();
  360. trace("La situación experimentándose es "+Situacion);
  361. EvaluarAplicabilidadEt3();
  362. }
  363. // Usada luego de que cambia la SaE y/o la acción, en Et3:
  364. function EvaluarAplicabilidadEt3 () {
  365. trace("Ejecutando EvaluarAplicabilidadEt3");
  366. if (Situacion[Action] == "v") {
  367. trace("La acción "+Action+" es realizable.");
  368. AplicarAccionEt3();
  369. } else {
  370. trace("La acción "+Action+" no es realizable.");
  371. SinResetBuscarOtraAccionEt3();
  372. }
  373. }
  374. // Usada luego de EvaluarAplicabilidadEt3,
  375. // si una acción es realizable:
  376. function AplicarAccionEt3 () {
  377. // Los datos se guardarán bien en GuardarDatosEt3.
  378. // Por ahora varios se están guardando en variables más simples de nombrar.
  379. // Además algunos no se pueden guardar aún (VictoriasDeX, NewVictoriasDe0...).
  380. // Y DistanciaaGanar se está guardando como -1 de lo que debe, para no tener que estar sumando.
  381. trace("Ejecutando AplicarAccionEt3");
  382. Situacion[Action] = Turno;
  383. trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  384. // ¿Ganó?
  385. // Si no se detecta victoria vertical,
  386. // revisa de otros modos (ver las funciones Chequear):
  387. ChequearVertical();
  388. if (Win == "No") {
  389. // Agregar los posibles resultados de la...
  390. // situación obtenida:
  391. // Estas 5 variables son para evitar reconcatenar:
  392. SituacionJoined = Situacion.join("");
  393. NewS_ = "S"+SituacionJoined;
  394. NewVictoriasDeX = eval(NewS_+"VictoriasDeX");
  395. NewVictoriasDe0 = eval(NewS_+"VictoriasDe0");
  396. NewEmpates = eval(NewS_+"Empates");
  397. VictoriasDeX = VictoriasDeX+NewVictoriasDeX;
  398. VictoriasDe0 = VictoriasDe0+NewVictoriasDe0;
  399. Empates = Empates+NewEmpates;
  400. // Si en la SaE ya se halló una acción que...
  401. // causa victoria segura:
  402. if (BestResultadoEObtenido == Turn) {
  403. // Si la acción recién usada también causa eso:
  404. if (eval(NewS_+"ResultadoEsperado") == Turn) {
  405. // Si dicha acción la causa faster:
  406. if (eval(NewS_+"DistanciaaGanar") < BestDistanciaaGanar) {
  407. // Sustituir datos:
  408. BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
  409. BestAction = Action;
  410. }
  411. // SINO SI LA CAUSA IGUAL DE RÁPIDO HABRÍA QUE AVERIGUAR CHANCES, pero se gana igual...
  412. // sino dicha acción es peor, no prestarle más atención.
  413. }
  414. // idem.
  415. // sino si el mejor resultado esperado hallado...
  416. // en esta SaE es empate:
  417. } else if (BestResultadoEObtenido == "E") {
  418. // Si la acción recién usada causa que...
  419. // el resultado esperado sea victoria:
  420. if (eval(NewS_+"ResultadoEsperado") == Turn) {
  421. // Sustituir datos:
  422. BestResultadoEObtenido = Turn;
  423. BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
  424. BestAction = Action;
  425. // sino si es empate:
  426. } else if (eval(NewS_+"ResultadoEsperado") == "E") {
  427. // Averiguar chance de victoria:
  428. Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
  429. ChanceDeGanar = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  430. // Si es mejor que la hallada antes:
  431. if (ChanceDeGanar > BestChanceDeGanarEnE) {
  432. // Sustituir datos:
  433. BestChanceDeGanarEnE = ChanceDeGanar;
  434. BestChanceDeEmpatarEnE = NewEmpates*100/Posibilidades;
  435. BestAction = Action;
  436. // sino si la chance es igual:
  437. } else if (ChanceDeGanar == BestChanceDeGanarEnE) {
  438. // Averiguar chance de empate:
  439. ChanceDeEmpatar = NewEmpates*100/Posibilidades;
  440. // Si es mejor que la hallada antes:
  441. if (ChanceDeEmpatar > BestChanceDeEmpatarEnE) {
  442. // Sustituir datos:
  443. BestChanceDeGanarEnE = ChanceDeGanar;
  444. BestChanceDeEmpatarEnE = ChanceDeEmpatar;
  445. BestAction = Action;
  446. }
  447. }
  448. // SINO SI LAS CHANCES SON LAS MISMAS HABRÍA QUE DECIDIR SI SE PREFIERE LA QUE LO CAUSA MÁS RÁPIDO O NO.
  449. // sino dicha acción no es mejor, no prestarle más atención.
  450. // idem.
  451. }
  452. // El resultado esperado es derrota:
  453. } else {
  454. // Si la acción recién usada causa que...
  455. // el resultado esperado sea victoria:
  456. if (eval(NewS_+"ResultadoEsperado") == Turn) {
  457. // Sustituir datos:
  458. BestResultadoEObtenido = Turn;
  459. BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
  460. BestAction = Action;
  461. // sino si es empate:
  462. } else if (eval(NewS_+"ResultadoEsperado") == "E") {
  463. // Averiguar chances y sustituir datos:
  464. Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
  465. BestChanceDeGanarEnE = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  466. BestChanceDeEmpatarEnE = NewEmpatesDeX*100/Posibilidades;
  467. BestResultadoEObtenido = "E";
  468. BestAction = Action;
  469. // sino es derrota:
  470. } else {
  471. // Averiguar chance de perder:
  472. Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
  473. ChanceDePerder = (Posibilidades-eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  474. // Si es más baja (mejor) que la hallada antes:
  475. if (ChanceDePerder < LowestChanceDePerderEnD) {
  476. // Sustituir datos:
  477. LowestChanceDePerderEnD = ChanceDePerder;
  478. BestChanceDeGanarEnD = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  479. BestAction = Action;
  480. // sino si la chance es igual:
  481. } else if (ChanceDePerder == LowestChanceDePerderEnD) {
  482. // Averiguar chance de victoria:
  483. ChanceDeGanar = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  484. // Si es mejor que la hallada antes:
  485. if (ChanceDeGanar > BestChanceDeGanarEnD) {
  486. // Sustituir datos:
  487. LowestChanceDePerderEnD = ChanceDePerder;
  488. BestChanceDeGanarEnD = ChanceDeGanar;
  489. BestAction = Action;
  490. }
  491. }
  492. }
  493. }
  494. // sino la acción causa una victoria inmediata:
  495. } else {
  496. // Incrementar victorias:
  497. // Esta es para evitar reconcatenar:
  498. VariableaIncrementar = "VictoriasDe"+Turno;
  499. set (VariableaIncrementar, eval(VariableaIncrementar)+1);
  500. if (BestDistanciaaGanar > 0) {
  501. // Sustituir datos:
  502. BestResultadoEObtenido = Turn;
  503. BestDistanciaaGanar = 0;
  504. BestAction = Action;
  505. }
  506. }
  507. // ¿Queda alguna acción sin probar en la situación?
  508. BuscarOtraAccionEt3();
  509. }
  510. // Usada en EvaluarAplicabilidadEt3 cuando una acción no es...
  511. // realizable:
  512. function SinResetBuscarOtraAccionEt3 () {
  513. trace("Ejecutando SinResetBuscarOtraAccionEt3");
  514. if (Action < LastActionPosible) {
  515. // Si queda alguna acción sin probar...
  516. // en la situación, probarla:
  517. Action++;
  518. EvaluarAplicabilidadEt3();
  519. } else {
  520. trace("No hay más acciones realizables.");
  521. BuscarOtraSituacionEt3();
  522. }
  523. }
  524. // Usada luego de AplicarAccionEt3:
  525. function BuscarOtraAccionEt3 () {
  526. trace("Ejecutando BuscarOtraAccionEt3");
  527. if (Action < LastActionPosible) {
  528. // Si queda alguna acción sin probar...
  529. // en la situación, probarla:
  530. Action++;
  531. // Se ejecutará ResetearSituacionEt3.
  532. } else {
  533. trace("No hay más acciones realizables.");
  534. BuscarOtraSituacionEt3();
  535. }
  536. }
  537. // Usada cuando no hay más acciones posibles:
  538. function GuardarDatosEt3 () {
  539. trace("Ejecutando GuardarDatosEt3");
  540. set(S_+"VictoriasDeX", VictoriasDeX);
  541. set(S_+"VictoriasDe0", VictoriasDe0);
  542. set(S_+"Empates", Empates);
  543. set(S_+"BestAction", BestAction);
  544. set(S_+"DistanciaaGanar", BestDistanciaaGanar+1);
  545. set(S_+"ResultadoEsperado", BestResultadoEObtenido);
  546. }
  547. // Usada en BuscarOtraAccionEt3 cuando no hay más acciones posibles,
  548. // y en SinResetBuscarOtraAccionEt3:
  549. function BuscarOtraSituacionEt3 () {
  550. trace("Ejecutando BuscarOtraSituacionEt3");
  551. NroDeSExperimentandose++;
  552. if (eval(L_SaE+NroDeSExperimentandose) != undefined) {
  553. // Hay otra situación en la lista,
  554. // prepararse a usarla:
  555. L_SaE_ = L_SaE+NroDeSExperimentandose;
  556. PrepararSaEEt3();
  557. } else {
  558. trace("No hay más situaciones a experimentar en la lista actual, se mirará otra.");
  559. BuscarOtraListaEt3();
  560. }
  561. }
  562. // /////////////////////////////////////////////
  563. // /////////////////  Chequeos  ////////////////
  564. // /////////////////////////////////////////////
  565. // Usada en ChequeoHorizontal y requerida en otros casos:
  566. function ObtenerColumnayFilaDelMarcado () {
  567. FilaDelMarcado = Math.floor(Action/CasillerosPorFila);
  568. ColumnaDelMarcado = Action%CasillerosPorFila;
  569. }
  570. function ChequearVertical () {
  571. // trace ("Ejecutando ChequearVertical");
  572. //
  573. // SOLO FUNCIONA SI CasillerosPorFila >= JuntosRequeridos.
  574. //
  575. // Se revisará la vertical. Desde el casillero más arriba...
  576. // que pueda estar incluído en la línea,
  577. // hasta el casillero marcado. Si se halla alguno que no...
  578. // tenga la marca requerida, se repite el proceso mirando...
  579. // desde uno más abajo del fallado, y mirando ahora hasta...
  580. // más abajo, según corresponda:
  581. Desde = Action-CasillerosPorFila*(JuntosRequeridos-1);
  582. // Mientras el casillero no exista:
  583. while (Desde<0) {
  584. // trace ("Desde es "+Desde+", se aumentará");
  585. // Indicar que se empiece a mirar desde más abajo:
  586. Desde = Desde+CasillerosPorFila;
  587. }
  588. do {
  589. Hasta = Desde+CasillerosPorFila*(JuntosRequeridos-1);
  590. if (Hasta>MaxCasillero) {
  591. // Para ganar se necesitaría más casilleros hacia...
  592. // abajo de los que hay, terminar análisis:
  593. // trace ("No hay suficientes cuadraditos abajo");
  594. break;
  595. }
  596. Puntero = Desde;
  597. // trace ("Comenzando chequeo desde "+Desde+" hasta "+Hasta);
  598. // Puede cambiar:
  599. Win = "Sí";
  600. do {
  601. // trace ("Chequando el casillero "+Puntero);
  602. if (Situacion[Action] != Situacion[Puntero]) {
  603. Win = "No";
  604. Desde = Puntero+CasillerosPorFila;
  605. break;
  606. }
  607. Puntero = Puntero+CasillerosPorFila;
  608. } while (Puntero<=Hasta);
  609. } while (Desde<=Action && Win == "No");
  610. if (Win == "No") {
  611. // ChequearHorizontal();
  612. }
  613. }
  614. function ChequearHorizontal () {
  615. // trace ("Ejecutando ChequearHorizontal");
  616. // Es similar al chequeo vertical, pero aquí no sirve...
  617. // sumar o restar a un puntero que marque el casillero...
  618. // porque puede existir ese casillero pero no estar en...
  619. // un costado. En vez de eso, se obtiene su columna y...
  620. // fila, se modifica la columna si es posible,
  621. // y se calcula cual es el casillero a mirar:
  622. ObtenerColumnayFilaDelMarcado();
  623. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  624. // Para que no mire cuadraditos inexistentes en la izq:
  625. if (DesdeColumna<0) {
  626. DesdeColumna = 0;
  627. }
  628. do {
  629. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  630. if (HastaColumna>MaxColumna) {
  631. // Para ganar se necesitaría más casilleros hacia...
  632. // la derecha de los que hay, terminar análisis:
  633. // trace ("No hay suficientes cuadraditos a la derecha");
  634. break;
  635. }
  636. Puntero = DesdeColumna;
  637. // trace ("Comenzando chequeo desde "+DesdeColumna+" hasta "+HastaColumna);
  638. // Puede cambiar:
  639. Win = "Sí";
  640. do {
  641. CasilleroaMirar = FilaDelMarcado*CasillerosPorFila+Puntero;
  642. // trace ("Chequando el casillero "+CasilleroaMirar);
  643. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  644. Win = "No";
  645. DesdeColumna = Puntero+1;
  646. break;
  647. }
  648. Puntero++;
  649. } while (Puntero<=HastaColumna);
  650. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  651. if (Win == "No") {
  652. ChequearDesdeUpIzq();
  653. }
  654. }
  655. // La diagonal así \
  656. function ChequearDesdeUpIzq () {
  657. // trace ("Ejecutando ChequearDesdeUpIzq");
  658. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  659. // trace("DesdeColumna: "+DesdeColumna);
  660. DesdeFila = FilaDelMarcado-JuntosRequeridos+1;
  661. // trace("DesdeFila: "+DesdeFila);
  662. // Para que no mire cuadraditos inexistentes:
  663. if (DesdeColumna<DesdeFila) {
  664. Sumar = DesdeColumna;
  665. } else {
  666. Sumar = DesdeFila;
  667. }
  668. // trace("Sumar: "+Sumar);
  669. if (Sumar<0) {
  670. // trace("Sumando.");
  671. DesdeColumna = DesdeColumna-Sumar;
  672. // trace("DesdeColumna: "+DesdeColumna);
  673. DesdeFila = DesdeFila-Sumar;
  674. // trace("DesdeFila: "+DesdeFila);
  675. }
  676. do {
  677. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  678. if (HastaColumna>MaxColumna) {
  679. // Para ganar se necesitaría más casilleros hacia...
  680. // la derecha de los que hay, terminar análisis:
  681. // trace ("No hay suficientes cuadraditos a la derecha");
  682. break;
  683. }
  684. HastaFila = DesdeFila+JuntosRequeridos-1;
  685. // Sirve usar MaxColumna en vez de crear MaxFila...
  686. // porque como el tablero es cuadrado serían iguales:
  687. if (HastaFila>MaxColumna) {
  688. // Para ganar se necesitaría más casilleros hacia...
  689. // abajo de los que hay, terminar análisis:
  690. // trace ("No hay suficientes cuadraditos abajo");
  691. break;
  692. }
  693. PunteroDeColumna = DesdeColumna;
  694. PunteroDeFila = DesdeFila;
  695. // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila);
  696. // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila);
  697. // Puede cambiar:
  698. Win = "Sí";
  699. do {
  700. CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna;
  701. // trace ("Chequando el casillero "+CasilleroaMirar);
  702. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  703. Win = "No";
  704. DesdeColumna = PunteroDeColumna+1;
  705. DesdeFila = PunteroDeFila+1;
  706. break;
  707. }
  708. PunteroDeColumna++;
  709. PunteroDeFila++;
  710. } while (PunteroDeColumna<=HastaColumna);
  711. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  712. if (Win == "No") {
  713. ChequearDesdeDownIzq();
  714. }
  715. }
  716. // La diagonal así /
  717. function ChequearDesdeDownIzq () {
  718. // trace ("Ejecutando ChequearDesdeDownIzq");
  719. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  720. // trace("DesdeColumna: "+DesdeColumna);
  721. DesdeFila = FilaDelMarcado+JuntosRequeridos-1;
  722. // trace("DesdeFila: "+DesdeFila);
  723. // Para que no mire cuadraditos inexistentes:
  724. ColumnasInexistentes = 0;
  725. if (DesdeColumna<0) {
  726. ColumnasInexistentes = DesdeColumna*-1;
  727. }
  728. FilasInexistentes = 0;
  729. // Está bien usar MaxColumna porque MaxFila sería igual:
  730. if (DesdeFila>MaxColumna) {
  731. FilasInexistentes = DesdeFila-MaxColumna;
  732. }
  733. if (ColumnasInexistentes>=FilasInexistentes) {
  734. Ajuste = ColumnasInexistentes;
  735. } else {
  736. Ajuste = FilasInexistentes;
  737. }
  738. // trace("Ajuste: "+Ajuste);
  739. if (Ajuste>0) {
  740. // trace("Ajustando.");
  741. DesdeColumna = DesdeColumna+Ajuste;
  742. // trace("DesdeColumna: "+DesdeColumna);
  743. DesdeFila = DesdeFila-Ajuste;
  744. // trace("DesdeFila: "+DesdeFila);
  745. }
  746. do {
  747. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  748. if (HastaColumna>MaxColumna) {
  749. // Para ganar se necesitaría más casilleros hacia...
  750. // la derecha de los que hay, terminar análisis:
  751. // trace ("No hay suficientes cuadraditos a la derecha");
  752. break;
  753. }
  754. HastaFila = DesdeFila-JuntosRequeridos+1;
  755. if (HastaFila<0) {
  756. // Para ganar se necesitaría más casilleros hacia...
  757. // arriba de los que hay, terminar análisis:
  758. // trace ("No hay suficientes cuadraditos arriba");
  759. break;
  760. }
  761. PunteroDeColumna = DesdeColumna;
  762. PunteroDeFila = DesdeFila;
  763. // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila);
  764. // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila);
  765. // Puede cambiar:
  766. Win = "Sí";
  767. do {
  768. CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna;
  769. // trace ("Chequando el casillero "+CasilleroaMirar);
  770. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  771. Win = "No";
  772. DesdeColumna = PunteroDeColumna+1;
  773. DesdeFila = PunteroDeFila-1;
  774. break;
  775. }
  776. PunteroDeColumna++;
  777. PunteroDeFila--;
  778. } while (PunteroDeColumna<=HastaColumna);
  779. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  780. // trace("Win: "+Win);
  781. }
110  Foros Generales / Sugerencias y dudas sobre el Foro / El foro cambia haya (con ll) por haya. en: 16 Agosto 2025, 15:35 pm
El 1ero se usa como sinónimo de "encuentra".

El 2ndo es como un pasado de haber.

https://www.rae.es/duda-linguistica/es-haya-o-haya

Hasta el nombre del link se cambia  :o

Páginas: 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... 251
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines