{*****************************************************************************}
{ }
{ UNIVERSIDADE DE SÃO PAULO }
{ INSTITUTO DE FÍSICA DE SÃO CARLOS }
{ }
{ Disciplina: Introdução à Programação de Computadores (SCE0285) }
{ Professor: Prof. Dr. Alneu de Andrade Lopes }
{ Curso: Física Computacional }
{ Semestre: 1º }
{ }
{ TRABALHO II - Campo Minado em Pascal }
{ }
{ Alunos: }
{ Gustavo Garcia Rondina N.USP: 5725706 }
{ Lucas Assirati N.USP: 5626629 }
{ }
{*****************************************************************************}
program campo_minado;
uses crt;
{ Constantes }
const
espaco = 5;
bomba = 9;
{ Variáveis globais }
var
field : array[1..10, 1..10] of integer;
temp_field : array[1..10, 1..10] of boolean;
restante : integer;
linha : integer;
coluna : integer;
i, j : integer;
num_linhas : integer;
num_cols : integer;
bomb_rate : integer;
bomb_num : integer;
perdeu : boolean;
ganhou : boolean;
option : char;
{*****************************************************************************}
{ desenha_tabela() }
{ }
{ Desenha uma tabela na tela usando os caracteres espeiciais do MS-DOS. A }
{ tabela é o próprio campo minado. Esse procedmento é chamado várias vezes, }
{ sempre que o campo precisa ser atualizado. Ele foi desenvolvida a fim de }
{ ter um bom nível de generalização. }
{ }
{ Parâmetros: }
{ }
{ line: número de linhas da tabela; }
{ col: número de colunas da tabela; }
{ sp: número de espaços em branco antes da tabela. }
{ }
{*****************************************************************************}
procedure desenha_tabela(line : integer; col : integer; sp : integer);
var
i : integer;
j : integer;
s : integer;
begin
writeln;
for s := 1 to sp do
write(' ');
for i := 1 to col do
write(' ', i, ' ');
writeln;
for s := 1 to sp do
write(' ');
write(char(218));
for i := 1 to (col - 1) do
write(char(196), char(196), char(196), char(194));
writeln(char(196), char(196), char(196), char(191));
for j := 1 to line do
begin
for s := 1 to sp do
write(' ');
for i := 1 to (col + 1) do
begin
write(char(179));
if (i <> col + 1) then
begin
if (temp_field[j, i] = false) then
write(' ')
else
begin
if (field[j, i] = bomba) then
write(' * ')
else
write(' ', field[j, i], ' ');
end;
{
if (field[j, i] = 9) then
write(' * ')
else
write(' ', field[j, i], ' ');
}
end;
end;
write(j:3);
writeln;
if (j <> line) then
begin
for s := 1 to sp do
write(' ');
write(char(195));
for i := 1 to (col - 1) do
begin
write(char(196), char(196), char(196), char(197));
end;
writeln(char(196), char(196), char(196), char(180));
end;
end;
for s := 1 to sp do
write(' ');
write(char(192));
for i := 1 to (col - 1) do
write(char(196), char(196), char(196), char(193));
writeln(char(196), char(196), char(196), char(217));
end; { fim desenha_tabela }
{*****************************************************************************}
{ random_bombs() }
{ }
{ Parâmetros: }
{ }
{ bnum: número de bombas; }
{ l: número de linhas do campo; }
{ c: número de colunas do campo. }
{ }
{ Esse procedimento distribui 'bnum' bombas aleatoriamente dentro do vetor }
{ field, de 'l' linhas por 'c' colunas. As posições das linhas e das colunas }
{ são geradas aleatoriamente usando as funções randomize() e random(). }
{ }
{*****************************************************************************}
procedure random_bombs(bnum : integer; l : integer; c : integer);
var
c_pos : integer;
l_pos : integer;
i : integer;
begin
randomize;
for i := 1 to bnum do
begin
c_pos := random(c) + 1;
l_pos := random(l) + 1;
while (field[l_pos, c_pos] = bomba) do
begin
c_pos := random(c) + 1;
l_pos := random(l) + 1;
end;
field[l_pos, c_pos] := bomba;
end;
end; { fim random_bombs }
{*****************************************************************************}
{ calcula quantas bombas tem ao redor de cada coordenada
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 4 | x | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+
}
{*****************************************************************************}
procedure calc_bombs(l : integer; c : integer);
var
i, j : integer;
count : integer;
begin
for i := 1 to l do
begin
for j := 1 to c do
begin
count := 0;
if (field[i, j] <> bomba) then
begin
{verifica posicao 1}
if (j > 1) and (i > 1) then
if (field[i - 1, j - 1] = bomba) then
count := count + 1;
{verifica posicao 2}
if (i > 1) then
if (field[i - 1, j] = bomba) then
count := count + 1;
{verifica posicao 3}
if (j < c) and (i > 1) then
if (field[i - 1, j + 1] = bomba) then
count := count + 1;
{verifica posicao 4}
if (j > 1) then
if (field[i, j - 1] = bomba) then
count := count + 1;
{verifica posicao 5}
if (j < c) then
if (field[i, j + 1] = bomba) then
count := count + 1;
{verifica posicao 6}
if (j > 1) and (i < l) then
if (field[i + 1, j - 1] = bomba) then
count := count + 1;
{verifica posicao 7}
if (i < l) then
if (field[i + 1, j] = bomba) then
count := count + 1;
{verifica posicao 8}
if (i < l) and (j < c) then
if (field[i + 1, j + 1] = bomba) then
count := count + 1;
field[i, j] := count;
end;
end;
end;
end; { fim calc_bombs }
{*****************************************************************************}
{ Programa Principal }
{ }
{ O programa principal pede que o usuário entre o número de linhas e de }
{ colunas do campo e o percentual de bombas que o campo deve ter. O número }
{ total de bombas é então calculado e o jogo começa. O usuário vai selecio- }
{ nando as coordenadas das casas do campo que quer abrir. Quando todas as }
{ as casas que não contém bombas forem abertas, o usuário vence. Quando uma }
{ bomba for encontrada, o jogador perde. }
{*****************************************************************************}
begin
perdeu := false;
ganhou := false;
{ inicializa a matriz com 0 em tudo }
for i := 1 to 10 do
for j := 1 to 10 do
field[i, j] := 0;
{ inicializa a matriz temporaria com false em tudo,
pois nenhuma posicao foi aberta até agora }
for i := 1 to 10 do
for j := 1 to 10 do
temp_field[i, j] := false;
writeln;
write(' Numero de linhas do campo: ');
readln(num_linhas);
writeln;
write(' Numero de colunas do campo: ');
readln(num_cols);
writeln;
write(' Porcentagem de bombas: ');
readln(bomb_rate);
{ calcula o numero de bombas no campo }
bomb_num := round((num_linhas * num_cols) * (bomb_rate / 100));
restante := (num_linhas * num_cols) - bomb_num;
clrscr;
writeln;
writeln(' INFORMACOES');
writeln(' * numero de linhas...............', num_linhas);
writeln(' * numero de colunas..............', num_cols);
writeln(' * percentual de bombas...........', bomb_rate, '%');
writeln(' * numero de bombas...............', bomb_num);
{ popula o campo com bombas aleatorias }
random_bombs(bomb_num, num_linhas, num_cols);
{ determina os numeros de cada posicao sem bomba }
calc_bombs(num_linhas, num_cols);
writeln;
write(' Pressione ENTER para iniciar o jogo...');
readln;
repeat
clrscr;
desenha_tabela(num_linhas, num_cols, espaco);
writeln;
write(' Numero da linha: ');
readln(linha);
write(' Numero da Coluna: ');
readln(coluna);
if (temp_field[linha, coluna] = true) then
begin
writeln;
writeln(' ESSA POSICAO JA FOI ABERTA! ');
writeln;
writeln(' Pressione ENTER para continuar...');
readln;
end
else if (field[linha, coluna] = bomba) then
begin
writeln;
writeln(' KABOOOOM! PERDEU! ');
writeln;
write(' Pressione ENTER para continuar...');
readln;
perdeu := true;
end
else
begin
temp_field[linha, coluna] := true;
restante := restante - 1;
if (restante = 0) then
begin
ganhou := true;
clrscr;
desenha_tabela(num_linhas, num_cols, espaco);
writeln;
writeln(' PARABENS! VENCEU!');
writeln(' Voce abriu todas as casas sem bombas!');
writeln;
write(' Pressione ENTER para continuar...');
readln;
end;
end;
until (perdeu = true) or (ganhou = true);
clrscr;
writeln;
write(' Quer visualizar o campo com todas as casas abertas? [S/N] ');
readln(option);
if (upcase(option) = 'S') then
begin
for i := 1 to num_linhas do
for j := 1 to num_cols do
temp_field[i, j] := true;
desenha_tabela(num_linhas, num_cols, espaco);
end;
writeln;
write(' Pressione ENTER para finalizar...');
readln;
end. { fim programa principal }