Jogue um jogo perfeito de Mu Torere


14

fundo

Mu Torere é um dos dois jogos conhecidos pelo povo maori da Nova Zelândia antes da influência européia. Isso o torna um jogo muito único, pois possui um "critério de vitória objetivo" e regras de jogo diferentes da maioria dos outros jogos existentes.

Jogabilidade:

O quadro é um octógono. Existem conexões entre cada vértice adjacente e há um nó central conectado a todos os vértices. A qualquer momento, oito dos nove nós são ocupados por pedras. No início, existem quatro pedras brancas e quatro pedras negras que ocupam metade do octógono, com o nó central vazio. O preto se move primeiro.

A cada turno, um jogador pode mover uma de suas pedras ao longo de uma das 16 arestas de um nó para o nó vazio. Uma pedra só pode ser movida de um nó externo para o nó central se a pedra estiver próxima à pedra do oponente.

Um jogador perde quando é incapaz de fazer uma jogada legal, o que ocorre quando não há arestas conectando uma pedra ao nó vazio.

Um diagrama e explicação das regras

Aqui está um site que explica as regras (com um diagrama) e oferece algumas análises.

O desafio

Seu desafio é escrever o programa mais curto que possa jogar um jogo perfeito de Mu Torere contra um oponente humano. Seu programa deve poder exibir e atualizar o tabuleiro do jogo, fazer jogadas e receber jogadas de um oponente humano. Mais importante ainda, deve jogar um jogo perfeito.

Jogo perfeito?

Sim, jogo perfeito. Eu tenho feito algumas análises de jogos e descobri que o jogo dura uma quantidade infinita de tempo se jogado perfeitamente pelos dois lados. Isso significa que seu programa nunca deve perder. Além disso, seu programa deve ser capaz de forçar uma vitória sempre que o oponente humano cometer um erro que permita ao programa forçar uma vitória. Quanto à forma como seu programa encontra a jogada perfeita, isso depende de você.

Detalhes

Após cada jogada (e no início do jogo), seu programa deve imprimir o tabuleiro do jogo. No entanto, você escolhe exibir o quadro, ele deve mostrar todos os nós e estar totalmente conectado (todas as 16 linhas de conexão devem ser desenhadas sem linhas cruzadas). No início, o quadro deve ter a posição inicial correta. Uma maneira de conseguir isso é colocando o tabuleiro de jogo em um quadrado.

w-w-w
|\|/|
b-o-w
|/|\|
b-b-b

As duas cores são preto e branco ou escuro / claro. O tabuleiro deve mostrar quais nós estão ocupados pelas peças de cada jogador, como marcá-los com um "b" ou "w" e qual nó está vago. Os participantes são incentivados (mas não obrigatórios) a tornar o tabuleiro de jogo mais gráfico, em vez de texto simples.

Seu tabuleiro de jogo deve ter um sistema de numeração que dê a cada nó um número único. Você pode numerar o quadro da maneira que desejar, mas isso deve ser explicado na sua resposta ou no programa. O quadro quadrado pode ser numerado da seguinte maneira:

1-2-3
|\|/|
4-5-6
|/|\|
7-8-9

O humano é o primeiro a se mover. Sua entrada será um único número. Este será o número do nó em que a pedra movida está atualmente. Se eu quiser mover uma pedra do nó 4 para um nó vazio 5, digitarei a 4. O 5 está implícito, pois é o único nó vazio.

Suponha que o humano sempre faça uma jogada legal.

Depois que o humano fizer sua jogada, um quadro atualizado deve ser impresso. Depois que seu programa decide uma mudança legal, ele deve imprimir outra placa atualizada e aguardar o humano entrar em outra mudança.

Seu programa deve terminar assim que vencer.

Notas

Aplicam-se regras de código padrão de golfe, sem acesso a arquivos externos, etc., etc. Além disso, vou impor um limite de tempo flexível de 15 segundos (em uma máquina razoável) para que seu programa faça cada uma de suas movimentações. Como afirmado, este jogo tem a possibilidade de formar loops infinitos, e eu não quero uma pesquisa profunda entrando em um loop infinito.


2
Grande desafio. Somente "Se o humano introduzir uma jogada ilegal, seu programa deverá esperar e permitir que ele insira uma jogada diferente". parece-me um pouco anti-golfe: não podemos simplesmente deixar o comportamento indefinido em caso de insumos ilegais?
deixou de girar no sentido contrário ao relógio

1
Joguei esse requisito no último minuto e acho que seria bom eliminá-lo. Isso apenas torna mais difícil para o humano, que já está condenado a não vencer. :)
PhiNotPi

1
Não é que difícil de entrar sempre um lance legal ... By the way, após uma análise bastante detalhada Eu acho que é desnecessário para pesquisar mais de 1,5 movimentos à frente. Se essa abordagem é a mais curta é outra questão.
22412 Peter Peter

3
O site vinculado não está mais disponível, seria melhor transformá-lo em um link para uma versão arquivada.
Tally

Respostas:


6

Ruby, 390 caracteres

o=->s,c{f=s=~/o/;[*0..8].select{|t|s[t]==c&&(t<1||(t+6)%8+1==f||t%8+1==f||f<1&&(s[(t+6)%8+1]!=c||s[t%8+1]!=c))}.map{|t|k=s*1;k[f]=c;k[t]=?o;k}}
v=->s,c,h{f=o[s,c];f==[]?0:h<1?1:2-f.map{|t|v[t,c>?b??b:?w,h-1]}.min}
q=->g{puts"1-2-3\n|\\|/|\n8-0-4\n|/|\\|\n7-6-5\n".tr"0-8",g;$>.flush}
q[g="obbbbwwww"]
(g.tr!?o,?b;g[gets.to_i]=?o;q[g];q[g=o[g,?w].sort_by{|q|v[q,?w,5]}[-1]])while v[g,?b,5]>0

Uma implementação em ruby ​​que calcula diretamente a árvore do jogo (que requer bastante código) e, portanto, sempre é reproduzida da melhor maneira. As posições da placa estão em espiral para fora, como mostrado na figura a seguir:

1 - 2 - 3
| \ | / |
8 - 0 - 4
| / | \ |
7 - 6 - 5

5

festança e amigos ( 463 447 caracteres)

t(){ tr 0-8a-i $b$b
}
p(){ t<<E
0-1-2
|\|/|
3-4-5
|/|\|
6-7-8

E
}
g(){ b=`tr $x$e $e$x<<<012345678|t`
p
e=$x
}
b=bbbbowwww
e=4
m=0
p
while [ $m != 5 ]&&read x;do
g
m=0
for y in {0..8};do
s=0
S=05011234
grep -E "w.*($y$e|$e$y)"<<<${b:$y:1}30125876340142548746>/dev/null&&for p in wow.\*/ww wow.\*/w bbo.\*/b obb.\*/b www wbw .
do
((s++))
tr $y$e $e$y<<<3012587630/4e|t|grep $p>/dev/null&&break
done
s=${S:$s:1}
[ $s -gt $m ]&&m=$s x=$y
done
g
done

Humano joga como b, computador como w. A posição do conselho é numerada como no documento aqui na parte superior. Acontece que as heurísticas para jogar um jogo perfeito são surpreendentemente simples.

Por outro lado, perder o caminho interessante é bastante difícil. http://ideone.com/sXJPy demonstra o menor suicídio possível contra esse bot. Observe que o 0 extra no final é para testar se ele rompe o loop corretamente.


NB: eu poderia salvar um personagem tornando read xobrigatório, mas isso tornaria o teste bastante frustrante. Eu também poderia salvar um personagem removendo a linha em branco após a bordo, mas ...
Peter Taylor
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.