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


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


  Mostrar Mensajes
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 243
1  Programación / Programación General / Re: Posible aporte: Código para jugar bien Signos en línea, aún no probado. en: Hoy a las 03:45
No comenzaba, debido a errores que corregí, pero la etapa 3 no funciona bien. Intenté poner traces en ella para entender mejor qué está pasando pero me entrevera lo de mejor resultado hallado y resultado esperado.
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("La lista preparada es 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. SituacionBase = eval(L_SaE_).slice();
  108. trace("Se inician experimentos en otra situación de la lista, la nro "+NroDeSExperimentandose+", que es "+SituacionBase);
  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. trace("Ejecutando ResetearSituacionEt1");
  118. // Plantear situación porque puede modificarse pero...
  119. // podría requerirse su estado original luego:
  120. Situacion = SituacionBase.slice();
  121. // trace("La situación experimentándose es "+Situacion);
  122. EvaluarAplicabilidadEt1();
  123. }
  124. // Usada luego de que cambia la SaE y/o la acción, en Et1:
  125. function EvaluarAplicabilidadEt1 () {
  126. trace("Ejecutando EvaluarAplicabilidadEt1");
  127. if (Situacion[Action] == "v") {
  128. trace("La acción "+Action+" es realizable.");
  129. AplicarAccionEt1();
  130. } else {
  131. trace("La acción "+Action+" no es realizable.");
  132. SinResetBuscarOtraAccionEt1();
  133. }
  134. }
  135. // Usada luego de EvaluarAplicabilidadEt1,
  136. // si una acción es realizable:
  137. function AplicarAccionEt1 () {
  138. trace("Ejecutando AplicarAccionEt1");
  139. Situacion[Action] = Turno;
  140. trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  141. // ¿Ganó?
  142. // Si no se detecta victoria vertical,
  143. // revisa de otros modos (ver las funciones Chequear):
  144. ChequearVertical();
  145. if (Win == "No") {
  146. EvaluarConocimientoSobreSEt1();
  147. }
  148. // ¿Queda alguna acción sin probar en la situación?
  149. BuscarOtraAccionEt1();
  150. }
  151. // Usada en EvaluarAplicabilidadEt1 cuando una acción no es...
  152. // realizable:
  153. function SinResetBuscarOtraAccionEt1 () {
  154. trace("Ejecutando SinResetBuscarOtraAccionEt1");
  155. if (Action < LastActionPosible) {
  156. // Si queda alguna acción sin probar...
  157. // en la situación, probarla:
  158. Action++;
  159. EvaluarAplicabilidadEt1();
  160. } else {
  161. trace("No hay más acciones realizables.");
  162. BuscarOtraSituacionEt1();
  163. }
  164. }
  165. // Usada luego de AplicarAccionEt1:
  166. function BuscarOtraAccionEt1 () {
  167. trace("Ejecutando BuscarOtraAccionEt1");
  168. if (Action < LastActionPosible) {
  169. // Si queda alguna acción sin probar...
  170. // en la situación, probarla:
  171. Action++;
  172. trace("La nueva acción a probar es "+Action);
  173. // Se ejecutará ResetearSituacionEt1.
  174. } else {
  175. trace("No hay más acciones realizables.");
  176. BuscarOtraSituacionEt1();
  177. }
  178. }
  179. // Usada en AplicarAccionEt1 cuando no hay victoria (ni empate,
  180. // aunque por ahora no ocurren):
  181. function EvaluarConocimientoSobreSEt1 () {
  182. trace("Ejecutando EvaluarConocimientoSobreSEt1");
  183. // Estas 3 variables son para evitar reconcatenar:
  184. SituacionJoined = Situacion.join("");
  185. NewS_ = "S"+SituacionJoined;
  186. NewS_BestAction = NewS_+"BestAction";
  187. // ¿Se ha llegado antes a la situación?
  188. if (eval(NewS_BestAction) == undefined) {
  189. // No, anotar que debe investigarse:
  190. SituacionesNuevas++;
  191. // Copiar array (porque no se puede normalmente):
  192. trace("Situación a copiar a "+NextL_SaE+SituacionesNuevas+" es "+Situacion);
  193. set (NextL_SaE+SituacionesNuevas, Situacion.slice());
  194. trace("Esa situación no está anotada; se anota como nro "+SituacionesNuevas);
  195. // trace(" NewS_: "+NewS_);
  196. // trace(" NewS_BestAction: "+NewS_BestAction);
  197. set(NewS_BestAction, "Desconocida");
  198. if (Turno == "X") {
  199. set (NewS_+"Turno", "0");
  200. } else {
  201. set (NewS_+"Turno", "X");
  202. }
  203. // Averiguar cual es su 1er acción posible:
  204. AccionRevisandose = -1;
  205. do {
  206. AccionRevisandose++;
  207. if (Situacion[AccionRevisandose] == "v") {
  208. set (NewS_+"FirstAPosible", AccionRevisandose);
  209. break;
  210. }
  211. } while (true);
  212. // Averiguar cual es su última acción posible:
  213. AccionRevisandose = Casilleros;
  214. do {
  215. AccionRevisandose--;
  216. if (Situacion[AccionRevisandose] == "v") {
  217. set (NewS_+"LastAPosible", AccionRevisandose);
  218. break;
  219. }
  220. } while (true);
  221. }
  222. }
  223. // Usada en BuscarOtraAccionEt1 cuando no hay más acciones posibles,
  224. // y en SinResetBuscarOtraAccionEt1:
  225. function BuscarOtraSituacionEt1 () {
  226. trace("Ejecutando BuscarOtraSituacionEt1");
  227. NroDeSExperimentandose++;
  228. if (eval(L_SaE+NroDeSExperimentandose) != undefined) {
  229. // Hay otra situación en la lista,
  230. // prepararse a usarla:
  231. L_SaE_ = L_SaE+NroDeSExperimentandose;
  232. PrepararSaE();
  233. } else {
  234. trace("No hay más situaciones a experimentar en la lista actual, se mirará otra.");
  235. BuscarOtraListaEt1();
  236. }
  237. }
  238. // /////////////////////////////////////////////
  239. // /////////////////  Etapa 2  /////////////////
  240. // /////////////////////////////////////////////
  241. // Consiste en guardar el resultado de las situaciones en que...
  242. // sólo 1 acción es posible. Puede ser victoria o empate.
  243. //
  244. // Usada en frame 3 (o etapa 2) repetidamente:
  245. function ResetearSituacionEt2 () {
  246. trace("Ejecutando ResetearSituacionEt2");
  247. // Plantear situación porque puede modificarse pero...
  248. // podría requerirse su estado original luego:
  249. Situacion = SituacionBase.slice();
  250. trace("La situación experimentándose es "+Situacion);
  251. AplicarAccionEt2();
  252. }
  253. // Usada luego de ResetearSituacionEt2, parece innecesario que sea función:
  254. function AplicarAccionEt2 () {
  255. trace("Ejecutando AplicarAccionEt2");
  256. Situacion[Action] = Turno;
  257. trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  258. // ¿Ganó?
  259. // Si no se detecta victoria vertical,
  260. // revisa de otros modos (ver las funciones Chequear):
  261. ChequearVertical();
  262. set(S_+"BestAction", Action);
  263. if (Win == "Sí") {
  264. trace("Victoria conseguida, guardando datos.");
  265. if (Turno == "X") {
  266. // Estas son las chances de que gane...
  267. // X, 0 o que haya empate:
  268. set(S_+"VictoriasDeX", 1);
  269. set(S_+"VictoriasDe0", 0);
  270. set(S_+"ResultadoEsperado", "X");
  271. } else {
  272. set(S_+"VictoriasDeX", 0);
  273. set(S_+"VictoriasDe0", 1);
  274. set(S_+"ResultadoEsperado", "0");
  275. }
  276. set(S_+"DistanciaaGanar", 1);
  277. set(S_+"Empates", 0);
  278. } else {
  279. trace("Empate conseguido, guardando datos.");
  280. set(S_+"VictoriasDeX", 0);
  281. set(S_+"VictoriasDe0", 0);
  282. set(S_+"Empates", 1);
  283. set(S_+"ResultadoEsperado", "E");
  284. }
  285. // ¿Queda alguna situación en la lista experimentándose?
  286. BuscarOtraSituacionEt2();
  287. }
  288. // Usada luego de AplicarAccionEt2, parece innecesario que sea función:
  289. function BuscarOtraSituacionEt2 () {
  290. trace("Ejecutando BuscarOtraSituacionEt2");
  291. NroDeSExperimentandose++;
  292. if (eval(L_SaE+NroDeSExperimentandose) != undefined) {
  293. // Hay otra situación en la lista,
  294. // prepararse a usarla:
  295. L_SaE_ = L_SaE+NroDeSExperimentandose;
  296. PrepararSaE();
  297. } else {
  298. trace("No hay más situaciones a experimentar en la lista actual, inicia la etapa 3.");
  299. BuscarOtraListaEt3();
  300. gotoAndStop(4);
  301. }
  302. }
  303. // /////////////////////////////////////////////
  304. // /////////////////  Etapa 3  /////////////////
  305. // /////////////////////////////////////////////
  306. // Consiste en guardar los resultados de las acciones en...
  307. // situaciones en que más de 1 acción es posible.
  308. // Particularmente se guarda la mejor acción.
  309. // El resultado de las acciones puede ser victoria,
  310. // una situación con posibles resultados,
  311. // y en la penúltima lista una situación con un único posible...
  312. // resultado.
  313. //
  314. // Usada antes y durante esta etapa...
  315. // cuando no hay más situaciones en la lista revisándose:
  316. function BuscarOtraListaEt3 () {
  317. trace("Ejecutando BuscarOtraListaEt3");
  318. NroDeListaRevisandose--;
  319. if (NroDeListaRevisandose > -1) {
  320. // Si se halla una lista:
  321. PrepararUsoDeLista();
  322. PrepararSaEEt3();
  323. } else {
  324. trace("No hay más listas a revisar; programa terminado.");
  325. // En este frame nada hay, es sólo para mostrar el mensaje:
  326. gotoAndStop(5);
  327. }
  328. }
  329. // Casi como PrepararSaE. Usada cuando se elige una SaE,
  330. // en BuscarOtraListaEt3 y BuscarOtraSituacionEt3:
  331. function PrepararSaEEt3 () {
  332. trace("Ejecutando PrepararSaEEt3");
  333. PrepararSaE();
  334. // Para evitar evals y concatenaciones repetidamente:
  335. BestAction = "";
  336. VictoriasDeX = 0;
  337. VictoriasDe0 = 0;
  338. Empates = 0;
  339. // Establecer que hasta ahora los resultados hallados...
  340. // son peores que lo posible, para que se sustituyan por...
  341. // cualquier acción:
  342. if (Turno == "X") {
  343. // La E antes de Obtenido es Esperado:
  344. BestResultadoEObtenido = "0";
  345. } else {
  346. BestResultadoEObtenido = "X";
  347. }
  348. // Si 2 acciones causan victoria segura,
  349. // esto sirve para elegir la mejor de ellas:
  350. BestDistanciaaGanar = Casilleros;
  351. // Si 2 acciones causan empate seguro,
  352. // esto sirve para elegir la mejor de ellas:
  353. BestChanceDeGanarEnE = -1;
  354. BestChanceDeEmpatarEnE = -1;
  355. // Si 2 acciones causan derrota segura,
  356. // esto sirve para elegir la mejor de ellas:
  357. LowestChanceDePerderEnD = -1;
  358. BestChanceDeGanarEnD = -1;
  359. }
  360. // Usada en frame 4 (o etapa 3) repetidamente:
  361. function ResetearSituacionEt3 () {
  362. // Plantear situación porque puede modificarse pero...
  363. // podría requerirse su estado original luego:
  364. Situacion = SituacionBase.slice();
  365. trace("La situación experimentándose es "+Situacion);
  366. EvaluarAplicabilidadEt3();
  367. }
  368. // Usada luego de que cambia la SaE y/o la acción, en Et3:
  369. function EvaluarAplicabilidadEt3 () {
  370. trace("Ejecutando EvaluarAplicabilidadEt3");
  371. if (Situacion[Action] == "v") {
  372. trace("La acción "+Action+" es realizable.");
  373. AplicarAccionEt3();
  374. } else {
  375. trace("La acción "+Action+" no es realizable.");
  376. SinResetBuscarOtraAccionEt3();
  377. }
  378. }
  379. // Usada luego de EvaluarAplicabilidadEt3,
  380. // si una acción es realizable:
  381. function AplicarAccionEt3 () {
  382. // Los datos se guardarán bien en GuardarDatosEt3.
  383. // Por ahora varios se están guardando en variables más simples de nombrar.
  384. // Además algunos no se pueden guardar aún (VictoriasDeX, NewVictoriasDe0...).
  385. // Y DistanciaaGanar se está guardando como -1 de lo que debe, para no tener que estar sumando.
  386. trace("Ejecutando AplicarAccionEt3");
  387. Situacion[Action] = Turno;
  388. trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  389. // ¿Ganó?
  390. // Si no se detecta victoria vertical,
  391. // revisa de otros modos (ver las funciones Chequear):
  392. ChequearVertical();
  393. if (Win == "No") {
  394. trace("No hubo victoria, agregando datos...");
  395. // Agregar los posibles resultados de la...
  396. // situación obtenida:
  397. // Estas 5 variables son para evitar reconcatenar:
  398. SituacionJoined = Situacion.join("");
  399. NewS_ = "S"+SituacionJoined;
  400. NewVictoriasDeX = eval(NewS_+"VictoriasDeX");
  401. NewVictoriasDe0 = eval(NewS_+"VictoriasDe0");
  402. NewEmpates = eval(NewS_+"Empates");
  403. VictoriasDeX = VictoriasDeX+NewVictoriasDeX;
  404. VictoriasDe0 = VictoriasDe0+NewVictoriasDe0;
  405. Empates = Empates+NewEmpates;
  406. trace(VictoriasDeX+", "+VictoriasDe0+", "+Empates);
  407. // Si en la SaE ya se halló una acción que...
  408. // causa victoria segura:
  409. if (BestResultadoEObtenido == Turn) {
  410. trace("El mejor resultado logrado es victoria");
  411. // Si la acción recién usada también causa eso:
  412. if (eval(NewS_+"ResultadoEsperado") == Turn) {
  413. trace("La acción causa victoria segura (no inmediata)");
  414. trace("Pero ya se halló otra, se verá cual causa más rápido");
  415. // Si dicha acción la causa faster:
  416. if (eval(NewS_+"DistanciaaGanar") < BestDistanciaaGanar) {
  417. // Sustituir datos:
  418. trace("La nueva fue mejor, sustituyendo datos...");
  419. BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
  420. BestAction = Action;
  421. }
  422. // SINO SI LA CAUSA IGUAL DE RÁPIDO HABRÍA QUE AVERIGUAR CHANCES, pero se gana igual...
  423. // sino dicha acción es peor, no prestarle más atención.
  424. }
  425. // idem.
  426. // sino si el mejor resultado esperado hallado...
  427. // en esta SaE es empate:
  428. } else if (BestResultadoEObtenido == "E") {
  429. trace("Por ahora el mejor resultado logrado es empate");
  430. // Si la acción recién usada causa que...
  431. // el resultado esperado sea victoria:
  432. if (eval(NewS_+"ResultadoEsperado") == Turn) {
  433. // Sustituir datos:
  434. trace("La acción causa victoria segura (no inmediata)");
  435. trace("Sustituyendo datos...");
  436. BestResultadoEObtenido = Turn;
  437. BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
  438. BestAction = Action;
  439. // sino si es empate:
  440. } else if (eval(NewS_+"ResultadoEsperado") == "E") {
  441. trace("La acción causa empate seguro (no inmediato)");
  442. // Averiguar chance de victoria:
  443. Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
  444. ChanceDeGanar = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  445. // Si es mejor que la hallada antes:
  446. if (ChanceDeGanar > BestChanceDeGanarEnE) {
  447. // Sustituir datos:
  448. BestChanceDeGanarEnE = ChanceDeGanar;
  449. BestChanceDeEmpatarEnE = NewEmpates*100/Posibilidades;
  450. BestAction = Action;
  451. // sino si la chance es igual:
  452. } else if (ChanceDeGanar == BestChanceDeGanarEnE) {
  453. // Averiguar chance de empate:
  454. ChanceDeEmpatar = NewEmpates*100/Posibilidades;
  455. // Si es mejor que la hallada antes:
  456. if (ChanceDeEmpatar > BestChanceDeEmpatarEnE) {
  457. // Sustituir datos:
  458. // BestChanceDeGanarEnE = ChanceDeGanar;
  459. BestChanceDeEmpatarEnE = ChanceDeEmpatar;
  460. BestAction = Action;
  461. }
  462. }
  463. // SINO SI LAS CHANCES SON LAS MISMAS HABRÍA QUE DECIDIR SI SE PREFIERE LA QUE LO CAUSA MÁS RÁPIDO O NO.
  464. // sino dicha acción no es mejor, no prestarle más atención.
  465. // idem.
  466. }
  467. // El resultado esperado es derrota:
  468. } else {
  469. // Si la acción recién usada causa que...
  470. // el resultado esperado sea victoria:
  471. if (eval(NewS_+"ResultadoEsperado") == Turn) {
  472. // Sustituir datos:
  473. BestResultadoEObtenido = Turn;
  474. BestDistanciaaGanar = eval(NewS_+"DistanciaaGanar");
  475. BestAction = Action;
  476. // sino si es empate:
  477. } else if (eval(NewS_+"ResultadoEsperado") == "E") {
  478. // Averiguar chances y sustituir datos:
  479. Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
  480. BestChanceDeGanarEnE = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  481. BestChanceDeEmpatarEnE = NewEmpates*100/Posibilidades;
  482. BestResultadoEObtenido = "E";
  483. BestAction = Action;
  484. // sino es derrota:
  485. } else {
  486. // Averiguar chance de perder:
  487. Posibilidades = NewVictoriasDeX+NewVictoriasDe0+NewEmpates;
  488. ChanceDePerder = 100-(eval("NewVictoriasDe"+Turno)+NewEmpates)*100/Posibilidades;
  489. // Si es más baja (mejor) que la hallada antes:
  490. if (ChanceDePerder < LowestChanceDePerderEnD) {
  491. // Sustituir datos:
  492. LowestChanceDePerderEnD = ChanceDePerder;
  493. BestChanceDeGanarEnD = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  494. BestAction = Action;
  495. // sino si la chance es igual:
  496. } else if (ChanceDePerder == LowestChanceDePerderEnD) {
  497. // Averiguar chance de victoria:
  498. ChanceDeGanar = eval("NewVictoriasDe"+Turno)*100/Posibilidades;
  499. // Si es mejor que la hallada antes:
  500. if (ChanceDeGanar > BestChanceDeGanarEnD) {
  501. // Sustituir datos:
  502. LowestChanceDePerderEnD = ChanceDePerder;
  503. BestChanceDeGanarEnD = ChanceDeGanar;
  504. BestAction = Action;
  505. }
  506. }
  507. }
  508. }
  509. // sino la acción causa una victoria inmediata:
  510. } else {
  511. // Incrementar victorias:
  512. // Esta es para evitar reconcatenar:
  513. VariableaIncrementar = "VictoriasDe"+Turno;
  514. set (VariableaIncrementar, eval(VariableaIncrementar)+1);
  515. if (BestDistanciaaGanar > 0) {
  516. // Sustituir datos:
  517. BestResultadoEObtenido = Turn;
  518. BestDistanciaaGanar = 0;
  519. BestAction = Action;
  520. }
  521. }
  522. // ¿Queda alguna acción sin probar en la situación?
  523. BuscarOtraAccionEt3();
  524. }
  525. // Usada en EvaluarAplicabilidadEt3 cuando una acción no es...
  526. // realizable:
  527. function SinResetBuscarOtraAccionEt3 () {
  528. trace("Ejecutando SinResetBuscarOtraAccionEt3");
  529. if (Action < LastActionPosible) {
  530. // Si queda alguna acción sin probar...
  531. // en la situación, probarla:
  532. Action++;
  533. EvaluarAplicabilidadEt3();
  534. } else {
  535. trace("No hay más acciones realizables.");
  536. BuscarOtraSituacionEt3();
  537. }
  538. }
  539. // Usada luego de AplicarAccionEt3:
  540. function BuscarOtraAccionEt3 () {
  541. trace("Ejecutando BuscarOtraAccionEt3");
  542. if (Action < LastActionPosible) {
  543. // Si queda alguna acción sin probar...
  544. // en la situación, probarla:
  545. Action++;
  546. // Se ejecutará ResetearSituacionEt3.
  547. } else {
  548. trace("No hay más acciones realizables.");
  549. BuscarOtraSituacionEt3();
  550. }
  551. }
  552. // Usada cuando no hay más acciones posibles:
  553. function GuardarDatosEt3 () {
  554. trace("Ejecutando GuardarDatosEt3");
  555. set(S_+"VictoriasDeX", VictoriasDeX);
  556. set(S_+"VictoriasDe0", VictoriasDe0);
  557. set(S_+"Empates", Empates);
  558. set(S_+"BestAction", BestAction);
  559. set(S_+"DistanciaaGanar", BestDistanciaaGanar+1);
  560. set(S_+"ResultadoEsperado", BestResultadoEObtenido);
  561. }
  562. // Usada en BuscarOtraAccionEt3 cuando no hay más acciones posibles,
  563. // y en SinResetBuscarOtraAccionEt3:
  564. function BuscarOtraSituacionEt3 () {
  565. trace("Ejecutando BuscarOtraSituacionEt3");
  566. NroDeSExperimentandose++;
  567. if (eval(L_SaE+NroDeSExperimentandose) != undefined) {
  568. // Hay otra situación en la lista,
  569. // prepararse a usarla:
  570. L_SaE_ = L_SaE+NroDeSExperimentandose;
  571. PrepararSaEEt3();
  572. } else {
  573. trace("No hay más situaciones a experimentar en la lista actual, se mirará otra.");
  574. BuscarOtraListaEt3();
  575. }
  576. }
  577. // /////////////////////////////////////////////
  578. // /////////////////  Chequeos  ////////////////
  579. // /////////////////////////////////////////////
  580. // Usada en ChequeoHorizontal y requerida en otros casos:
  581. function ObtenerColumnayFilaDelMarcado () {
  582. FilaDelMarcado = Math.floor(Action/CasillerosPorFila);
  583. ColumnaDelMarcado = Action%CasillerosPorFila;
  584. }
  585. function ChequearVertical () {
  586. // trace ("Ejecutando ChequearVertical");
  587. //
  588. // SOLO FUNCIONA SI CasillerosPorFila >= JuntosRequeridos.
  589. //
  590. // Se revisará la vertical. Desde el casillero más arriba...
  591. // que pueda estar incluído en la línea,
  592. // hasta el casillero marcado. Si se halla alguno que no...
  593. // tenga la marca requerida, se repite el proceso mirando...
  594. // desde uno más abajo del fallado, y mirando ahora hasta...
  595. // más abajo, según corresponda:
  596. Desde = Action-CasillerosPorFila*(JuntosRequeridos-1);
  597. // Mientras el casillero no exista:
  598. while (Desde<0) {
  599. // trace ("Desde es "+Desde+", se aumentará");
  600. // Indicar que se empiece a mirar desde más abajo:
  601. Desde = Desde+CasillerosPorFila;
  602. }
  603. do {
  604. Hasta = Desde+CasillerosPorFila*(JuntosRequeridos-1);
  605. if (Hasta>MaxCasillero) {
  606. // Para ganar se necesitaría más casilleros hacia...
  607. // abajo de los que hay, terminar análisis:
  608. // trace ("No hay suficientes cuadraditos abajo");
  609. break;
  610. }
  611. Puntero = Desde;
  612. // trace ("Comenzando chequeo desde "+Desde+" hasta "+Hasta);
  613. // Puede cambiar:
  614. Win = "Sí";
  615. do {
  616. // trace ("Chequando el casillero "+Puntero);
  617. if (Situacion[Action] != Situacion[Puntero]) {
  618. Win = "No";
  619. Desde = Puntero+CasillerosPorFila;
  620. break;
  621. }
  622. Puntero = Puntero+CasillerosPorFila;
  623. } while (Puntero<=Hasta);
  624. } while (Desde<=Action && Win == "No");
  625. if (Win == "No") {
  626. // ChequearHorizontal();
  627. }
  628. }
  629. function ChequearHorizontal () {
  630. // trace ("Ejecutando ChequearHorizontal");
  631. // Es similar al chequeo vertical, pero aquí no sirve...
  632. // sumar o restar a un puntero que marque el casillero...
  633. // porque puede existir ese casillero pero no estar en...
  634. // un costado. En vez de eso, se obtiene su columna y...
  635. // fila, se modifica la columna si es posible,
  636. // y se calcula cual es el casillero a mirar:
  637. ObtenerColumnayFilaDelMarcado();
  638. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  639. // Para que no mire cuadraditos inexistentes en la izq:
  640. if (DesdeColumna<0) {
  641. DesdeColumna = 0;
  642. }
  643. do {
  644. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  645. if (HastaColumna>MaxColumna) {
  646. // Para ganar se necesitaría más casilleros hacia...
  647. // la derecha de los que hay, terminar análisis:
  648. // trace ("No hay suficientes cuadraditos a la derecha");
  649. break;
  650. }
  651. Puntero = DesdeColumna;
  652. // trace ("Comenzando chequeo desde "+DesdeColumna+" hasta "+HastaColumna);
  653. // Puede cambiar:
  654. Win = "Sí";
  655. do {
  656. CasilleroaMirar = FilaDelMarcado*CasillerosPorFila+Puntero;
  657. // trace ("Chequando el casillero "+CasilleroaMirar);
  658. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  659. Win = "No";
  660. DesdeColumna = Puntero+1;
  661. break;
  662. }
  663. Puntero++;
  664. } while (Puntero<=HastaColumna);
  665. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  666. if (Win == "No") {
  667. ChequearDesdeUpIzq();
  668. }
  669. }
  670. // La diagonal así \
  671. function ChequearDesdeUpIzq () {
  672. // trace ("Ejecutando ChequearDesdeUpIzq");
  673. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  674. // trace("DesdeColumna: "+DesdeColumna);
  675. DesdeFila = FilaDelMarcado-JuntosRequeridos+1;
  676. // trace("DesdeFila: "+DesdeFila);
  677. // Para que no mire cuadraditos inexistentes:
  678. if (DesdeColumna<DesdeFila) {
  679. Sumar = DesdeColumna;
  680. } else {
  681. Sumar = DesdeFila;
  682. }
  683. // trace("Sumar: "+Sumar);
  684. if (Sumar<0) {
  685. // trace("Sumando.");
  686. DesdeColumna = DesdeColumna-Sumar;
  687. // trace("DesdeColumna: "+DesdeColumna);
  688. DesdeFila = DesdeFila-Sumar;
  689. // trace("DesdeFila: "+DesdeFila);
  690. }
  691. do {
  692. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  693. if (HastaColumna>MaxColumna) {
  694. // Para ganar se necesitaría más casilleros hacia...
  695. // la derecha de los que hay, terminar análisis:
  696. // trace ("No hay suficientes cuadraditos a la derecha");
  697. break;
  698. }
  699. HastaFila = DesdeFila+JuntosRequeridos-1;
  700. // Sirve usar MaxColumna en vez de crear MaxFila...
  701. // porque como el tablero es cuadrado serían iguales:
  702. if (HastaFila>MaxColumna) {
  703. // Para ganar se necesitaría más casilleros hacia...
  704. // abajo de los que hay, terminar análisis:
  705. // trace ("No hay suficientes cuadraditos abajo");
  706. break;
  707. }
  708. PunteroDeColumna = DesdeColumna;
  709. PunteroDeFila = DesdeFila;
  710. // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila);
  711. // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila);
  712. // Puede cambiar:
  713. Win = "Sí";
  714. do {
  715. CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna;
  716. // trace ("Chequando el casillero "+CasilleroaMirar);
  717. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  718. Win = "No";
  719. DesdeColumna = PunteroDeColumna+1;
  720. DesdeFila = PunteroDeFila+1;
  721. break;
  722. }
  723. PunteroDeColumna++;
  724. PunteroDeFila++;
  725. } while (PunteroDeColumna<=HastaColumna);
  726. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  727. if (Win == "No") {
  728. ChequearDesdeDownIzq();
  729. }
  730. }
  731. // La diagonal así /
  732. function ChequearDesdeDownIzq () {
  733. // trace ("Ejecutando ChequearDesdeDownIzq");
  734. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  735. // trace("DesdeColumna: "+DesdeColumna);
  736. DesdeFila = FilaDelMarcado+JuntosRequeridos-1;
  737. // trace("DesdeFila: "+DesdeFila);
  738. // Para que no mire cuadraditos inexistentes:
  739. ColumnasInexistentes = 0;
  740. if (DesdeColumna<0) {
  741. ColumnasInexistentes = DesdeColumna*-1;
  742. }
  743. FilasInexistentes = 0;
  744. // Está bien usar MaxColumna porque MaxFila sería igual:
  745. if (DesdeFila>MaxColumna) {
  746. FilasInexistentes = DesdeFila-MaxColumna;
  747. }
  748. if (ColumnasInexistentes>=FilasInexistentes) {
  749. Ajuste = ColumnasInexistentes;
  750. } else {
  751. Ajuste = FilasInexistentes;
  752. }
  753. // trace("Ajuste: "+Ajuste);
  754. if (Ajuste>0) {
  755. // trace("Ajustando.");
  756. DesdeColumna = DesdeColumna+Ajuste;
  757. // trace("DesdeColumna: "+DesdeColumna);
  758. DesdeFila = DesdeFila-Ajuste;
  759. // trace("DesdeFila: "+DesdeFila);
  760. }
  761. do {
  762. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  763. if (HastaColumna>MaxColumna) {
  764. // Para ganar se necesitaría más casilleros hacia...
  765. // la derecha de los que hay, terminar análisis:
  766. // trace ("No hay suficientes cuadraditos a la derecha");
  767. break;
  768. }
  769. HastaFila = DesdeFila-JuntosRequeridos+1;
  770. if (HastaFila<0) {
  771. // Para ganar se necesitaría más casilleros hacia...
  772. // arriba de los que hay, terminar análisis:
  773. // trace ("No hay suficientes cuadraditos arriba");
  774. break;
  775. }
  776. PunteroDeColumna = DesdeColumna;
  777. PunteroDeFila = DesdeFila;
  778. // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila);
  779. // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila);
  780. // Puede cambiar:
  781. Win = "Sí";
  782. do {
  783. CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna;
  784. // trace ("Chequando el casillero "+CasilleroaMirar);
  785. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  786. Win = "No";
  787. DesdeColumna = PunteroDeColumna+1;
  788. DesdeFila = PunteroDeFila-1;
  789. break;
  790. }
  791. PunteroDeColumna++;
  792. PunteroDeFila--;
  793. } while (PunteroDeColumna<=HastaColumna);
  794. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  795. // trace("Win: "+Win);
  796. }

Necesito practicar con un juego más sencillo :/
2  Foros Generales / Foro Libre / Los teclados son así porque enlentecían la escritura, según Deepseek. en: Ayer a las 00:53
Citar
La distribución de las letras en el teclado, conocida como **QWERTY** (por las primeras seis letras de la fila superior), no es aleatoria ni sigue un orden alfabético estricto. Su diseño es el resultado de una evolución histórica con un propósito muy concreto: **frenar a los mecanógrafos**.

Aquí te explico las razones principales de su diseño:

### 1. El Problema Original: Las Máquinas de Escribir Mecánicas
El teclado QWERTY fue diseñado en la década de 1870 por **Christopher Latham Sholes** para las primeras máquinas de escribir mecánicas.

*   **El problema técnico:** En estas máquinas, cada letra estaba unida a un brazo metálico (martillo) que golpeaba el papel. Cuando un mecanógrafo era muy rápido y pulsaba dos teclas adyacentes en secuencia muy rápida, los martillos se **atascaban**, frenando la producción y obligando a desenredarlos manualmente.

### 2. La Solución: Separar las Combinaciones de Letras más Comunes
La solución de Sholes fue ingeniosa: **rediseñar el teclado para separar físicamente los pares de letras que se usan con más frecuencia en inglés**. El objetivo era ralentizar ligeramente la escritura para evitar que los martillos chocaran entre sí.

*   Por ejemplo, en inglés, secuencias como "**TH**", "**HE**", "**ST**" o "**RE**" son muy comunes. En el teclado QWERTY, estas letras están intencionadamente separadas y distribuidas en diferentes filas y manos.
*   Fíjate en la palabra "**TYPEWRITER**" (máquina de escribir en inglés). Todas sus letras están en la **fila superior**, lo que la hacía muy fácil de demostrar para los vendedores y, de paso, evitaba atascos al usar esa palabra específica.

### 3. ¿Por qué no es Alfabético?
Un teclado alfabético (ABCDEF...) sería mucho más intuitivo de aprender, pero sería **terriblemente ineficiente** para escribir rápido.

*   Colocar las letras más usadas juntas (como A, E, I, O, S, T) en la fila central o en posiciones fáciles de alcanzar permite una escritura más fluida y ergonómica.
*   Aunque el objetivo principal de QWERTY era *ralentizar*, irónicamente, esta distribución resultó ser bastante buena para la mecanografía rápida con ambas manos, ya que alterna la carga de trabajo entre los dedos.

### 4. El Mito de la "Palabra TYPEWRITER"
Es un mito muy común que el teclado QWERTY se diseñó para que la palabra "TYPEWRITER" pudiera escribirse solo con la fila superior y así facilitar las demostraciones de venta. Si bien es una coincidencia curiosa, **no fue la razón principal de su diseño**. La razón de fondo era, como ya vimos, evitar los atascos.

### 5. La Inercia y la Estandarización: Por qué se quedó
Aunque los problemas técnicos de las máquinas de escribir ya no existen con los teclados digitales, el teclado QWERTY se mantuvo debido a:

*   **La inercia y el costo del cambio:** Para la década de 1890, miles de personas ya habían aprendido a mecanografiar con este sistema. Cambiar a uno nuevo (como el **Dvorak**, diseñado específicamente para la eficiencia y ergonomía) habría requerido reentrenar a millones de personas, rehacer todos los manuales y rediseñar la infraestructura. El costo era demasiado alto.
*   **El "Efecto Red":** Cuanta más gente usa un estándar, más valioso se vuelve. QWERTY se convirtió en la norma indiscutible.

### Resumen de las Razones:

| Parte del Teclado | ¿Por qué parece así? |
| :--- | :--- |
| **Fila Superior (QWERTYUIOP)** | Diseñada para colocar letras comunes en una posición que, junto con la fila central, permite alternar manos y evitar atascos. |
| **Fila Central (ASDFGHJKL)** | Actúa como la "fila base" o de descanso. Contiene vocales y consonantes muy comunes (A, S, D, F, J, K, L) para que los dedos estén en una posición neutral. |
| **Fila Inferior (ZXCVBNM)** | Alberga letras menos frecuentes. Su diseño también busca complementar la alternancia de manos. |
| **Teclas como J, K, etc.** | Están colocadas estratégicamente para ser alcanzadas por los dedos más fuertes (índice y corazón) y separar combinaciones problemáticas. |

