mayara santos
/
Damas
Um jogo de damas em mbed os
Diff: main.cpp
- Revision:
- 0:e1459cfa4a6a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Dec 10 17:07:22 2016 +0000 @@ -0,0 +1,1601 @@ + +#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); + } +}