Jogo da Forca com Arduíno UNO

Olá, como estão? A princípio iremos falar sobre a Serial (também conhecida como UART e USART) e iremos desenvolver o jogo da forca com a Serial. Então para este projeto usaremos o KIT básico com Arduíno da WJ Componentes.

Componentes Utilizados no Projeto Jogo da Forca


OU

Principais Funções da Serial


A Serial possui muitas funções, por isso somente iremos comentar sobre as suas principais funções, entre elas estão:

  • begin ()
  • available ()
  • end ()
  • print ()
  • println ()
  • read ()
  • readString ()
  • readStringUntil ()

Contudo caso queira conferir todas as funções da Serial clique aqui.

Função begin ();

Antes de mais nada a função begin() é responsável por inicializar a Serial. Se utilizarmos a Serial não poderemos utilizar os pinos 0 e 1 do Arduíno, pois eles são para a comunicação serial.

Sintaxe begin:

Serial.begin(speed);

Parâmetros begin:

  • Serial – Identifica a Serial.
  • speed – Velocidade na qual a Serial se comunicar (padrão 9600).
  • Retorna True em caso de sucesso ou false em caso de falha.

Exemplo begin:

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
	 
//Loop -----------------------------------------------------------------------------------------------
void loop() {}

Função available ();

Em seguida tempos a função que é responsável por obter o número de bytes disponíveis para a leitura.

Sintaxe available:

Serial.available();

Parâmetros available:

  • Serial – Identifica a Serial.
  • Retorna O número de bytes disponíveis para leitura.

Exemplo available:

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    while(!Serial.available()){                  // Cria um loop até que retorno da Serial.available()
        char letra= Serial.read();               // seja diferente de 0 assim possamos identificar
    }                                            // que possui bytes a serem lidos na serial.
}

Função end ();

Apenas esta função é responsável por desativar a comunicação Serial, assim permitindo que os pinos RX e TX sejam usados como entrada e saída. Entretanto para estar reativando a comunicação serial, basta chamar Serial.begin().

Sintaxe end:

Serial.end();

Parâmetros end:

  • Serial – Identifica a Serial.
  • Retorna Nada.

Exemplo end:

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    Serial.print("EAI PESSOAL");                 // Após utilizar a Serial podemos estar utilizando
    Serial.end();                                // a função Serial.end() para finalizar a Serial e
    pinMode(0, OUTPUT);                          // liberar os pinos 0 e 1 para outros propósitos
}

Função print ();

Contudo esta função será responsável por imprimir na Serial, porém o texto será impresso em texto ASCII.

Sintaxe print:

Serial.print(val, format);

Parâmetros print:

  • Serial – Identifica a Serial.
  • val – O valor a ser impresso, todos os tipos são permitidos.
  • format – Formato a ser impresso na Serial (opcional).
  • Retorna True em caso de sucesso ou false em caso de falha.

Exemplo print:

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
	 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    // Sem Formato
    Serial.print(78);                            // Imprime o número inteiro "78"
    Serial.print(1.59);                          // Imprime o número float "1.59"
    Serial.print('N');                           // Imprime a letra "N"
    Serial.print("WJ COMPONETES");               // Imprime o texto "WJ COMPONETES"
    String variável = "Arduino UNO";
    Serial.print(variável);                      // Imprime o que estiver contido na variável
     
    // Com Formato
    Serial.print(78, BIN);                       // Imprime 78 em Binário "1001110"
    Serial.print(78, OCT);                       // Imprime 78 em Octal "116"
    Serial.print(78, DEC);                       // Imprime 78 em Decimal "78"
    Serial.print(78, HEX);                       // Imprime 78 em Hexadecimal "4E"
    Serial.print(1.23456, 0);                    // Imprime 1.23456 em 0 casas decimais assim "1"
    Serial.print(1.23456, 2);                    // Imprime 1.23456 em 2 casas decimais assim "1.23"
    Serial.print(1.23456, 4);                    // Imprime 1.23456 em 4 casas decimais assim "1.2345"
}

Obs.: Vocês irão notar que quando forem utilizar um grande número de print, irá ser consumida muita memória dinâmica, em outras palavras, memória RAM do seu microcontrolador. Essa função permite passar uma strings alocada na memória FLASH, ou seja, não haverá o consumo de memória RAM, mas sim de memória FLASH. Para isso basta envolver o val com F(), Por exemplo:

1.	Serial.print(F(“Olá Mundo”));

Função read ();

Em contrapartida esta função é responsável por ler dados recebidos na porta Serial.

Sintaxe read:

Serial.read();

Parâmetros read:

  • Serial – Identifica a Serial.
  • Retorna O primeiro byte recebido, caso não encontrar bytes disponíveis para leitura será retornado -1, ou seja, com essa função só podemos estar lendo uma letra ou número por vez.

Exemplo read:

 //Setup ---------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    while(!Serial.available()){                  // Cria loop até que tenha algum dado disponível
        char letra = Serial.read();              // após isso realizamos a leitura dos dados e 
    }                                            // atribuímos a letra
}

Função readString ();

Do mesmo modo esta função é responsável por ler frases e palavras recebida pela Serial de uma única vez.

Sintaxe readString:

Serial.readString();

Parâmetros readString:

  • Serial – Identifica a Serial.
  • Retorna A String lida do buffer Serial.

Exemplo readString:

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
	 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    while(!Serial.available()){                  // Cria loop até que tenha algum dado disponível
        char palavra = Serial.readString();      // após isso realizamos a leitura dos dados e 
    }                                            // atribuímos a palavra
}

Função readStringUntil ();

Essa função é responsável por ler os dados recebidos na Serial igual a função Serial.readString, porém, com uma única diferença que ela para de ler assim que encontrar o caractere especificado.

Sintaxe readStringUntil:

Serial.readStringUntil(terminador);

Parâmetros readStringUntil:

  • Serial – Identifica a Serial.
  • terminador: O caractere a ser buscado para finalizar a leitura.
  • Retorna A String lida do buffer Serial.

Exemplo readStringUntil:

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                          // Inicializa Serial com 9600 de velocidade
}
	 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    while(!Serial.available()){                  // Cria loop até que tenha algum dado disponível
        char t = Serial.readStringUntil("\n");   // após isso realizamos a leitura dos dados e 
    }                                            // atribuímos a t até um '\n'
}

Funcionamento do Projeto Jogo da Forca


Como foi comentado anteriormente iremos desenvolver um projeto para demonstrar e colocar em prática as funções apresentadas acima, para isso desenvolvemos o jogo da forca. Então para este projeto utilizamos um LED para indicar o erro, e outro para o acerto. Por fim usamos também dois botões um para começar o jogo e outro para acessar as configurações do jogo.

Montagem do Projeto Jogo da Forca


Logo após compra dos componentes na WJ Componentes, vamos à montagem!
Em seguida conectamos os LEDs na protoboard com os resistores que ligaremos nos catodos dos LEDs, e para finalizar ligamos no anodo dos pinos 3 e 4 do Arduíno. Logo após conectamos dois botões na protoboard e ligamos aos pinos 2 e 5 do Arduíno UNO.

Contudo segue abaixo uma imagem que demonstra a montagem do circuito.

Pinout LED Código Morse
Pinout LED
Montagem do Circuito Eletrônico na Protoboard - Jogo da Forca

Diagrama Esquemático do Projeto Jogo da Forca


Diagrama do Circuito Eletrico - Jogo da Forca

Código-fonte do Projeto Jogo da Forca


Em seguida terá o código completo do projeto do jogo da forca.

//Definições -----------------------------------------------------------------------------------------
#define btnStart 2                                                 // Botão para inicializar o Jogo
#define ledErro 3                                                  // Led para indicar Erro
#define ledSucesso 4                                               // Led para indicar Sucesso
#define btnConfig 5                                                // Botão para entrar nas Configurações
	 
//Variáveis Globais ----------------------------------------------------------------------------------
String palavra, aux;                                               // Armazena palavra e auxiliar
String dica;                                                       // Armazena dica
byte chance = 5, vitória = 0;                                      // Variáveis para controle
char letra[26] = {};                                               // Armazena as letras já digitadas
	 
//Funções Auxiliares ---------------------------------------------------------------------------------
void game();                                                       // Responsável por iniciar o jogo
void rest();                                                       // Responsável por reiniciar variáveis
void imprime();                                                    // Responsável por imprimir na Serial
String getString();                                                // Responsável por obter as Strings
void piscaLed(byte led);                                           // Responsável por piscar os LEDs
void logo();                                                       // Responsável por imprimir a logo
 
//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                                            // Inicializa Serial
    logo();                                                        // Chama função logo()
    pinMode(btnStart, INPUT_PULLUP);                               // Configura pino como INPUT_PULLUP
    pinMode(ledErro, OUTPUT);                                      // Configura pino como OUTPUT
    pinMode(ledSucesso, OUTPUT);                                   // Configura pino como OUTPUT
    pinMode(btnConfig, INPUT_PULLUP);                              // Configura pino como INPUT_PULLUP
}
	 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    if (!digitalRead(btnConfig)) {                                 // Se btnConfig foi pressionado
        Serial.println(F("Digite uma palavra para o Jogo:"));      // Imprime na Serial
        palavra = getString();                                     // Atribui o retorno de getString
        palavra.toUpperCase();                                     // Converte todo para maiúsculo
        Serial.println(F("Digite a dica: "));                      // Imprime na Serial
        dica = getString();                                        // Atribui o retorno getString a dica
        Serial.println(F("Configuração concluída com Sucesso"));   // Imprime na Serial
        Serial.print(F("Pressione o Botão Esquerdo para"));        // Imprime na Serial 
        Serial.print(F("inicializar o Jogo e o Direito para "));   // Imprime na Serial
        Serial.println(F("Inserir a Palavra "));                   // Imprime na Serial
        piscaLed(ledSucesso);                                      // Chama função piscaLed()
    }
    else if (!digitalRead(btnStart)) {                             // Verifica se btnStart foi pressionado
        if (palavra.length() == 0) {                               // Verifica se o tamanho da palavra = 0
            if (vitória == 0) {                                    // Verifica se vitória = 0
                palavra = "RESISTOR";                              // Atribui RESISTOR a palavra
    	        dica = "Eletrônica";                                 // Atribui Eletrônica a dica
            }
            else if (vitória == 1) {                               // Se não verifica se vitória = 1
                palavra = "CACHORRO";                              // Atribui CACHORRO a palavra
                dica = "Animal";                                   // Atribui Animal a dica
            }
            else if (vitória == 2) {                               // Se não verifica se vitória = 2
                palavra = "BANGLADESH";                            // Atribui BANGLADESH a palavra
                dica = "Pais";                                     // Atribui Pais a dica
            }
            else if (vitória == 3) {                               // Se não verifica se vitória = 3
                palavra = "HOMEM DE FERRO";                        // Atribui HOMEM DE FERRO a palavra
                dica = "Filme";                                    // Atribui Filme a dica
            }
            else if (vitória == 4) {                               // Se não verifica se vitória = 4
                palavra = "COUNTER STRIKE";                        // Atribui COUNTER STRIKE a palavra
                dica = "Jogo";                                     // Atribui Jogo a dica
            }
            else if (vitória == 5) {                               // Se não verifica se vitória = 5
                palavra = "PRETO";                                 // Atribui PRETO a palavra
                dica = "Cor";                                      // Atribui Cor a dica
            }
            else if (vitória == 6) {                               // Se não verifica se vitória = 6
                palavra = "SKATE";                                 // Atribui SKATE a palavra
                dica = "Esporte";                                  // Atribui Esporte a dica
            }
            else if (vitória == 7) {                               // Se não verifica se vitória = 7
                palavra = "HEFESTO";                               // Atribui HEFESTO a palavra
                dica = "Mitologia Grega";                          // Atribui Mitologia Grega a dica
            }
            else if (vitória == 8) {                               // Se não verifica se vitória = 8
                palavra = "SVARTALFHEIM";                          // Atribui SVARTALFHEIM a palavra
                dica = "Mitologia Nórdica";                        // Atribui Mitológica Nórdica a dica
            }
            else if (vitória == 9) {                               // Se não verifica se vitória = 9
                palavra = "HUALLAGA";                              // Atribui HUALLAGA a palavra
                dica = "Afluente Rio Amazônia";                    // Atribui Afluente Rio Amazônia a dica
            }
            else {                                                 // Se não
                Serial.println(F("Completou o Jogo Parabéns!!!")); // Imprime na Serial
                while (1) {                                        // Cria loop infinito
                    delay(10);                                     // Espera 0,01s
                }
            }
        }
        game();                                                    // Chama função game()
    }
}
 
//Game -----------------------------------------------------------------------------------------------
void game() {
    delay(200);                                                    // Espera 0,2s
    String tentativa;                                              // Declara variável tentativa
    for (byte i = 0; i < 26; i++) {                                // Loop para pode limpar variável letra 
        letra[i] = NULL;                                           // Limpar variável
    }
    for (byte i = 0; i < palavra.length(); i++) {                  // Loop com o tamanho  da palavra
        if (palavra.charAt(i) != ' ') {                            // Verifica se não é espaço
            aux += '-';                                            // Se não for atribui "-" a aux
        }
	    else {                                                       // Se for
            aux += ' ';                                            // atribuímos " " a aux
        }
    }
    while (1) {                                                    // Cria loop infinito
        imprime();                                                 // Chama função imprime()
	    Serial.println(F("\nDigite uma Letra:"));                    // Imprime na Serial
	    tentativa = getString();                                     // Atribui o retorno de getString
	    tentativa.toUpperCase();                                     // Converte todo para maiúsculo
	    for (byte i = 0; i < 26; i++) {                              // Cria loop do mesmo tamanho da letra
            if (letra[i] == tentativa.charAt(0)) {                 // Se letra da tentativa = alguma letra
                Serial.println(F("Tentativa Repetida"));           // Se for imprime na Serial
                break;                                             // E sai do loop
            }
            else if (letra[i] == NULL) {                           // Se não verificamos se letra = NULL
    	        letra[i] = tentativa.charAt(0);                      // Atribuímos a letra tentativa
    	        if (palavra.indexOf(letra[i]) >= 0) {                // Se tem letra na variável palavra
                    for (byte j = 0; j < palavra.length(); j++) {  // Criar um loop para verificar quantas
                        if (palavra.charAt(j) == letra[i]) {       // Se a letra da palavra = letra
                            aux.setCharAt(j, letra[i]);            // Trocamos as letras na variável aux
                            piscaLed(ledSucesso);                  // Chamamos função piscaLed()
                        }
                    }
                }
                else {                                             // Se não
                    chance--;                                      // Decrementa -1 a chance
                    piscaLed(ledErro);                             // Chama função piscaLed()
                }
                break;                                             // Sai do loop
            }
        }
        if (aux == palavra) {                                      // Chama função imprime()
            imprime();                                             // Imprime na Serial 
            Serial.println(F("\nVENCEU"));                         // Imprime na Serial
            Serial.println(F("PALAVRA DESCOBERTA"));               // Imprime na Serial
            Serial.println(F("Aperte no botão Esquerdo para Próximo Nível")); // Imprime na Serial
            for (byte i = 0; i < 10; i++) {                        // Cria for de 10 vezes
                piscaLed(ledSucesso);                              // Chama função piscaLed()
                piscaLed(ledErro);                                 // Chama função piscaLed()
            }
            rest();                                                // Chama função rest()
            palavra = "";                                          // Atribuía nada a variável palavra
            vitória++;                                             // Incrementa +1 em vitória 
            break;                                                 // Sai do loop
        }
        else if (chance == 0) {                                    // Imprime na Serial
            Serial.println(F("\nGAME OVER"));                      // Imprime na Serial
            Serial.println(F("PALAVRA NÃO FOI DESCOBERTA"));       // Imprime na Serial
            Serial.println(F("Aperte no Botão Esquerdo para Tentar novamente")); // Imprime na Serial
            for (byte i = 0; i < 10; i++) {                        // Criar for de 10 vezes
                digitalWrite(ledSucesso, !digitalRead(ledSucesso));// Inverte sinal do ledSucesso
                digitalWrite(ledErro, !digitalRead(ledErro));      // Inverte sinal do ledErro
                delay(200);                                        // Espera 0,2s
            }
            rest();                                                // Chama função rest()
            break;                                                 // Sai do loop
        } 
    }
}

//Reinicia Variáveis ---------------------------------------------------------------------------------
void rest() {
    aux = "";                                                      // Atribui nada a aux
    chance = 5;                                                    // Atribuía 5 a chance
} 
	
//Imprime --------------------------------------------------------------------------------------------
void imprime() {
    Serial.println(F("\nJOGO DA FORCA"));                          // Imprime na Serial
    Serial.print(F("Dica: "));                                     // Imprime na Serial
    Serial.println(dica);                                          // Imprime dica na Serial
    Serial.print(F("Letras já Utilizadas: "));                     // Imprime na Serial
    for (byte i = 0; i < 26; i++) {                                // Cria loop para imprimir letra
        Serial.print(letra[i]);                                    // Imprime letra na Serial
    }
    Serial.print(F("\nChances: "));                                // Imprime na Serial
    Serial.println(chance);                                        // Imprime chance na Serial
    Serial.println(F("  |-----------|"));                          // Imprime na Serial
    Serial.println(F("  |           |"));                          // Imprime na Serial
    Serial.println(F("  |         -----"));                        // Imprime na Serial
    for (byte i = 0; i < 4; i++) {                                 // Cria loop de 4 vezes para desenhar
        Serial.println(F("  |"));                                  // Imprime na Serial
    }
    Serial.print(F("-----    "));                                  // Imprime na Serial
    Serial.print(aux);                                             // Imprime aux na Serial
} 
	
//Obtém String ---------------------------------------------------------------------------------------
String getString() {                            
    while (!Serial.available()) delay(100);                        // Loop até possuir dados disponíveis
    return Serial.readStringUntil('\n');                           // Retorna a leitura da Serial até "\n"
}
	 
//Pisca Led ------------------------------------------------------------------------------------------
void piscaLed(byte led) {
    digitalWrite(led, HIGH);                                       // Liga LED
    delay(500);                                                    // Espera 0,5s
    digitalWrite(led, LOW);                                        // Desliga LED
}
 
//Logo -----------------------------------------------------------------------------------------------
void logo() {
    Serial.println(F(" __        ___    ____                                             _            "));
    Serial.println(F(" \\ \\      / (_)  / ___|___  _ __ ___  _ __   ___  _ __   ___ _ __ | |_ ___  ___ "));
    Serial.println(F("  \\ \\ /\\ / /| | | |   / _ \\| '_ ` _ \\| '_ \\ / _ \\| '_ \\ / _ \\ '_ \\| __/ _ \\/ __|"));
    Serial.println(F("   \\ V  V / | | | |__| (_) | | | | | | |_) | (_) | | | |  __/ | | | ||  __/\\__ \\"));
    Serial.println(F("    \\_/\\_/ _/ |  \\____\\___/|_| |_| |_| .__/ \\___/|_| |_|\\___|_| |_|\\__\\___||___/"));
    Serial.println(F("          |__/                       |_|                                        \n\n"));
    Serial.println(F("Pressione o Botão Esquerdo para inicializar o Jogo e o Direito para Inserir a Palavra"));
}

Vamos dar uma olhada mais de perto no código:

Definições de Pinos

Primeiramente temos que estar definindo dos pinos que utilizamos em nosso projeto.

//Definições -----------------------------------------------------------------------------------------
#define btnStart 2                                                 // Botão para inicializar o Jogo
#define ledErro 3                                                  // Led para indicar Erro
#define ledSucesso 4                                               // Led para indicar Sucesso
#define btnConfig 5                                                // Botão para entrar nas Configurações

Variáveis Globais

Em seguida declaramos seis variáveis globais. Sendo elas, palavra que guardar a frase, aux que auxilia com a manipulação de strings, dica que armazenará uma pista referente a palavra. Logo em seguida declaramos duas variáveis de controle chamadas, chance e vitória que contem as chances de adivinhar a palavra e a quantidade de vitórias. Por fim temos uma variável chamada letra com vetor de 26 para conter as letras já digitadas.

//Variáveis Globais ----------------------------------------------------------------------------------
String palavra, aux;                                               // Armazena palavra e auxiliar
String dica;                                                       // Armazena dica
byte chance = 5, vitória = 0;                                      // Variáveis para controle
char letra[26] = {};                                               // Armazena as letras já digitadas

Funções Auxiliares

Do mesmo modo vamos para as funções auxiliares. Então entre elas temos a função game que é responsável por todo o jogo, rest que é encarregado por reiniciar todas as variáveis, imprime que consiste em imprimir serial, getString que é responsável por ler as palavras da Serial, piscaLed que é responsável por piscar o LED. Por fim a logo que imprime a logo no início do programa na Serial.

//Funções Auxiliares ---------------------------------------------------------------------------------
void game();                                                       // Responsável por iniciar o jogo
void rest();                                                       // Responsável por reiniciar variáveis
void imprime();                                                    // Responsável por imprimir na Serial
String getString();                                                // Responsável por obter as Strings
void piscaLed(byte led);                                           // Responsável por piscar os LEDs
void logo();                                                       // Responsável por imprimir a logo

Funções Setup

Em seguida vamos para a função setup, aonde inicializamos a Serial com uma velocidade de 9600. Logo após chamamos a função logo, configuramos o btnConfig e btnStart (pinos 2 e 5) como INPUT_PULLUP e configuramos outros dois LED o ledSucesso e ledErro (pinos 3 e 4) como OUTPUT.

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                                            // Inicializa Serial
    logo();                                                        // Chama função logo()
    pinMode(btnStart, INPUT_PULLUP);                               // Configura pino como INPUT_PULLUP
    pinMode(ledErro, OUTPUT);                                      // Configura pino como OUTPUT
    pinMode(ledSucesso, OUTPUT);                                   // Configura pino como OUTPUT
    pinMode(btnConfig, INPUT_PULLUP);                              // Configura pino como INPUT_PULLUP
}

Funções Loop

Logo em seguida vamos para a função loop, verificamos se o btnConfig foi pressionado, se for imprimimos na Serial pedindo para o usuário digite a frase secreta com getString. Em seguida atribuímos o retorno da função getString a variável palavra, após isso imprimimos na Serial pedindo que digite a dica. Esperamos digitar e atribuímos a dica com a função getString, em seguida imprimimos na Serial algumas instruções e piscamos o ledSucesso.