**En conclusión:** La distribución QWERTY es un fascinante vestigio de la era mecánica. No es alfabética porque su diseño respondió a una necesidad técnica de **evitar atascos** separando letras de uso frecuente, y se mantuvo debido a la **inercia cultural y económica** de ser el primer estándar ampliamente adoptado.

Yo en general escribo con 3 dedos, el índice de la izquierda y derecha y el largo de la derecha.

Claro que no tiene sentido querer que el teclado universal español sea como me sirva, pero a ver... ¿es mejor que combinaciones poco usadas estén juntas? Por ejemplo K y L casi no uso, pero P y O sí. Sería interesante probar distintas distribuciones a ver cual queda más cómoda. Además a estas alturas no debería ser tan difícil hacer teclados configurables, en celular al menos.
El problema en parte es la costumbre. Quizá para quien esté acostumbrado, siempre el tiempo y esfuerzo que le tome escribir con otra configuración será mayor.

Yo sigo con el teclado que tiene ghosting o como se llame, no he podido conseguir uno mejor.

En fin, escribir PO me queda más cómodo que escribir QW, porque el dedo izquierdo largo lo tengo un poco atrofiado pero, a ver, o ponemos combinaciones comunes juntas o no, esto así como está no tiene sentido... ¿no puede una empresa española hacer teclados mejor adaptados al idioma español? Ah, ya no se venden tantos teclados...

¿?



Por curiosidad hice un test aquí:
https://10fastfingers.com/typing-test/spanish

Aparentemente no soy rápido, dice que algunos llegan a escribir 100 PPM  :o
3  Programación / Programación General / Black Jack ¿cómo llamar a las cartas? en: 18 Septiembre 2025, 06:28 am
Empiezo videojuego que se supone es sencillo de hacer:
Código
  1. // Generar array de cartas:
  2. Cartas = [];
  3. Nro = 0;
  4. do {
  5. Nro++;
  6. Cartas[Cartas.length] = "Pica"+Nro;
  7. Cartas[Cartas.length] = "Trebol"+Nro;
  8. Cartas[Cartas.length] = "Corazon"+Nro;
  9. Cartas[Cartas.length] = "Diamante"+Nro;
  10. } while (Nro < 13);
  11. // Ordenarlas al azar:
  12. Posicion1aReubicarse = Cartas.length-1;
  13. while (Posicion1aReubicarse>0) {
  14. Posicion2aReubicarse = random(Posicion1aReubicarse+1);
  15. // trace (Cartas[Posicion1aReubicarse]+" se intercambiará con "+Cartas[Posicion2aReubicarse]);
  16. SaveDeElemento1 = Cartas[Posicion1aReubicarse];
  17. Cartas[Posicion1aReubicarse] = Cartas[Posicion2aReubicarse];
  18. Cartas[Posicion2aReubicarse] = SaveDeElemento1;
  19. Posicion1aReubicarse--;
  20. }
  21. trace (Cartas);

Ejemplo de salida:
Corazon8,Diamante9,Trebol11,Trebol6,Diamante11,Corazon2,Corazon1,Pica2,Pica3,Pica5,etc

Cuando un jugador tome cartas, el programa deberá poder calcular cuánto suman.

Ya sé, en vez de ponerles nombres tan largos, les pongo:
P, T, C, D
luego cuando deba sumar les quito el caracter y ya tengo el número.

¿Algún método mejor? ¿consejos sobre cómo hacer el juego?

He pensado en estos pasos a seguir (orden a realizar, no es que en el código vayan a estar así):
- Lograr que las cartas se ordenen al azar. Hecho.
- Mensaje dice cuales son las 2 obtenidas.
- Se suman pero, las 1 valen 11 (salvo que sean 2 1s, en ese caso el 2ndo vale 1) y las que están por encima de 10 valen 10.
- Un rival también obtiene 2 cartas.
- Se suman por separado y se compara quién obtuvo mayor suma.
- Se pregunta al jugador si quiere otra carta. Si dice que sí se le da y se acaba, sino lo de siempre.
- Ajustar la suma, ahora 1 podría valer 1 o 11.
- El jugador puede pedir carta de nuevo, hasta... 4+8+12, digo, mientras tenga menos de 11 cartas. Eso fue calcular que tendría 4 de 1 (1*4=4), 4 de 2, y 4 de 3, las mínimas cartas, 12, pero con esas suma más de 21, no tiene sentido que llegue a tener 12.
- El rival tomará cartas mientras su suma no llegue a 17. Me lo dijo GPT, sólo sería para probar.
- Se analiza quién ganó y se dice en pantalla.
- Para cada posible situación (cartas de la IA y cuántas tiene la persona) generar un archivo txt cuyo nombre marque qué situación es.
- En cada archivo guardar 2 variables, ambas con valor 0: P y T. Plantarse o tomar.
- Cuando la partida acabe, si la IA ganó, aumentar 1 al valor de la acción que usó en las situaciones en que estuvo, sino restarle. No sé exacto cómo sería esto.
- La IA hace lo que el correspondiente archivo marque como más valioso.
- Lo de aumentar o restar se aplica usando también las cartas de la persona, o sea, desde su perspectiva, conociendo sus cartas pero no las de la IA.

También se podría hacer un generador de las situaciones posibles y probar cada acción así, pero las situaciones son como 52*51*50*49 para empezar...
Ah pero no importa si se tiene el 1 de pica o trebol, etc, así que...
10*10*10*10 para empezar. Igual serían demasiados archivos... La información se puede poner en 1 solo, o distinta info en más de 1, habrá que ver...

- Opción de jugar contra 2.
- Nuevo aprendizaje, basado en jugar contra 2.

Supongo que no llegaré a tanto xP
4  Foros Generales / Dudas Generales / Re: ¿Cómo elimino lo extra de una lista que quiero copiar? en: 18 Septiembre 2025, 03:39 am
Por ahora sólo probé el método simple de EdePC, me sirvió.

Aclaro que esa página no es muy completa que digamos.

Me hago mucho lío con los juegos, busco juegos simples, así que miro por año de lanzamiento, pero no son tan simples o fáciles, y algunos son horribles o no de mi gusto.
Otra cosa que hago es mirar los mejores de cada género, pero como las listas puede que estén incompletas...
Esta es mejor por si a alguien le interesa:
https://www.mobygames.com/game/platform:nes/sort:date/page:1/
Copiar es más fácil, sólo se selecciona todo, se copia, se pega, y usando Reemplazar se elimina una palabra que tienen delante.
5  Foros Generales / Foro Libre / Re: Game boy color por menos de 50 euros? en: 18 Septiembre 2025, 02:27 am
No sé si hablamos de lo mismo, si tienes PC no necesitas que sea portable, ni conviene creo.

Un emulador es un programa que en muchos casos ni siquiera se instala, sólo lo extraes del rar.

Luego, así como con Paint puedes abrir imágenes, con el emulador puedes abrir juegos, o sea ejecutarlos, jugarlos.

Claro que para jugar los juegos necesitas tenerlos, se llaman roms, los puedes descargar de Internet también.
6  Media / Juegos y Consolas / Re: [RETRO] que tan buenos son en arkanoid NES? en: 16 Septiembre 2025, 18:15 pm
Es posible que nunca termine de hacer un juego en mi vida...

Pero te paso:

Versión 17:
https://drive.google.com/file/d/1axzfOO3e1qwQB6k-Dcx_SRsRbGKv4FF9/view?usp=sharing
- Incluye un exe, un swf (que es como un exe pero menos peligroso pero requiere Flash Player) y un fla que es el archivo editable.
- Con A y S puedes apuntar a izquierda/derecha pero no hay límite creo, así que si lo presionas demasiado pronto tu disparo sale muy hacia el costado. Igual no es necesario presionarlas, sólo que en ese caso tus tiros tendrán dirección al azar.
- La dificultad depende de por cuántos puntos vayas ganando/perdiendo.
- Todos los tiros pueden tener comba, giro.

Versión 21, la más reciente:
https://drive.google.com/file/d/1f97thWcyVEkIuwrp62vcCKL7I7uGOUqu/view?usp=sharing
- Una diferencia es que ahora el apuntar funciona más lento y limitado, o sea, no se va para los costados por presionar el botón un ratito antes, requiere presionarlo antes. Además aparece una mira que indica hacia dónde estás apuntando.
- Tus tiros no tienen curva. Eso hace que el juego esté bastante injusto, está así porque tenía que chequear que los tiros vayan a donde se apunta, si se curvan puede que vayan para otro lado, y agregar el factor curva en los cálculos es algo que en principio no hice, es algo que tengo pensado hacer.

La raqueta troll:
https://drive.google.com/file/d/11rT7sH4D3B56Lc7I4O2EElx21W_QCv2P/view?usp=sharing
- Aparentemente lo hice en el 2013, sólo tengo el swf, los demás archivos estarán en algún DVD que debo revisar.
- Es como una versión más simple de Pong, no hay rival ni cosas que romper, simplemente la pelota cae.
- El modo A tarda en ponerse rápido.
- El modo B es más rápido pero si mal no recuerdo no ocurren las cosas "locas" que pueden ocurrir en el A. Es que ahí cuando la bola toca una pared su rotación cambia, en tenis el efecto liftado hace que la bola caiga rápido y el cortado lento o que incluso comience a ir hacia arriba luego de haber bajado (pero es muy difícil de hacer, con pelotas de espumaplaz es más fácil), entonces si la pelota tiene liftado y toca una pared, en el juego cambia a cortado y eso hace que la bola empiece a subir, o cosas así.
7  Foros Generales / Foro Libre / Re: Game boy color por menos de 50 euros? en: 16 Septiembre 2025, 17:37 pm
¿Seguro que no te sirve un emulador?

Yo uso VisualBoyAdvance. Sirve para GB y GBC también, no sólo GBA.

- Son gratis y también los juegos.
- Puedes poner cheats.
- Puedes copiar tu partida de Pokemon Gold por ejemplo, a una partida de Pokemon Silver, entonces con el mismo personaje atrapar Pokemon de Gold y Silver, además transmitirte Pokemon de un juego a otro es algo que no podrías hacer con sólo 1 Game boy, creo.
- Puedes pelear contra ti mismo (yo tengo pensado hacerlo, pero quiero aprender cosas de otros juegos más simples antes).
- En Mario Tennis de GBC puedes pasarte personajes y retos de N64 sin tener un N64. Pero esto es medio complicado... Yo lo vi hace años no sé dónde y poco recuerdo de eso. Pero tengo una partida con todo.
- Puedes guardar/cargar en cualquier momento.
- Puedes acelerar la partida.
- Puedes jugar en una pantalla más grande.

Qué sé yo, las ventajas son abrumadoras.
8  Foros Generales / Dudas Generales / ¿Cómo elimino lo extra de una lista que quiero copiar? en: 14 Septiembre 2025, 20:56 pm
https://www.nintendolife.com/games/browse?sort=score&system=nes&genre=action

Quisiera copiar los nombres de los juegos, pero al ir arrastrando el mouse para copiar la lista entera, se copian más cosas.

De lo que se me ocurre lo mejor me parece pegarlo en Excel (de hecho lo quiero ahí) y cada X filas (donde aparezca lo que quiero copiar) poner un número en otra columna, luego ordenar por ese número. El problema es que quizá haya casos en que los juegos estén más abajo o más arriba, o sea que haya distintas filas de diferencia. Busco un método más seguro.
9  Foros Generales / Foro Libre / Re: Un vídeo inédito muestra un ovni resistiendo el ataque de un misil Hellfire de EEUU en la costa de Yemen en: 13 Septiembre 2025, 19:10 pm
Los videos que presenta el gobierno suelen ser en blanco y negro y no se ven claro.

Yo tengo uno a color pero creo que es un dron porque no parece muy lejano y se ve bajar, además tampoco se ve bien. Lo tengo en celular, no sé cómo pasarlo a PC.
Es sólo una luz que cambia de color a rojo y azul. Parecía estar girando. El video tiene zoom al máximo y está un poco borrosa esa luz.
Ese día anduvo mucho un helicóptero. Cuando volví a casa vi una luz celeste, que podía ser el helicóptero pero su luz de no tiene ese color que yo sepa. Luego no me acuerdo si empezó a tener luces más intensas y cambiar de color, o si antes de eso fui a buscar el celular y un láser. Creo que fui cuando vi que no es una luz celeste cualquiera, que de hecho como digo ya de por sí era raro. Puede que sea un dron de la policía o alguien estuviera jugando/probando uno, no sé. Tengo pensado ir a consultar, pasa que no salgo con el celular como para eso. El objeto es estaba moviendo medio al azar, no pude ver bien, pero más o menos iba hacia el oeste, y quedó en un sitio donde lo pude ver mejor. Subió un poco, se movió para un costado, hizo así pocos movimientos como al azar, y bajó. Hay árboles delante así que ni idea dónde o qué hizo luego.

Ya conseguí un método. El video fue cortado unas 4 veces para evitar que se vean unas cosas del sitio.
https://drive.google.com/file/d/1FvlvKa6cmeXVVccNCupEym-JFYP8XzF4/view?usp=sharing
10  Programación / Programación General / Re: Elección al azar de punto de elipse o rectángulo. Misma probabilidad para cada punto. en: 8 Septiembre 2025, 23:29 pm
Conseguí la respuesta:
Código
  1. onClipEvent (load) {
  2. Globos = 0;
  3. }
  4. onClipEvent (enterFrame) {
  5. t = random(Math.PI*2);
  6. x = 100 * Math.cos(t);
  7. y = 50 * Math.sin(t);
  8. Globos++;
  9. if (Globos > 100) {
  10. Globos = 1;
  11. }
  12. Name = "Globo"+Globos;
  13. attachMovie("sGlobo", Name, Globos);
  14. setProperty (Name, _x, x );
  15. setProperty (Name, _y, y );
  16. }

https://youtu.be/1mV1lUpW2iw
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 243
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines