// Programa tirado exatamente de Arnow e Weiss
// Introduction to Progamming Using Java
// (traduzido)
// Advertencia: isso nao eh um programa muito bem feito:
// Ache as imperfeicoes (incluindo bugs) e remova-as.
import java.io.*;
class JogoMancala {
int jogadorCorrente = 0;
TabuleiroMancala tabuleiro;
Jogador [] jogadores;
JogoMancala( String nome0, String nome1 ) {
tabuleiro = new TabuleiroMancala();
tabuleiro.prepareAJogar();
jogadores = new Jogador[2];
jogadores[0] = new Jogador( nome0, 0 );
jogadores[1] = new Jogador( nome1, 1 );
jogadorCorrente = 0;
}
public void joga() throws IOException {
mostraTabuleiro();
while( !tabuleiro.partidaTerminou() ) {
int numBuraco = jogadores[jogadorCorrente].selecioneJogada(tabuleiro);
boolean jogaNovamente = tabuleiro.facaJogada( jogadorCorrente, numBuraco );
System.out.println( "Jogador " + jogadorCorrente +
" moveu de " + numBuraco );
mostraTabuleiro();
if( !jogaNovamente ) {
if( jogadorCorrente == 0 ) {
jogadorCorrente = 1;
} else {
jogadorCorrente = 0;
}
} else {
System.out.println( "Jogador " +
jogadorCorrente + " joga novamente" );
}
}
tabuleiro.passaPedrasParaMancalas();
mostraTabuleiro();
if( tabuleiro.pedrasNaMancala(0) > tabuleiro.pedrasNaMancala(1) ) {
System.out.println( jogadores[0].pegaNome() + " ganha" );
} else if( tabuleiro.pedrasNaMancala(1) > tabuleiro.pedrasNaMancala(0) ) {
System.out.println( jogadores[1].pegaNome() + " ganha" );
} else {
System.out.println( "Empate" );
}
}
private void mostraTabuleiro() {
String espacoLinhaMancala = ""; // Usado para colocar espacos na linha
// da mancala
System.out.println( "-----------------------" );
// linha de buracos do jogador 1
System.out.print( " " );
for( int i = 1; i <= tabuleiro.buracosNoJogo; i++ ) {
System.out.print( tabuleiro.pedrasNoBuraco(1, i) + " " );
espacoLinhaMancala += " ";
}
mostraJogador(1);
// linha das mancalas
System.out.print( tabuleiro.pedrasNaMancala(1) + " " );
System.out.print( espacoLinhaMancala );
System.out.println( tabuleiro.pedrasNaMancala(0) );
// linha de buracos do jogador 0
System.out.print( " " );
for( int i = tabuleiro.buracosNoJogo; i >= 1; i-- ) {
System.out.print( tabuleiro.pedrasNoBuraco( 0, i ) + " " ); // livro errado
}
mostraJogador(0);
System.out.println( "-----------------------" );
}
private void mostraJogador( int numDoJogador ) {
// indicador da vez
if( jogadorCorrente == numDoJogador ) {
System.out.print( " -->" );
} else {
System.out.print( " ");
}
// informacao sobre o jogador
System.out.println( "Jogador " + numDoJogador + " (" + jogadores[numDoJogador].pegaNome() + ")" );
}
public static void main( String [] args ) throws IOException {
JogoMancala jogo = new JogoMancala( "Jacques", null );
jogo.joga();
}
}
class TabuleiroMancala {
private Buraco [] buracos;
public static final int buracosNoJogo = 6,
totalBuracos = 2*(buracosNoJogo+1);
TabuleiroMancala() {
buracos = new Buraco[totalBuracos];
for( int numBuraco = 0; numBuraco < totalBuracos; numBuraco++ ) {
buracos[numBuraco] = new Buraco();
}
}
public void prepareAJogar() {
for( int numBuraco = 0; numBuraco < totalBuracos; numBuraco++ ) {
if( ! ehUmaMancala( numBuraco ) ) {
buracos[numBuraco].adicionePedras(4);
}
}
}
public int pedrasNaMancala( int numDoJogador ) {
return buracos[pegaMancala(numDoJogador)].pegaPedras();
}
public int pedrasNoBuraco( int numDoJogador, int numBuraco ) {
return buracos[pegaNumDoBuraco(numDoJogador, numBuraco)].pegaPedras();
}
private int pegaNumDoBuraco( int numDoJogador, int numBuraco ) {
return numDoJogador * (buracosNoJogo+1) + numBuraco;
}
private int pegaMancala( int numDoJogador ) {
return numDoJogador * (buracosNoJogo+1);
}
private boolean ehUmaMancala( int numBuraco ) {
return numBuraco % (buracosNoJogo+1) == 0;
}
public TabuleiroMancala copiaTabuleiro() {
TabuleiroMancala novoTabuleiro = new TabuleiroMancala();
for( int numBuraco = 0; numBuraco < totalBuracos; numBuraco++ ) {
novoTabuleiro.buracos[numBuraco].adicionePedras( this.buracos[numBuraco].pegaPedras() );
}
return novoTabuleiro;
}
public boolean facaJogada( int numJogadorCorrente, int numBuracoEscolhido ) {
int numBuraco = pegaNumDoBuraco( numJogadorCorrente, numBuracoEscolhido );
int pedras = buracos[numBuraco].removePedras();
while( pedras != 0 ) {
numBuraco--;
if( numBuraco < 0 ) {
numBuraco = totalBuracos - 1;
}
if( numBuraco != pegaMancala( numOutroJogador(numJogadorCorrente) ) ) {
buracos[numBuraco].adicionePedras(1);
pedras--;
}
}
if( numBuraco == pegaMancala( numJogadorCorrente ) ) {
return true;
}
if( dono(numBuraco) == numJogadorCorrente && buracos[numBuraco].pegaPedras() == 1 ) {
pedras = buracos[numBuracoOposto(numBuraco)].removePedras();
buracos[pegaMancala(numJogadorCorrente)].adicionePedras(pedras);
}
return false;
}
private int dono( int numBuraco ) {
return numBuraco / (buracosNoJogo + 1);
}
private int numBuracoOposto( int numBuraco ) {
return totalBuracos - numBuraco;
}
private int numOutroJogador( int numDoJogador ) {
if( numDoJogador == 0 ) {
return 1;
} else {
return 0;
}
}
public boolean partidaTerminou() {
for( int jogador = 0; jogador < 2; jogador++ ) {
int pedras = 0;
for( int numBuraco = 1; numBuraco <= buracosNoJogo; numBuraco++ ) {
pedras += buracos[pegaNumDoBuraco(jogador, numBuraco)].pegaPedras();
}
if( pedras == 0 ) {
return true;
}
}
return false;
}
public void passaPedrasParaMancalas() {
for( int jogador = 0; jogador < 2; jogador++ ) {
for( int numBuraco = 1; numBuraco <= buracosNoJogo; numBuraco++ ) {
int pedras = buracos[pegaNumDoBuraco(jogador, numBuraco)].removePedras();
buracos[pegaMancala(jogador)].adicionePedras(pedras);
}
}
}
}
class Buraco {
int pedras;
public Buraco() { this.pedras = 0; }
public int pegaPedras() { return pedras; }
public void adicionePedras( int pedras ) { this.pedras += pedras; }
public boolean estaVazio() { return pedras == 0; }
public int removePedras() {
int pedras = this.pedras;
this.pedras = 0;
return pedras;
}
}
class Jogador {
private String nome;
private int numDoJogador;
public Jogador( String nome, int numDoJogador ) {
this.nome = nome;
this.numDoJogador = numDoJogador;
}
public String pegaNome() {
if( nome != null ) {
return nome;
} else {
return "Computador";
}
}
public int pegaNumDoJogador() {
return this.numDoJogador;
}
public int selecioneJogada( TabuleiroMancala tabuleiro ) throws IOException {
if( nome != null ) {
BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
System.out.print( "Entra com numero do buraco da jogada: " );
System.out.flush();
int numBuraco = Integer.parseInt( br.readLine() );
return numBuraco;
}
// Jogador eh computador: devemos determinar a melhor jogada
int melhorJogada = -1;
int jogadaComRepeticao = -1;
int maxPedrasAdicionais = -1;
// tente as possiveis jogadas
for( int numBuraco = 1; numBuraco <= tabuleiro.buracosNoJogo; numBuraco++ ) {
if( tabuleiro.pedrasNoBuraco( numDoJogador, numBuraco ) != 0 ) {
TabuleiroMancala tabuleiroDeTeste = tabuleiro.copiaTabuleiro();
boolean jogaNovamente = tabuleiroDeTeste.facaJogada( numDoJogador, numBuraco );
if( jogaNovamente ) {
jogadaComRepeticao = numBuraco;
}
int pedrasAdicionais = tabuleiroDeTeste.pedrasNaMancala(numDoJogador) -
tabuleiro.pedrasNaMancala(numDoJogador);
if( pedrasAdicionais > maxPedrasAdicionais ) {
maxPedrasAdicionais = pedrasAdicionais;
melhorJogada = numBuraco;
}
}
}
// tentamos todas as possibilidades: escolhe a melhor
if( maxPedrasAdicionais > 1 ) {
return melhorJogada;
} else if( jogadaComRepeticao != -1 ) {
return jogadaComRepeticao;
} else {
return melhorJogada;
}
}
}