Created
September 21, 2023 14:30
-
-
Save wellington1993/6e56c2df3058c964037601d5a8fcf87e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
program CampoMinado; | |
uses crt; | |
const | |
N = 10; // tamanho do tabuleiro | |
M = 10; // número de minas | |
type | |
Tabuleiro = array[1..N,1..N] of integer; // matriz que armazena as minas e os números | |
Visao = array[1..N,1..N] of char; // matriz que armazena o que o jogador vê | |
var | |
tab: Tabuleiro; // variável do tipo tabuleiro | |
vis: Visao; // variável do tipo visão | |
x, y: integer; // coordenadas do cursor | |
c: char; // tecla pressionada pelo jogador | |
fim: boolean; // indica se o jogo terminou ou não | |
procedure InicializarTabuleiro(var tab: Tabuleiro); | |
// preenche o tabuleiro com zeros e minas aleatórias | |
var | |
i, j, k: integer; | |
begin | |
randomize; | |
for i := 1 to N do | |
for j := 1 to N do | |
tab[i,j] := 0; | |
k := 0; | |
while k < M do begin | |
i := random(N) + 1; | |
j := random(N) + 1; | |
if tab[i,j] <> -1 then begin | |
tab[i,j] := -1; | |
k := k + 1; | |
end; | |
end; | |
end; | |
procedure CalcularNumeros(var tab: Tabuleiro); | |
// calcula o número de minas ao redor de cada célula vazia | |
var | |
i, j, di, dj, ni, nj: integer; | |
begin | |
for i := 1 to N do | |
for j := 1 to N do | |
if tab[i,j] <> -1 then begin | |
for di := -1 to 1 do | |
for dj := -1 to 1 do begin | |
ni := i + di; | |
nj := j + dj; | |
if (ni >= 1) and (ni <= N) and (nj >= 1) and (nj <= N) then | |
if tab[ni,nj] = -1 then | |
tab[i,j] := tab[i,j] + 1; | |
end; | |
end; | |
end; | |
procedure InicializarVisao(var vis: Visao); | |
// preenche a visão com pontos para indicar as células não reveladas | |
var | |
i, j: integer; | |
begin | |
for i := 1 to N do | |
for j := 1 to N do | |
vis[i,j] := '.'; | |
end; | |
procedure DesenharTabuleiro(var vis: Visao; x, y: integer); | |
// desenha o tabuleiro na tela, destacando a posição do cursor | |
var | |
i, j: integer; | |
begin | |
clrscr; | |
writeln('CAMPO MINADO'); | |
writeln('Use as setas para mover o cursor'); | |
writeln('Pressione ENTER para revelar uma célula'); | |
writeln('Pressione ESPAÇO para marcar uma célula com uma bandeira'); | |
writeln('Pressione ESC para sair'); | |
writeln; | |
for i := 1 to N do begin | |
for j := 1 to N do begin | |
if (i = x) and (j = y) then begin // se é a posição do cursor, muda a cor de fundo | |
textbackground(white); | |
textcolor(black); | |
end else begin // se não é a posição do cursor, usa a cor padrão | |
textbackground(black); | |
textcolor(white); | |
end; | |
write(vis[i,j], ' '); | |
end; | |
writeln; | |
writeln; | |
end; | |
end; | |
procedure RevelarCelula(var tab: Tabuleiro; var vis: Visao; x, y: integer); | |
// revela o conteúdo de uma célula e propaga a revelação para as células vizinhas se for vazia | |
var | |
di, dj, ni, nj: integer; | |
begin | |
if vis[x,y] = '.' then begin // se a célula não foi revelada ainda | |
if tab[x,y] = -1 then begin // se é uma mina, mostra um X e termina o jogo | |
vis[x,y] := 'X'; | |
fim := true; | |
end else if tab[x,y] > 0 then begin // se é um número, mostra o número | |
vis[x,y] := chr(tab[x,y] + ord('0')); | |
end else begin // se é uma célula vazia, mostra um espaço e revela as células vizinhas | |
vis[x,y] := ' '; | |
for di := -1 to 1 do | |
for dj := -1 to 1 do begin | |
ni := x + di; | |
nj := y + dj; | |
if (ni >= 1) and (ni <= N) and (nj >= 1) and (nj <= N) then | |
RevelarCelula(tab, vis, ni, nj); // chamada recursiva | |
end; | |
end; | |
end; | |
end; | |
procedure MarcarCelula(var vis: Visao; x, y: integer); | |
// marca ou desmarca uma célula com uma bandeira | |
begin | |
if vis[x,y] = '.' then // se a célula não foi revelada, marca com uma bandeira | |
vis[x,y] := 'F' | |
else if vis[x,y] = 'F' then // se a célula já foi marcada, desmarca | |
vis[x,y] := '.'; | |
end; | |
function VerificarVitoria(var tab: Tabuleiro; var vis: Visao): boolean; | |
// verifica se o jogador revelou todas as células sem minas e marcou todas as minas com bandeiras | |
var | |
i, j: integer; | |
venceu: boolean; | |
begin | |
venceu := true; | |
for i := 1 to N do | |
for j := 1 to N do | |
if (tab[i,j] = -1) and (vis[i,j] <> 'F') then // se há uma mina não marcada | |
venceu := false | |
else if (tab[i,j] <> -1) and (vis[i,j] = '.') then // se há uma célula sem mina não revelada | |
venceu := false; | |
VerificarVitoria := venceu; | |
end; | |
begin | |
InicializarTabuleiro(tab); // inicializa o tabuleiro com minas e zeros | |
CalcularNumeros(tab); // calcula os números ao redor das células vazias | |
InicializarVisao(vis); // inicializa a visão com pontos | |
x := 1; // posição inicial do cursor | |
y := 1; | |
fim := false; // indica que o jogo não terminou ainda | |
repeat | |
DesenharTabuleiro(vis, x, y); // desenha o tabuleiro na tela | |
c := readkey; // lê uma tecla pressionada pelo jogador | |
case c of | |
#0: begin // se é uma tecla especial, lê o segundo código | |
c := readkey; | |
case c of | |
#72: if x > 1 then x := x - 1; // seta para cima, move o cursor para cima se possível | |
#80: if x < N then x := x + 1; // seta para baixo, move o cursor para baixo se possível | |
#75: if y > 1 then y := y - 1; // seta para esquerda, move o cursor para esquerda se possível | |
#77: if y < N then y := y + 1; // seta para direita, move o cursor para direita se possível | |
end; | |
end; | |
#13: RevelarCelula(tab, vis, x, y); // ENTER, revela a célula na posição do cursor | |
#32: MarcarCelula(vis, x, y); // ESPAÇO, marca ou desmarca a célula na posição do cursor com uma bandeira | |
end; | |
fim := fim or VerificarVitoria(tab, vis); // verifica se o jogador venceu o jogo | |
until (c = #27) or fim; // repete até que o jogador pressione ESC ou o jogo termine | |
DesenharTabuleiro(vis, x, y); // desenha o tabuleiro final na tela | |
if c = #27 then // se o jogador pressionou ESC, mostra uma mensagem de abandono | |
writeln('Você abandonou o jogo.') | |
else if VerificarVitoria(tab, vis) then // se o jogador venceu o jogo, mostra uma mensagem de vitória | |
writeln('Parabéns! Você venceu o jogo.') | |
else // se o jogador perdeu o jogo, mostra uma mensagem de derrota | |
writeln('Que pena! Você perdeu o jogo.'); | |
end. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment