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


Tema destacado: Estamos en la red social de Mastodon


  Mostrar Mensajes
Páginas: 1 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [33] 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 ... 273
321  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. }
322  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

323  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...
324  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.
325  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é.
326  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 ();
327  Media / Juegos y Consolas / Ayuda para hacer experimentos eficientemente en videojuegos. en: 13 Agosto 2025, 06:42 am
Kung Fu Master de NES es sencillo, ya lo pasé hace mucho, e hice experimentos recientemente, pero quiero hacerlos mejor. Elijo ese juego porque es sencillo y suficientemente bueno.
https://www.youtube.com/watch?v=e7PIr6hpaBY

La idea es empezar también por un experimento sencillo, por ejemplo sólo usar puñetazos normales (no agachado ni saltando). Supongamos que así vencí a 0 jefes. Tengo que anotar datos sobre el resultado:
Usar 1 ataque: 0
Ataque tipo puñetazo: 0
Ataque tipo normal: 0
Puñetazo: 0

El siguiente experimento debe ser lo más distinto posible a ese pero sin complicarme demasiado: 2 ataques, preferentemente que no sean tipo puñetazo, ni normal, y claro que no sean puñetazo.  Por ejemplo patada agachado y patada saltando sin avanzar. Luego pongo los resultados de eso.

Poco a poco se complica comprender cual es el siguiente experimento que conviene hacer, pero mi pregunta es ¿cómo se recomienda que sea la tabla de Excel para anotar los datos o cómo los anotarían? Ciertos datos deben llenarse automáticamente cuando se pone algo en ciertas celdas.

Para empezar pienso en algo así:

Ahí nada se está llenando automáticamente, parece innecesario, es poca cosa.

Luego pienso en algo así:

No sé si tiene sentido tanto dato, creo que es para en el futuro ir viendo qué combinaciones no volver a probar aún, o cuales probar preferentemente, la cosa es que siendo así, ya varios datos se tendrían que llenar automáticamente y probablemente ajustar la tabla para eso o para que quede mejor. Además, si algo tiene puntaje en varias columnas, veo 2 opciones:
A- Crear otra columna que haga un promedio.
B- Que en cada columna se use el nuevo puntaje para promediarlo con el anterior. Creo que esto hace que los últimos puntajes tengan más influencia, no es bueno.

Se va a complicar aún más. El tema es cómo automatizar que se llenen los datos. Lo de las combinaciones lo estoy hablando con GPT.

Pensé en algo así:

Los datos se llenarían así:
Usar 1 ataque: Si en Ataques dice 1, se pone el contenido de Puntaje.
2 ataques: Si en Ataques dice 2, contenido de Puntaje.
Ataque tipo puñetazo: Se busca eso (Ataque tipo puñetazo) en el rango de datos de la columna (hasta donde dice Tipo 2 de Ataque 2). Si se encuentra alguna vez, se pone el Puntaje.
Y así sucesivamente, se busca lo que marca la celda en la fila, y si se encuentra se pone el puntaje.
Entonces llegamos a:
2 ataques   Ataque tipo patada:
Si en Ataques dice 2 y se encuentra "Ataque tipo patada" en el rango de datos, se pone el puntaje.
Más adelante llegamos a:
Ataque tipo patada   Ataque tipo agachado:
Desde ahí se me complica porque lo que se preguntaría es ¿en el experimento se hicieron ataques tipo patada y además otro ataque tipo agachado? Y se se pondría el puntaje si la respuesta es sí, pero no es cuestión de buscar y si aparecen ambas palabras ya está, porque si por ejemplo hubo patadas agachado y puñetazos normales no es que hubo ataques tipo patadas y otro tipo agachado, sino que 1 ataque cumple ambas condiciones, no es lo mismo...
Dicho de otro modo, si es un juego de cartas Pokemon y pongo:
Carta tipo Pokemon   Carta tipo Pokemon tipo planta
lo que se pregunta es ¿hubo una carta Pokemon y otra Pokemon tipo planta? Si hubo un Pokemon tipo planta, eso cumple una condición u otra, no ambas a la vez, para que se cumplan ambas debe haber uno de esos y otro cualquiera.
¿Cómo puedo poner los datos y fórmulas para que se llenen automáticamente la mayoría de datos teniendo en cuenta eso?
328  Programación / Programación General / Re: ¿Error al convertir nùmero grande a binario? en: 12 Agosto 2025, 03:38 am
No sé qué alternativas tengo.

Consigo en binario la cantidad de dibujos que se van a mostrar en pantalla. DIBUJOS.

Esa cantidad la necesito dividir entre el número de cuadros (o minipantallas), que está en decimal. CUADROS.
Salvo que pudiera hallar alguna regla, que luego comento.

Así que debo convertir el binario en decimal, y luego hacer la división. DIBUJOS/CUADROS.
Una alternativa, trabajar con binarios, lo veo complicado. Supongamos que convierto la cantidad de cuadros, a binario. Luego puedo hacer una división entre binarios, puedo preguntarle a GPT cómo. Pero luego a DIBUJOS tengo que irle restando eso, o sea, hacer restas en binario, y no sé realmente si voy a obtener los números que preciso.
Pero sea como sea, las divisiones van a tener que ser con strings.

Lo de la regla es que los dibujos podrían empezar de cierta forma sin que haya mucho problema. Por ejemplo si hay 4 cuadros de 3*3 cuadraditos cada uno y ponemos que empiecen así:
NNN  NNN
NBB  NBN
NBB  NBB  

NNN  NNN
NBB  NBB
NNB  NBN
Hay que ver si el cuadro inferior derecho queda todo negro (los dibujos van variando) después de que los otros cuadros mostraran todos los dibujos que deben. Si es así y se sigue cumpliendo cuando aumenta la cantidad de cuadros y cuadraditos, bueno, no sería la solución ideal, pero podría ser una solución. Como es difícil saberlo, prefiero hacer una división como se debe. Supongamos que se van a mostrar 512 dibujos. Son menos pero supongamos. Hacemos eso /4, entonces:
512   384
256   128
Me refiero a que un cuadro mostrará el dibujo 512, otro el nro 384, otro el 256, y así. Enseguida, cada uno mostrará el anterior, así:
511  383
255  127
Y así seguirán variando hasta que el inferior derecho llegue a 0 (todo negro), es decir, se muestran todos los dibujos posibles.
Cada número al convertirse a binario se convierte en una representación del dibujo, 0 es negro, 1 blanco.
Más o menos es eso, me puedo haber confundido en algo.
Si los convierto a binario ¿para qué inician como decimales? No sé, me pareció más fácil, lo pensé así, para entender mejor qué estoy haciendo. No creo que sea el problema...

En fin, que yo sepa, para empezar, tengo un binario enorme que debo convertir a decimal pero que sea string. Espero no confundirme en esto.

GPT:
Citar
Para no perder precisión en Flash 5 necesitas hacer aritmética “grande” con strings (sin usar Number para el valor completo). La idea: recorre el binario de izquierda a derecha y mantén el acumulado en decimal como un arreglo de dígitos; en cada bit haces “decimal = decimal*2 + bit”. Multiplicar por 2 y sumar 1 se hacen dígito a dígito.

Aquí tienes una función ActionScript (Flash 5) que convierte un string binario a su string decimal sin pérdida:

```actionscript
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.  // Saltar ceros líderes
  5.  var i = 0;
  6.  var n = bin.length;
  7.  while (i < n && bin.charAt(i) == "0") { i++; }
  8.  if (i >= n) return "0";
  9.  
  10.  // digits almacena el número decimal en dígitos base 10, LSB primero (digits[0] es las unidades)
  11.  var digits = [0];
  12.  
  13.  for (; i < n; i++) {
  14.    var c = bin.charAt(i);
  15.    if (c != "0" && c != "1") {
  16.      // Si hay caracteres no binarios, puedes elegir lanzar error o ignorar; aquí se ignoran.
  17.      continue;
  18.    }
  19.  
  20.    // decimal *= 2
  21.    var carry = 0;
  22.    var j;
  23.    for (j = 0; j < digits.length; j++) {
  24.      var x = digits[j] * 2 + carry; // x siempre pequeño, seguro
  25.      digits[j] = x % 10;
  26.      carry = Math.floor(x / 10);
  27.    }
  28.    while (carry > 0) {
  29.      digits[digits.length] = carry % 10;
  30.      carry = Math.floor(carry / 10);
  31.    }
  32.  
  33.    // decimal += bit (0 o 1)
  34.    if (c == "1") {
  35.      var k = 0;
  36.      var add = 1;
  37.      while (add > 0) {
  38.        if (k >= digits.length) digits[digits.length] = 0;
  39.        var y = digits[k] + add;
  40.        digits[k] = y % 10;
  41.        add = Math.floor(y / 10);
  42.        k++;
  43.      }
  44.    }
  45.  }
  46.  
  47.  // Construir string (invertir los dígitos)
  48.  var s = "";
  49.  for (var t = digits.length - 1; t >= 0; t--) {
  50.    s += digits[t];
  51.  }
  52.  return s;
  53. }
  54.  
  55. // Ejemplos:
  56. trace(binToDecString("0"));                // "0"
  57. trace(binToDecString("1"));                // "1"
  58. trace(binToDecString("10"));               // "2"
  59. trace(binToDecString("11111111"));         // "255"
  60. trace(binToDecString("10000000000000000"));// "131072"
```

Notas:
- Complejidad aproximada O(bits × dígitos_decimales). Para binarios muy largos funciona bien en Flash 5 si no son cientos de miles de bits.
- Si quieres validar estrictamente el input, en vez de “continue” cuando c != '0'/'1', lanza un error o retorna null.

Ahora tengo que intentar entender ese código... Ya había conseguido uno parecido y no pude. Le puedo ir preguntando a GPT lo que no entienda pero... si alguien pudiera hacer un código más comprensible y explicarlo con un ejemplo estaría bueno.
329  Programación / Programación General / Re: ¿Error al convertir nùmero grande a binario? en: 22 Julio 2025, 03:01 am
Intento resumir y corregir algunos posibles errores que haya cometido en posts anteriores.

Se consigue el número binario que forma la L invertida, aunque es un string:
"1111111011111110111111101111111011111110111111101111111000000000"

Se intenta convertir a decimal, pero como el número resultante es tan grande, Flash falla:
9.22337203685478e+18
Según GPT, el resultado debería ser 18374686492081295424 y el número raro que pone Flash es casi la mitad de eso. Falla.

Entonces, en principio necesito un método de convertir un string que representa un número binario, en un string que represente un decimal, pero sin que dicho método use variables tipo número que sean demasiado grandes, porque sino falla.

El método que usaba, para convertir DibujoEnBinario en DibujoaMostrar, es:
Código
  1. // Convertirlo en decimal:
  2. DibujoaMostrar = 0;
  3. do {
  4. DibujoaMostrar = DibujoaMostrar+(Number(DibujoEnBinario.charat(NroDelCaracter))*Math.round(Math.pow(2, DibujoEnBinario.length-1-NroDelCaracter)));
  5. trace("Convirtiendo en decimal... "+DibujoaMostrar);
  6. NroDelCaracter++;
  7. } while (NroDelCaracter<Cuadraditos);
  8. DibujoaMostrar = Number(DibujoaMostrar);

Le expliqué a GPT y me dijo esto:
Código
  1. function binaryToDecimalString(binStr) {
  2.    var decimal = "0";
  3.    var i = 0;
  4.  
  5.    while (i < binStr.length) {
  6.        // Multiplicar el decimal actual por 2
  7.        decimal = multiplyDecimalStringByTwo(decimal);
  8.  
  9.        // Sumar el bit actual si es 1
  10.        if (binStr.charAt(i) == "1") {
  11.            decimal = addDecimalString(decimal, "1");
  12.        }
  13.  
  14.        i++;
  15.    }
  16.  
  17.    return decimal;
  18. }
  19.  
  20. // Multiplica un string decimal por 2
  21. function multiplyDecimalStringByTwo(decimal) {
  22.    var result = "";
  23.    var carry = 0;
  24.  
  25.    for (var i = decimal.length - 1; i >= 0; i--) {
  26.        var digit = Number(decimal.charAt(i)) * 2 + carry;
  27.        carry = Math.floor(digit / 10);
  28.        result = String(digit % 10) + result;
  29.    }
  30.  
  31.    if (carry > 0) {
  32.        result = String(carry) + result;
  33.    }
  34.  
  35.    return result;
  36. }
  37.  
  38. // Suma dos strings decimales
  39. function addDecimalString(a, b) {
  40.    var result = "";
  41.    var carry = 0;
  42.    var i = a.length - 1;
  43.    var j = b.length - 1;
  44.  
  45.    while (i >= 0 || j >= 0 || carry > 0) {
  46.        var digitA = i >= 0 ? Number(a.charAt(i)) : 0;
  47.        var digitB = j >= 0 ? Number(b.charAt(j)) : 0;
  48.        var sum = digitA + digitB + carry;
  49.        carry = Math.floor(sum / 10);
  50.        result = String(sum % 10) + result;
  51.        i--;
  52.        j--;
  53.    }
  54.  
  55.    return result;
  56. }

Lo voy a pensar.

Luego creo que tendría que dividir un número entre otro, pero siendo strings, y también tendría que hacer restas usando strings.
330  Foros Generales / Sugerencias y dudas sobre el Foro / No sé qué título. en: 12 Julio 2025, 14:46 pm
Quizá debería aprender a no prestar atención a asuntos ajenos. Probablemente. Pero mirar temas de foros parece algo normal.

En Quora, gente postea chistes, curiosidades de la historia, respuestas varias a preguntas de los usuarios... En general, nada me parece tonto, nomás bloqueé a uno que daba mensajes "espirituales" crípticos disfrazados de sabiduría y a otro no recuerdo exactamente por qué, algo como que daba información irrelevante o le ponía demasiada opinión suya con la que no estaba de acuerdo.

Acá, El_Andaluz postea, no cualquier cosa sobre guerras, pero muchas cosas sobre guerras ¿demasiadas? Para mí sí, considerando que es un foro de Informática y que en teoría no se puede opinar de política. Lo que postea sobre eso es generalmente casi todo noticias copiadas de otro lado, que quien quiera verlas las podría leer en otro lado, así que no entiendo para qué. Se puede decir que es un tema importante, preocupante, y que cada uno puede postear de lo que se le de la gana, pero a mí me choca que casi siempre se esté hablando de lo mismo, como si te tiraran el tema en la cara, una y otra vez, donde para colmo no se puede opinar casi y no parece que corresponda, por ser un foro de informática, no de guerras ni tan general como otros foros. No entiendo la intención, me parece incomprensible, esa manía de copiar cosas de guerra de un diario hacia un foro de informática.
También de vez en cuando postea videos de cosas paranormales. Que me hacen sentir más o menos lo mismo: ¿Para qué muestra videos random? ¿por qué tengo que leer sobre eso en un foro de informática? Se lee acá:
https://foro.elhacker.net/unread.html;all
y sí entro porque quiero creer que es algo importante, revolucionario, como pareció que fue lo de la esfera de buga, aunque pasó mucho tiempo y no la abrieron, así que quedó en probable farsa, pero ese video que puso sí estuvo bueno.

Por otro lado, Elektro publicó un tema donde casi que dice haber alcanzado la iluminación, la sabiduría, y hace muchas recomendaciones pero parece decir nada, que tienes que ver los videos enteros o leer los libros para poder opinar debidamente. Para mí si alguien tiene algo importante y sabio que decir lo debería poder resumir un poco, pero bueno, no quise creer que fuera una tontería, aunque ese no resumen inspira desconfianza. Leí un resumen, el señor que recomienda cree que la vida es un videojuego, un montaje de la consciencia para evolucionar.

Ante tanta "espiritualidad" en el foro, me pregunté: ¿Esta gente ha experimentado algo paranormal alguna vez o...?
Por eso en parte hice el tema preguntando si alguna vez experimentaron algo paranormal. Y me pareció interesante. Videos probablemente hechos para lucrar, no. Tampoco me gusta asustarme al pedo.

Electro me insultó más o menos, y el tema se desvió.

Ahora, hice este tema que están leyendo porque quería preguntar cómo se supone que evite que se desvíe si me insulta y casi cualquier cosa menos decir lo que más me interesaba. Si él cree que la vida es un videojuego o no sé qué cosa aparentemente paranormal, podría explicar por qué ¿ha tenido alguna experiencia que lo induzca a creer eso? No explicó. ¿Qué debo pensar? Probablemente nada, pero ese tipo de gente me cansa. Si tienen algo importante que decir, que lo digan, sino es como una burla, no sé explicarlo, como si uno tuviese hambre (de sabiduría) y estos tipos nos intentaran hacer ver que están comiendo, pero algo probablemente falso, que probablemente ni ellos se dan cuenta, así que siento una mezcla de rabia y pena.

Más allá de eso, no sé lo que quiero, explicar algunas cosas sí.

Y bueno, no quiero que se prohíban ciertos temas en el foro, ni quiero que la gente se dedique sólo a cosas "inteligentes", pero siento que algo está mal, que no encaja, puede que sea yo, que necesite unas vacaciones de las redes sociales, o de este foro, pero como digo en Quora es muy difícil que te llegue una notificación de un video random de YT de dudosa credibilidad, de cada puñetero ataque en una guerra, o si llegan, como los mensajes espirituales crípticos, se tiene la opción de bloquear, de ignorar.

Quizá, por ejemplo, podrían hacer que los temas del foro libre no aparezcan acá:
https://foro.elhacker.net/unread.html;all
o denme un link donde no aparezcan, aunque igual me siento un poco mal, se me olvida esto: ¿Por qué no hacen algo más importante o relacionado con la Informática? Avances en la IA por ejemplo. No sé, es como que siento que está mal que alguien pierda su tiempo viendo o leyendo "estupideces", no sé, porque lo que siento cambia a veces, me olvido qué era, yo puedo pensar, en teoría, que son unos locos e ignorarlos, pero los temas me aparecen en el link, así que los veo, no puedo ignorarlos... Además a veces me da como rabia que pierdan el tiempo en "estupideces" pudiendo hacer algo mejor, aunque claro no debo obligarlos, pero me molesta ser obligado a ver esos temas.

En mi barrio hay gente durmiendo en la calle, y varios más revisan contenedores de basura, buscando sobras de comida o algo que vender. Yo no me siento tan distinto. Muy cerca se reúnen unos hinchas de políticos a charlar. ¿Debería spamearles una y otra vez lo mal que está el país? No lo hago porque hacer propaganda, joder una y otra vez con lo mismo, me parece mal.

No sé, lamento si soy el problema, demasiado intolerante, intentaré no prestar atención a temas que no sean de informática aquí y no dar importancia a lo "no importante" que hagan otros, pero sería bueno, y quizá importante, que haya una mejora en el foro como para que nos llegue lo que nos interesa, y no lo que no. ¿Qué sentido tiene que se pueda publicar cualquier cosa y que a la gente le llegue cualquier cosa aunque no quieran?
Páginas: 1 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [33] 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 ... 273
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines