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


Tema destacado: Introducción a Git (Primera Parte)


  Mostrar Mensajes
Páginas: 1 2 [3] 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... 243
21  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.
22  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.
23  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?
24  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.
25  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. }
26  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

27  Programación / Programación General / Excel 2013 en un rango de celdas indicar en cual está el mínimo valor. en: 16 Agosto 2025, 15:28 pm
GPT me dijo:
=DIRECCION(FILA(D8)-1+COINCIDIR(MIN(D8:D22);D8:D22;0); COLUMNA(D8))
y funciona pero sólo entiendo lo que está en negrita, quisiera una alternativa o a ver si me lo pueden hacer entender.

(MIN(D8:D22):
haya el mínimo en ese rango de celdas.
(ll, el foro me cambia la palabra)

COINCIDIR(MIN(D8:D22);D8:D22;0):
Asumo que se lee como:
Buscar índice de (Valor; en el rango; coincidencia total)

¿ DIRECCION(qué fila; qué columna) ?

FILA(D8)-1:
No tengo mucha idea. Creo que le suma 7 al resultado de COINCIDIR, pero ahí dice -1, además pone una D no sé para qué.
Edit: Ya entendí esto, de D8 toma el 8, le resta 1, queda 7, y luego la fórmula dice +, así que ese 7 se suma...

Citar
Piensa en COINCIDIR como “posición dentro del rango”, no como “número de fila de la hoja”.

- Tu rango es D8:D22.
- COINCIDIR(MIN(D8:D22); D8:D22; 0) devuelve 1 si el mínimo está en D8, 2 si está en D9, 3 si está en D10, etc. Es una posición relativa al inicio del rango.

Para convertir esa posición en la fila real de la hoja, hay que “desplazarla” hasta la fila de inicio del rango.

- La fila real de D8 es 8.
- Si COINCIDIR devuelve 1 (está en la primera celda del rango), la fila real debe ser 8.
- Si devuelve 2 (segunda celda), la fila real debe ser 9.
- Si devuelve 3, la fila real debe ser 10, y así sucesivamente.

Fórmula del desplazamiento:
- FILA(D8) devuelve 8 (la fila donde empieza el rango).
- Si sumas la posición y restas 1: FILA(D8) + COINCIDIR(...) - 1
  - Caso posición 1: 8 + 1 - 1 = 8 → D8
  - Caso posición 2: 8 + 2 - 1 = 9 → D9
  - Caso posición 3: 8 + 3 - 1 = 10 → D10

Por eso verás escrito como:
- FILA(D8) - 1 + COINCIDIR(...)  (equivale a lo mismo que FILA(D8) + COINCIDIR(...) - 1)

Aplicado a tu fórmula completa (con punto y coma si tu Excel los usa):
- Dirección del mínimo:
  =DIRECCION(FILA(D8)+COINCIDIR(MIN(D8:D22);D8:D22;0)-1; COLUMNA(D8))

- Solo la fila del mínimo:
  =FILA(D8)+COINCIDIR(MIN(D8:D22);D8:D22;0)-1

Esto convierte la posición relativa (1, 2, 3, ...) en el número de fila real (8, 9, 10, ...).

COLUMNA(D8):
Idem. Si toma la columna del parámetro D8, sería más fácil simplemente poner D.

O sea, de D8 a D22 tengo unos datos, y en otra celda quiero que me diga en cual de esas celdas está el mínimo valor. No creo que sea tan complicado ¿GPT se lió?

Edit: Ya entendí más, pero hay como cosas innecesarias, que deberían ser más simples ¿se pueden simplificar?

Edit 2: Según probé se puede simplificar así:
=DIRECCION(7+COINCIDIR(MIN(D8:D22);D8:D22;0); COLUMNA(D8))
Faltaría la columna. Si siempre va a ser D...
28  Programación / Programación General / Re: ¿Por qué el meteoro no va a donde le digo? en: 14 Agosto 2025, 19:52 pm
La mira es a donde tiene que ir el meteoro cuando toque la nave de abajo. Cuando queda en una punta es como si estuvieses jugando al tenis y apuntando a la punta, es normal.

No importa aquí qué lugar de la nave de abajo toque el meteoro. Mover la nave no cambia la posición de la mira, es como un "charging", apretás A o S y en vez de que el tiro sea más fuerte debe ir más a la punta.

Una forma que se me ocurre para que lo puedas solucionar es hacer que la mira se mueva por las paredes hacia abajo al llegar al muro del lado izquierdo (lo mismo para el otro lado).
Tengo pensado hacer eso pero no veo que sea la solución al problema... Eso va a ser una 2nda etapa del charging, que vaya justo al centro y rebote, ya que es efectivo contra la IA. Así como está el juego es muy difícil hacerle un punto.

Citar
Esto es necesario ya que tal y como lo tienes ahora mismo, no estás calculando el rebote de la pelota en la pared. Este rebote altera en donde va a golpear la pelota en la parte superior tras el rebote contra la pared horizontal.
Creo que hay confusión, la trayectoria del tiro debe decidirse cuando toca la nave de abajo y por ahora no debe tocar las paredes. Hago un dibujo...

Cuando el meteoro toque la nave de abajo, debe rebotar siguiendo la línea verde, hacia la mira, sin tocar las paredes.
Si va a tardar 100 frames en recorrer la distanciaY, debe tardar 100 frames en recorrer la distanciaX. Ese es el razonamiento que hago y el cálculo que intento hacer, pero no sé qué pasa.


En tu ejemplo a veces choca en la pared, esa no es la idea, lo demás está bien, no sé cómo hiciste el cálculo...

Ignora la pared por ahora, se va a usar más adelante. Supón que es un juego de golf de cuando usas el palo que la pelota no sube, o sea, todo 2d, visto de arriba, y la mira el hoyo, y se quiere que la pelota vaya ahí.
Se determina una velocidad Y al azar:
MeteorYSpeed = -Math.random()*(2+Dificultad)-1;
¿y luego? Capaz que me falla el cálculo porque esa velocidad es negativa, luego veo.
29  Programación / Programación General / Elección al azar de punto de elipse o rectángulo. Misma probabilidad para cada punto. en: 14 Agosto 2025, 13:56 pm
Si elipse es muy complicado será rectángulo.

Quiero imitar una nube cambiando, más o menos. Circulos aparecerían detrás, crecerían y se achicarían hasta desaparecer. Hay un video que me gustó que más o menos hace eso pero no lo encuentro.

Entonces, tenemos una elipse de 200 de ancho y 100 de alto. Supongamos que está colocado en las coordenadas 0, 0. ¿Cómo los circulos podrían aparecer en cualquier parte del perímetro con igual probabilidad? No en el área.

Si es muy complicado, tenemos un rectángulo, digamos de la misma medida y lugar. Y misma pregunta.
Sobre este lo pensé y no supe. Puedo hacer que aparezca en el perímetro, pero con igual chance cada punto no sé.
30  Programación / Programación General / ¿Por qué el meteoro no va a donde le digo? en: 14 Agosto 2025, 12:13 pm
https://youtu.be/TmACx8Du3as

Cuando el meteoro se está acercando a la nave de abajo, si presiono A o S aparece una mira, que se va moviendo a la izquierda si apreté A y a la derecha si apreté S.
Cuando el meteoro toque la nave de abajo, debe ir hacia donde haya quedado la mira.

Pueden ver que a veces funciona, y a veces no, no sé por qué...

La pantalla es de 800 pixeles de ancho y 600 de largo. Las coordenadas avanzan a la derecha y abajo, así que arriba a la izquierda es 0, 0
y abajo a la derecha es 800, 600
El 1er número corresponde a X, el 2ndo a Y.

La mira es algo provisorio para mostrar la falla, no habrá mira en el juego.

Creo que el error está acá:
Código
  1. if (Meteor.hitTest(Player) && MeteorYSpeed>0) {
  2. // Determinar velocidad Y al azar:
  3. MeteorYSpeed = -Math.random()*(2+Dificultad)-1;
  4. // Distancia Y desde el meteoro hasta el punto hacia donde se lo apuntó:
  5. DistanciaY = Meteor._y-20.5;
  6. // Cuánto tardará el meteoro en recorrerla:
  7. TardanzaY = Math.ceil(DistanciaY/-MeteorYSpeed);
  8. // Distancia X desde el meteoro hasta el punto hacia donde se lo apuntó:
  9. DistanciaX = Meteor._x-400+Apuntando;
  10. // Determinar la velocidad X para que el meteoro llegue...
  11. // al punto X apuntado justo cuando llega al punto Y apuntado:
  12. MeteorXSpeed = DistanciaX/TardanzaY;

Código completo:
Código
  1. // Algo como esto if (MeteorYSpeed>0) { se está haciendo 2 veces,
  2. // pero evitarlo implicaría unir cosas del jugador y la IA?
  3. //
  4. fscommand ("fullscreen", "true");
  5. // Varía según diferencia de puntajes:
  6. Dificultad = 0;
  7. // Player:
  8. attachMovie("sShip", "Player", 1);
  9. setProperty ("Player", _x, 400);
  10. setProperty ("Player", _y, 579.5);
  11. PlayerSpeed = 3;
  12. PlayerScore = 0;
  13. // IA:
  14. attachMovie("sIA", "IA", 2);
  15. setProperty ("IA", _x, 400);
  16. setProperty ("IA", _y, 20.5);
  17. IASpeed = 3;
  18. IAScore = 0;
  19. // Meteor:
  20. attachMovie("sMeteor", "Meteor", 3);
  21. setProperty ("Meteor", _x, 400);
  22. setProperty ("Meteor", _y, 544.5);
  23. // Se define acá para que luego el programa considere que...
  24. // hubo contacto entre la nave del jugador y el meteoro:
  25. MeteorYSpeed = 1;
  26. // Para que la curvatura dependa de MeteorYSpeed
  27. // (1 es hacia arriba, -1 hacia abajo):
  28. MeteorYDirection = -1;
  29. // Valores del color más brillante del meteoro (F0D9C8):
  30. MaxRojo = 255;
  31. MaxVerde = 217;
  32. MaxAzul = 200;
  33. // /////////////////////////////////////////////
  34. // /////////////////// Ship ////////////////////
  35. // /////////////////////////////////////////////
  36. function ControlShip () {
  37. if (Key.isDown(39)) {
  38. // Derecha.
  39. // Para evitar que se vaya demasiado al extremo derecho:
  40. if (Player._x<722) {
  41. Player._x = Player._x+PlayerSpeed;
  42. } else {
  43. Player._x = 725;
  44. }
  45. } else if (Key.isDown(37)) {
  46. // Izquierda.
  47. // Para evitar que se vaya demasiado al extremo izquierdo:
  48. if (Player._x>78) {
  49. Player._x = Player._x-PlayerSpeed;
  50. } else {
  51. Player._x = 75;
  52. }
  53. }
  54. // Si el meteoro va hacia abajo:
  55. if (MeteorYSpeed>0) {
  56. // Si aún no se eligió hacia dónde rebotarlo:
  57. if (Apuntando == 0) {
  58. if (Key.isDown(65)) {
  59. Apuntando = -1;
  60. attachMovie("sMira", "Mira", 4);
  61. setProperty ("Mira", _x, 399);
  62. setProperty ("Mira", _y, 20.5);
  63. } else if (Key.isDown(83)) {
  64. Apuntando = 1;
  65. attachMovie("sMira", "Mira", 4);
  66. setProperty ("Mira", _x, 401);
  67. setProperty ("Mira", _y, 20.5);
  68. }
  69. } else if (Apuntando < 0) {
  70. Apuntando = Apuntando-3;
  71. if (Apuntando < -400) {
  72. Apuntando = -400;
  73. }
  74. setProperty ("Mira", _x, 400+Apuntando);
  75. } else {
  76. Apuntando = Apuntando+3;
  77. if (Apuntando > 400) {
  78. Apuntando = 400;
  79. }
  80. setProperty ("Mira", _x, 400+Apuntando);
  81. }
  82. }
  83. }
  84. // /////////////////////////////////////////////
  85. // ////////////////////  IA  ///////////////////
  86. // /////////////////////////////////////////////
  87. function IATurn () {
  88. // Si el meteoro va hacia arriba:
  89. if (MeteorYSpeed<0) {
  90. // La IA se moverá hacia él:
  91. Distancia = IA._x-Meteor._x;
  92. } else {
  93. // La IA irá hacia el centro:
  94. Distancia = IA._x-400;
  95. }
  96. if (Distancia < 0) {
  97. IA._x = IA._x+IASpeed;
  98. // Para evitar que se vaya demasiado a la derecha:
  99. if (IA._x > 725) {
  100. IA._x = 725;
  101. }
  102. } else if (Distancia > 0) {
  103. IA._x = IA._x-IASpeed;
  104. // Para evitar que se vaya demasiado a la izquierda:
  105. if (IA._x < 75) {
  106. IA._x = 75;
  107. }
  108. }
  109. }
  110. // /////////////////////////////////////////////
  111. // /////////////////  Meteor  //////////////////
  112. // /////////////////////////////////////////////
  113. function VariarMeteoro () {
  114. Diametro = 44;
  115. Radio = Diametro/2;
  116. // Insertarle imágenes:
  117. Imagen = 0;
  118. do {
  119. Imagen++;
  120. Name = "Imagen"+Imagen;
  121. Meteor.attachMovie("sCirculo", Name, Imagen);
  122. Name = "Meteor."+Name;
  123. // Para los tamaños y rotación:
  124. setProperty (Name, _xscale, 400*Math.random());
  125. setProperty (Name, _yscale, 400*Math.random());
  126. setProperty (Name, _rotation, 360*Math.random());
  127. // Para las posiciones:
  128. X = Math.random()*Diametro - Radio;
  129. setProperty (Name, _x, X);
  130. MaxY = Math.sqrt(Radio*Radio - X*X);
  131. Y = Math.random() * (MaxY*2) - MaxY;
  132. setProperty (Name, _y, Y);
  133. // Para los colores:
  134. ColorDeName = new Color(Name);
  135. Brillo = 0.2 + 0.8 * Math.random();
  136. Rojo = Math.round(MaxRojo * Brillo);
  137. Verde = Math.round(MaxVerde * Brillo);
  138. Azul = Math.round(MaxAzul * Brillo);
  139. ColorElegido = (Rojo << 16) | (Verde << 8) | Azul;
  140. ColorDeName.setRGB(ColorElegido);
  141. } while (Imagen < 1000);
  142. }
  143. VariarMeteoro ();
  144. function MeteorMoves () {
  145. MeteorXSpeed = MeteorXSpeed+MeteorRotation/1000*MeteorYDirection;
  146. MeteorRotation = MeteorRotation/1.01;
  147. Meteor._x = Meteor._x+MeteorXSpeed;
  148. Meteor._y = Meteor._y+MeteorYSpeed;
  149. Meteor._rotation = Meteor._rotation+MeteorRotation;
  150. // Choque con nave derecha:
  151. if (Meteor._x > 752.5) {
  152. MeteorXSpeed = -MeteorXSpeed;
  153. if (MeteorYSpeed > 0) {
  154. // Si va hacia abajo:
  155. MeteorYSpeed = Math.max (MeteorYSpeed, MeteorYSpeed-MeteorRotation/50);
  156. } else if (MeteorYSpeed < 0) {
  157. MeteorYSpeed = Math.min (MeteorYSpeed, MeteorYSpeed+MeteorRotation/50);
  158. }
  159. MeteorRotation = Math.random()*10*(2*random(2)-1);
  160. } else if (Meteor._x < 47.5) {
  161. // Choque con nave izquierda:
  162. MeteorXSpeed = -MeteorXSpeed;
  163. if (MeteorYSpeed > 0) {
  164. // Si va hacia abajo:
  165. MeteorYSpeed = Math.max (MeteorYSpeed, MeteorYSpeed+MeteorRotation/50);
  166. } else if (MeteorYSpeed < 0) {
  167. MeteorYSpeed = Math.min (MeteorYSpeed, MeteorYSpeed-MeteorRotation/50);
  168. }
  169. MeteorRotation = Math.random()*10*(2*random(2)-1);
  170. }
  171. if (Meteor.hitTest(Player) && MeteorYSpeed>0) {
  172. // Determinar velocidad Y al azar:
  173. MeteorYSpeed = -Math.random()*(2+Dificultad)-1;
  174. if (Apuntando < -400) {
  175. Apuntando = -400;
  176. } else if (Apuntando > 400) {
  177. Apuntando = 400;
  178. }
  179. // Distancia Y desde el meteoro hasta el punto hacia donde se lo apuntó:
  180. DistanciaY = Meteor._y-20.5;
  181. // Cuánto tardará el meteoro en recorrerla:
  182. TardanzaY = Math.ceil(DistanciaY/-MeteorYSpeed);
  183. // Distancia X desde el meteoro hasta el punto hacia donde se lo apuntó:
  184. DistanciaX = Meteor._x-400+Apuntando;
  185. // Determinar la velocidad X para que el meteoro llegue...
  186. // al punto X apuntado justo cuando llega al punto Y apuntado:
  187. MeteorXSpeed = DistanciaX/TardanzaY;
  188. MeteorRotation = 0;
  189. // MeteorRotation = Math.random()*(180+Dificultad)*(2*random(2)-1);
  190. MeteorYDirection = 1;
  191. trace("MeteorYSpeed: "+MeteorYSpeed);
  192. trace("Apuntando: "+Apuntando);
  193. trace("DistanciaY: "+DistanciaY);
  194. trace("TardanzaY: "+TardanzaY);
  195. trace("DistanciaX: "+DistanciaX);
  196. trace("MeteorXSpeed: "+MeteorXSpeed);
  197. removeMovieclip("Mira");
  198. } else if (Meteor.hitTest(IA) && MeteorYSpeed<0) {
  199. MeteorYSpeed = Math.random()*(2+Dificultad)+1;
  200. MeteorXSpeed = Math.random()*(3+Dificultad)*(2*random(2)-1);
  201. MeteorRotation = Math.random()*(180+Dificultad)*(2*random(2)-1);
  202. MeteorYDirection = -1;
  203. Apuntando = 0;
  204. } else if (Meteor._y<0) {
  205. setProperty ("Meteor", _x, 400);
  206. setProperty ("Meteor", _y, 55.5);
  207. PlayerScore++;
  208. Dificultad++;
  209. PlayerSpeed = PlayerSpeed+0.1;
  210. IASpeed = IASpeed+0.11;
  211. ShowScore();
  212. } else if (Meteor._y>600) {
  213. setProperty ("Meteor", _x, 400);
  214. setProperty ("Meteor", _y, 544.5);
  215. IAScore++;
  216. Dificultad--;
  217. PlayerSpeed = PlayerSpeed-0.1;
  218. IASpeed = IASpeed-0.11;
  219. ShowScore();
  220. }
  221. }
  222. //
  223. function ShowScore () {
  224. attachMovie("sPuntaje", "Mensaje", 4);
  225. setProperty ("Mensaje", _x, 400);
  226. setProperty ("Mensaje", _y, 300);
  227. setProperty ("Player", _x, 400);
  228. setProperty ("IA", _x, 400);
  229. gotoAndStop (3);
  230. }
  231. // stop ();
Páginas: 1 2 [3] 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... 243
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines