
Una IA que crea crucigramas
Las IA de go, gomoku y Othello que hemos hecho hasta ahora eran rivales que juegan contra personas. El crucigrama es distinto. La IA no resuelve el crucigrama ni compite con las personas: crea crucigramas para que los resuelvan las personas. Son crucigramas en coreano, así que cada casilla de la cuadrícula contiene una sílaba coreana.
La web se hizo sobre el mismo esquema que los demás juegos.
- Está en crossword.mariago.kr. Se ejecuta en el puerto 3009 del Mac de casa, y el nginx del centro de datos (IDC) le redirige el tráfico.
- Al elegir la dificultad en la sala de espera y entrar en una sala de juego, se crea una cuadrícula nueva.
- La cuadrícula y cada una de las entradas se guardan en SQLite como registro de partida.
El primer orden: palabras → pistas → cuadrícula
Al principio, elegía palabras de un banco de palabras, le ponía una pista a cada una y después las iba uniendo en la cuadrícula. Si una palabra tenía una sílaba igual que otra ya colocada, se colocaba cruzándola en ese punto.
Las cuadrículas que salían no eran crucigramas.
- Una cuadrícula de 12×12 tenía solo 7~8 pistas. La mayor parte de la cuadrícula eran casillas negras.
- La mayoría de las respuestas eran de dos sílabas.
- Las palabras solo se unían por la primera y la última sílaba, y quedaban en fila como una escalera en diagonal. Casi no había cruces por sílabas intermedias, como el de "keu-ri-seu-ma-seu" (Navidad) y "al-peu-seu" (los Alpes) cruzándose en la sílaba común "seu".
- Las palabras se amontonaban solo en el centro de la cuadrícula.
- Cuando jugué dos cuadrículas difíciles seguidas, todas las palabras menos una habían salido en la cuadrícula anterior.
Las 24 cuadrículas guardadas el primer día
En la base de datos de registros de partidas quedan 24 cuadrículas creadas ese día. Todas son cuadrículas difíciles de 12×12.
- Tenían de 6 a 8 palabras, 6.8 de media.
- Las casillas blancas eran de media el 6.5% de la cuadrícula.
- El 76% de las respuestas eran de dos sílabas.
- Ninguna cuadrícula tenía simetría de 180°.
En 22 de las 24 cuadrículas volví a pulsar nueva cuadrícula sin rellenar ni una casilla. Las regeneré nada más verlas.
Lo que intentamos arreglar
- Exigimos 15 pistas o más entre horizontales y verticales. Pasaba las pruebas, pero en la pantalla seguían saliendo cuadrículas de 8 pistas. La sala de espera seguía abriendo una cuadrícula creada antes.
- Hicimos un agente de texto que ejecuta directamente el generador e imprime en texto la cuadrícula y la lista de pistas. También revisa las cuadrículas de la base de datos de registros y marca las islas de palabras de dos sílabas.
- También salió un método que rellenaba la cuadrícula repitiendo bloques en forma de cruz de tres sílabas. Es la imagen de arriba a la derecha. El número de pistas aumentó, pero todas las respuestas eran de tres sílabas y los bloques no se conectaban entre sí. Era una idea muy propia de una IA, y un crucigrama así no existe en ningún sitio.
Decidimos cambiar el orden
Si se colocan primero las palabras, la forma de la cuadrícula sale simplemente como consecuencia, y no se puede controlar. Así que decidimos crear primero la cuadrícula, después elegir las palabras que encajen en la longitud de los huecos y escribir las pistas al final.
El código real de esta etapa
Esta es la parte en la que el agente de texto revisa las cuadrículas guardadas. Si la longitud media es corta o no hay cruces intermedios, imprime que hace falta una partida nueva.
scripts/text-agent.ts
for (const row of rows) {
let across = 0;
let down = 0;
let mid = 0;
let avg = 0;
try {
const puzzle = JSON.parse(row.puzzle_json) as Puzzle;
across = puzzle.across?.length ?? 0;
down = puzzle.down?.length ?? 0;
mid = countMiddleCrosses(puzzle);
avg = avgWordLength(puzzle);
} catch {
/* ignore */
}
const mark = avg >= 2.7 && mid >= 1 ? "교차있음" : "2글자섬 ← 새 게임 필요";
console.log(
`${row.code} ${row.difficulty} ${row.size}×${row.size} ${row.status} 가로 ${across} 세로 ${down} 교차 ${mid} 평균 ${avg.toFixed(2)} ${mark} ${row.created_at}`,
);Estas son las reglas del colocador que une las palabras. Una palabra nueva debe solaparse exactamente en una casilla con una palabra ya colocada, y no puede haber otra sílaba en una casilla contigua. Este colocador sigue existiendo como vía de reserva, y vuelve a aparecer en la entrada 3.
lib/gridFill.ts
for (const [nr, nc] of neighbors) {
if (inBoard(size, nr, nc) && grid[idx(size, nr, nc)] != null) return null;
}
}
if (intersections !== 1 || newCells < 1) return null;La siguiente entrada es "2. Primero la cuadrícula, después las palabras y al final las pistas".
COMMENTS · CHAPTER 01
Colocar las palabras primero no dio un crucigrama 0 comentarios
Todavía no hay comentarios. Deja una pregunta o algo que quieras añadir.
Para publicar un comentario, empieza con Google y registra un apodo y un correo.
Empezar con Google