Um jogo de damas em mbed os

Dependencies:   Terminal

main.cpp

Committer:
mayarasi
Date:
2016-12-10
Revision:
0:e1459cfa4a6a

File content as of revision 0:e1459cfa4a6a:


#define MINLINHA 1
#define MAXLINHA 8
#define MINCOLUNA 1
#define MAXCOLUNA 8
#define PEDRA_NORMAL_JOGADOR1 '1'
#define PEDRA_NORMAL_JOGADOR2 '2'
#define PEDRA_DAMA_JOGADOR1 '3'
#define PEDRA_DAMA_JOGADOR2 '4'
#define VAZIO 'S'
#define JOGADA 'J'
#define CAPTURADA 'C'
#define BORDA "                    "

#define VITORIAS 0
#define EMPATES  1
#define DERROTAS 2

#define HUMANO1  '1'
#define HUMANO2  '2'
#define MAQUINA1 '3'
#define MAQUINA2 '4'

#define NOME_HUMANO1  "HUMANO1"
#define NOME_HUMANO2  "HUMANO2"
#define NOME_MAQUINA1 "MAQUINA1"
#define NOME_MAQUINA2 "MAQUINA2"
#define TAM_NOME 30

#define ASCII_PEDRA_NORMAL 'O'
#define ASCII_PEDRA_DAMA   'D'

#define ENTER 13

//#define __PC__ 1
#define __EMBARCADO__ 1

#ifdef __PC__
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <string.h>
#define PRINTF _cprintf
#define SLEEP  sleep
#define FIM_DE_LINHA "\n"
#define GETCHE _getche

#define ASCII_BLOCK     219
#define ASCII_BORDER_H  205
#define ASCII_BORDER_V  186
#define ASCII_BORDER_TL 201
#define ASCII_BORDER_TR 187
#define ASCII_BORDER_BL 200
#define ASCII_BORDER_BR 188

HANDLE hConsoleHandle;
CONSOLE_SCREEN_BUFFER_INFO *ConsoleInfo;

#define BACKGROUND_WHITE (BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_BLUE)
#define FOREGROUND_WHITE (FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE)
#define BACKGROUND_BLACK 0
#define FOREGROUND_BLACK 0

#define COR_FUNDO_BORDA BACKGROUND_BLUE
#define COR_TEXTO_BORDA FOREGROUND_WHITE

#define COR_FUNDO_CASA_SEM_PEDRA BACKGROUND_WHITE
#define COR_TEXTO_CASA_SEM_PEDRA FOREGROUND_WHITE

#define COR_FUNDO_CASA_COM_PEDRA BACKGROUND_GREEN
#define COR_TEXTO_CASA_COM_PEDRA_VAZIO FOREGROUND_GREEN
#define COR_TEXTO_CASA_COM_PEDRA_JOGADOR1 FOREGROUND_WHITE
#define COR_TEXTO_CASA_COM_PEDRA_JOGADOR2 FOREGROUND_RED

#define COR_FUNDO_CASA_COM_PEDRA_CAPTURADA (BACKGROUND_GREEN|BACKGROUND_INTENSITY)
#define COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_VAZIO (BACKGROUND_GREEN|BACKGROUND_INTENSITY)
#define COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR1 (COR_TEXTO_CASA_COM_PEDRA_JOGADOR1|BACKGROUND_INTENSITY)
#define COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR2 (COR_TEXTO_CASA_COM_PEDRA_JOGADOR2|BACKGROUND_INTENSITY)

#define COR_FUNDO_CASA_COM_PEDRA_JOGADA BACKGROUND_BLACK
#define COR_TEXTO_CASA_COM_PEDRA_JOGADA_VAZIO BACKGROUND_BLACK
#define COR_TEXTO_CASA_COM_PEDRA_JOGADA_JOGADOR1 COR_TEXTO_CASA_COM_PEDRA_JOGADOR1
#define COR_TEXTO_CASA_COM_PEDRA_JOGADA_JOGADOR2 COR_TEXTO_CASA_COM_PEDRA_JOGADOR2

#define COR_FUNDO_MENSAGEM BACKGROUND_BLACK
#define COR_TEXTO_MENSAGEM FOREGROUND_WHITE


#else
#include "mbed.h"
#include "Terminal.h"

//Serial pc( USBTX, USBRX);
Terminal term(USBTX, USBRX); // tx, rx
//#define PRINTF pc.printf
#define PRINTF term.printf
#define SLEEP  Thread::wait
#define FIM_DE_LINHA "\r\n"
#define GETCHE pega_tecla_echo

#define ASCII_BLOCK     219
#define ASCII_BORDER_H  205
#define ASCII_BORDER_V  186
#define ASCII_BORDER_TL 201
#define ASCII_BORDER_TR 187
#define ASCII_BORDER_BL 200
#define ASCII_BORDER_BR 188

#define WHITE 0xFFFFFF
#define WHITE_DIFERENCIADO 0x888888
#define BLACK 0x000000
#define GREEN 0x00FF00
#define GREEN_DIFERENCIADO 0x008800
#define BLUE 0x0000FF
#define BLUE_DIFERENCIADO 0x000088
#define RED 0xFF0000
#define RED_DIFERENCIADO 0x880000

#define COR_FUNDO_BORDA BLUE
#define COR_TEXTO_BORDA WHITE

#define COR_FUNDO_CASA_SEM_PEDRA WHITE
#define COR_TEXTO_CASA_SEM_PEDRA WHITE

#define COR_FUNDO_CASA_COM_PEDRA GREEN
#define COR_TEXTO_CASA_COM_PEDRA_VAZIO GREEN
#define COR_TEXTO_CASA_COM_PEDRA_JOGADOR1 WHITE
#define COR_TEXTO_CASA_COM_PEDRA_JOGADOR2 RED

#define COR_FUNDO_CASA_COM_PEDRA_CAPTURADA GREEN_DIFERENCIADO
#define COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_VAZIO GREEN_DIFERENCIADO
#define COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR1 WHITE_DIFERENCIADO
#define COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR2 RED_DIFERENCIADO

#define COR_FUNDO_CASA_COM_PEDRA_JOGADA BLACK
#define COR_TEXTO_CASA_COM_PEDRA_JOGADA_VAZIO BLACK
#define COR_TEXTO_CASA_COM_PEDRA_JOGADA_JOGADOR1 COR_TEXTO_CASA_COM_PEDRA_JOGADOR1
#define COR_TEXTO_CASA_COM_PEDRA_JOGADA_JOGADOR2 COR_TEXTO_CASA_COM_PEDRA_JOGADOR2

#define COR_FUNDO_MENSAGEM BLACK
#define COR_TEXTO_MENSAGEM WHITE


#endif

char tabuleiro_controle[MAXLINHA][MAXCOLUNA], tabuleiro_jogada[MAXLINHA][MAXCOLUNA];
int jogadas = 0;
int jogada_em_que_ultima_pedra_capturada = 0;
int jogada_em_que_ultima_pedra_nomal_movimentada = 0;
int jogada_empate_lances_especiais = 0;
int placar[4][3];
//int numero_pedras_para_capturar = -1;

int numero_pedras_capturadas_jogador1 = 0;
int numero_pedras_capturadas_jogador2 = 0;

int numero_pedras_capturadas_antes_jogador1 = 0;
int numero_pedras_capturadas_antes_jogador2 = 0;

#ifdef __EMBARCADO__

char pega_tecla_echo(void) {
    char retorno;
    
    //retorno = pc.getc();
    retorno = term.getc();
    //pc.putc(retorno);
    term.putc(retorno);
    return retorno;
}

#endif

void SELECIONA_COR(int cor_fundo, int cor_texto) {

#ifdef __PC__
    SetConsoleTextAttribute(hConsoleHandle, cor_fundo | cor_texto);
#else
    term.foreground(cor_texto);
    term.background(cor_fundo);
#endif

}

void LOCATE(int coluna, int linha) {

#ifdef __PC__
    COORD coordScreen;

    coordScreen.X = coluna;
    coordScreen.Y = linha;
    SetConsoleCursorPosition(hConsoleHandle, coordScreen);
#else
    term.locate(coluna, linha);
#endif

}


int lerIteiro(void) {
    
    char buffer[100+1];
    int indice;
    char lido;
    
    memset(buffer, 0, sizeof(buffer));
    
    for(indice = 0; indice < sizeof(buffer) - 1; ++indice) {
        lido = GETCHE();
        
        if(lido == ENTER) {
            break;
        } else {
            buffer[indice] = lido;
        }
    }
    
    return(atoi(buffer));
}

#ifdef __PC__

void cls(HANDLE hConsole)
{
    COORD coordScreen = { 0, 0 };    /* here's where we'll home the
                                     cursor */
    BOOL bSuccess;
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
    DWORD dwConSize;                 /* number of character cells in
                                     the current buffer */

                                     /* get the number of character cells in the current buffer */

    SetConsoleTextAttribute(hConsoleHandle, ConsoleInfo->wAttributes);

    bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

    /* fill the entire screen with blanks */

    bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
        dwConSize, coordScreen, &cCharsWritten);

    /* get the current text attribute */

    bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);

    /* now set the buffer's attributes accordingly */

    bSuccess = FillConsoleOutputAttribute(hConsole, csbi.wAttributes,
        dwConSize, coordScreen, &cCharsWritten);

    /* put the cursor at (0, 0) */

    bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
    return;
}

void LimparTela(void) {
    //system("CLS");
    cls(hConsoleHandle);
}

#else
    
void LimparTela(void) {
    //PRINTF("\033[2J\033[1;1H");
    //PRINTF("\e[1;1H\e[2J");
    term.cls();
}

#endif

char * retorna_nome_jogador(char opcao1, char *nome) {

    switch (opcao1) {
        case HUMANO1:
            strcpy(nome, NOME_HUMANO1);
            break;
        case HUMANO2:
            strcpy(nome, NOME_HUMANO2);
            break;
        case MAQUINA1:
            strcpy(nome, NOME_MAQUINA1);
            break;
        case MAQUINA2:
            strcpy(nome, NOME_MAQUINA2);
            break;
    }

    return nome;
}

char * retorna_nome_jogador_tipo_jogo(int indice, char opcao1, char *nome) {

    switch(opcao1) {
        case '1':
            if(indice == 1) {
                strcpy(nome, NOME_HUMANO1);
            } else {
                strcpy(nome, NOME_HUMANO2);
            }
            break;
        case '2':
            if(indice == 1) {
                strcpy(nome, NOME_HUMANO1);
            } else {
                strcpy(nome, NOME_MAQUINA1);
            }
            break;
        case '3':
            if(indice == 1) {
                strcpy(nome, NOME_MAQUINA1);
            } else {
                strcpy(nome, NOME_MAQUINA2);
            }
            break;
    }
    
    return nome;
}

char retorna_jogador(int indice, char opcao1) {
    
    char jogador;

    switch(opcao1) {
        case '1':
            if(indice == 1) {
                jogador = HUMANO1;
            } else {
                jogador = HUMANO2;
            }
            break;
        case '2':
            if(indice == 1) {
                jogador = HUMANO1;
            } else {
                jogador = MAQUINA1;
            }
            break;
        case '3':
            if(indice == 1) {
                jogador = MAQUINA1;
            } else {
                jogador = MAQUINA2;
            }
            break;
    }
    
    return jogador;
}

void imprime_placar(void) {
    
    char nome[TAM_NOME + 1];
    int indice, tamanho;

    LimparTela();

    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    LOCATE(10, 1);
    PRINTF("PLACAR%s", FIM_DE_LINHA);
    PRINTF("%- *.*s|VITORIAS|EMPATES|DERROTAS%s", TAM_NOME, TAM_NOME, "JOGADOR", FIM_DE_LINHA);
    
    tamanho = TAM_NOME + 1 + strlen("VITORIAS") + 1 + strlen("EMPATES") + 1 + strlen("DERROTAS");

    for (indice = 0; indice < tamanho; ++indice) {
        PRINTF("%c", ASCII_BORDER_H);
    }
    PRINTF("%s", FIM_DE_LINHA);



    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
    PRINTF("%- *.*s|%0*d|%0*d|%0*d%s", 
        TAM_NOME, TAM_NOME, retorna_nome_jogador(HUMANO1, nome), 
        strlen("VITORIAS"), placar[HUMANO1 - '1'][VITORIAS],
        strlen("EMPATES"), placar[HUMANO1 - '1'][EMPATES],
        strlen("DERROTAS"), placar[HUMANO1 - '1'][DERROTAS], FIM_DE_LINHA);
    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
    PRINTF("%- *.*s|%0*d|%0*d|%0*d%s",
        TAM_NOME, TAM_NOME, retorna_nome_jogador(HUMANO2, nome),
        strlen("VITORIAS"), placar[HUMANO2 - '1'][VITORIAS],
        strlen("EMPATES"), placar[HUMANO2 - '1'][EMPATES],
        strlen("DERROTAS"), placar[HUMANO2 - '1'][DERROTAS], FIM_DE_LINHA);
#if 0
    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
    PRINTF("%- *.*s|%0*d|%0*d|%0*d%s",
        TAM_NOME, TAM_NOME, retorna_nome_jogador(MAQUINA1, nome),
        strlen("VITORIAS"), placar[MAQUINA1 - '1'][VITORIAS],
        strlen("EMPATES"), placar[MAQUINA1 - '1'][EMPATES],
        strlen("DERROTAS"), placar[MAQUINA1 - '1'][DERROTAS], FIM_DE_LINHA);
    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
    PRINTF("%- *.*s|%0*d|%0*d|%0*d%s",
        TAM_NOME, TAM_NOME, retorna_nome_jogador(MAQUINA2, nome),
        strlen("VITORIAS"), placar[MAQUINA2 - '1'][VITORIAS],
        strlen("EMPATES"), placar[MAQUINA2 - '1'][EMPATES],
        strlen("DERROTAS"), placar[MAQUINA2 - '1'][DERROTAS], FIM_DE_LINHA);
#endif

    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    PRINTF("%s", FIM_DE_LINHA);
    PRINTF("Pressione <Qualquer Tecla>");
    GETCHE();
}


void ImprimeMenu(char &jogador1, char &jogador2) {
    
    char opcao1, opcao2;
    int indice;
    char nome[TAM_NOME + 1];
    
    do {
        LimparTela();
        SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
        PRINTF("1 - %s  X %s%s", NOME_HUMANO1, NOME_HUMANO2, FIM_DE_LINHA);
#if 0
        PRINTF("2 - %s  X %s%s", NOME_HUMANO1, NOME_MAQUINA1, FIM_DE_LINHA);
        PRINTF("3 - %s X %s%s",  NOME_MAQUINA1, NOME_MAQUINA2, FIM_DE_LINHA);
#endif
        //PRINTF("4 - PLACAR%s", FIM_DE_LINHA);
        PRINTF("2 - PLACAR%s", FIM_DE_LINHA);
        
        opcao1 = GETCHE();
        
        //if(opcao1 == '4') {
        if (opcao1 == '2') {
            imprime_placar();
        }
        
    } while( opcao1 < '1'  || opcao1 > '1' );
    
    do {
        indice = 0;
        LimparTela();
        ++indice;
        SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
        PRINTF("%d - %s INICIA O JOGO%s", indice, retorna_nome_jogador_tipo_jogo(indice, opcao1, nome), FIM_DE_LINHA);
        ++indice;
        PRINTF("%d - %s INICIA O JOGO%s", indice, retorna_nome_jogador_tipo_jogo(indice, opcao1, nome), FIM_DE_LINHA);
        
        opcao2 = GETCHE();
    } while( opcao2 < '1'  || opcao2 > '2' );
    
    if(opcao2 == '1') {
        jogador1 = retorna_jogador(1, opcao1);
        jogador2 = retorna_jogador(2, opcao1);
    } else {
        jogador1 = retorna_jogador(2, opcao1);
        jogador2 = retorna_jogador(1, opcao1);
    }

    LimparTela();
    
}

void InicializarTabuleiro(char jogador_que_inicia, char segundo_jogador) {
    
    int indice1, indice2;
    
    memset(tabuleiro_jogada, VAZIO, sizeof(tabuleiro_controle));
    
    for(indice1 = 0; indice1 < MAXCOLUNA; ++indice1) {
        //for(indice2 = 0; indice2 < ((MAXLINHA/2)-1); ++indice2) {
        for (indice2 = 0; indice2 < 1; ++indice2) {
            if( (indice2 == 0) || (indice2 == 2) ){
                if((indice1%2) == 1) {
                    tabuleiro_jogada[indice2][indice1] = segundo_jogador;
                }
            } else {
                if((indice1%2) == 0) {
                    tabuleiro_jogada[indice2][indice1] = segundo_jogador;
                }
            }
        }
    }
    
    for(indice1 = 0; indice1 < MAXCOLUNA; ++indice1) {
        for(indice2 = (MAXLINHA - 1); indice2 > (MAXLINHA/2); --indice2) {
            if(indice2 == 6){
                if((indice1%2) == 1) {
                    tabuleiro_jogada[indice2][indice1] = jogador_que_inicia;
                }
            } else {
                if((indice1%2) == 0) {
                    tabuleiro_jogada[indice2][indice1] = jogador_que_inicia;
                }
            }
        }
    }
    
    memcpy(tabuleiro_controle, tabuleiro_jogada, sizeof(tabuleiro_jogada));
}

void ImprimirTabuleiro(char jogador1, char jogador2) {
    
    char nome1[TAM_NOME + 1];
    char nome2[TAM_NOME + 1];
    int linha, coluna;

    LimparTela();
    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);

    LOCATE(10, 1);
    PRINTF("PARTIDA DE DAMAS ");
    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
    PRINTF("%s", retorna_nome_jogador(jogador1, nome1));
    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    PRINTF("(%d) VERSUS ", numero_pedras_capturadas_jogador1);
    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
    PRINTF("%s", retorna_nome_jogador(jogador2, nome2));
    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    PRINTF("(%d) % s", numero_pedras_capturadas_jogador2, FIM_DE_LINHA);

    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    PRINTF("%s", BORDA);

    SELECIONA_COR(COR_FUNDO_BORDA, COR_TEXTO_BORDA);
    PRINTF("  12345678 %s", FIM_DE_LINHA);

    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    PRINTF("%s", BORDA);

    SELECIONA_COR(COR_FUNDO_BORDA, COR_TEXTO_BORDA);
    PRINTF(" %c", ASCII_BORDER_TL);
    for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
        PRINTF("%c", ASCII_BORDER_H);
    }
    PRINTF("%c%s", ASCII_BORDER_TR, FIM_DE_LINHA);

    for (linha = 0; linha < MAXLINHA; ++linha) {

        SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
        PRINTF("%s", BORDA);

        SELECIONA_COR(COR_FUNDO_BORDA, COR_TEXTO_BORDA);
        PRINTF("%d%c", linha + 1, ASCII_BORDER_V);
        if (linha % 2 == 0) {
            // Este tipo de linha comeca com um tipo de casa na qual 
            //  as pedras nao podem se movimentar
            for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
                if (coluna % 2 == 0) {
                    SELECIONA_COR(COR_FUNDO_CASA_SEM_PEDRA, COR_TEXTO_CASA_SEM_PEDRA);
                    PRINTF(" ");
                }
                else {
                    switch (tabuleiro_jogada[linha][coluna]) {
                        case PEDRA_NORMAL_JOGADOR1:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
                            PRINTF("%c", ASCII_PEDRA_NORMAL);
                            break;
                        case PEDRA_NORMAL_JOGADOR2:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
                            PRINTF("%c", ASCII_PEDRA_NORMAL);
                            break;
                        case PEDRA_DAMA_JOGADOR1:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
                            PRINTF("%c", ASCII_PEDRA_DAMA);
                            break;
                        case PEDRA_DAMA_JOGADOR2:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
                            PRINTF("%c", ASCII_PEDRA_DAMA);
                            break;
                        case VAZIO:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_VAZIO);
                            PRINTF(" ");
                            break;
                        case JOGADA:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_JOGADA, COR_TEXTO_CASA_COM_PEDRA_JOGADA_VAZIO);
                            PRINTF(" ");
                            break;
                        case CAPTURADA:
                            switch (tabuleiro_controle[linha][coluna]) {
                                case PEDRA_NORMAL_JOGADOR1:
                                    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR1);
                                    PRINTF("%c", ASCII_PEDRA_NORMAL);
                                    break;
                                case PEDRA_DAMA_JOGADOR1:
                                    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR1);
                                    PRINTF("%c", ASCII_PEDRA_DAMA);
                                    break;
                                case PEDRA_NORMAL_JOGADOR2:
                                    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR2);
                                    PRINTF("%c", ASCII_PEDRA_NORMAL);
                                    break;
                                case PEDRA_DAMA_JOGADOR2:
                                    SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR2);
                                    PRINTF("%c", ASCII_PEDRA_DAMA);
                                    break;
                            }
                            break;
                    }
                }
            }
            SELECIONA_COR(COR_FUNDO_BORDA, COR_TEXTO_BORDA);
            PRINTF("%c", ASCII_BORDER_V);
            PRINTF("%s", FIM_DE_LINHA);
        }
        else {
            // Este tipo de linha comeca com um tipo de casa na qual 
            //  as pedras podem se movimentar
            for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
                if (coluna % 2 == 1) {
                    SELECIONA_COR(COR_FUNDO_CASA_SEM_PEDRA, COR_TEXTO_CASA_SEM_PEDRA);
                    PRINTF(" ");
                }
                else {
                    switch (tabuleiro_jogada[linha][coluna]) {
                    case PEDRA_NORMAL_JOGADOR1:
                        SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
                        PRINTF("%c", ASCII_PEDRA_NORMAL);
                        break;
                    case PEDRA_NORMAL_JOGADOR2:
                        SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
                        PRINTF("%c", ASCII_PEDRA_NORMAL);
                        break;
                    case PEDRA_DAMA_JOGADOR1:
                        SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR1);
                        PRINTF("%c", ASCII_PEDRA_DAMA);
                        break;
                    case PEDRA_DAMA_JOGADOR2:
                        SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_JOGADOR2);
                        PRINTF("%c", ASCII_PEDRA_DAMA);
                        break;
                    case VAZIO:
                        SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA, COR_TEXTO_CASA_COM_PEDRA_VAZIO);
                        PRINTF(" ");
                        break;
                    case JOGADA:
                        SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_JOGADA, COR_TEXTO_CASA_COM_PEDRA_JOGADA_VAZIO);
                        PRINTF(" ");
                        break;
                    case CAPTURADA:
                        switch (tabuleiro_controle[linha][coluna]) {
                        case PEDRA_NORMAL_JOGADOR1:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR1);
                            PRINTF("%c", ASCII_PEDRA_NORMAL);
                            break;
                        case PEDRA_DAMA_JOGADOR1:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR1);
                            PRINTF("%c", ASCII_PEDRA_DAMA);
                            break;
                        case PEDRA_NORMAL_JOGADOR2:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR2);
                            PRINTF("%c", ASCII_PEDRA_NORMAL);
                            break;
                        case PEDRA_DAMA_JOGADOR2:
                            SELECIONA_COR(COR_FUNDO_CASA_COM_PEDRA_CAPTURADA, COR_TEXTO_CASA_COM_PEDRA_CAPTURADA_JOGADOR2);
                            PRINTF("%c", ASCII_PEDRA_DAMA);
                            break;
                        }
                        break;
                    }
                }
            }
            SELECIONA_COR(COR_FUNDO_BORDA, COR_TEXTO_BORDA);
            PRINTF("%c", ASCII_BORDER_V);
            PRINTF("%s", FIM_DE_LINHA);
        }
    }

    SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
    PRINTF("%s", BORDA);

    SELECIONA_COR(COR_FUNDO_BORDA, COR_TEXTO_BORDA);
    PRINTF(" %c", ASCII_BORDER_BL);
    for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
        PRINTF("%c", ASCII_BORDER_H);
    }
    PRINTF("%c%s", ASCII_BORDER_BR, FIM_DE_LINHA);
}

// 0 - Movimento simples
// 1 - Movimento com multiplas capturas
int Movimento_Multiplo(void) {

    int linha, coluna;

    return 0;

    for (linha = 0; linha < MAXLINHA; ++linha) {
        for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
            if (tabuleiro_jogada[linha][coluna] == JOGADA) {
                // nao pode jogar sem capturar em uma jogada com multiplas capturas
                return 1;
            }
        }
    }
    return 0;
}

// 0 - Movimento de pedra simples nao eh para traz
// 1 - Movimento de pedra simples eh para traz
int Movimento_Para_Traz(int linha_origem, int linha_destino, char jogador1, char jogador_vez) {

    int retorno = 0;

    // O jogador 1 sempre começa o jogo e ele sempre inicia a partir da parte de baixo do tabuleiro
    if (jogador_vez == jogador1) {
        if ((linha_origem - linha_destino) <= 0) {
            retorno = 1;
        }
    }
    else {
        if ((linha_destino - linha_origem) <= 0) {
            retorno = 1;
        }
    }

    return retorno;
}

// retorna numero de pedras que faltam capturar
int Existe_Pedra_Para_Capturar(void) {

    return 0;
#if 0
    if ( (numero_pedras_para_capturar == -1) || (numero_pedras_para_capturar == 0) ) {
        return 0;
    }
    return numero_pedras_para_capturar;
#endif
}

char Posiciona_Pedra(int linha_origem, int coluna_origem, int linha_destino, int coluna_destino, char jogador_vez, char jogador1) {
    char retorno;

    // O jogador 1 sempre começa o jogo e ele sempre inicia a partir da parte de baixo do tabuleiro
    if (jogador_vez == jogador1) {
        //if ( (linha_destino == (MINLINHA - 1)) && ( (numero_pedras_para_capturar == -1) || (numero_pedras_para_capturar == 0)) ) {
        if (linha_destino == (MINLINHA - 1)) {
            retorno = PEDRA_DAMA_JOGADOR1;
        }
        else {
            retorno = tabuleiro_jogada[linha_origem][coluna_origem];
        }
    }
    else {
        //if ((linha_destino == (MAXLINHA - 1)) && ((numero_pedras_para_capturar == -1) || (numero_pedras_para_capturar == 0))) {
        if (linha_destino == (MAXLINHA - 1)) {
            retorno = PEDRA_DAMA_JOGADOR2;
        }
        else {
            retorno = tabuleiro_jogada[linha_origem][coluna_origem];
        }
    }

    return retorno;
}

// 0 - Esta no caminho maximo de captura
// 1 - Nao esta no caminho maximo de captura
int Caminho_Maximo_Captura(int linha_origem, int coluna_origem, int linha_destino, int coluna_destino) {
    // @todo fazer funcao
    //int retorno = 1;
    int retorno = 0;

    return retorno;
}

void Calcula_Quantidade_Maxima_Capturas(char jogador_vez, char jogador1, char jogador2) {

    // @todo fazer funcao

    return;

    //if (numero_pedras_para_capturar > 0) {
    //    return;  // funcao ja foi executada
    //}

}

void contabiliza_pedra(char jogador_vez, char jogador1, char jogador2) {

    if (jogador_vez == jogador1) {
        ++numero_pedras_capturadas_jogador1;
    }
    else {
        ++numero_pedras_capturadas_jogador2;
    }
}

// 0 - Movimento Invalido
// 1 - Movimento Valido
int Movimento_Valido(int &linha_origem, int &coluna_origem, int &linha_destino, int &coluna_destino, char jogador_vez, char jogador1, char jogador2) {

    char pedra_normal = 1;
    char pedra_normal_oponente;
    char pedra_dama_oponente;
    char pedra_normal_jogador;
    char pedra_dama_jogador;
    int  unidade_linha, unidade_coluna, linha_aux, coluna_aux, pedras_capturadas;
    int  linha_pedra_capturada, coluna_pedra_capturada;

    // Valida se existe uma pedra deste jogador no tabuleiro de jogada na posicao de origem.
    // O tabuleiro de jogada server para guardar a memoria de uma jogada com multiplas capturas, 
    //  por isso que´eh utilizado para validar as jogadas.
    if (jogador_vez == jogador1) {
        pedra_normal_jogador = PEDRA_NORMAL_JOGADOR1;
        pedra_dama_jogador = PEDRA_DAMA_JOGADOR1;
        pedra_normal_oponente = PEDRA_NORMAL_JOGADOR2;
        pedra_dama_oponente = PEDRA_DAMA_JOGADOR2;
        if (tabuleiro_jogada[linha_origem][coluna_origem] == PEDRA_NORMAL_JOGADOR1) {
        } else if (tabuleiro_jogada[linha_origem][coluna_origem] == PEDRA_DAMA_JOGADOR1) {
            pedra_normal = 0;
        } else {
            return 0; // pedra nao pertence ao jogador
        }
    }
    else {
        pedra_normal_jogador = PEDRA_NORMAL_JOGADOR2;
        pedra_dama_jogador = PEDRA_DAMA_JOGADOR2;
        pedra_normal_oponente = PEDRA_NORMAL_JOGADOR1;
        pedra_dama_oponente = PEDRA_DAMA_JOGADOR1;
        if (tabuleiro_jogada[linha_origem][coluna_origem] == PEDRA_NORMAL_JOGADOR2) {
        } else if (tabuleiro_jogada[linha_origem][coluna_origem] == PEDRA_DAMA_JOGADOR2) {
            pedra_normal = 0;
        }
        else {
            return 0; // pedra nao pertence ao jogador
        }
    }

    Calcula_Quantidade_Maxima_Capturas(jogador_vez, jogador1, jogador2);

    if (pedra_normal) {
        // pedra jogada eh normal
        // valida se a coordenada de destino eh valida para uma captura
        if ((linha_origem - linha_destino) == 2) { 
            if ((coluna_origem - coluna_destino) == 2) {
                if (Caminho_Maximo_Captura(linha_origem, coluna_origem, linha_destino, coluna_destino)) {
                    return 0; // Eh obrigatorio executar a jogada que 
                              //   captura o maximo de pedras do adversario
                }
                // diagonal para cima e para esquerda 
                if ( (tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) || 
                     (tabuleiro_jogada[linha_destino][coluna_destino] == JOGADA) ) { // a posicao destino deve estar vazia ou foi uma jogada 
                    if (tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] == pedra_normal_oponente) {
                        // pedra normal do oponente capturada
                        tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] = 
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino, 
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else if (tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] == pedra_dama_oponente) {
                        // pedra dama do oponente capturada
                        tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else {
                        // pedra capturada invalida!!
                        return 0;
                    }
                }
                else {
                    return 0;  // casa destino ocupada!!
                }
            }
            else if ((coluna_destino - coluna_origem) == 2) {
                if (Caminho_Maximo_Captura(linha_origem, coluna_origem, linha_destino, coluna_destino)) {
                    return 0; // Eh obrigatorio executar a jogada que 
                              //   captura o maximo de pedras do adversario
                }
                // diagonal para cima e para direita
                if ((tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) ||
                    (tabuleiro_jogada[linha_destino][coluna_destino] == JOGADA)) { // a posicao destino deve estar vazia ou foi uma jogada 
                    if (tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] == pedra_normal_oponente) {
                        // pedra normal do oponente capturada
                        tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else if (tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] == pedra_dama_oponente) {
                        // pedra dama do oponente capturada
                        tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else {
                        // pedra capturada invalida!!
                        return 0;
                    }
                }
                else {
                    // casa destino ocupada!!
                    return 0;
                }
            }
            else {
                // uma jogada de uma pedra normal apenas pode capturar uma pedra para esquerda ou para direita em diagonal
                return 0;
            }
        } else if ((linha_destino - linha_origem) == 2) {
            if ((coluna_origem - coluna_destino) == 2) {
                if (Caminho_Maximo_Captura(linha_origem, coluna_origem, linha_destino, coluna_destino)) {
                    return 0; // Eh obrigatorio executar a jogada que 
                              //   captura o maximo de pedras do adversario
                }
                // diagonal para baixo e para esquerda 
                if ((tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) ||
                    (tabuleiro_jogada[linha_destino][coluna_destino] == JOGADA)) { // a posicao destino deve estar vazia ou foi uma jogada 
                    if (tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] == pedra_normal_oponente) {
                        // pedra normal do oponente capturada
                        tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else if (tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] == pedra_dama_oponente) {
                        // pedra dama do oponente capturada
                        tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else {
                        // pedra capturada invalida!!
                        return 0;
                    }
                }
                else {
                    // casa destino ocupada!!
                    return 0;
                }
            }
            else if ((coluna_destino - coluna_origem) == 2) {
                if (Caminho_Maximo_Captura(linha_origem, coluna_origem, linha_destino, coluna_destino)) {
                    return 0; // Eh obrigatorio executar a jogada que 
                              //   captura o maximo de pedras do adversario
                }
                // diagonal para baixo e para direita
                if ((tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) ||
                    (tabuleiro_jogada[linha_destino][coluna_destino] == JOGADA)) { // a posicao destino deve estar vazia ou foi uma jogada 
                    if (tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] == pedra_normal_oponente) {
                        // pedra normal do oponente capturada
                        tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else if (tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] == pedra_dama_oponente) {
                        // pedra dama do oponente capturada
                        tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] = CAPTURADA;
                        //--numero_pedras_para_capturar;
                        contabiliza_pedra(jogador_vez, jogador1, jogador2);
                        jogada_em_que_ultima_pedra_capturada = jogadas + 1;
                        tabuleiro_jogada[linha_destino][coluna_destino] =
                            Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                                jogador_vez, jogador1);
                        tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
                    }
                    else {
                        // pedra capturada invalida!!
                        return 0;
                    }
                }
                else {
                    // casa destino ocupada!!
                    return 0;
                }
            }
            else {
                // uma jogada de uma pedra normal apenas pode capturar uma pedra para esquerda ou para direita em diagonal
                return 0;
            }
        }
        else if ((linha_origem - linha_destino) == 1) {
            if (Movimento_Para_Traz(linha_origem, linha_destino, jogador1, jogador_vez)) {
                return 0; // Uma pedra simples nao pode se movimentar para traz
            }
            else if (Existe_Pedra_Para_Capturar()) {
                return 0; // Eh obrigatorio capturar uma pedra
            }
            else if (Movimento_Multiplo()) {
                return 0; // Movimento de multiplas capturas, nao pode fazer um movimento simples apos a captura
            }
            // pedra fez um movimento, nao esta capturando uma pedra
            if ((coluna_origem - coluna_destino) == 1) {
                // diagonal para cima e para esquerda 
                if (tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) { // a posicao destino deve estar vazia
                    tabuleiro_jogada[linha_destino][coluna_destino] =
                        Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                            jogador_vez, jogador1);;
                    jogada_em_que_ultima_pedra_nomal_movimentada = jogadas + 1;
                    tabuleiro_jogada[linha_origem][coluna_origem] = VAZIO;
                }
                else {
                    return 0;
                }
            }
            else if ((coluna_destino - coluna_origem) == 1) {
                // diagonal para cima e para direita
                if (tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) { // a posicao destino deve estar vazia 
                    tabuleiro_jogada[linha_destino][coluna_destino] =
                        Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                            jogador_vez, jogador1);
                    jogada_em_que_ultima_pedra_nomal_movimentada = jogadas + 1;
                    tabuleiro_jogada[linha_origem][coluna_origem] = VAZIO;
                }
                else {
                    // casa destino ocupada!!
                    return 0;
                }
            }
            else {
                // uma jogada de uma pedra normal apenas pode andar uma casa para esquerda ou para direita em diagonal
                return 0;
            }
        }
        else if ((linha_destino - linha_origem) == 1) {
            if (Movimento_Para_Traz(linha_origem, linha_destino, jogador1, jogador_vez)) {
                return 0; // Uma pedra simples nao pode se movimentar para traz
            }
            else if (Existe_Pedra_Para_Capturar()) {
                return 0; // Eh obrigatorio capturar uma pedra
            }
            else if (Movimento_Multiplo()) {
                return 0; // Movimento de multiplas capturas, nao pode fazer um movimento simples apos a captura
            }
            if ((coluna_origem - coluna_destino) == 1) {
                // diagonal para baixo e para esquerda 
                if (tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) { // a posicao destino deve estar vazia 
                    tabuleiro_jogada[linha_destino][coluna_destino] =
                        Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                            jogador_vez, jogador1);
                    jogada_em_que_ultima_pedra_nomal_movimentada = jogadas + 1;
                    tabuleiro_jogada[linha_origem][coluna_origem] = VAZIO;
                }
                else {
                    // casa destino ocupada!!
                    return 0;
                }
            }
            else if ((coluna_destino - coluna_origem) == 1) {
                // diagonal para baixo e para direita
                if (tabuleiro_jogada[linha_destino][coluna_destino] == VAZIO) { // a posicao destino deve estar vazia 
                    tabuleiro_jogada[linha_destino][coluna_destino] =
                        Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                            jogador_vez, jogador1);
                    jogada_em_que_ultima_pedra_nomal_movimentada = jogadas + 1;
                    tabuleiro_jogada[linha_origem][coluna_origem] = VAZIO;
                }
                else {
                    // casa destino ocupada!!
                    return 0;
                }
            }
            else {
                // uma jogada de uma pedra normal apenas pode andar uma casa para esquerda ou para direita em diagonal
                return 0;
            }
        }
        else {
            // pedra normal executou um movimento invalido!!
            return 0;
        }
    } else {
        
        if (tabuleiro_jogada[linha_destino][coluna_destino] != VAZIO) {
            return 0; // A dama nao pode movimentar-se para uma casa ocupada
        }

        linha_aux = linha_origem;
        coluna_aux = coluna_origem;
        if (coluna_origem > coluna_destino) {
            unidade_coluna = -1;
        }
        else {
            unidade_coluna = 1;
        }

        if (linha_origem > linha_destino) {
            unidade_linha = -1;
        }
        else {
            unidade_linha = 1;
        }

        pedras_capturadas = 0;

        do {
            linha_aux += unidade_linha;
            coluna_aux += unidade_coluna;

            if ((tabuleiro_jogada[linha_aux][coluna_aux] == pedra_normal_jogador) || 
                (tabuleiro_jogada[linha_aux][coluna_aux] == pedra_dama_jogador)) {
                return 0;  // Dama nao pode pular pedras do mesmo jogador
            } else if ((tabuleiro_jogada[linha_aux][coluna_aux] == pedra_normal_oponente) ||
                (tabuleiro_jogada[linha_aux][coluna_aux] == pedra_dama_oponente)) {
                ++pedras_capturadas;  // A dama capturou uma pedra do oponente
                linha_pedra_capturada = linha_aux;
                coluna_pedra_capturada = coluna_aux;
            }

            if (pedras_capturadas > 1) {
                return 0; // A dama nao pode capturar mais de uma pedra em um unico movimento
            }

        } while (linha_aux != linha_destino);

        if ((pedras_capturadas == 0) && (Existe_Pedra_Para_Capturar() || Movimento_Multiplo())) {
            return 0; // Eh obrigatorio a captura
        } else if (Caminho_Maximo_Captura(linha_origem, coluna_origem, linha_destino, coluna_destino)) {
            return 0; // Eh obrigatorio executar a jogada que 
                      //   captura o maximo de pedras do adversario
        }

        if (pedras_capturadas == 1) {
            contabiliza_pedra(jogador_vez, jogador1, jogador2);
            jogada_em_que_ultima_pedra_capturada = jogadas + 1;
            tabuleiro_jogada[linha_destino][coluna_destino] =
                Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                    jogador_vez, jogador1);
            tabuleiro_jogada[linha_origem][coluna_origem] = JOGADA;
            tabuleiro_jogada[linha_pedra_capturada][coluna_pedra_capturada] = CAPTURADA;
        }
        else {
            tabuleiro_jogada[linha_destino][coluna_destino] =
                Posiciona_Pedra(linha_origem, coluna_origem, linha_destino, coluna_destino,
                    jogador_vez, jogador1);
            jogada_em_que_ultima_pedra_nomal_movimentada = jogadas + 1;
            tabuleiro_jogada[linha_origem][coluna_origem] = VAZIO;
        }
    }

    return 1;
}

// 0 - Faixa invalida
// 1 - Faixa valida
int Faixa_Valida(int linha_origem, int coluna_origem, int linha_destino, int coluna_destino) {
    
    int retorno = 1;

    // Testa a faixa de valores
    if ( (linha_origem < 0) || (linha_origem > (MAXLINHA - 1)) ) {
        retorno = 0;
    }
    else if ((linha_destino < 0) || (linha_destino > (MAXLINHA - 1))) {
        retorno = 0;
    }
    else if ((coluna_origem < 0) || (coluna_origem > (MAXCOLUNA - 1))) {
        retorno = 0;
    }
    else if ((coluna_destino < 0) || (coluna_destino > (MAXCOLUNA - 1))) {
        retorno = 0;
    }
    // Testa se eh uma casa de movimentacao de pedra
    else if ( (linha_origem % 2 == 0) && (coluna_origem % 2 == 0) ) {
        retorno = 0;
    }
    else if ((linha_destino % 2 == 0) && (coluna_destino % 2 == 0)) {
        retorno = 0;
    }
    else if ((linha_origem % 2 == 1) && (coluna_origem % 2 == 1)) {
        retorno = 0;
    }
    else if ((linha_destino % 2 == 1) && (coluna_destino % 2 == 1)) {
        retorno = 0;
    }

    return retorno;
}

void Entrada(int &linha_origem, int &coluna_origem, int &linha_destino, int &coluna_destino, char jogador_vez, char jogador1, char jogador2){

    char nome[TAM_NOME + 1];
    
    do {
        //LimparTela();
        PRINTF("%s", FIM_DE_LINHA);
        SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
        PRINTF("Jogador %s entre com a coordenada de origem da pedra a ser movida.%s", retorna_nome_jogador(jogador_vez, nome), FIM_DE_LINHA);
        PRINTF("Entre com o valor da linha(1-8): ");
        linha_origem = lerIteiro() - 1;
        PRINTF("%s", FIM_DE_LINHA);
        PRINTF("Entre com o valor de coluna(1-8): ");
        coluna_origem = lerIteiro() - 1;
        PRINTF("%s", FIM_DE_LINHA);

        PRINTF("Jogador %s entre com a coordenada de destino da pedra a ser movida.%s", retorna_nome_jogador(jogador_vez, nome), FIM_DE_LINHA);
        PRINTF("Entre com o valor de linha(1-8): ");
        linha_destino = lerIteiro() - 1;
        PRINTF("%s", FIM_DE_LINHA);
        PRINTF("Entre com o valor de coluna(1-8): ");
        coluna_destino = lerIteiro() - 1;
        PRINTF("%s", FIM_DE_LINHA);

        if (Faixa_Valida(linha_origem, coluna_origem, linha_destino, coluna_destino) && 
            Movimento_Valido(linha_origem, coluna_origem, linha_destino, coluna_destino, jogador_vez, jogador1, jogador2)) {
            break;
        } else {
            PRINTF("%s", FIM_DE_LINHA);
            PRINTF("Movimento invalido!! Pressione <Qualquer Tecla>");
            GETCHE();
        }
    }   while (1);
}

void Numero_Oponentes(int &jogador1_pedra_normal, int &jogador1_pedra_dama, 
                      int &jogador2_pedra_normal, int &jogador2_pedra_dama) {

    int linha, coluna;

    for (linha = 0; linha < MAXLINHA; ++linha) {
        for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
            switch (tabuleiro_jogada[linha][coluna]) {
            case PEDRA_NORMAL_JOGADOR1:
                ++jogador1_pedra_normal;
                break;
            case PEDRA_DAMA_JOGADOR1:
                ++jogador1_pedra_dama;
                break;
            case PEDRA_NORMAL_JOGADOR2:
                ++jogador2_pedra_normal;
                break;
            case PEDRA_DAMA_JOGADOR2:
                ++jogador2_pedra_dama;
                break;
            }
        }
    }
}

// 0 - Existem oponentes
// 1 - Sem oponentes
int Sem_Oponentes(void) {

    int jogador1_pedra_normal = 0, jogador1_pedra_dama = 0, 
        jogador2_pedra_normal = 0, jogador2_pedra_dama = 0;

    Numero_Oponentes(jogador1_pedra_normal, jogador1_pedra_dama, 
                     jogador2_pedra_normal, jogador2_pedra_dama);

    if ( (jogador1_pedra_normal || jogador1_pedra_dama) && (jogador2_pedra_normal || jogador2_pedra_dama) ) {
        return 0;
    }
    return 1;
}

// 0 - Sem condicoes especiais
// 1 - Com comdicoes especiais
int Codicoes_Especiais(void) {
    // @todo falta terminar as codicoes especiais

    int retorno = 0;

    int jogador1_pedra_normal = 0, jogador1_pedra_dama = 0,
        jogador2_pedra_normal = 0, jogador2_pedra_dama = 0;

    Numero_Oponentes(jogador1_pedra_normal, jogador1_pedra_dama,
        jogador2_pedra_normal, jogador2_pedra_dama);

    if ((jogador1_pedra_normal == 0) &&
        (jogador2_pedra_normal == 0) &&
        (jogador1_pedra_dama == 2) &&
        (jogador2_pedra_dama == 2)) {
        // 2 damas contras 2 damas
    }

    return retorno;
}

// 0 - Sem empate
// 1 - Emapate
int Verifica_Empate(void) {

    // @todo Verificar como iniciar as condicoes especiais

    return 0;

    int retorno = 0;

    if( ((jogadas - jogada_em_que_ultima_pedra_capturada) == 20) ||
        ((jogadas - jogada_em_que_ultima_pedra_nomal_movimentada) == 20) ) {
        // Apos 20 lances sucessivos de damas, sem captura ou deslocamento de pedra, 
        //  a partida eh declarada empatada
        retorno = 1;
    }
    else if ( (jogada_empate_lances_especiais) && 
              ((jogadas - jogada_empate_lances_especiais) == 5) && 
              Codicoes_Especiais() ) {
            retorno = 1;
    }

    return retorno;
}

// 0 - Existe pedra a ser movimentada
// 1 - Nao existe pedra a ser movimentada
int Existe_Pedra_Movimento(int linha_destino, int coluna_destino, char jogador1, char jogador2, char jogador) {

    int retorno = 1;

    if (jogador == jogador1) {
        if ((linha_destino - 1 >= 0) &&
            (coluna_destino - 1 >= 0) &&
            (tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] == VAZIO)) {
            retorno = 0;
        }
        else if ((linha_destino - 1 >= 0) &&
            (coluna_destino + 1 < MAXCOLUNA) &&
            (tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] == VAZIO)) {
            retorno = 0;
        }
    }
    else {
        if ((linha_destino + 1 < MAXLINHA) &&
            (coluna_destino + 1 < MAXCOLUNA) &&
            (tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] == VAZIO)) {
            retorno = 0;
        }
        else if ((linha_destino + 1 < MAXLINHA) &&
            (coluna_destino - 1 >= 0) &&
            (tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] == VAZIO)) {
            retorno = 0;
        }
    }
    return retorno;
}

// 0 - Existe pedra a ser capturada
// 1 - Nao existe pedra a ser capturada
int Existe_Pedra_Capturar(int linha_destino, int coluna_destino, char jogador1, char jogador2, char jogador) {
    
    int retorno = 1;
    char pedra_nomal, pedra_dama;

    if (jogador == jogador1) {
        pedra_nomal = PEDRA_NORMAL_JOGADOR2;
        pedra_dama = PEDRA_DAMA_JOGADOR2;
    }
    else {
        pedra_nomal = PEDRA_NORMAL_JOGADOR1;
        pedra_dama = PEDRA_DAMA_JOGADOR1;
    }

    if ((linha_destino + 2 < MAXLINHA) &&
        (coluna_destino + 2 < MAXCOLUNA) &&
        ((tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] == pedra_nomal) ||
         (tabuleiro_jogada[linha_destino + 1][coluna_destino + 1] == pedra_dama)) && 
        (tabuleiro_jogada[linha_destino + 2][coluna_destino + 2] == VAZIO)) {
        retorno = 0;
    }
    else if ((linha_destino + 2 < MAXLINHA) &&
                (coluna_destino - 2 >= 0) &&
                ((tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] == pedra_nomal) ||
                 (tabuleiro_jogada[linha_destino + 1][coluna_destino - 1] == pedra_dama)) &&
                (tabuleiro_jogada[linha_destino + 2][coluna_destino - 2] == VAZIO)) {
        retorno = 0;
    }
    else if ((linha_destino - 2 >= 0) &&
                (coluna_destino - 2 >= 0) &&
                ((tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] == pedra_nomal) ||
                 (tabuleiro_jogada[linha_destino - 1][coluna_destino - 1] == pedra_dama)) &&
                (tabuleiro_jogada[linha_destino - 2][coluna_destino - 2] == VAZIO)) {
        retorno = 0;
    }
    else if ((linha_destino - 2 >= 0) &&
                (coluna_destino + 2 < MAXCOLUNA) &&
                ((tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] == pedra_nomal) ||
                 (tabuleiro_jogada[linha_destino - 1][coluna_destino + 1] == pedra_dama)) &&
                (tabuleiro_jogada[linha_destino - 2][coluna_destino + 2] == VAZIO)) {
        retorno = 0;
    }

    return retorno;
}

// 0 - Nao existe jogada para o jogador selecionado
// 1 - Existe jogada para o jogador selecionado
int Existe_Jogada(char jogador1, char jogador2, char jogador) {
    int retorno = 0;
    int linha, coluna;


    if (jogador == jogador1) {
        for (linha = 0; linha < MAXLINHA; ++linha) {
            for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
                if (tabuleiro_jogada[linha][coluna] == PEDRA_NORMAL_JOGADOR1) {
                    if (!Existe_Pedra_Movimento(linha, coluna, jogador1, jogador2, jogador)) {
                        return 1;
                    }
                    else if (!Existe_Pedra_Capturar(linha, coluna, jogador1, jogador2, jogador)) {
                        return 1;
                    }
                }
            }
        }
    }
    else {
        for (linha = 0; linha < MAXLINHA; ++linha) {
            for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
                if (tabuleiro_jogada[linha][coluna] == PEDRA_NORMAL_JOGADOR2) {
                    if (!Existe_Pedra_Movimento(linha, coluna, jogador1, jogador2, jogador)) {
                        return 1;
                    }
                    else if (!Existe_Pedra_Capturar(linha, coluna, jogador1, jogador2, jogador)) {
                        return 1;
                    }
                }
            }
        }
    }
    return retorno;
}

int Analisar(int linha_origem, int coluna_origem, int linha_destino, int coluna_destino, 
             char &jogador_vez, char jogador1, char jogador2){

    int linha, coluna;
    char nome[TAM_NOME + 1];
    int retorno = 0;

    ++jogadas;

    // Verifica se existem oponentes
    if (Sem_Oponentes()) {
        if (jogador_vez == jogador1) {
            placar[jogador1 - '1'][VITORIAS] += 1;
            placar[jogador2 - '1'][DERROTAS] += 1;
        }
        else {
            placar[jogador2 - '1'][VITORIAS] += 1;
            placar[jogador1 - '1'][DERROTAS] += 1;
        }
        //LimparTela();
        PRINTF("%s", FIM_DE_LINHA);
        SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
        PRINTF("Jogador %s VENCEU!! com %d jogadas.%s", retorna_nome_jogador(jogador_vez, nome), jogadas, FIM_DE_LINHA);
        PRINTF("Pressione <Qualquer Tecla>");
        GETCHE();
        jogadas = 0;
        retorno = 1;
    }
    // Verifica empate
    else if (Verifica_Empate()) {
        placar[jogador1 - '1'][EMPATES] += 1;
        placar[jogador2 - '1'][EMPATES] += 1;
        //LimparTela();
        PRINTF("%s", FIM_DE_LINHA);
        SELECIONA_COR(COR_FUNDO_MENSAGEM, COR_TEXTO_MENSAGEM);
        PRINTF("Jogadores %s  e %s EMPATARAM!! apos %d jogadas.%s", retorna_nome_jogador(jogador1, nome),
            retorna_nome_jogador(jogador2, nome), jogadas, FIM_DE_LINHA);
        PRINTF("Pressione <Qualquer Tecla>");
        GETCHE();
        jogadas = 0;
        retorno = 1;
    }
    // Verifica mudanca de vez de jogador
    else {//if ( (numero_pedras_para_capturar == 0) || (numero_pedras_para_capturar == -1) ) {

        for (linha = 0; linha < MAXLINHA; ++linha) {
            for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
                switch (tabuleiro_jogada[linha][coluna]) {
                case PEDRA_NORMAL_JOGADOR1:
                case PEDRA_DAMA_JOGADOR1:
                case PEDRA_NORMAL_JOGADOR2:
                case PEDRA_DAMA_JOGADOR2:
                    break;
                default:
                    tabuleiro_jogada[linha][coluna] = VAZIO;
                    break;
                }
            }
        }
        memcpy(tabuleiro_controle, tabuleiro_jogada, sizeof(tabuleiro_jogada));

        // @todo falta verificar o caso em que o jogador nao tem casa para jogar
        if (jogador_vez == jogador1) {
            if (numero_pedras_capturadas_jogador1 > numero_pedras_capturadas_antes_jogador1) {
                if (Existe_Pedra_Capturar(linha_destino, coluna_destino, jogador1, jogador2, jogador1)) {
                    jogador_vez = jogador2;
                }
            }
            else if (Existe_Jogada(jogador1, jogador2, jogador2)) {
                jogador_vez = jogador2;
            }
        }
        else {
            if (numero_pedras_capturadas_jogador2 > numero_pedras_capturadas_antes_jogador2) {
                if (Existe_Pedra_Capturar(linha_destino, coluna_destino, jogador1, jogador2, jogador2)) {
                    jogador_vez = jogador1;
                }
            }
            else if (Existe_Jogada(jogador1, jogador2, jogador1)) {
                jogador_vez = jogador1;
            }
        }
        //numero_pedras_para_capturar = -1;

        numero_pedras_capturadas_antes_jogador1 = numero_pedras_capturadas_jogador1;
        numero_pedras_capturadas_antes_jogador2 = numero_pedras_capturadas_jogador2;
#if 0
        for (linha = 0; linha < MAXLINHA; ++linha) {
            for (coluna = 0; coluna < MAXCOLUNA; ++coluna) {
                switch (tabuleiro_jogada[linha][coluna]) {
                    case PEDRA_NORMAL_JOGADOR1:
                    case PEDRA_DAMA_JOGADOR1:
                    case PEDRA_NORMAL_JOGADOR2:
                    case PEDRA_DAMA_JOGADOR2:
                        break;
                    default :
                        tabuleiro_jogada[linha][coluna] = VAZIO;
                        break;
                }
            }
        }
        memcpy(tabuleiro_controle, tabuleiro_jogada, sizeof(tabuleiro_jogada));
#endif
    }
    
    return(retorno);
} 

void Jogar(char jogador1, char jogador2) {
    
    char fim = '0';
    char jogador_vez;
    int linha_origem, coluna_origem, linha_destino, coluna_destino;
    
    InicializarTabuleiro(jogador1, jogador2);
    
    jogador_vez = jogador1;
    
    do {
        ImprimirTabuleiro(jogador1, jogador2);
        
        Entrada(linha_origem, coluna_origem, linha_destino, coluna_destino,jogador_vez, jogador1, jogador2);
        
        if(Analisar(linha_origem, coluna_origem, linha_destino, coluna_destino, jogador_vez, jogador1, jogador2)) {
            fim = '1';
        }
    } while(fim != '1');
}

int main() {
    
    char jogador1, jogador2;
    
#ifdef __PC__

    hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    ConsoleInfo = new CONSOLE_SCREEN_BUFFER_INFO();
    GetConsoleScreenBufferInfo(hConsoleHandle, ConsoleInfo);

#else

    //pc.baud(115200);
    term.baud(115200);
    
#endif

    // Zerando o placar
    memset(placar, 0, sizeof(placar));
    
    while(true) {
        
        ImprimeMenu(jogador1, jogador2);
        
        Jogar(jogador1, jogador2);
    }
}