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


Tema destacado:


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 [7] 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... 235
61  Programación / Programación General / ¿Cómo mejoro mi juego Signos en linea? en: 24 Marzo 2025, 23:59 pm
Sobre ponerle IA ya hice un tema, en ese sentido no pregunto en este.

Tampoco sobre el modo conque chequea si hubo victoria.

Lo que pregunto tiene que ver conque quiero agregarle cosas, por ejemplo:
- Opción de que jueguen más de 2 jugadores.
- Si es posible, opción de casilleros con otras formas, de modo que la cantidad de direcciones posibles sea distinta a 8. Por ahora sólo vi de 6:
https://es.wikipedia.org/wiki/Teselado_hexagonal
- Opción de que no se gane por hacer una línea de signos requeridos, sino por ser quien haya hecho más cuando el tablero esté lleno.
- Opción de que se gane por tener la mayor cantidad de unidos, independientemente de cuan larga sea la línea. Aunque debo pensar si esto tendría gracia.
- Opción de que se gane por haber formado la línea más larga posible (puede ocurrir antes de que el casillero se llene).
- Opciones anti, como el antichess, o sea, que en vez de ganar por hacer una cosa u otra, eso lleve a perder.
- Opción de que se gane no por hacer una línea, sino alguna figura. Por ejemplo una L.
- Opción de que gane quien haga la figura más grande.
- Opción de que en vez de ser signos se pongan letras y gane quien 1ero forme una palabra.
- Que gane quien forme más palabras.
- Las letras a poner van rotando, el jugador no elige. Por ejemplo si hay que formar "Win".
- Al comienzo los jugadores se turnan en elegir una letra, luego empieza el juego poniéndolas según el orden conque las eligieron.
- Lo mismo pero en cualquier orden.
- Lo mismo pero puedes usar las letras de tu oponente.
- Repetición de letras se permite.

Y tal vez más... Algunas cosas no son excluyentes.

Algunas cosas quizá sea mejor hacerlas en un programa aparte, pero ya que son juegos tan similares sería bueno un "todo en 1" ¿no? Además no sé cuales debería hacer aparte, tal vez el que se puede poner letras y el que es sobre formar figuras. Serían 3. ¿Ustedes harían 3 juegos o más o menos?

Teniendo en cuenta todo eso, quisiera que mi código esté mejor preparado, porque intenté hacrlo eficiente pero en eso decidí hacerlo así nomás y por ahora está así. ¿Cómo lo mejorarían?

Imagen para referencia:


Frame 1:
Código
  1. CasillerosPorFila = 9;
  2. JuntosRequeridos = 3;
  3. MarcadorDeX = "Humano";
  4. MarcadorDe0 = "IA";
  5. Jugadores = "HumanoIA";
  6. // Usado en el botón de quién marca con X:
  7. function CambiarMarcadorDeX () {
  8. if (MarcadorDeX == "Humano") {
  9. MarcadorDeX = "IA";
  10. } else {
  11. MarcadorDeX = "Humano";
  12. }
  13. Jugadores = MarcadorDeX+MarcadorDe0;
  14. HacerTablero();
  15. }
  16. // Usado en el botón de quién marca con 0:
  17. function CambiarMarcadorDe0 () {
  18. if (MarcadorDe0 == "IA") {
  19. MarcadorDe0 = "Humano";
  20. } else {
  21. MarcadorDe0 = "IA";
  22. }
  23. Jugadores = MarcadorDeX+MarcadorDe0;
  24. HacerTablero();
  25. }
  26. // Usado ahora y en general cuando se cambia la configuración de la partida:
  27. function HacerTablero () {
  28. // Esto se irá especificando en el próximo while:
  29. Situacion = [];
  30. PosiblesAcciones = [];
  31. // Los casilleros se cuentan desde 0:
  32. MaxCasillero = CasillerosPorFila*CasillerosPorFila-1;
  33. // Las columnas también. Esto es para no repetir restas por ahí:
  34. MaxColumna = CasillerosPorFila-1;
  35. LargoDeCasilleros = 384/CasillerosPorFila;
  36. NroDeCasilleroaColocar = -1;
  37. // Sus columnas y filas se cuentan desde 0,
  38. // sirven para posicionarlos más fácil:
  39. Columna = 0;
  40. Fila = 0;
  41. do {
  42. NroDeCasilleroaColocar++;
  43. // v es vacío:
  44. Situacion.push("v");
  45. PosiblesAcciones.push(NroDeCasilleroaColocar);
  46. CasilleroaColocar = "Casillero"+NroDeCasilleroaColocar;
  47. // set ("SignoEn"+CasilleroaColocar, "v");
  48. // sCasillero tiene código:
  49. attachMovie("sCasillero", CasilleroaColocar, NroDeCasilleroaColocar);
  50. setProperty (CasilleroaColocar, _x, LargoDeCasilleros*Columna);
  51. setProperty (CasilleroaColocar, _y, LargoDeCasilleros*Fila);
  52. setProperty (CasilleroaColocar, _width, LargoDeCasilleros);
  53. setProperty (CasilleroaColocar, _height, LargoDeCasilleros);
  54. Columna++;
  55. if (Columna == CasillerosPorFila) {
  56. Columna = 0;
  57. Fila++;
  58. }
  59. // Para que al presionar el botón se sepa qué modificar:
  60. set (CasilleroaColocar+".CasilleroAsociado", NroDeCasilleroaColocar);
  61. // trace("Colocado el "+NroDeCasilleroaColocar);
  62. } while (NroDeCasilleroaColocar < MaxCasillero);
  63. // Para que no muestre el mensaje de victoria:
  64. Win = "No";
  65. // Esto es para evitar restas:
  66. LastNroDeAcccionPosible = PosiblesAcciones.length-1;
  67. trace ("LastNroDeAcccionPosible: "+LastNroDeAcccionPosible);
  68. SignoDeTurno = "X";
  69. if (Jugadores == "HumanoIA") {
  70. gotoAndStop(2);
  71. } else if (Jugadores == "IAHumano") {
  72. TurnoDeIA();
  73. if (Win == "No") {
  74. // OJO QUE SI HAY EMPATE NO DEBE IR AL F2, O NO ES NEC
  75. gotoAndStop(2);
  76. }
  77. } else if (Jugadores == "HumanoHumano") {
  78. gotoAndStop(2);
  79. } else {
  80. // IA VS IA:
  81. InutilizarBotones();
  82. gotoAndStop(3);
  83. }
  84. }
  85. HacerTablero();
  86. // Usada cuando el humano marca en un casillero:
  87. function HumanoHaMarcado () {
  88. // trace("PosiblesAcciones.length: "+PosiblesAcciones.length);
  89. // trace("Humano ha marcado");
  90. // Inutilizar botón del casillero marcado:
  91. setProperty (eval("Casillero"+CasilleroMarcado+".Boton"), _visible, false);
  92. // Agregar signo:
  93. // SignosColocados++;
  94. eval("Casillero"+CasilleroMarcado).attachMovie("s"+SignoDeTurno, "Signo", 1);
  95. Situacion[CasilleroMarcado] = SignoDeTurno;
  96. // set ("SignoEnCasillero"+CasilleroMarcado, "X");
  97. // ¿Gana?
  98. // Si esta función dice que no, usa otras:
  99. ChequearVertical();
  100. if (Win == "Sí") {
  101. // Sí, inutilizar botones del tablero
  102. // (debería ser sólo los activos):
  103. InutilizarBotones();
  104. // Mostrar mensaje de victoria:
  105. attachMovie("sGano"+SignoDeTurno, "Mensaje", NroDeCasilleroaColocar+1);
  106. UbicarMensaje();
  107. } else if (PosiblesAcciones.length>=2) {
  108. // Sino, si aún hay >=2 acciones posibles
  109. // (la que usó aún no se quitó):
  110. // Quitar su acción de las posibles acciones:
  111. // Se busca en qué posición del array está:
  112. AccionRevisandose = -1;
  113. // Condición original: AccionRevisandose < LastNroDeAcccionPosible
  114. do {
  115. AccionRevisandose++;
  116. if (PosiblesAcciones[AccionRevisandose] == CasilleroMarcado) {
  117. // Se elimina la acción de la lista de posibles:
  118. PosiblesAcciones.splice(AccionRevisandose, 1);
  119. trace (PosiblesAcciones.join(""));
  120. break;
  121. }
  122. } while (true);
  123. LastNroDeAcccionPosible--;
  124. trace ("LastNroDeAcccionPosible disminuyó: "+LastNroDeAcccionPosible);
  125. // trace("PosiblesAcciones.length: "+PosiblesAcciones.length);
  126. CambiarSigno();
  127. if (Jugadores == "HumanoIA" or Jugadores == "IAHumano") {
  128. TurnoDeIA();
  129. }
  130. } else {
  131. // (sólo queda 1 acción en la lista,
  132. // pero es la que acaba de usar,
  133. // que debe borrarse, así que no quedan)
  134. trace ("Empate luego de que marcó el humano");
  135. // trace("PosiblesAcciones.length: "+PosiblesAcciones.length);
  136. Empate();
  137. }
  138. }
  139. // Usada en ChequeoHorizontal y requerida en otros chequeos:
  140. function ObtenerColumnayFilaDelMarcado () {
  141. ColumnaDelMarcado = CasilleroMarcado%CasillerosPorFila;
  142. // trace ("Su Columna según el cálculo es: "+ColumnaDelMarcado);
  143. FilaDelMarcado = Math.floor(CasilleroMarcado/CasillerosPorFila);
  144. // trace ("Su Fila: "+FilaDelMarcado);
  145. }
  146. // Usada cuando alguien gana o en HacerTablero si es IA VS IA:
  147. function InutilizarBotones () {
  148. BotonesInutilizados = -1;
  149. do {
  150. BotonesInutilizados++;
  151. setProperty ("Casillero"+BotonesInutilizados+".Boton", _visible, false);
  152. } while (BotonesInutilizados<MaxCasillero);
  153. }
  154. // Usada cuando hay que ubicar un mensaje, duh:
  155. function UbicarMensaje () {
  156. setProperty (Mensaje, _x, 192.4);
  157. setProperty (Mensaje, _y, 192);
  158. // gotoAndStop (3);
  159. }
  160. // En caso de empate:
  161. function Empate () {
  162. attachMovie("sEmpate", "Mensaje", NroDeCasilleroaColocar+1);
  163. UbicarMensaje();
  164. // Para que en el modo IA VS IA, la IA no juegue más:
  165. Win = "Sí";
  166. trace("Empate");
  167. }
  168. function CambiarSigno () {
  169. if (SignoDeTurno == "X") {
  170. SignoDeTurno = 0;
  171. } else {
  172. SignoDeTurno = "X";
  173. }
  174. }
  175. function TurnoDeIA () {
  176. // Elegir una acción al azar:
  177. NroDeAccionElegida = random(PosiblesAcciones.length);
  178. AccionElegida = PosiblesAcciones[NroDeAccionElegida];
  179. trace ("IA ha marcado: "+AccionElegida);
  180. // Eliminar la que está en el nro elegido:
  181. PosiblesAcciones.splice(NroDeAccionElegida, 1);
  182. trace (PosiblesAcciones.join(""));
  183. LastNroDeAcccionPosible--;
  184. trace ("LastNroDeAcccionPosible disminuyó: "+LastNroDeAcccionPosible);
  185. eval("Casillero"+AccionElegida).attachMovie("s"+SignoDeTurno, "Signo", 0);
  186. Situacion[AccionElegida] = SignoDeTurno;
  187. // Inutilizar el botón de ahí:
  188. setProperty (eval("Casillero"+AccionElegida+".Boton"), _visible, false);
  189. // Ver si IA ganó:
  190. CasilleroMarcado = AccionElegida;
  191. // trace ("JuntosRequeridos: "+JuntosRequeridos);
  192. ChequearVertical();
  193. // trace("PosiblesAcciones.length: "+PosiblesAcciones.length);
  194. if (Win == "Sí") {
  195. // Sí, inutilizar botones del tablero
  196. // (debería ser sólo los activos):
  197. InutilizarBotones();
  198. // Mostrar mensaje de victoria:
  199. attachMovie("sGano"+SignoDeTurno, "Mensaje", NroDeCasilleroaColocar+1);
  200. UbicarMensaje ();
  201. } else if (PosiblesAcciones.length == 0) {
  202. trace ("Empate luego de que marcó la IA");
  203. // trace("PosiblesAcciones.length: "+PosiblesAcciones.length);
  204. Empate();
  205. } else {
  206. CambiarSigno();
  207. }
  208. }

ChequeoHorizontal lo que hace es fijarse si hay victoria. Si hay, hace que Win sea "Sí". Sino, llama a otros chequeos que hacen cosas parecidas. Pueden ver el código en mi otro tema reciente, pero como dije no es la cuestión aquí.

Frame 2:
stop();
Nada relevante aquí, simplemente ocurre el juego, el jugador hace clic en los casilleros. Los casilleros tienen un botón con esto:
Código:
on (release) {
_level0.CasilleroMarcado = _parent.CasilleroAsociado;
_level0.HumanoHaMarcado();
}

Frame 3:
Aquí funciona el modo IA VS IA, un objeto tiene:
Código
  1. onClipEvent (enterFrame) {
  2. trace("SignoDeTurno: "+_level0.SignoDeTurno);
  3. _level0.TurnoDeIA();
  4. trace("Win: "+_level0.Win);
  5. if (_level0.Win == "No") {
  6. trace("SignoDeTurno: "+_level0.SignoDeTurno);
  7. _level0.TurnoDeIA();
  8. trace("Win: "+_level0.Win);
  9. }
  10. trace("Win: "+_level0.Win);
  11. // No va un else, esto es que si la IA ganó en su 1er turno o...
  12. // en su 2ndo, frana:
  13. if (_level0.Win == "Sí") {
  14. trace("Va al frame 2");
  15. _root.gotoAndStop (2);
  16. }
  17. }

No me gusta mucho usar distintos frames pero parece la forma más eficiente de evitar ifs, evals, etc, no sé...
62  Programación / Programación General / ¿Cómo hacer un programa que aprenda a jugar expertamente Signos en línea? en: 24 Marzo 2025, 07:12 am
Aquí pueden ver a la máquina jugando al azar:
https://youtu.be/NtGWCFXvfk8

En vez de 4 en línea puede ser 3, 5, etc.

Lo que tengo no es suficiente y no lo apliqué:
Código
  1. // Signos en línea en tablero de Lado*Lado:
  2. // Este programa tiene básicamente 2 etapas,
  3. // que se pueden resumir así:
  4. // 1:
  5. // Desde la situación inicial probar las acciones,
  6. // guardando las situaciones nuevas,
  7. // y probando acciones en ellas también.
  8. // Guardar las situación-acción que causan una victoria,
  9. // y las que causan un empate. Es el RE de esa situación,
  10. // resultado esperado (porque en otros casos es el que...
  11. // se espera o supone si el rival juega bien).
  12. // 2: ACTUALIZAR ESTA
  13. // En las situaciones no resueltas, probar las acciones.
  14. // Si las consecuencias tienen RE, anotar cuantas de ellas...
  15. // son victoria de X, 0 o empate y anotar la acción que...
  16. // cause la RE más favorable, considerando secundariamente...
  17. // las cantidades.
  18. //
  19. JuntosRequeridos = 2;
  20. CasillerosPorFila = 2;
  21. // Contando desde 0:
  22. MaxColumna = CasillerosPorFila-1;
  23. // Los casilleros están numerados así:
  24. // 0 1 2
  25. // 3 4 5
  26. // 6 7 8
  27. Casilleros = CasillerosPorFila*CasillerosPorFila;
  28. MaxCasillero = Casilleros-1;
  29. // Uso arrays porque es más fácil así modificar partes...
  30. // de los valores de variables (los casilleros):
  31. // Situación a experimentar nro 1, signo en los casilleros
  32. // (a este array se le agregarán valores):
  33. SaE1 = [];
  34. ValoraAgregar = -1;
  35. do {
  36. ValoraAgregar++;
  37. // v significa vacío
  38. SaE1.push("v");
  39. // trace("ValoraAgregar es "+ValoraAgregar);
  40. } while (ValoraAgregar < MaxCasillero);
  41. delete (ValoraAgregar);
  42. // Situaciones a experimentar (cuántas son):
  43. SaE = 1;
  44. NroDeSExperimentandose = 0;
  45. NoEvaluedSaE = "SaE1";
  46. SaEEvaluedyJoined = "S"+(eval(NoEvaluedSaE).join(""));
  47. // Usada para fácilmente saber de qué signo es turno:
  48. set (SaEEvaluedyJoined+"Turno", "X");
  49. // Con LastAPosible, usada para evitar probar...
  50. // acciones innecesarias y saber si sólo queda 1:
  51. set (SaEEvaluedyJoined+"FirstAPosible", 0);
  52. set (SaEEvaluedyJoined+"LastAPosible", MaxCasillero);
  53. // Usada a continuación y en varios casos:
  54. function PrepararExperimentosEnOtraS () {
  55. // trace("Ejecutando PrepararExperimentosEnOtraS");
  56. NroDeSExperimentandose++;
  57. trace("Se inician experimentos en otra situación, la anotada nro "+NroDeSExperimentandose);
  58. // Usada para evitar concatenar repetidamente:
  59. NoEvaluedSaE = "SaE"+NroDeSExperimentandose;
  60. SituacionBase = eval(NoEvaluedSaE);
  61. SaEEvaluedyJoined = "S"+(SituacionBase.join(""));
  62. Turno = eval(SaEEvaluedyJoined+"Turno");
  63. FirstActionPosible = eval(SaEEvaluedyJoined+"FirstAPosible");
  64. LastActionPosible = eval(SaEEvaluedyJoined+"LastAPosible");
  65. Action = FirstActionPosible;
  66. }
  67. PrepararExperimentosEnOtraS();
  68. // Usada en frame 2 repetidamente:
  69. function BuscarBuenasSituacionesEt1 () {
  70. // Plantear situación porque puede modificarse pero...
  71. // podría requerirse su estado original luego:
  72. Situacion = SituacionBase.slice();
  73. // trace("La situación experimentándose es "+Situacion);
  74. EvaluarAplicabilidadEt1();
  75. }
  76. // Usada luego de que cambia la SaE y/o la acción:
  77. function EvaluarAplicabilidadEt1 () {
  78. // trace("Ejecutando EvaluarAplicabilidadEt1");
  79. if (Situacion[Action] == "v") {
  80. // trace("La acción "+Action+" es realizable.");
  81. AplicarAccionEt1();
  82. } else {
  83. // trace("La acción "+Action+" no es realizable.");
  84. BuscarAccionEt1();
  85. }
  86. }
  87. // Usada luego de EvaluarAplicabilidadEt1,
  88. // si una acción es realizable:
  89. function AplicarAccionEt1 () {
  90. // trace("Ejecutando AplicarAccionEt1");
  91. Situacion[Action] = Turno;
  92. // trace("Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  93. // ¿Ganó?
  94. // Si no se detecta victoria vertical,
  95. // revisa de otros modos (ver las funciones Chequear):
  96. ChequearVertical();
  97. if (Win == "Sí") {
  98. // Sí, crear datos sobre eso:
  99. // trace("Ganó, ahora se sabe que en la situación "+SituacionBase+" se gana usando la acción "+Action);
  100. set (SaEEvaluedyJoined+"BestAction", Action);
  101. set (SaEEvaluedyJoined+"RE", Turno);
  102. // Se borra la situación de la lista a experimentar,
  103. // pues ya se halló la mejor acción en ella:
  104. BorrarSaE();
  105. BuscarOtraSituacionEt1();
  106. } else if (FirstActionPosible == LastActionPosible) {
  107. // sino si es empate (no hay más acciones posibles):
  108. // Parecido, crear datos sobre eso:
  109. // trace("Empató, ahora se sabe que en la situación "+SituacionBase+" se empata usando la acción "+Action);
  110. // (y es la mejor acción porque no hay otra)
  111. set (SaEEvaluedyJoined+"BestAction", Action);
  112. set (SaEEvaluedyJoined+"RE", "Empate");
  113. // Se borra la situación de la lista a experimentar,
  114. // pues ya se halló la mejor acción en ella:
  115. BorrarSaE();
  116. BuscarOtraSituacionEt1();
  117. } else {
  118. EvaluarConocimientoSobreSEt1();
  119. // ¿Queda alguna acción sin probar...
  120. // en la situación?
  121. BuscarAccionEt1();
  122. }
  123. }
  124. // Usada luego de AplicarAccionEt1,
  125. // si causa victoria o empate:
  126. function BorrarSaE () {
  127. // La última SaE ponerla en la actual:
  128. // trace("ATENCIÓN: "+NoEvaluedSaE+", que es "+SaEEvaluedyJoined);
  129. set (NoEvaluedSaE, eval("SaE"+SaE).slice());
  130. // trace("...ahora es: "+eval(NoEvaluedSaE));
  131. // Borrar la última:
  132. delete (eval("SaE"+SaE));
  133. // Indicar que hay una menos:
  134. SaE--;
  135. // También se borran datos prácticos que ya no se usarán:
  136. // trace("SaEEvaluedyJoined: "+SaEEvaluedyJoined);
  137. // trace("SaEEvaluedyJoined+Turno: "+eval(SaEEvaluedyJoined+"Turno"));
  138. delete (eval(SaEEvaluedyJoined+"Turno"));
  139. // trace("SaEEvaluedyJoined+Turno: "+eval(SaEEvaluedyJoined+"Turno"));
  140. delete (eval(SaEEvaluedyJoined+"FirstAPosible"));
  141. delete (eval(SaEEvaluedyJoined+"LastAPosible"));
  142. // Indicar que vuelva a invertigarse la del número actual,
  143. // pues ahora es otra:
  144. NroDeSExperimentandose--;
  145. }
  146. // Usada luego de EvaluarAplicabilidadEt1,
  147. // cuando una acción no es realizable:
  148. function BuscarAccionEt1 () {
  149. // trace("Ejecutando BuscarAccionEt1");
  150. if (Action < LastActionPosible) {
  151. // Si queda alguna acción sin probar...
  152. // en la situación, probarla:
  153. Action++;
  154. // Se ejecutará BuscarBuenasSituaciones.
  155. } else {
  156. // trace("No hay más acciones realizables.");
  157. BuscarOtraSituacionEt1();
  158. }
  159. }
  160. // Usada luego de que hay victoria, empate o si no hay más acciones posibles:
  161. function BuscarOtraSituacionEt1 () {
  162. // trace("Ejecutando BuscarOtraSituacionEt1");
  163. if (SaE > NroDeSExperimentandose) {
  164. PrepararExperimentosEnOtraS();
  165. } else {
  166. trace( "No hay más situaciones a experimentar; inicia la etapa 2.");
  167. // IniciarEtapa2();
  168. gotoAndStop(4);
  169. }
  170. }
  171. // Usada en AplicarAccionEt1 cuando no hay victoria ni empate:
  172. function EvaluarConocimientoSobreSEt1 () {
  173. // trace("Ejecutando EvaluarConocimientoSobreSEt1");
  174. SituacionJoined = Situacion.join("");
  175. NombreDeSituacion = "S"+SituacionJoined;
  176. ResumenDeBest = NombreDeSituacion+"BestAction";
  177. // ¿Se ha llegado antes a la situación?
  178. if (eval(ResumenDeBest) == undefined) {
  179. // No, anotar que debe investigarse:
  180. SaE++;
  181. // Copiar array (porque no se puede normalmente):
  182. set ("SaE"+SaE, Situacion.slice());
  183. // trace("Esa situación no está anotada; se anota como nro "+SaE);
  184. set(ResumenDeBest, "Desconocida");
  185. if (Turno == "X") {
  186. set (NombreDeSituacion+"Turno", "0");
  187. } else {
  188. set (NombreDeSituacion+"Turno", "X");
  189. }
  190. // Averiguar cual es su 1er acción posible:
  191. AccionRevisandose = -1;
  192. do {
  193. AccionRevisandose++;
  194. if (Situacion[AccionRevisandose] == "v") {
  195. set (NombreDeSituacion+"FirstAPosible", AccionRevisandose);
  196. break;
  197. }
  198. } while (true);
  199. // Averiguar cual es su última acción posible:
  200. AccionRevisandose = Casilleros;
  201. do {
  202. AccionRevisandose--;
  203. if (Situacion[AccionRevisandose] == "v") {
  204. set (NombreDeSituacion+"LastAPosible", AccionRevisandose);
  205. break;
  206. }
  207. } while (true);
  208. }
  209. }
  210. function ObtenerColumnayFilaDelMarcado () {
  211. FilaDelMarcado = Math.floor(Action/CasillerosPorFila);
  212. ColumnaDelMarcado = Action%CasillerosPorFila;
  213. }
  214. function ChequearVertical () {
  215. // trace ("Ejecutando ChequearVertical");
  216. //
  217. // SOLO FUNCIONA SI CasillerosPorFila >= JuntosRequeridos.
  218. //
  219. // Se revisará la vertical. Desde el casillero más arriba...
  220. // que pueda estar incluído en la línea,
  221. // hasta el casillero marcado. Si se haya alguno que no...
  222. // tenga la marca requerida, se repite el proceso mirando...
  223. // desde uno más abajo del fallado, y mirando ahora hasta...
  224. // más abajo, según corresponda:
  225. Desde = Action-CasillerosPorFila*(JuntosRequeridos-1);
  226. // Mientras el casillero no exista:
  227. while (Desde<0) {
  228. // trace ("Desde es "+Desde+", se aumentará");
  229. // Indicar que se empiece a mirar desde más abajo:
  230. Desde = Desde+CasillerosPorFila;
  231. }
  232. do {
  233. Hasta = Desde+CasillerosPorFila*(JuntosRequeridos-1);
  234. if (Hasta>MaxCasillero) {
  235. // Para ganar se necesitaría más casilleros hacia...
  236. // abajo de los que hay, terminar análisis:
  237. // trace ("No hay suficientes cuadraditos abajo");
  238. break;
  239. }
  240. Puntero = Desde;
  241. // trace ("Comenzando chequeo desde "+Desde+" hasta "+Hasta);
  242. // Puede cambiar:
  243. Win = "Sí";
  244. do {
  245. // trace ("Chequando el casillero "+Puntero);
  246. if (Situacion[Action] != Situacion[Puntero]) {
  247. Win = "No";
  248. Desde = Puntero+CasillerosPorFila;
  249. break;
  250. }
  251. Puntero = Puntero+CasillerosPorFila;
  252. } while (Puntero<=Hasta);
  253. } while (Desde<=Action && Win == "No");
  254. if (Win == "No") {
  255. ChequearHorizontal();
  256. }
  257. }
  258. function ChequearHorizontal () {
  259. // trace ("Ejecutando ChequearHorizontal");
  260. // Es similar al chequeo vertical, pero aquí no sirve...
  261. // sumar o restar a un puntero que marque el casillero...
  262. // porque puede existir ese casillero pero no estar en...
  263. // un costado. En vez de eso, se obtiene su columna y...
  264. // fila, se modifica la columna si es posible,
  265. // y se calcula cual es el casillero a mirar:
  266. ObtenerColumnayFilaDelMarcado();
  267. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  268. // Para que no mire cuadraditos inexistentes en la izq:
  269. if (DesdeColumna<0) {
  270. DesdeColumna = 0;
  271. }
  272. do {
  273. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  274. if (HastaColumna>MaxColumna) {
  275. // Para ganar se necesitaría más casilleros hacia...
  276. // la derecha de los que hay, terminar análisis:
  277. // trace ("No hay suficientes cuadraditos a la derecha");
  278. break;
  279. }
  280. Puntero = DesdeColumna;
  281. // trace ("Comenzando chequeo desde "+DesdeColumna+" hasta "+HastaColumna);
  282. // Puede cambiar:
  283. Win = "Sí";
  284. do {
  285. CasilleroaMirar = FilaDelMarcado*CasillerosPorFila+Puntero;
  286. // trace ("Chequando el casillero "+CasilleroaMirar);
  287. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  288. Win = "No";
  289. DesdeColumna = Puntero+1;
  290. break;
  291. }
  292. Puntero++;
  293. } while (Puntero<=HastaColumna);
  294. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  295. if (Win == "No") {
  296. ChequearDesdeUpIzq();
  297. }
  298. }
  299. // La diagonal así \
  300. function ChequearDesdeUpIzq () {
  301. // trace ("Ejecutando ChequearDesdeUpIzq");
  302. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  303. // trace("DesdeColumna: "+DesdeColumna);
  304. DesdeFila = FilaDelMarcado-JuntosRequeridos+1;
  305. // trace("DesdeFila: "+DesdeFila);
  306. // Para que no mire cuadraditos inexistentes:
  307. if (DesdeColumna<DesdeFila) {
  308. Sumar = DesdeColumna;
  309. } else {
  310. Sumar = DesdeFila;
  311. }
  312. // trace("Sumar: "+Sumar);
  313. if (Sumar<0) {
  314. // trace("Sumando.");
  315. DesdeColumna = DesdeColumna-Sumar;
  316. // trace("DesdeColumna: "+DesdeColumna);
  317. DesdeFila = DesdeFila-Sumar;
  318. // trace("DesdeFila: "+DesdeFila);
  319. }
  320. do {
  321. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  322. if (HastaColumna>MaxColumna) {
  323. // Para ganar se necesitaría más casilleros hacia...
  324. // la derecha de los que hay, terminar análisis:
  325. // trace ("No hay suficientes cuadraditos a la derecha");
  326. break;
  327. }
  328. HastaFila = DesdeFila+JuntosRequeridos-1;
  329. // Sirve usar MaxColumna en vez de crear MaxFila...
  330. // porque como el tablero es cuadrado serían iguales:
  331. if (HastaFila>MaxColumna) {
  332. // Para ganar se necesitaría más casilleros hacia...
  333. // abajo de los que hay, terminar análisis:
  334. // trace ("No hay suficientes cuadraditos abajo");
  335. break;
  336. }
  337. PunteroDeColumna = DesdeColumna;
  338. PunteroDeFila = DesdeFila;
  339. // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila);
  340. // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila);
  341. // Puede cambiar:
  342. Win = "Sí";
  343. do {
  344. CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna;
  345. // trace ("Chequando el casillero "+CasilleroaMirar);
  346. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  347. Win = "No";
  348. DesdeColumna = PunteroDeColumna+1;
  349. DesdeFila = PunteroDeFila+1;
  350. break;
  351. }
  352. PunteroDeColumna++;
  353. PunteroDeFila++;
  354. } while (PunteroDeColumna<=HastaColumna);
  355. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  356. if (Win == "No") {
  357. ChequearDesdeDownIzq();
  358. }
  359. }
  360. // La diagonal así /
  361. function ChequearDesdeDownIzq () {
  362. // trace ("Ejecutando ChequearDesdeDownIzq");
  363. DesdeColumna = ColumnaDelMarcado-JuntosRequeridos+1;
  364. // trace("DesdeColumna: "+DesdeColumna);
  365. DesdeFila = FilaDelMarcado+JuntosRequeridos-1;
  366. // trace("DesdeFila: "+DesdeFila);
  367. // Para que no mire cuadraditos inexistentes:
  368. ColumnasInexistentes = 0;
  369. if (DesdeColumna<0) {
  370. ColumnasInexistentes = DesdeColumna*-1;
  371. }
  372. FilasInexistentes = 0;
  373. // Está bien usar MaxColumna porque MaxFila sería igual:
  374. if (DesdeFila>MaxColumna) {
  375. FilasInexistentes = DesdeFila-MaxColumna;
  376. }
  377. if (ColumnasInexistentes>=FilasInexistentes) {
  378. Ajuste = ColumnasInexistentes;
  379. } else {
  380. Ajuste = FilasInexistentes;
  381. }
  382. // trace("Ajuste: "+Ajuste);
  383. if (Ajuste>0) {
  384. // trace("Ajustando.");
  385. DesdeColumna = DesdeColumna+Ajuste;
  386. // trace("DesdeColumna: "+DesdeColumna);
  387. DesdeFila = DesdeFila-Ajuste;
  388. // trace("DesdeFila: "+DesdeFila);
  389. }
  390. do {
  391. HastaColumna = DesdeColumna+JuntosRequeridos-1;
  392. if (HastaColumna>MaxColumna) {
  393. // Para ganar se necesitaría más casilleros hacia...
  394. // la derecha de los que hay, terminar análisis:
  395. // trace ("No hay suficientes cuadraditos a la derecha");
  396. break;
  397. }
  398. HastaFila = DesdeFila-JuntosRequeridos+1;
  399. if (HastaFila<0) {
  400. // Para ganar se necesitaría más casilleros hacia...
  401. // arriba de los que hay, terminar análisis:
  402. // trace ("No hay suficientes cuadraditos arriba");
  403. break;
  404. }
  405. PunteroDeColumna = DesdeColumna;
  406. PunteroDeFila = DesdeFila;
  407. // trace ("Comenzando chequeo desde columna "+DesdeColumna+" y fila "+DesdeFila);
  408. // trace ("hasta columna "+HastaColumna+" y fila "+HastaFila);
  409. // Puede cambiar:
  410. Win = "Sí";
  411. do {
  412. CasilleroaMirar = PunteroDeFila*CasillerosPorFila+PunteroDeColumna;
  413. // trace ("Chequando el casillero "+CasilleroaMirar);
  414. if (Situacion[Action] != Situacion[CasilleroaMirar]) {
  415. Win = "No";
  416. DesdeColumna = PunteroDeColumna+1;
  417. DesdeFila = PunteroDeFila-1;
  418. break;
  419. }
  420. PunteroDeColumna++;
  421. PunteroDeFila--;
  422. } while (PunteroDeColumna<=HastaColumna);
  423. } while (DesdeColumna<=ColumnaDelMarcado && Win == "No");
  424. // trace("Win: "+Win);
  425. }

Resumen:


Mi idea con eso es hallar las mejores acciones en cada posible situación de un tablero de cierto tamaño cuando se requieren cierta cantidad de signos en línea, es decir, si por ejemplo en el "aprendedor" se configura que el tablero tiene 6 casilleros de largo y se requieren 5 signos en línea, el programa aprendería a jugar así, no en 5 casilleros de largo, ni 7, etc, ni con 6 signos requeridos, etc.
Así que en ese sentido no voy por buen camino, ya que no puedo correr el programa poniendo cada pares posibles de valores. Y aunque pudiera programar que los varíe, los resultados son de este estilo:
SvX0vBestAction = 0
es decir el nombre de la variable indica la situación, lo que sucederá es que serán un montón de variables con nombres cada vez más largos, es mejor algo más deductivo, unas reglas generales, siempre y cuando den buenos resultados.

La etapa 2 creo que debería tener en cuenta probabilidades, es decir, que cuando por ejemplo el resultado esperado es un empate, busque llegar a situaciones en que la mayoría de opciones del rival lo lleven a una derrota. Las probabilidades se basarían en la cantidad de opciones y las que salvan al rival, o a uno mismo (si el resultado esperado es derrota, aunque en este juego una IA no debería llegar a eso), no en cuan evidentes para un humano son las opciones mejores, porque eso parece subjetivo y complicado, ni lo intento.

Aún no tengo del todo claro cómo hacer la etapa 2. Y he estado cambiando cosas de la 1. En eso empecé a creer que en la etapa 1 debería guardar las posibilidades o en la 2nda no podría saber las probabilidades, o sería complicado. Creo que debería poner 3 etapas...
1- Se pueban acciones en las posibles situaciones, se van anotando las situaciones, y se anota "la mejor acción" y resultado cuando en la situación sólo hay 1 acción posible.
2- En las situaciones que quedaron sin resolver, se prueban acciones...

No sé bien... en ese punto una acción puede:
- Llevar a una situación resuelta, que luego será un empate o derrota.
- Llevar a una situación no resuelta.
- Llevar a una victoria.

Supongamos que está en:
0XX
XX0
0AB
Turno del 0.
Si pone en A, lleva a una situación resuelta, sólo queda una posible jugaba, B, y es empate.
Si pone en B, también es resuelta, pero es derrota.
Entonces deben crearse unas variables digamos así:
S0XXXX00vvWinX = 1
S0XXXX00vvEmpate = 1
marcando que en esa situación hay 1 posibilidad de que gane X y otra de que haya empate. La idea es que en la etapa 3, cuando haya que elegir cual es la mejor acción en una situación anterior a esta, cuando se llegue a esta se vea que X tiene 1/2 de probabilidad de ganar, aunque el resultado esperado sea empate, logrando entonces que el programa deduzca que para X es una situación más conveniente a llegar que otras, por ejemplo:
0CX
XX0
0AB
Turno de X. Si 0 juega bien, será empate, pero X poniendo en C o A tiene probabilidades de ganar, poniendo en B no.
Se trata de guardar posibilidades y luego guardar las acciones que lleven a situaciones en que haya más probabilidades de ganar.

Otra posibilidad es que lleve a una victoria, ejemplo:
0Xv
0Xv
vvv
Turno del X.
Lo que le conviene a X es evidente, pero... 0 debe tener en cuenta la posibilidad de que no haga eso. En tableros más grandes, puede que se deba elegir entre 2 situaciones inconvenientes, quizá en una X tiene 2 formas de ganar y en la otra sólo 1, por lo tanto debe grabarse la 2nda. Para eso debe haber datos sobre qué puede suceder, y por eso aunque la mejor acción aquí sea evidente, la situación no se puede resolver mientras no se tengan datos de las próximas, para saber exactamente qué tan probable es que gane X en esta (parece 1/5 pero es más complejo), para que previamente 0 pueda saber si esta situación es peor que otra alternativa, como expliqué.
Todo esto es como muy rebuscado, creo que sólo tiene sentido en tableros grandes. Normalmente la IA no llegaría a situaciones en que pueda perder. A ver un caso más realista:
vvvv
vXvv
vvvv
vvvv
Turno de 0, se requieren 3 para ganar. Parece que no importa lo que haga, perderá, pero la idea es que tenga las mayores probabilidades posibles de ganar o al menos empatar.

En fin, parece que entonces es cuestión de ir hacia atrás, en orden, es decir, resolver 1ero las situaciones en que sólo 1 acción es posible, luego las que sólo tienen 2, etc. Aunque en algunas sea obvio cómo ganar, no se pueden considerar resueltas antes de tiempo. Así que sería:
Etapa 1: Las acciones pueden llevar a situaciones nuevas, no resueltas, empates o victorias.
Etapa 2: Las acciones pueden llevar a situaciones no resueltas, resueltas o victorias.
Etapa 3: Las acciones pueden llevar a situaciones no resueltas o resueltas.
Considero importantes las diferencias para evitar ifs en vano...

Una posible mejora del programa sería, en vez de partir de un tablero vacío e ir grabando situaciones a las que se llegue, generar las posibles situaciones finales, resolverlas, generar las situaciones previas, resolverlas, y así. O en vez de tener 1 lista de situaciones, tener una por cada cantidad de signos puestos, o sea:
Una lista de situaciones en que sólo 1 acción es posible.
Otra en que sólo 2 acciones son posibles.
Etc.
Son mejoras alternativas. Sirven para evitar que el programa analice repetidamente situaciones que sabemos que aún no podrá resolver.

¿Ustedes cómo lo harían? Un programa que aprenda a jugar expertamente Signos en línea.
63  Foros Generales / Foro Libre / Re: En honor a quienes caminaron antes que nosotros (en el foro) en: 20 Marzo 2025, 06:47 am
Al unico que que veo aún aquí es a brujo que me llego a meter a un wargame que se hizo acá en el foro para entrenar gente
¿Me puedes explicar mejor dónde o cómo lo viste? Hace casi 2 meses que espero me responda un asunto y tampoco lo he visto postear en el foro.

¿O tu comentario es un sarcasmo/bait?

En otro tema preguntas qué pasó con el foro. Yo participo desde hace unos 10 7 años creo, no lo noto tan distinto. Antes no sé, pero no es poco común que un foro pierda actividad, las causas no las sé, en mi caso que me borraron comentarios sin explicación. Ahora postié porque es un caso especial ya que dijiste que viste al admin, pf, espero que sea cierto.

¿Y tú por qué te fuiste? Quejarse es fácil pero por haberte ído eres, probablemente, parte del culpable de que el foro haya perdido actividad o calidad según tu criterio.
64  Foros Generales / Sugerencias y dudas sobre el Foro / Hace como 1 mes envié un mensaje al administrador y no lo respondió. en: 24 Febrero 2025, 21:21 pm
Ni siquiera ha posteado en algún tema, o no lo he visto.

Hace poco he tenido días difíciles así que no estoy de ánimo para luchar por un foro más justo, si es que al admin le interesa, o para entender qué pasa con algún moderador o algunos, que me borra/n mensajes injustamente y sin explicar, pero, dejo este comentario, que quizá sea borrado también, meh, pero algún usuario lo verá:

Si quieren decirle algo al admin, mejor por email, quizá, es un consejo.

Yo es que paso de hablar por email con un hacker.

Mi idea era que él me explique o solucione el problema y luego seguir participando en el foro. Pero al parecer está muy ocupado, complicado, o no le interesa lo suficiente mi asunto o lo que pasa en su foro. O a lo mejor es una fachada y en realidad es de algún moderador.

No quiero hacer aportes a un foro que es injusto conmigo.

https://www.youtube.com/watch?v=htOqsFL14YU
65  Programación / Programación General / Captar victoria en juego estilo 3 en línea. 2 contiguos solamente. en: 20 Enero 2025, 19:40 pm
La cantidad de casilleros por fila y columna es configurable.

La cantidad de contiguos para ganar, también.

Pero por ahora quiero resolver el caso de 2 contiguos simplemente.

La situación se guarda en un array, es decir lo que tiene cada casillero, por ejemplo esta:
vv0
vXv
vvv
Es: v, v, 0, v, X, v, v, v, v
donde v es vacío

Mi idea es que, cuando un casillero se marque, se mire arriba, luego arriba-derecha, y así sucesivamente como las agujas de un reloj.

El reto es averiguar qué casillero en el array es el de arriba, y demás. Y si es que existe, sino capaz que mira alguno que no debe, no sé.

Si por ejemplo el casillero marcado es el nro 0, el de arriba no existe, el de arriba-derecha tampoco, el de la derecha es su +1...
Pero si se marca el nro 2, el de su derecha no es el +1, sino que no existe.

Quizá la mejor forma de resolver esto es creando variables estilo:
Casillero0_0 = "v"
Casillero1_0 = "v"
Casillero2_0 = "0"

Pero entre más grande sea el tablero, más variables así habría y son una copia de las otras así que no parece buena idea.

Debe haber una forma de calcular en qué posición del array está el casillero contiguo que se quiere mirar ¿cómo?
66  Programación / Programación General / Indicar que una acción no debe usarse. en: 20 Enero 2025, 04:16 am
Intento hacer una IA que aprenda a poner una X en un tablero y luego otra en la derecha o izquierda.

El problema que intento resolver en cuanto a eso, es que puede poner una X donde ya hay, debo evitarlo.

Sé que debo poner algo como:
Código:
if (Situacion[Action] == "v") {
   // Es realizable, realizarla...
sino
   // No, ver si hay otra...
Pero no sé bien qué pasa, es como que si hago eso tendría que poner código igual en distintos lados (aunque a ese código lo convierta en una función, siento que es innecesario que se repita), innecesariamente.

Aún no tengo el código completo. Díganme cómo pondrían uds ese if, dónde, o cómo harían.

Código
  1. // 2 en línea horizontal, en tablero de 2x2, sólo X:
  2. //
  3. // Uso arrays porque es más fácil así modificar los nombres...
  4. // de variables:
  5. //
  6. // Los casilleros están numerados así:
  7. // 0 1
  8. // 2 3
  9. // Situación inicial (v es casillero vacío):
  10. SituacionBase = ["v", "v", "v", "v"];
  11. // Ponerla en la lista de situaciones a experimentar:
  12. SaE1 = SituacionBase.slice();
  13. // Situaciones a experimentar (cuántas son):
  14. SaE = 1;
  15. NroDeSExperimentandose = 1;
  16. NombreDeSE = "S"+(SaE1.join(""));
  17. // Acción a realizarse (casillero a marcar):
  18. Action = 0;
  19. function BuscarAccionesGanadoras () {
  20. PlantearSyActuar();
  21. // ¿Ganó?
  22. // Para averiguarlo, calcular fila (contando desde 0):
  23. Fila = Math.floor(Action/2);
  24. // trace(" Fila: "+Fila);
  25. if (Situacion[Fila*2] == Situacion[Fila*2+1]) {
  26. // trace("Situacion[Fila*2] == Situacion[Fila*2+1]: "+Situacion[Fila*2]+" == "+Situacion[Fila*2+1]);
  27. // Sí, crear datos sobre eso:
  28. // En la situación base conviene la acción realizada:
  29. set (NombreDeSE+"BestAction", Action);
  30. // En esa situación se requiere 1 acción para ganar:
  31. set (NombreDeSE+"DistanciaaGanar", 1);
  32. trace("Ganó, ahora se sabe que en la situación "+SituacionBase+" se gana usando la acción "+Action);
  33. // ¿Aún hay situaciones a experimentar?
  34. if (SaE > NroDeSExperimentandose) {
  35. IniciarExperimentosEnOtraS();
  36. } else {
  37. // Comenzar la etapa 2.
  38. IniciarEtapa2();
  39. }
  40. } else {
  41. EvaluarConocimientoSobreSyEtc();
  42. }
  43. }
  44. function PlantearSyActuar () {
  45. // Plantear situación porque puede modificarse pero...
  46. // podría requerirse su estado original luego:
  47. Situacion = SituacionBase.slice();
  48. trace(" La situación experimentándose es "+Situacion);
  49. // Aplicación de la acción:
  50. Situacion[Action] = "X";
  51. trace(" Se realizó la acción "+Action+"; ahora la situación es "+Situacion);
  52. }
  53. function IniciarExperimentosEnOtraS () {
  54. NroDeSExperimentandose++;
  55. SituacionBase = eval("SaE"+NroDeSExperimentandose);
  56. // trace("SituacionBase: "+SituacionBase);
  57. // Reset de la acción a probar:
  58. Action = 0;
  59. trace("Se inician experimentos en otra situación");
  60. }
  61. function IniciarEtapa2 () {
  62. DistanciaaGanarAceptada = 1;
  63. trace("Se experimentaron todas las situaciones; se reexperimentarán buscando resultados menos óptimos");
  64. trace("Son "+SaE+" situaciones; se acepta que la distancia a la victoria sea "+DistanciaaGanarAceptada);
  65. gotoAndStop (3);
  66. }
  67. function EvaluarConocimientoSobreSyEtc () {
  68. SituacionHechaTexto = Situacion.join("");
  69. NombreDeSituacion = "S"+SituacionHechaTexto;
  70. Resumen = NombreDeSituacion+"BestAction";
  71. if (eval(Resumen) == undefined) {
  72. // No, anotar que debe investigarse:
  73. SaE++;
  74. set ("SaE"+SaE, Situacion.slice());
  75. trace("Esa situación no está anotada; se anota como nro "+SaE);
  76. // Esto para saber que está anotada:
  77. set (Resumen, "Desconocida");
  78. }
  79. // ¿Queda alguna acción sin probar?
  80. if (Action < 3) {
  81. // Sí, probar otra:
  82. Action++;
  83. } else if (SaE > NroDeSExperimentandose) {
  84. // Sino si aún hay situaciones a experimentar:
  85. trace("No hay más acciones posibles en la situación");
  86. IniciarExperimentosEnOtraS();
  87. } else {
  88. // Comenzar la etapa 2.
  89. IniciarEtapa2();
  90. }
  91. }

Ah, BuscarAccionesGanadoras se repite hasta que empiece la etapa 2.
67  Programación / Programación General / ¿Qué lío he hecho con mi generador de tableros estilo 3 en línea? en: 19 Enero 2025, 23:57 pm
Así funcionaba:
Código
  1. function HacerTablero () {
  2. MaxCasillero = CasillerosPorFila*CasillerosPorFila;
  3. LargoDeCasilleros = 384/CasillerosPorFila;
  4. CasillerosColocados = 0;
  5. // Sus columnas y filas se cuentan desde 0,
  6. // sirven para posicionarlos más fácil:
  7. Columna = 0;
  8. Fila = 0;
  9. do {
  10. CasillerosColocados++;
  11. CasilleroaColocar = "Casillero"+CasillerosColocados;
  12. // v es vacío.
  13. set ("SignoEn"+CasilleroaColocar, "v");
  14. // sCasillero tiene código.
  15. attachMovie("sCasillero", CasilleroaColocar, CasillerosColocados);
  16. setProperty (CasilleroaColocar, _x, LargoDeCasilleros*Columna);
  17. setProperty (CasilleroaColocar, _y, LargoDeCasilleros*Fila);
  18. setProperty (CasilleroaColocar, _width, LargoDeCasilleros);
  19. setProperty (CasilleroaColocar, _height, LargoDeCasilleros);
  20. Columna = Columna+1;
  21. if (Columna == CasillerosPorFila) {
  22. Columna = 0;
  23. Fila = Fila+1;
  24. }
  25. // Para que al presionar el botón se sepa qué modificar:
  26. set (CasilleroaColocar+".CasilleroAsociado", CasillerosColocados);
  27. } while (CasillerosColocados<MaxCasillero);
  28. }

Intenté poner que se cuenten desde 0 en vez desde 1 (o sea, que en vez de Casillero1, Casillero2, etc, sean Casillero0, Casillero1, etc) y ahora anda mal, pone uno menos y además lo borra mal (eso es otro tema):

Código
  1. function HacerTablero () {
  2. // Esto se irá especificando en el while:
  3. Situacion = [];
  4. PosiblesAcciones = [];
  5. // Los casilleros se cuentan desde 0:
  6. MaxCasillero = CasillerosPorFila*CasillerosPorFila-1;
  7. LargoDeCasilleros = 384/CasillerosPorFila;
  8. NroDeCasillerosaColocar = -1;
  9. // Sus columnas y filas se cuentan desde 0,
  10. // sirven para posicionarlos más fácil:
  11. Columna = 0;
  12. Fila = 0;
  13. do {
  14. NroDeCasilleroaColocar++;
  15. // v es vacío:
  16. Situacion.push("v");
  17. PosiblesAcciones.push(NroDeCasilleroaColocar);
  18. CasilleroaColocar = "Casillero"+NroDeCasilleroaColocar;
  19. // set ("SignoEn"+CasilleroaColocar, "v");
  20. // sCasillero tiene código.
  21. attachMovie("sCasillero", CasilleroaColocar, NroDeCasilleroaColocar);
  22. setProperty (CasilleroaColocar, _x, LargoDeCasilleros*Columna);
  23. setProperty (CasilleroaColocar, _y, LargoDeCasilleros*Fila);
  24. setProperty (CasilleroaColocar, _width, LargoDeCasilleros);
  25. setProperty (CasilleroaColocar, _height, LargoDeCasilleros);
  26. Columna = Columna+1;
  27. if (Columna == CasillerosPorFila) {
  28. Columna = 0;
  29. Fila = Fila+1;
  30. }
  31. // Para que al presionar el botón se sepa qué modificar:
  32. set (CasilleroaColocar+".CasilleroAsociado", NroDeCasilleroaColocar);
  33. trace("Colocado el "+NroDeCasilleroaColocar);
  34. } while (NroDeCasilleroaColocar<MaxCasillero);
  35. }

Si el tablero es de 3*3, se deben colocar 9, pero el máximo será 8 porque se cuentan desde 0. Y puse que el 1er colocado sea el 0. Pero el trace no lo indica, el 1er trace es del 1:
Colocado el 1
Colocado el 2
...
Colocado el 8

¿Qué pasa?

Edit: Creo que era una s de más, sorry >___<

NroDeCasillerosaColocar = -1;
debe ser:
NroDeCasilleroaColocar = -1;
68  Seguridad Informática / Hacking / Re: Hackeo de una cuenta de instagram en: 18 Enero 2025, 00:57 am
Pregunta a los de Insta si hay una opción para ver cómo se ha ingresado últimamente. Desde qué dispositivo, Windows, IP, esas cosas.
69  Programación / Programación General / Busco testers para mi generador de dibujos, hallar errores, paso el editable también. en: 15 Enero 2025, 16:18 pm
El siguiente link tiene un exe, un fla que es el archivo editable, y un swf que es como un exe menos peligroso pero sólo sirve si tienen Flash Player.
Actualización de acuerdo al momento en que el post fue editado: 25-01-15, 16:18
https://drive.google.com/file/d/17Mn04J7GUnn4CGaqjnE70UeGHISAVqbN/view?usp=sharing

Nota: Al cliquear un dibujo, muta.

Errores conocidos que intentaré arreglar más adelante:

1: La flecha de abajo que apunta a la izquierda, cuando se usa en la 1er pantalla quiero que lleve a las opciones de la última, pero aún no existe, así que está mal, no la usen en la 1er pantalla, saca las opciones y el programa se vuelve inusable.

2: Los botones de colores en la 2nda pantalla (flecha de abajo que apunta a la derecha) no deberían estar ahí. No los usen porque aún no llegué a arreglar esa parte, esos botones quedaron ahí por error.

3: No hay 3era pantalla así que tocar dos veces el botón de la derecha es mala idea.

4: Si habiendo X colores definidos (por ejemplo 3) se define uno salteando intermedios (por ejemplo habiendo 3, se define el 5), entonces al producirse los dibujos los colores intermedios serán negro.
Solución planeada: Se elegirán colores al azar para esos.

5: Aparentemente, si mientras se generan los dibujos señalas un botón de colores preestablecidos y quitas el mouse antes de que el proceso termine, el botón quedará parpadeando. Es un efecto que debería ocurrir sólo mientras el mouse apunta al botón, pero como el programa estaba haciendo otras cosas no notó que el mouse se fue de ahí, supongo. En PC rápidas posiblemente no ocurra por poca cosa, tendrían que aumentar la cantidad de dibujos y cuadraditos, tal vez.

6: Puede que se vean pequeñas líneas entre los cuadraditos, como si no ocuparan todo el espacio que deben. Un problema del largo y ancho supongo, que es calculado, si el resultado es en decimales ya saben que pueden pasar ese tipo de cosas.

7: Si bajas la cantidad de cuadraditos por fila, la mínima cantidad de colores requeridos debe bajar, porque si por ejemplo es 3 pero sólo hay 2 cuadraditos pintables (el resto son simétricos), entonces podrá haber 3 colores en el dibujo. Eso se corrige pero la corrección hace que a partir de ahí el último color definido se elimine, o se deje de usar, aunque en el la pantalla se vea que está definido.

8: Si agregas un color, luego aumentas la cantidad de mínimos requeridos, y luego bajas la cantidad de cuadraditos por fila, el programa se tranca por lo que expliqué en el punto anterior. No sé por qué no lo corrige en este caso.

Estoy corrigiendo, me toma tiempo...
70  Media / Diseño Gráfico / Re: Reducir tamaño de la hoja, no de la imagen. en: 14 Enero 2025, 20:41 pm
Sirvió, tema resuelto.


Songoku, te muestro.

Luego de tomar una foto que quería, quedó así:

La podría tomar de otro modo pero ya había tomado 4 así, además no creí que fuese un problema.

A las 4 las moví hacia arriba (con flechas) para que desapareciera el menú de arriba y quedara justito donde empieza el cuadro donde está la imagen, una cosa blanca y gris que se ve poco:


Ahora tenía que quitar todo lo de abajo, de modo que la imagen termine justito donde termina el cuadro que te comenté, así (esta es otra foto pero sirve para que se entienda):


Usando el mouse, no es fácil. Te pasás un pixel para un lado u otro, yo al menos sí, por más que ponga zoom. Poner un número como se mostró, es más fácil.

EdePC, al intentar eso me pone esto:

Pero tengo 160 GB libres, no sé. ¿Falta de ram?

Pero al intentar descargarla me descarga una página dice, no me dice que es un gif, me dice Chrome HTML document.

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