https://en.wikipedia.org/wiki/Connect_Four
Alguém se lembra do jogo para 2 jogadores conectar 4? Para quem não, era uma placa 6x7 vertical na superfície. O objetivo do connect 4 é conectar bem 4! A conexão é contada se for horizontal, diagonal ou vertical. Você coloca suas peças no quadro inserindo uma peça no topo de uma coluna, onde ela cai no fundo dessa coluna. Nossas regras alteram três coisas no connect 4.
- Mudança # 1 Vencer é definido como o jogador com mais pontos. Você ganha pontos conectando 4 como nas regras - mais sobre isso mais tarde.
- Mudança # 2 Você tem 3 jogadores a cada rodada.
- Alteração # 3 O tamanho da placa é 9x9.
Pontuação:
A pontuação é baseada em quantas você obtém em uma linha. Se você tem um grupo de 4 em linha, recebe 1 ponto. Se você tem um grupo 5 em linha, obtém 2 pontos, 6 em linha 3 e assim por diante.
Exemplos:
Observe o
e x
são substituídos por #
e ~
respectivamente, para melhor contraste
Exemplo de tabuleiro vazio: (todos os exemplos são tabuleiros de tamanho padrão para 2 jogadores)
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | | | | | | |
1 |_|_|_|_|_|_|_|
Se soltarmos um pedaço d
, ele pousará no local 1d
.
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | | | | | | |
1 |_|_|_|#|_|_|_|
Se agora deixarmos um pedaço no colo d
novamente, ele pousará no local 2d
. Aqui estão exemplos de 4 posições consecutivas:
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | |~| | | |
3 | | |~|#| | | |
2 | |~|#|~| |#| |
1 |~|#|~|#|_|#|_|
Nesse caso, x
obtém 1 ponto na diagonal ( 1a 2b 3c 4d
).
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | |#| | | |
3 | | | |#| | | |
2 | | | |#| | | |
1 |_|~|_|#|~|_|~|
Nesse caso, o
obtém 1 ponto na vertical ( 1d 2d 3d 4d
).
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | |#|#|#|#| |
1 |_|_|~|~|~|~|~|
Nesse caso, o
obtém 2 pontos horizontalmente ( 1c 1d 1e 1f 1g
) e x
obtém 1 ponto horizontalmente ( 2c 2d 2e 2f
).
a b c d e f g
6 | | |#| | | | |
5 | | |#| | | | |
4 | | |#| | | | |
3 | | |#| | |~| |
2 |~| |#| | |#|~|
1 |~|_|#|~| |~|~|
Desta vez, x
obtém 3 pontos por 6 em sequência ( 1c 2c 3c 4c 5c 6c
).
Entrada / Saída
Você terá acesso à placa através de uma matriz 2D. Cada local será representado com uma int
identificação do jogador. Você também terá seu ID de jogador passado para sua função. Você faz o seu movimento retornando em qual coll você quer colocar sua peça. Cada rodada 3 jogadores serão escolhidos para jogar. No final do jogo, todos os jogadores terão jogado uma quantidade uniforme de jogos.
No momento, 100 mil rodadas serão executadas (observe que isso leva muito tempo, você pode reduzi-lo para testes rápidos de resposta). No geral, o vencedor é o jogador com mais vitórias.
O controlador pode ser encontrado aqui: https://github.com/JJ-Atkinson/Connect-n/tree/master .
Escrevendo um bot:
Para escrever um bot, você deve estender a Player
classe. Player
é abstrato e tem um método para implementar int makeMove(void)
,. Em makeMove
que você vai decidir qual coll você gostaria de deixar cair a sua peça em. Se você escolheu um coll inválido (por exemplo, coll não existe, coll já foi preenchido), seu turno será pulado . Na Player
classe você tem muitos métodos auxiliares úteis. Segue uma lista dos mais importantes:
boolean ensureValidMove(int coll)
: Retorne true se o item estiver no quadro e o item ainda não estiver preenchido.int[] getBoardSize()
: Retorna uma matriz int onde[0]
é o número de colunas e[1]
o número de linhas.int[][] getBoard()
: Devolva uma cópia do quadro. Você deve acessá-lo como este:[coll number][row number from bottom]
.- Para encontrar o resto, veja a
Player
turma. EMPTY_CELL
: O valor de uma célula vazia
Como isso será multithread, também incluí uma random
função, se você precisar.
Depurando seu bot:
Eu incluí algumas coisas no controlador para simplificar a depuração de um bot. O primeiro é Runner#SHOW_STATISTICS
. Se isso estiver ativado, você verá uma impressão dos grupos de jogadores reproduzidos, incluindo uma contagem de vitórias em bot. Exemplo:
OnePlayBot, PackingBot, BuggyBot,
OnePlayBot -> 6
PackingBot -> 5
BuggyBot -> 3
Draw -> 1
Você também pode fazer um jogo personalizado com a connectn.game.CustomGame
classe, pode ver a pontuação e o vencedor de cada rodada. Você pode até se adicionar à mistura com UserBot
.
Adicionando seu bot:
Para adicionar seu bot à programação, vá para o PlayerFactory
bloco estático e adicione a seguinte linha:
playerCreator.put(MyBot.class, MyBot::new);
Outras coisas a serem observadas:
- As simulações são multiencadeadas. Se você quiser desativar isso, vá
Runner#runGames()
e comente esta linha (.parallel()
). - Para alterar o número de jogos, defina
Runner#MINIMUM_NUMBER_OF_GAMES
ao seu gosto.
Adicionado mais tarde:
- A comunicação entre bots é proibida.
Relacionados: Play Connect 4!
================================
Placar: (100 000 jogos)
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
================================
fonte
Player
classe para ver todos os métodos disponíveis.ensureValidMove
(a menos que sua estratégia seja passar nesta curva, é claro).Respostas:
MaxGayne
Este bot atribui uma pontuação a cada posição, com base principalmente no comprimento das peças conectadas. Parece 3 movimentos profundos, inspecionando 3 movimentos mais bonitos em cada estágio e escolhe aquele com a pontuação máxima esperada.
fonte
UserBot
e seu bot era que, depois de algum pontoMaxGayne
, jogaria fora os turnos (por exemplo, após 15 jogadas, ele salta a cada turno até o jogo terminar).javafx.util.Pair
não funciona no Eclipse porque não é considerado parte da API pública. E não tenho ideia de onde procurarsun.plugin.dom.exception.InvalidStateException
. Você provavelmente quis dizerjava.lang.IllegalStateException
.Pair
, é o mais próximo possível do tipo de dados que eu quero sem rodar sozinho, portanto, a menos que o eclipse não seja compilado, acho que está tudo bem. Quanto ao número 3, você está certo, meu preenchimento automático no IntelliJ nem sempre está certo. (na maioria das vezes ela é, é por isso que eu não verificar)Pair
problema realmente impede a compilação no Eclipse, a menos que você conheça a solução alternativa .RowBot
Olha em todas as direções e determina a coluna ideal. Tenta conectar suas peças, sem deixar que seus oponentes façam o mesmo.
fonte
OnePlayBot
Este bot tem apenas uma peça - coloque sua peça na célula mais à esquerda que é válida. Curiosamente, ele faz muito bem;)
fonte
RandomBot
Basta colocar uma peça em qualquer lugar que seja válido.
fonte
StraightForwardBot
Semelhante ao OnePlayBot, mas leva em consideração a última jogada e reproduz a próxima coluna que é válida.
fonte
JealousBot
Este bot odeia o outro jogador. E ele não gosta que derruba pedaços no tabuleiro. Então ele tenta ser o último a soltar uma peça em uma coluna.
É a minha primeira vez no CodeGolf, então espero que esta resposta seja boa o suficiente. Ainda não pude testá-lo, então, desculpe-me se houver algum erro.
EDIT : Adicionado uma linha para quebrar o segundo
for
.EDIT 2 : Descobriu por que o
while
era infinito. Agora está completo e pode ser usado!fonte
if(board[col][row]!=null && board[col][row]!=id)
deve ser alterado paraif(board[col][row]!=-1....
. Verifique game.Game.genBoard () no github do OP, se você quiser ter certeza. Também não sei se vocêrandom()
fará o que quiser, talvez use(int)Math.random()*col
?random()
método está naPlayer
classe! Então eu acho que vai funcionar =) Mas sim, eu não estava confiante em minhas condições. Não encontrei como isso está definido no código do OP, mas vou verificar novamente. Muito obrigado!public double random() {return ThreadLocalRandom.current().nextDouble();}
. Eu não sei exatamente como ele funciona, mas presumo que ele retorne um valor entre 0 e 1, por isso pode ser necessário(int)random()*col
:) :) #nextDouble
retorna um número entre0
e1
. Incluí-o porque as simulações são executadas em paralelo eMath.random()
não é seguro para threads.BasicBlockBot
Um bot de bloco simples (e ingênuo). Ele não sabe que você pode fazer um 4 consecutivo na horizontal ou na diagonal!
fonte
Progressivo
Progressivo é ... progressivo. Ele gosta de olhar para tudo , e alguns! (Não tenho certeza da metodologia disso. Funcionou contra um amigo, uma vez.) E, por algum motivo, funciona decentemente.
fonte
FairDiceRoll
Sempre retorna 4.
fonte
BuggyBot
Um exemplo de bot para você vencer (FYI: não é difícil;)
fonte
PackingBot
Este bot não está apontando diretamente para pontos. Ele tenta empacotar um máximo de fichas até o tabuleiro estar cheio. Ele entendeu que simplesmente subir uma e outra vez é estúpido, então ele coloca aleatoriamente tokens em torno de seu "domínio".
Ele deve conseguir alguns pontos em todas as direções, mas não será o melhor!
(Não testado)
fonte
Steve
fonte
BasicBlockBot
.