//Loop -----------------------------------------------------------------------------------------------
void loop() {
    if (!digitalRead(btnConfig)) {                                 // Se btnConfig foi pressionado
        Serial.println(F("Digite uma palavra para o Jogo:"));      // imprime na Serial
        palavra = getString();                                     // Atribui o retorno de getString
        palavra.toUpperCase();                                     // Converte todo para maiúsculo
        Serial.println(F("Digite a dica: "));                      // Imprime na Serial
        dica = getString();                                        // Atribui o retorno getString a dica
        Serial.println(F("Configuração concluída com Sucesso"));   // Imprime na Serial
        Serial.print(F("Pressione o Botão Esquerdo para"));        // Imprime na Serial 
        Serial.print(F("inicializar o Jogo e o Direito para "));   // Imprime na Serial
        Serial.println(F("Inserir a Palavra "));                   // Imprime na Serial
        piscaLed(ledSucesso);                                      // Chama função piscaLed()
    }

Continuação Loop

Contudo caso não tenha sido pressionado verificamos se o botão btnStart foi pressionado, caso tenha sido iremos verificar se o tamanho da variável palavra é igual a 0, caso seja isso indica que não possui palavra na variável. Nesse caso iremos realizar mais uma verificação se vitória é igual a 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9, caso seja iremos atribuir a palavra e dica uma palavra e uma dica predeterminada cada um com sua respectiva dificuldade, em seguida iremos chamar a variável game.

else if (!digitalRead(btnStart)) {                                 // Verifica se btnStart foi pressionado
        if (palavra.length() == 0) {                               // Verifica se o tamanho da palavra = 0
            if (vitória == 0) {                                    // Verifica se vitória = 0
                palavra = "RESISTOR";                              // Atribui RESISTOR a palavra
    	        dica = "Eletrônica";                                 // Atribui Eletrônica a dica
            }
            else if (vitória == 1) {                               // Se não verifica se vitória = 1
                palavra = "CACHORRO";                              // Atribui CACHORRO a palavra
                dica = "Animal";                                   // Atribui Animal a dica
            }
            else if (vitória == 2) {                               // Se não verifica se vitória = 2
                palavra = "BANGLADESH";                            // Atribui BANGLADESH a palavra
                dica = "Pais";                                     // Atribui Pais a dica
            }
            else if (vitória == 3) {                               // Se não verifica se vitória = 3
                palavra = "HOMEM DE FERRO";                        // Atribui HOMEM DE FERRO a palavra
                dica = "Filme";                                    // Atribui Filme a dica
            }
            else if (vitória == 4) {                               // Se não verifica se vitória = 4
                palavra = "COUNTER STRIKE";                        // Atribui COUNTER STRIKE a palavra
                dica = "Jogo";                                     // Atribui Jogo a dica
            }
            else if (vitória == 5) {                               // Se não verifica se vitória = 5
                palavra = "PRETO";                                 // Atribui PRETO a palavra
                dica = "Cor";                                      // Atribui Cor a dica
            }
            else if (vitória == 6) {                               // Se não verifica se vitória = 6
                palavra = "SKATE";                                 // Atribui SKATE a palavra
                dica = "Esporte";                                  // Atribui Esporte a dica
            }
            else if (vitória == 7) {                               // Se não verifica se vitória = 7
                palavra = "HEFESTO";                               // Atribui HEFESTO a palavra
                dica = "Mitologia Grega";                          // Atribui Mitologia Grega a dica
            }
            else if (vitória == 8) {                               // Se não verifica se vitória = 8
                palavra = "SVARTALFHEIM";                          // Atribui SVARTALFHEIM a palavra
                dica = "Mitologia Nórdica";                        // Atribui Mitológica Nórdica a dica
            }
            else if (vitória == 9) {                               // Se não verifica se vitória = 9
                palavra = "HUALLAGA";                              // Atribui HUALLAGA a palavra
                dica = "Afluente Rio Amazônia";                    // Atribui Afluente Rio Amazônia a dica
            }
            else {                                                 // Se não
                Serial.println(F("Completou o Jogo Parabéns!!!")); // Imprime na Serial
                while (1) {                                        // Cria loop infinito
                    delay(10);                                     // Espera 0,01s
                }
            }
        }
        game();                                                    // Chama função game()
    }
}

Funções Game

Em seguida vamos para a primeira função das funções auxiliares a função game, ela é responsável por todo o jogo, para isso primeiramente iremos precisar preparar o “ambiente”. Sendo assim esperamos 0,2 segundos, após isso declaramos uma variável do tipo String chamada tentativa, criamos um for de 26 vezes atribuindo NULL a cada vetor da variável letra. Então seguimos fazendo outro for, porém, dessa vez o número de loops irá ser a mesmo do tamanho da variável palavra, dentro do for verificamos se o carácter na posição i da variável palavra é diferente de espaço caso seja incrementamos “-” a variável aux, caso não seja atribuímos espaço a variável aux.

//Game -----------------------------------------------------------------------------------------------
void game() {
    delay(200);                                                    // Espera 0,2s
    String tentativa;                                              // Declara variável tentativa
    for (byte i = 0; i < 26; i++) {                                // Loop para pode limpar variável letra 
        letra[i] = NULL;                                           // Limpar variável
    }
    for (byte i = 0; i < palavra.length(); i++) {                  // Loop com o tamanho  da palavra
        if (palavra.charAt(i) != ' ') {                            // Verifica se não é espaço
            aux += '-';                                            // Se não for atribui "-" a aux
        }
	    else {                                                       // Se for
            aux += ' ';                                            // atribuímos " " a aux
        }
    }

Continuação Game

Seguindo agora iremos criar um while infinito, chamamos a função imprime para que assim possa ser impresso todo o jogo, em seguida solicitamos que o usuário digite uma letra para isso imprimimos uma mensagem na Serial, utilizamos a função auxiliar getString para que assim consigamos ler os dados recebidos da Serial e atribuímos o retorno dela para a variável tentativa e convertemos todas as letras para maiúscula.

    while (1) {                                                    // Cria loop infinito
        imprime();                                                 // Chama função imprime()
	    Serial.println(F("\nDigite uma Letra:"));                    // Imprime na Serial
	    tentativa = getString();                                     // Atribui o retorno de getString
	    tentativa.toUpperCase();                                     // Converte todo para maiúsculo

Continuação Game

Continuando criamos um for de 26 vezes, para que assim possamos verificar cada vetor da variável letra. Realizamos a verificação na posição da variável letra se é igual à tentativa, se for imprimimos na serial que é uma tentativa repetida e saímos do for. Se não, verificamos na posição da variável letra é igual a nada, caso seja quer dizer que essa letra não foi utilizada, então atribuímos a posição i da variável letra a variável tentativa. Em seguida conferimos se palavra possui esta letra. Caso possua criamos um for com o tamanho da palavra e verificamos cada posição j da variável é igual à letra, caso seja trocamos a posição j pela posição i da letra na aux e chamamos a função piscaLed passando ledSucesso, porém caso não possua a letra na variável palavra, decrementaremos -1 de chance e chamamos a função piscaLed passando ledErro, e saímos do for.

	    for (byte i = 0; i < 26; i++) {                              // Cria loop do mesmo tamanho da letra
            if (letra[i] == tentativa.charAt(0)) {                 // Se letra da tentativa = alguma letra
                Serial.println(F("Tentativa Repetida"));           // Se for imprime na Serial
                break;                                             // E sai do loop
            }
            else if (letra[i] == NULL) {                           // Se não verificamos se letra = NULL
    	        letra[i] = tentativa.charAt(0);                      // Atribuímos a letra tentativa
    	        if (palavra.indexOf(letra[i]) >= 0) {                // Se tem letra na variável palavra
                    for (byte j = 0; j < palavra.length(); j++) {  // Criar um loop para verificar quantas
                        if (palavra.charAt(j) == letra[i]) {       // Se a letra da palavra = letra
                            aux.setCharAt(j, letra[i]);            // Trocamos as letras na variável aux
                            piscaLed(ledSucesso);                  // Chamamos função piscaLed()
                        }
                    }
                }
                else {                                             // Se não
                    chance--;                                      // Decrementa -1 a chance
                    piscaLed(ledErro);                             // Chama função piscaLed()
                }
                break;                                             // Sai do loop
            }
        }

Continuação Game

Logo em seguida realizamos verificação da letra teremos que estar realizando a verificação se a palavra foi adivinhada. Para isso iremos realizar uma verificação se aux é igual nossa variável palavra, chamamos a função imprime, em seguida imprimimos na Serial que a palavra foi descoberta. Portanto para sinalizar criamos um for de 10 vezes que chama a função piscaLed duas vezes a primeira passando ledSucesso e a segunda passando ledErro, após isso chamamos a função rest. Dessa forma reiniciamos algumas variáveis, também atribuímos nada a palavra, incrementamos +1 a variável vitória e saímos do while infinito.

        if (aux == palavra) {                                      // Chama função imprime()
            imprime();                                             // Imprime na Serial 
            Serial.println(F("\nVENCEU"));                         // Imprime na Serial
            Serial.println(F("PALAVRA DESCOBERTA"));               // Imprime na Serial
            Serial.println(F("Aperte no botão Esquerdo para Próximo Nível")); // Imprime na Serial
            for (byte i = 0; i < 10; i++) {                        // Cria for de 10 vezes
                piscaLed(ledSucesso);                              // Chama função piscaLed()
                piscaLed(ledErro);                                 // Chama função piscaLed()
            }
            rest();                                                // Chama função rest()
            palavra = "";                                          // Atribuía nada a variável palavra
            vitória++;                                             // Incrementa +1 em vitória 
            break;                                                 // Sai do loop
        }

Continuação Game

Por fim, caso a variável aux seja diferente da variável palavra, verificamos se chance é igual 0. Entretanto caso seja iremos saber que o usuário perdeu o jogo. Então imprimimos na Serial que o usuário perdeu o jogo e criamos um for de 10 vezes com os LEDs piscando juntos, para sinalizar que o usuário perdeu o jogo, em seguida chamamos a função rest para reiniciar algumas variável e finalizamos saindo do while infinito.

        else if (chance == 0) {                                    // Imprime na Serial
            break;                                                 // Sai do loop
            Serial.println(F("\nGAME OVER"));                      // Imprime na Serial
            Serial.println(F("PALAVRA NÃO FOI DESCOBERTA"));       // Imprime na Serial
            Serial.println(F("Aperte no Botão Esquerdo para Tentar novamente")); // Imprime na Serial
            for (byte i = 0; i < 10; i++) {                        // Criar for de 10 vezes
                digitalWrite(ledSucesso, !digitalRead(ledSucesso));// Inverte sinal do ledSucesso
                digitalWrite(ledErro, !digitalRead(ledErro));      // Inverte sinal do ledErro
                delay(200);                                        // Espera 0,2s
            }
            rest();                                                // Chama função rest()
            break;                                                 // Sai do loop
        } 
    }
}

Funções Rest

Vamos agora para a função auxiliar rest, que é responsável por reiniciar duas variáveis, sendo elas aux atribuindo nada a ela e chance atribuindo 5 a ela.

//Reinicia Variáveis ---------------------------------------------------------------------------------
void rest() {
    aux = "";                                                      // Atribui nada a aux
    chance = 5;                                                    // Atribuía 5 a chance
} 

Funções Imprime

Em seguida iremos para a função imprime, que é responsável por fazer toda a impressão na Serial do jogo. Então para isso basicamente iremos imprimir todas as informações que querermos em nosso projeto utilizando as funções print e println.

//Imprime --------------------------------------------------------------------------------------------
void imprime() {
    Serial.println(F("\nJOGO DA FORCA"));                          // Imprime na Serial

    Serial.print(F("Dica: "));                                     // Imprime na Serial
    Serial.println(dica);                                          // Imprime dica na Serial
    Serial.print(F("Letras já Utilizadas: "));                     // Imprime na Serial
    for (byte i = 0; i < 26; i++) {                                // Cria loop para imprimir letra
        Serial.print(letra[i]);                                    // Imprime letra na Serial
    }
    Serial.print(F("\nChances: "));                                // Imprime na Serial
    Serial.println(chance);                                        // Imprime chance na Serial
    Serial.println(F("  |-----------|"));                          // Imprime na Serial
    Serial.println(F("  |           |"));                          // Imprime na Serial
    Serial.println(F("  |         -----"));                        // Imprime na Serial
    for (byte i = 0; i < 4; i++) {                                 // Cria loop de 4 vezes para desenhar
        Serial.println(F("  |"));                                  // Imprime na Serial
    }
    Serial.print(F("-----    "));                                  // Imprime na Serial
    Serial.print(aux);                                             // Imprime aux na Serial
} 

Funções getString

Contudo agora iremos para a função auxiliar getString, ela é responsável por fazer a leitura da Serial. Então para isso fazemos um while até ter dados disponíveis para leitura na Serial, enquanto não tiver esperamos 0,1 segundos para realizar uma nova verificação. Entretanto caso tenha retornamos lendo a Serial até que encontremos algum “\n”.

//Obtém String ---------------------------------------------------------------------------------------
String getString() {                            
    while (!Serial.available()) delay(100);                        // Loop até possuir dados disponíveis
    return Serial.readStringUntil('\n');                           // Retorna a leitura da Serial até "\n"
}

Funções piscaLed

Logo após iremos para a penúltima função chamada piscaLed, que é responsável por piscar o LED que foi passado. Contudo para realizar isso é muito simples, primeiramente iremos inverter o sinal do LED passado, esperar 0,5 segundos e inverter novamente o sinal do LED.

//Pisca Led ------------------------------------------------------------------------------------------
void piscaLed(byte LED) {
    digitalWrite(LED, HIGH);                                       // Liga LED
    delay(500);                                                    // Espera 0,5s
    digitalWrite(LED, LOW);                                        // Desliga LED
}

Funções Logo

Por fim temos a função logo, onde iremos estar imprimindo o nome da WJ Componentes com outra fonte. Então para você também estar fazendo facilmente acesse o site chamado patrorik. Assim que tiver acessado digite o que você quiser que apareça e a fonte desejada. Contudo segue imagem de demonstração.

Figura 3 – Logo WJ Componentes Site Patrorik

Entretanto para inserir em nosso código-fonte pasta copiar e colar dentro de um println. Contudo onde tiver aspas duplas ou barra invertida, você terá que colocar mais uma barra invertida. Pois barra invertida em C é um carácter especial que pode indicar tabulação, quebra de linha entre outros… Em seguida o resultado ao incorporado no código-fonte.

//Logo -----------------------------------------------------------------------------------------------
void logo() {
    Serial.println(F(" __        ___    ____                                             _            "));
    Serial.println(F(" \\ \\      / (_)  / ___|___  _ __ ___  _ __   ___  _ __   ___ _ __ | |_ ___  ___ "));
    Serial.println(F("  \\ \\ /\\ / /| | | |   / _ \\| '_ ` _ \\| '_ \\ / _ \\| '_ \\ / _ \\ '_ \\| __/ _ \\/ __|"));
    Serial.println(F("   \\ V  V / | | | |__| (_) | | | | | | |_) | (_) | | | |  __/ | | | ||  __/\\__ \\"));
    Serial.println(F("    \\_/\\_/ _/ |  \\____\\___/|_| |_| |_| .__/ \\___/|_| |_|\\___|_| |_|\\__\\___||___/"));
    Serial.println(F("          |__/                       |_|                                        \n\n"));
    Serial.println(F("Pressione o Botão Esquerdo para inicializar o Jogo e o Direito para Inserir a Palavra"));
}

Assim finalizamos todo o código com a explicação sobre o projeto com Arduíno UNO.

Resultado do Projeto Jogo da Forca


Por fim esse foi o resultado obtido com o projeto.

Projeto Jogo da Forca com Arduíno na Serial

Agradecemos sua Presença


Por fim, espero que tenham gostado e aprendido. Então compartilhe com seus colegas e deixe um comentário de qual projeto deveria ser o próximo aqui no Blog da WJ Componentes!!
Enfim estarei deixando o arquivo Arduíno e Fritzing, link dos posts anteriores referentes ao projeto e software e sites utilizados.
Fique à vontade para tirar suas dúvidas nos comentários.

Software e Sites Utilizados

Post Relacionados

Posts mais Recentes

Julio Cesar Bonow Manoel

Julio Cesar Bonow Manoel

Cursando Engenharia da Computação pelo Centro Universitário Facens e atua no desenvolvimento de projetos na WJ Componentes. Participante da equipe de robótica Omegabotz.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *