sábado, 21 de novembro de 2015

Jogo da Velha (tic-tac-toe) Android


Olá,

Hoje vou mostrar como construir um jogo da velha (tic-tac-toe) em Android.

Requisitos do aplicativo:
  • Deverá ser jogado por 2 jogadores, um jogador representado pelo ícone do Android e o outro representado pelo ícone do Java;
  • O aplicativo deverá mostrar a vez de cada jogador;
  • Caso um dos jogadores complete uma série, o aplicativo deverá animar as peças mostrando a série completada e também mostrar quem foi o vencedor;
  • Se forem esgotadas todas possibilidades, o aplicativo deverá exibir a mensagem “Deu Velha!!!”.

OK, agora que os requisitos foram definidos, vamos à construção. Antes de partir para codificação, vejamos como funciona o jogo da velha:
  • O jogo contém 8 possibilidades de vitória (3 linhas, 3 colunas e 2 diagonais), no aplicativo chamaremos estas possibilidades de games (l1, l2, l3, c1, c2, c3, d1 e d2) e cada game é formado por 3 botões;




  • Cada escolha do jogador, afeta de 2 a 4 games, como mostrado na figura abaixo:




  • Quando o jogador clica na célula central (B4), ele incrementa sua possibilidade de vitória em 4 games, se clicar nas células dos cantos (B0, B2B6 e B8) em 3 games e nas células laterais (B1, B3, B5, B7) em 2 games.

Vamos criar a classe Game que recebe em seu construtor o conjunto de botões que a compõe. A partir dessa classe, vamos instanciar 8 objetos, um para cada possibilidade.

    public Game(ImageButton...imageButtons) {
        for (ImageButton btn : imageButtons)
            this.imageButtons.add(btn);
        this.serie[0] = 0;
        this.serie[1] = 0;
    }

A classe Game possui o método que incrementa a série de cada jogador. Se o jogador completar um game, este game será retornado pelo método, caso contrário, o método retornará nulo.

    public Game addSerie(int jogador) {
        Game g = (++serie[jogador] < 3) ? null : this;
        return g;
    }

Criaremos também a classe Games que receberá em seu construtor um conjunto de objetos da classe Game (usando o conceito de varargs do Java).

    public Games(Game...games) {
        for (Game g : games)
            this.games.add(g);
    }

Na classe Games, temos o método que incrementa para o jogador, todos os games que foram passados no construtor da classe. Se um dos games for completado, ele imediatamente será retornado pelo método.

    public Game gamesAddSerie(int jogador) {
        Game g;
        for (Game game : games) {
            g = game.addSerie(jogador);
            if (g != null) return g;
        }
        return null;
    }

Agora na classe MainActivity, temos que passar para a tag de cada botão o conjunto de games que esse botão afeta ao ser clicado.


        //Lista de botões
        iB[0] = (ImageButton) findViewById(R.id.b0);
        iB[1] = (ImageButton) findViewById(R.id.b1);
        iB[2] = (ImageButton) findViewById(R.id.b2);
        iB[3] = (ImageButton) findViewById(R.id.b3);
        iB[4] = (ImageButton) findViewById(R.id.b4);
        iB[5] = (ImageButton) findViewById(R.id.b5);
        iB[6] = (ImageButton) findViewById(R.id.b6);
        iB[7] = (ImageButton) findViewById(R.id.b7);
        iB[8] = (ImageButton) findViewById(R.id.b8);

        //Lista de possibilidades de games
        l1 = new Game(iB[0], iB[1], iB[2]);
        l2 = new Game(iB[3], iB[4], iB[5]);
        l3 = new Game(iB[6], iB[7], iB[8]);
        c1 = new Game(iB[0], iB[3], iB[6]);
        c2 = new Game(iB[1], iB[4], iB[7]);
        c3 = new Game(iB[2], iB[5], iB[8]);
        d1 = new Game(iB[0], iB[4], iB[8]);
        d2 = new Game(iB[2], iB[4], iB[6]);

        //Primeiro fila
        iB[0].setTag(new Games(l1, c1, d1));
        iB[1].setTag(new Games(l1, c2));
        iB[2].setTag(new Games(l1, c3, d2));
        //Segunda fila
        iB[3].setTag(new Games(l2, c1));
        iB[4].setTag(new Games(l2, c2, d1, d2));
        iB[5].setTag(new Games(l2, c3));
        //Terceira fila
        iB[6].setTag(new Games(l3, c1, d2));
        iB[7].setTag(new Games(l3, c2));
        iB[8].setTag(new Games(l3, c3, d1));

No evento onClick do botão chamamos o método que incrementa seus games (cada botão clicado afeta um conjunto de games, lembra?). Se for retornado pelo método um game completado, animamos as imagens da sua série (ImageButtons) e exibimos o vencedor, caso contrário, verificamos se “deu velha” informado ao método verificaVelha(int jogadas) o número de jogadas realizadas até o momento.

    private String fimJogo(List<ImageButton> buttons, int jogador) {
        for (ImageButton button : buttons)
            button.animate().rotationY(360).setDuration(1000);
        disableButtons();
        return getResources().getString(R.string.vencedor, pl[jogador]);
    }

E é isso. Baixe o exemplo e rode no emulador ou no celular. Até a próxima postagem!

Nenhum comentário:

Postar um comentário