https://en.wikipedia.org/wiki/Connect_Four
¿Alguien recuerda el juego de 2 jugadores conecta 4? Para aquellos que no lo hicieron, fue una tabla de 6x7 que se coloca vertical sobre una superficie. ¡El objetivo de connect 4 es conectar bien 4! La conexión se cuenta si es horizontal, diagonal o vertical. Colocas tus piezas en el tablero insertando una pieza en la parte superior de una columna donde cae en la parte inferior de esa columna. Nuestras reglas cambian 3 cosas en connect 4.
- Cambio # 1 Ganar se define como el jugador con más puntos. Obtienes puntos conectando 4 como en las reglas, más sobre eso más adelante.
- Cambio # 2 Tienes 3 jugadores en cada ronda.
- Cambio n. ° 3 El tamaño del tablero es de 9x9.
Puntuación:
El puntaje se basa en cuántos obtienes en una fila. Si tienes un grupo 4 en fila, obtienes 1 punto. Si tiene un grupo 5 en fila, obtiene 2 puntos, 6 en fila 3 y así sucesivamente.
Ejemplos:
Nota o
y x
se reemplazan con #
y ~
respectivamente, para un mejor contraste
Ejemplo de tablero vacío: (todos los ejemplos son tableros de tamaño estándar para 2 jugadores)
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | | | | | | |
1 |_|_|_|_|_|_|_|
Si dejamos caer una pieza en coll d
, aterrizará en la ubicación 1d
.
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | | | | | | |
1 |_|_|_|#|_|_|_|
Si ahora dejamos caer una pieza en coll d
nuevamente, aterrizará en la ubicación 2d
. Aquí hay ejemplos de 4 posiciones seguidas:
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | |~| | | |
3 | | |~|#| | | |
2 | |~|#|~| |#| |
1 |~|#|~|#|_|#|_|
En este caso x
obtiene 1 punto en diagonal ( 1a 2b 3c 4d
).
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | |#| | | |
3 | | | |#| | | |
2 | | | |#| | | |
1 |_|~|_|#|~|_|~|
En este caso, o
obtiene 1 punto verticalmente ( 1d 2d 3d 4d
).
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | |#|#|#|#| |
1 |_|_|~|~|~|~|~|
En este caso o
obtiene 2 puntos horizontalmente ( 1c 1d 1e 1f 1g
) y x
obtiene 1 punto horizontalmente ( 2c 2d 2e 2f
).
a b c d e f g
6 | | |#| | | | |
5 | | |#| | | | |
4 | | |#| | | | |
3 | | |#| | |~| |
2 |~| |#| | |#|~|
1 |~|_|#|~| |~|~|
Esta vez x
obtiene 3 puntos por un 6 en fila ( 1c 2c 3c 4c 5c 6c
).
De entrada y salida
Tendrá acceso a la placa a través de una matriz 2D. Cada ubicación estará representada con una int
identificación de un jugador. También tendrá su identificación de jugador pasado a su función. Haces tu movimiento devolviendo en qué coll quieres colocar tu pieza. Cada ronda 3 jugadores serán elegidos para jugar. Al final del juego, todos los jugadores habrán jugado una cantidad par de juegos.
Por el momento se ejecutarán 100k rondas (tenga en cuenta que esto lleva mucho tiempo, es posible que desee reducirlo para una prueba de respuesta rápida). En general, el ganador es el jugador con más victorias.
El controlador se puede encontrar aquí: https://github.com/JJ-Atkinson/Connect-n/tree/master .
Escribiendo un bot:
Para escribir un bot debes extender la Player
clase. Player
es abstracto y tiene un método para implementar int makeMove(void)
,. En makeMove
usted decidirá en qué coll le gustaría colocar su pieza. Si elige un coll no válido (por ejemplo, coll no existe, coll ya está lleno), su turno será omitido . En la Player
clase tienes muchos métodos auxiliares útiles. A continuación se incluye una lista de los más importantes:
boolean ensureValidMove(int coll)
: Devuelve verdadero si el coll está en el tablero y el coll aún no está lleno.int[] getBoardSize()
: Devuelve una matriz int donde[0]
es el número de columnas y[1]
es el número de filas.int[][] getBoard()
: Devuelve una copia de la pizarra. Usted debe acceder a él de esta manera:[coll number][row number from bottom]
.- Para encontrar el resto, mira la
Player
clase. EMPTY_CELL
: El valor de una celda vacía
Como esto será multiproceso, también he incluido una random
función si la necesita.
Depuración de su bot:
He incluido algunas cosas en el controlador para simplificar la depuración de un bot. La primera de ellas es Runner#SHOW_STATISTICS
. Si está habilitado, verá una impresión de los grupos de jugadores jugados, incluido un recuento de victorias de bot. Ejemplo:
OnePlayBot, PackingBot, BuggyBot,
OnePlayBot -> 6
PackingBot -> 5
BuggyBot -> 3
Draw -> 1
También puedes hacer un juego personalizado con la connectn.game.CustomGame
clase, puedes ver los puntajes y el ganador de cada ronda. Incluso puede agregarse a la mezcla con UserBot
.
Agregando su bot:
Para agregar su bot a la alineación, vaya al PlayerFactory
bloque estático y agregue la siguiente línea:
playerCreator.put(MyBot.class, MyBot::new);
Otras cosas a tener en cuenta:
- Las simulaciones son multiproceso. Si desea desactivar eso, vaya
Runner#runGames()
y comente esta línea (.parallel()
). - Para cambiar el número de juegos, ajústelo
Runner#MINIMUM_NUMBER_OF_GAMES
a su gusto.
Agregado más tarde:
- La comunicación entre bots no está permitida.
Relacionado: Play Connect 4!
================================
Marcador: (100 000 juegos)
MaxGayne -> 22662
RowBot -> 17884
OnePlayBot -> 10354
JealousBot -> 10140
Progressive -> 7965
Draw -> 7553
StraightForwardBot -> 7542
RandomBot -> 6700
PackingBot -> 5317
BasicBlockBot -> 1282
BuggyBot -> 1114
FairDiceRoll -> 853
Steve -> 634
================================
fuente
Player
clase para ver todos los métodos disponibles.ensureValidMove
(a menos que su estrategia sea pasar este turno, por supuesto).Respuestas:
MaxGayne
Este bot asigna un puntaje a cada posición, basado principalmente en la longitud de las partes conectadas. Se ve 3 movimientos profundos inspeccionando 3 movimientos más atractivos en cada etapa, y elige el que tenga la puntuación máxima esperada.
fuente
UserBot
y tu bot fue que después de algún puntoMaxGayne
tirará los turnos (por ejemplo, después de 15 movimientos, salta cada turno hasta que finaliza el juego).javafx.util.Pair
no funciona en Eclipse porque no se considera parte de la API pública. Y no tengo idea de dónde buscarsun.plugin.dom.exception.InvalidStateException
. Probablemente quisiste decirjava.lang.IllegalStateException
.Pair
, eso es lo más cerca que puedo llegar al tipo de datos que quiero sin rodar el mío, así que a menos que eclipse no se compile, creo que está bien. En cuanto al número 3, tienes razón, mi autocompletado en IntelliJ no siempre es correcto. (la mayoría de las veces es así, por eso no lo comprobé)Pair
problema realmente impide compilar en Eclipse, a menos que conozca la solución .RowBot
Mira en todas las direcciones y determina la columna óptima. Intenta conectar sus piezas, sin dejar que sus oponentes hagan lo mismo.
fuente
OnePlayBot
Este bot solo tiene una jugada: coloca su pieza en la celda de la izquierda que sea válida. Por extraño que parezca, hace bastante bien;)
fuente
RandomBot
Simplemente ponga una pieza en cualquier lugar que sea válida.
fuente
StraightForwardBot
Similar al OnePlayBot, pero tiene en cuenta el último movimiento y reproduce la siguiente columna que es válida.
fuente
CelosoBot
Este bot odia al otro jugador. Y no le gusta que deje caer piezas en el tablero. Entonces él trata de ser el último en dejar caer una pieza en una columna.
Es mi primera vez en CodeGolf, así que espero que esta respuesta sea lo suficientemente buena. Todavía no pude probarlo, así que discúlpeme si hay algún error.
EDITAR : se agregó una línea para romper el segundo
for
.EDIT 2 : descubrí por qué el
while
era infinito. ¡Ahora está completo y se puede usar!fuente
if(board[col][row]!=null && board[col][row]!=id)
debería cambiarse aif(board[col][row]!=-1....
. Comprueba game.Game.genBoard () en el github de OP si quieres estar seguro. Tampoco sé sirandom()
harás lo que quieras, ¿quizás usar(int)Math.random()*col
?random()
método está en laPlayer
clase! Así que creo que funcionará =) Pero sí, no tenía confianza en mis condiciones. No encontré cómo se define en el código de OP, pero lo comprobaré nuevamente. ¡Muchas gracias!public double random() {return ThreadLocalRandom.current().nextDouble();}
. No sé exactamente cómo funciona, pero supongo que devuelve un valor entre 0 y 1, por lo que podría ser necesario(int)random()*col
:)nextDouble
devuelve un número entre0
y1
. Lo incluí porque las simulaciones se ejecutan en paralelo yMath.random()
no es seguro para subprocesos.BasicBlockBot
Un simple (e ingenuo) bloque de bot. ¡Él no sabe que puedes hacer un 4 en fila horizontal o diagonalmente!
fuente
Progresivo
Progresivo es ... progresivo. ¡Le gusta mirar todo y algo más! (No estoy seguro de la metodología de esto. Funcionó contra un amigo, una vez). Y, por alguna razón, funciona decentemente.
fuente
FairDiceRoll
Siempre devuelve 4.
fuente
BuggyBot
Un bot de muestra para que puedas vencer (FYI: no es difícil;)
fuente
EmbalajeBot
Este bot no apunta a puntos directamente. Intenta empacar un máximo de fichas hasta que se llena el tablero. Entendió que simplemente subir una y otra vez es una estupidez, por lo que colocará al azar fichas alrededor de su "dominio".
Debería poder obtener algunos puntos en todas las direcciones, ¡pero no será el mejor!
(No probado)
fuente
Steve
fuente
BasicBlockBot
.