{*****************************************************************************} { } { 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 }