Nesta aula vamos finalizar o desenvolvimento do nosso Jogo Campo Minado em Portugol, desenvolvendo o loop principal do jogo e finalizando a impressão do tabuleiro na tela.
Jogo Campo Minado Parte I
Jogo Campo Minado Parte II
O procedimento a seguir é fundamento em nosso jogo campo minado. É neste procedimento que as ações de imprimir tabuleiro, ler as coordenadas, abrir posições e verificar se o jogador ganhou ou perdeu serão repetidas até que uma das situações de encerramento (vitória ou derrota) seja alcançada.
/*
* procedimento com o loop principal do jogo
*/
funcao jogar(){
inteiro perdeu, ganhou
faca{
imprimirTabuleiro()
leCoordenadas()
abrirPosicao(linha, coluna)
perdeu = Perdeu(linha, coluna)
ganhou = Ganhou(linha, coluna)
}enquanto(perdeu == 0 e ganhou == 0)
se(perdeu == 1)
escreva("\n\tVocê perdeu!!!\n")
se(ganhou == 1)
escreva("\n\tPARABÉNS. VOCÊ GANHOU!!!\n")
}
Agora podemos finalizar o procedimento para imprimir nosso tabuleiro na tela. Este procedimento é alterado realmente na tentativa e erro, ajustando e testando, até atingir a impressão desejada.
// procedimento para imprimir nosso campo minado
funcao imprimirTabuleiro(){
escreva("\n\n\t 0 1 2 3 4 5 6 7 8 9\n") // índice das colunas
escreva("\t-----------------------------------------\n")
para(linha = 0; linha < tamanho; linha++){
escreva("\t|") // primeira coluna de barras à esquerda
para(coluna = 0; coluna < tamanho; coluna++){
se(estaAberta(linha, coluna) == 1){
se(eBomba(linha, coluna) == 1)
escreva(" * |") // posição está aberta e é uma bomba
senao{
// posição está aberta mas não é uma bomba
escreva(" ", Texto.extrair_subtexto(tabuleiro[linha][coluna],2,3)," |")
}
}
senao
escreva(" |") // posição fechada
se(coluna == tamanho - 1)
escreva(" ", linha) // índice das linhas impresso à direita
}
escreva("\n\t-----------------------------------------\n")
}
}
Dentro do procedimento inicio podemos perguntar ao jogador se ele deseja jogar novamente ao terminar um jogo, como feito a seguir. Observe que todo o processamento inicial para inicializar a matriz, sortear bombas e contar as bombas vizinhas precisam ser feitos novamente, pois um novo jogo será iniciado.
funcao inicio(){
inteiro opcao
faca{
inicializarTabuleiro()
sortearBombas(10)
contarBombasVizinhas()
jogar()
escreva("\n\tDigite 1 para jogar novamente: \n")
leia(opcao)
}enquanto(opcao == 1)
}
Código completo em Portugol para o Jogo Campo Minado
programa{
inclua biblioteca Util
inclua biblioteca Texto
/*
* Escrito por Wagner Gaspar
* Abril de 2021
*
*
* O tabuleiro é uma matriz de caracteres
* índice 0 da cadeia indica posição aberta ou fechada:
* A = aberta
* F = fechada
* índice 1 da cadeia indica se é bomba ou não:
* * = é uma bomba
* + = não é uma bomba
* índice 2 da cadeia significa a quantidade de bombas vizinhas
* 0 = zero bombas na vizinhança
* 1 = uma bomba na vizinhança
* 2 = duas bombas na vizinhança
* 3 = três bombas na vizinhança
* 4 = quatro bombas na vizinhança
* OBSERVAÇÃO: são consideradas vizinhas de uma posição l c apenas 4 posições:
* - imediatamente acima
* - imediatamente abaixo
* - imediatamente à direita
* - imediatamente à esquerda
* EXEMPLOS:
* F+1 -> ainda fechada, não é bomba e possui 1 bomba vizinha
* A+2 -> aberta, não é bomba e possui duas bombas vizinhas
* F*0 -> ainda fechada, é uma bomba
*/
// Variáveis globais
cadeia tabuleiro[10][10]
inteiro tamanho = 10, linha, coluna
/*
* Este procedimento inicializa nosso matriz
* F significa fechado
* A - aberto
* * - bomba
* + - não é bomba
* 0 - zero bombas vizinhas
*/
funcao inicializarTabuleiro(){
para(linha = 0; linha < tamanho; linha++){
para(coluna = 0; coluna < tamanho; coluna++){
tabuleiro[linha][coluna] = "F+0"
}
}
}
// procedimento para imprimir nosso campo minado
funcao imprimirTabuleiro(){
escreva("\n\n\t 0 1 2 3 4 5 6 7 8 9\n")
escreva("\t-----------------------------------------\n")
para(linha = 0; linha < tamanho; linha++){
escreva("\t|")
para(coluna = 0; coluna < tamanho; coluna++){
se(estaAberta(linha, coluna) == 1){
se(eBomba(linha, coluna) == 1)
escreva(" * |")
senao{
escreva(" ", Texto.extrair_subtexto(tabuleiro[linha][coluna],2,3)," |")
}
}
senao
escreva(" |")
se(coluna == tamanho - 1)
escreva(" ", linha)
}
escreva("\n\t-----------------------------------------\n")
}
}
/*
* procedimento que sorteia bombas
* recebe como parâmetro a quantidade de bombas que deve ser gerado
*/
funcao sortearBombas(inteiro quantidade){
inteiro l, c
para(linha = 1; linha <= quantidade; linha++){
l = Util.sorteia(0, tamanho - 1) // 0 até 9
c = Util.sorteia(0, tamanho - 1)
// F+0 trocar o + por um *
tabuleiro[l][c] = Texto.substituir(tabuleiro[l][c], "+", "*")
}
}
/*
* função que verifica se uma coordenada é válida
* 1 - é válida
* 0 - não é válida
*/
funcao inteiro eValida(inteiro l, inteiro c){
se(l >= 0 e l < tamanho e c >= 0 e c < tamanho)
retorne 1 // é válido
retorne 0 // não é válido
}
/*
* Função que verifica se uma posição é bomba ou não
* 1 - é bomba
* 0 - não é bomba
*/
funcao inteiro eBomba(inteiro l, inteiro c){
se(eValida(l, c) == 1){
se(Texto.posicao_texto("*", tabuleiro[l][c], 1) != -1)
retorne 1 // é uma bomba
senao
retorne 0 // não é uma bomba
}
retorne 0 // não é bomba ou é inválida
}
/*
* Procedimento para contar a quantidade de bombas na vizinhança para cada posição
*/
funcao contarBombasVizinhas(){
inteiro quantidade = 0
para(linha = 0; linha < tamanho; linha++){
para(coluna = 0; coluna < tamanho; coluna++){
quantidade += eBomba(linha - 1, coluna) // acima
quantidade += eBomba(linha + 1, coluna) // abaixo
quantidade += eBomba(linha, coluna + 1) // à direita
quantidade += eBomba(linha, coluna - 1) // à esquerda
tabuleiro[linha][coluna] = Texto.substituir(tabuleiro[linha][coluna], "0", ""+quantidade)
quantidade = 0
}
}
}
/*
* função que lê uma única coordenada
* retorna a coordenada lida quando for válida
*/
funcao inteiro leCoordenada(){
inteiro x
leia(x)
enquanto(x < 0 ou x >= tamanho){
escreva("\n\tÍndice Inválido. Digite um valor entre 0 e ", tamanho -1, ".\n")
leia(x)
}
retorne x
}
/*
* função que verifica se uma posição já foi aberta
* 1 - aberta
* 0 fechada
*/
funcao inteiro estaAberta(inteiro l, inteiro c){
se(Texto.posicao_texto("A", tabuleiro[l][c], 0) != -1)
retorne 1 // está aberta
retorne 0 // está fechada
}
/*
* procedimento que faz a leitura das coordenadas de linha e coluna
*/
funcao leCoordenadas(){
faca{
escreva("\n\tDigite a coordenada de linha:\n")
linha = leCoordenada()
escreva("\n\tDigite a coordenada de coluna:\n")
coluna = leCoordenada()
se(estaAberta(linha, coluna) == 1)
escreva("\n\tEsta posição já foi aberta. Digite outra posição!\n")
}enquanto(estaAberta(linha, coluna) == 1)
}
/*
* procedimento para abrir posição jogada
* se tiver 0 bombas vizinhas, seus vizinhos devem ser abertos também
*/
funcao abrirPosicao(inteiro l, inteiro c){
se(eValida(l, c) == 1 e estaAberta(l, c) == 0){
tabuleiro[l][c] = Texto.substituir(tabuleiro[l][c], "F", "A")
se(Texto.posicao_texto("0", tabuleiro[l][c], 2) != -1){
abrirPosicao(l - 1, c) // acima
abrirPosicao(l + 1, c) // abaixo
abrirPosicao(l, c + 1) // direita
abrirPosicao(l, c - 1) // esquerda
}
}
}
/*
* função que verifica se o jogador perdeu
* 1 - perdeu
* 0 - não perdei ainda
*/
funcao inteiro Perdeu(inteiro l, inteiro c){
se(eBomba(l, c) == 1)
retorne 1 // perdeu
retorne 0 // ainda não perdeu
}
/*
* função que conta e retorna a quantidade de posições fechadas que não são bombas
*/
funcao inteiro totalFechadas(){
inteiro quantidade = 0
para(linha = 0; linha < tamanho; linha++){
para(coluna = 0; coluna < tamanho; coluna++){
se(eBomba(linha, coluna) == 0 e estaAberta(linha, coluna) == 0)
quantidade++
}
}
//escreva("\n==== quantidade: ", quantidade, "====\n")
retorne quantidade
}
/*
* função para verificar se o jogador ganhou
* 1 - ganhou
* 0 - não ganhou ainda
*/
funcao inteiro Ganhou(inteiro l, inteiro c){
se(totalFechadas() == 0)
retorne 1 // jogador ganhou
retorne 0 // jogador não ganhou ainda
}
/*
* procedimento com o loop principal do jogo
*/
funcao jogar(){
inteiro perdeu, ganhou
faca{
imprimirTabuleiro()
leCoordenadas()
abrirPosicao(linha, coluna)
perdeu = Perdeu(linha, coluna)
ganhou = Ganhou(linha, coluna)
}enquanto(perdeu == 0 e ganhou == 0)
se(perdeu == 1)
escreva("\n\tVocê perdeu!!!\n")
se(ganhou == 1)
escreva("\n\tPARABÉNS. VOCÊ GANHOU!!!\n")
}
funcao inicio(){
inteiro opcao
faca{
inicializarTabuleiro()
sortearBombas(10)
contarBombasVizinhas()
jogar()
escreva("\n\tDigite 1 para jogar novamente: \n")
leia(opcao)
}enquanto(opcao == 1)
}
}
