Falaí povo. Me registrei faz um tempinho mas nunca postei. Resolvi então compartilhar o source de um trabalho meu pra facul. Tou no primeiro ano de Ciências da Computação e esse aqui foi um trabalho que eu tive que fazer. Foi feito em Pascal (diagmos que é a versão não gráfica de Delphi), e justamente por nao ter GUI, foi foda de fazer. O programa deveria dar a opção de salvar e abrir um novo jogo, mas ele não abre com sucesso (tá dando erro quando vai gerar a matriz a partir dos dados armazenados no arquivo de salvamento). Quem quiser fuçar, fica à vontade.
Pra compilar, eu recomendo o Dev Pascal. O Turbo ou mesmo o Free Pascal também compilam, mas precisa fazer algumas modificações no source porque eles não aceitam procedures sem declaração de parâmetros. Fora que são feios aiwuewaiueh
Tá aí o source:
{
Campo Minado (Tr.2)
}
program campominado;
uses crt;
type matriz = array[1..100,1..100] of char; {servira para guardar os chars do campo grafico}
reg = record
stat:boolean; {verdadeiro se a casa ja tiver sido visitada}
tembomba:boolean; {verdadeiro se a casa contiver uma bomba}
tembandeira:boolean; {verdadeiro se a casa contiver uma bandeira}
lin,col:integer; {contem o numero de linhas e colunas do campo (especificado pelo usuario, facilita salvamento e recuperacao)}
numero:integer; {se uma casa for selecionada e um numero for escrito, este numero e guardado aqui}
difi:integer {guarda a dificuldade escolhida pelo usuario}
end;
matrizc = array[1..100,1..100] of reg; {matriz que formara a base de dados do campo}
arq = file of matrizc; {arquivo para manipulacao de jogos salvos}
var cmd: char;
camp: matrizc;
procedure perdeu();
begin
Textbackground(black);
clrscr;
gotoxy(18,8);
TextColor(white);
writeln('Voce Perdeu x(');
Textbackground(White);
Textbackground(black);
delay(2000);
halt;
gotoxy(1,1);
end;
procedure venceu();
begin
clrscr;
gotoxy(18,8);
TextColor(green);
writeln('Voce Venceu x)');
TextColor(black);
delay(2000);
halt;
gotoxy(1,1);
end;
{Procedimento da tecla X}
procedure bandeira(Xa,Ya,totalminas:integer;var campo:matrizc;var contaband:integer);
begin
if (campo[Xa,Ya].stat=false) then {verifica se a casa nao foi visitada antes}
begin
if (campo[Xa,Ya].tembandeira=false) then {verifica se ja nao ha uma bandeira aqui}
begin
campo[Xa,Ya].tembandeira:=true;
TextColor(green);
write('X');
TextColor(black);
gotoxy(Xa,Ya);
if (campo[Xa,Ya].tembomba=true) then contaband:=contaband+1; {incrementa o contador de bandeiras CERTAS (se chegar no total (=total de casas - total de minas), o usuario ganha}
if (contaband=totalminas) then venceu();
end
else
begin
campo[Xa,Ya].tembandeira:=false;
TextColor(black);
write('0'); {se a casa ja tiver bandeira, entao o programa a retira}
contaband:=contaband-1;
gotoxy(Xa,Ya);
end;
end;
end;
{Fim do Procedimento de bandeiras}
{Início dos procedimentos de movimento pelas teclas W, S, A, D}
{ Em cada movimento, o procedimento respectivo verifica se o cursor nao esta no limite do campo atraves das variaveis Xma, Xmi, Yma e Ymi}
procedure movecima(Xa,Ya,Ymi,Yma:integer);
begin
Ya:=Ya-1;
if (Ymi < Ya) and (Ya < Yma) then gotoxy(Xa,Ya);
end;
procedure movebaixo(Xa,Ya,Ymi,Yma:integer);
begin
Ya:=Ya+1;
if (Ymi < Ya) and (Ya <= Yma) then gotoxy(Xa,Ya);
end;
procedure movedireita(Xa,Ya,Xmi,Xma:integer);
begin
Xa:=Xa-1;
if (Xmi < Xa) and (Xa <= Xma) then gotoxy(Xa,Ya);
end;
procedure moveesquerda(Xa,Ya,Xmi,Xma:integer);
begin
Xa:=Xa+1;
if (Xmi < Xa) and (Xa <= Xma) then gotoxy(Xa,Ya);
end;
{Fim dos procedimentos de movimento}
{ Início do procedimento que cuida das detonações (tecla Z) }
procedure detonar(X,Y,Xmi,Xma,Ymi,Yma,li,co:integer;var contalivre:integer;totalminas:integer;var mapa:matrizc;nrecur:integer);
var numero,c1,c2,ponttotal:integer;
begin
if(nrecur < 4) then {checa o fator de recursao do campo minado (quantas expansoes serao feitas a partir da casa atual)}
begin
nrecur:=nrecur+1; {incrementa o fator a cada vez que e executado}
ponttotal:=(li*co)-totalminas;
numero:=0;
if (mapa[X,Y].stat=false) then {verifica se a casa selecionada ja nao foi visitada antes}
begin
if (mapa[X,Y].tembandeira=false) then {verifica se a casa nao tem bandeira}
begin
if (mapa[X,Y].tembomba=true) then {se tiver bomba, o jogador perde}
begin
gotoxy(X,Y);
TextColor(Red);
write('@');
TextColor(black);
gotoxy(X,Y);
perdeu();
end
else
begin
if (mapa[Y,X].stat=false) then
begin
for c1:=-1 to 1 do {o programa roda em torno da casa selecionada para verificar se ha bombas. Se nao houver, abre
as casas. Se houver, nao as abre e incrementa o contador que determinara o numero que sera escrito
na casa selecionada}
begin
for c2:=-1 to 1 do
begin
if (c1<>0) or (c2<>0) and (X+c1 < Xma) or (X+c1 > Xmi) and (Y+c2 > Ymi) or (Y+c2 < Yma) then
begin
if (mapa[X+c1,Y+c2].tembandeira=false) then
begin
if (mapa[X+c1,Y+c2].tembomba=true) then {se tiver bomba, incrementar o contador}
begin
numero:=numero+1;
gotoxy(X,Y);
end
else
begin
if (mapa[X+c1,Y+c2].stat=false) then {se a casa perimetral nao tiver sido visitada, mexer com ela}
begin
gotoxy(X+c1,Y+c2);
write(' ');
contalivre:=contalivre+1;
detonar(X+c1,Y+c2,Xmi,Xma,Ymi,Yma,li,co,contalivre,totalminas,mapa,nrecur); {ativar a recursividade para expansao}
mapa[X+c1,Y+c2].stat:=true;
gotoxy(X,Y);
end;
end;
end;
end;
end;
end;
if numero<>0 then {se houver bombas ao redor da casa, o contador sera positivo. Neste caso, escrever o numero.}
begin
gotoxy(X,Y);
TextColor(Red);
write(numero);
TextColor(Black);
contalivre:=contalivre+1; {incrementar o contador de acertos}
mapa[X,Y].stat:=true;
mapa[X,Y].numero:=numero; {gravar o numero escrito nesta casa, para o salvamento do jogo}
gotoxy(X,Y);
end
else
begin
gotoxy(X,Y);
write(' ');
contalivre:=contalivre+1; {se o contador = 0, nao escrever nada na casa}
gotoxy(X,Y);
mapa[X,Y].stat:=true;
end;
end;
end;
end;
end;
ponttotal:=(li*co)-totalminas; {verifica se o usuario ja ganhou o jogo neste lance}
if (contalivre=ponttotal) then
clrscr
;
end
else
gotoxy(X,Y);
;
end;
{Fim do procedimento das detonações}
{Inicio do procedimento da tecla K}
procedure sair(campo:matrizc);
var resposta,extensao,nomearq,inicio:string;
arquivo:arq;
c1,c2:integer;
begin
clrscr;
readln(c1);readln(c2);
writeln(campo[c1,c2].stat);
inicio:='C:\';
extensao:='.cm';
write('Deseja salvar o jogo? (sim/nao) '); readln(resposta);
if (upcase(resposta)='SIM') or (upcase(resposta)='S') then
begin
writeln;
writeln;
write('Digite o nome do jogo a ser salvo: '); readln(resposta); {sera o nome do arquivo}
nomearq:=concat({inicio,}resposta,extensao); {junta o nome do arquivo a extensao do jogo. Aqui, eu comentei o nome do drive para que os arquivos sejam criados no mesmo diretorio.}
assign(arquivo,nomearq); {cria o handle}
rewrite(arquivo); {apaga quaisquer jogos com o mesmo nome e cria um nobo arquivo}
write(arquivo,campo); {armazena os dados do campo no arquivo}
writeln;
writeln;
close(arquivo); {fecha o arquivo}
writeln;
writeln;
writeln('Jogo salvo com sucesso. Pressione qualquer tecla para sair');
readkey;
halt; {sai do programa}
end
else
halt
;
end;
{Procedimento de coordenação do andamento do jogo pela captura das teclas.}
procedure jogar(li,co,totalminas,diff:integer;mapa:matrizc); {co e li são usadas para determinar o valor máximo das posições X e Y para os quais
o usuário pode mover-se. O valor é passado do procedimento que gera o campo minado
para que possa ser enviado para os procedimentos de movimento, e lá ser usado por ele
para limitar o movimento dentro do campo. }
var tecla: char;
xmi,xma,ymi,yma,contaband,contalivre,nini:integer; {variáveis de x e y máximo e mínimos. Serão usadas para passar informações aos procedimentos de movimento.
contaband e a variavel que cuida do controle de bandeiras certas, para garantir vitoria caso todas as minas
sejam cobertas. Contalivre faz o mesmo com as casas livres.}
sempre:boolean; {garante que as teclas sempre serão detectadas}
begin
nini:=1;
contaband:=0;
contalivre:=0;
sempre:=true;
xma:=WhereX; {detecta a posição máxima do eixo X, pois neste momento o campo acabou de ser gerado e escrito}
xmi:=xma-li; {calcula a posição mínima do mesmo eixo}
yma:=WhereY; {detecta a posição máxima do eixo Y, pois neste momento o campo acabou de ser gerado e escrito}
ymi:=yma-co; {calcula a posição mínima do mesmo eixo}
gotoxy(xmi-18,yma+5);
writeln('Z: testar posicao | X: colocar bandeira | K: sair e salvar');
gotoxy(xmi-9,ymi+5);
write('W');
gotoxy(xmi-9,ymi+6);
write('S');
gotoxy(xmi-7,ymi+6);
write('A');
gotoxy(9,ymi+6);
write('D');
gotoxy(xma,yma);
while(sempre) do
begin
tecla:=readkey;
case upcase(tecla) of
'W' : movecima(WhereX,WhereY,ymi,yma);
'S' : movebaixo(WhereX,WhereY,ymi,yma); {Chama os procedimentos referentes a cada tecla}
'A' : movedireita(WhereX,WhereY,xmi,xma);
'D' : moveesquerda(WhereX,WhereY,xmi,xma);
'Z' : detonar(WhereX,WhereY,xmi,xma,ymi,yma,li,co,contalivre,totalminas,mapa,nini);
'K' : sair(mapa);
'X' : bandeira(WhereX,WhereY,totalminas,mapa,contaband);
end;
end;
end;
{Início do procedimento que gera o campo minado.}
procedure geramina(mapa:matrizc;linhas,colunas,diff:integer);
var c1,c2,cont1,cont2,li,co,total,minas: integer;
campopro: matriz;
begin
randomize;
clrscr;
writeln('Gerando campo minado...');
total:=linhas*colunas*diff div 10; {total de minas a ser geradas, determinado pela dificuldade escolhida}
writeln('Total de Casas: ',linhas*colunas);
writeln('Minas a serem geradas: ',total);
writeln('Linhas: ',linhas);
writeln('Colunas: ',colunas);
minas:=0;
writeln;
writeln('Pressione qualquer tecla para jogar.');
for c1:=1 to 100 do
begin
for c2:=1 to 100 do
begin
mapa[c2,c1].stat:=false; { Esta parte reseta os dados da matriz, e ja armazena alguns dados novos (linhas, colunas, dificuldade)}
mapa[c2,c1].tembomba:=false;
mapa[c2,c1].tembandeira:=false;
mapa[c2,c1].lin:=linhas;
mapa[c2,c1].col:=colunas;
mapa[c2,c1].difi:=diff;
end;
end;
while (minas < total) do {enquanto o número de minas não for alcançado, continuar gerando}
begin
li:=random(linhas)+6; {calcular uma coordenada para a mina, usando o fator de correcao 6, por causa da funcao gotoxy(20,5)}
co:=random(colunas)+21; {o mesmo}
if (mapa[co,li].tembomba=false) then {checa se a posicao encontrada ja nao contem uma mina}
begin
mapa[co,li].tembomba:=true;
minas:=minas+1;
end
end;
readln;
clrscr;
TextColor(black);
gotoxy(20,5); { <---------------------------------- }
for cont1:=1 to linhas do {gera e desenha o campo na tela}
begin
for cont2:=1 to colunas do
begin
campopro[cont2,cont1]:='0'; {a matriz grafica recebe os 0s que formam o campo grafico inicial}
end;
end;
for cont1:=1 to linhas do
begin
for cont2:=1 to colunas do
begin
if (cont2 = colunas) then
begin
gotoxy(20+cont2,5+cont1);
write(campopro[cont2,cont1]);
end
else
begin
gotoxy(20+cont2,5+cont1);
write(campopro[cont2,cont1]);
end;
end;
end;
TextColor(black);
gotoxy(20+cont2,5+cont1);
jogar(colunas,linhas,total,diff,mapa); {Comeca o jogo}
end;
{Início do procedimento de novo jogo.}
procedure novojogo(var mapa:matrizc);
var diff, linhas, colunas: integer;
begin { A parte a seguir e referente a coleta de dados (opcoes do usuario)}
clrscr;
writeln;
gotoxy(10,10);
write('Determine a dificuldade desejada (1 a 8, ou 0 para default): '); readln(diff);
if (diff < 1) or (diff > 8) then {checa os limites}
begin
if (diff <> 0) then
begin
writeln('Dificuldade invalida!');
readln;
novojogo(mapa);
end
else
begin
writeln;
diff:=2; {se o valor for 0, foi escolhido default}
end;
end;
clrscr;
gotoxy(5,10);
write('Determine o numero de linhas do campo (de 8 a 20, ou 0 para default): '); readln(linhas);
if (linhas < 8) or (linhas > 20) then {checa os limites}
begin
if (linhas <> 0) then
begin
writeln('O numero de linhas fornecido e invalido.');
readln;
novojogo(mapa);
end
else {se o valor for 0, foi escolhido default}
begin
writeln;
linhas:=10;
end;
end;
clrscr;
gotoxy(5,10);
write('Determine o numero de colunas do campo: (de 8 a 50, ou 0 para default): '); readln(colunas);
if (colunas < 8) or (colunas > 50) then {checa os limites}
begin
if (colunas <> 0) then
begin
writeln('O numero de colunas fornecido e invalido.');
readln;
novojogo(mapa);
end
else
begin
writeln;
colunas:=10; {se o valor for 0, foi escolhido default}
end;
end;
clrscr;
geramina(mapa,linhas,colunas,diff);
end;
{Fim do procedimento de novo jogo.}
{Procedimento usado para abrir um jogo existente de um arquivo.}
procedure abrir();
var nome,extensao,nomefinal,inicio:string;
arquivo:arq;
armazena:matrizc;
graf:matriz;
c1,c2,linhas,colunas,minas,diff:integer;
begin
clrscr;
write('Escolheu abrir jogo salvo');
readln;
clrscr;
extensao:='.cm';
inicio:='C:\';
write('Digite o nome do seu jogo: '); readln(nome); {nome do jogo, que coincide com o nome do arquivo}
nomefinal:=concat({inicio,}nome,extensao);
writeln('Caminho do arquivo criado');
assign(arquivo,nomefinal);
writeln;
writeln('Arquivo associado ao handle');
reset(arquivo);
writeln('Arquivo aberto com sucesso... carregando.');
while not eof(arquivo) do
begin
read(arquivo,armazena); {armazena o conteudo do arquivo em uma nova matriz de registros}
writeln;
writeln('Leu o arquivo');
{pega o numero de linhas e colunas do campo salvo. Este dado esta presente em
todos os elementos da matriz de registros}
linhas:=armazena[21,6].lin;
colunas:=armazena[21,6].col;
writeln('iniciando criacao grafica');
writeln('linhas: ',linhas);
writeln('colunas: ',colunas); readln;
clrscr;
TextColor(black);
for c1:=1 to linhas do
begin
for c2:=1 to colunas do
begin {Aqui, uma nova matriz grafica e preenchida de acordo com os dados do arquivo}
if (armazena[c1,c2].stat=false) then
graf[c1,c2]:='0'
;
if (armazena[c1,c2].numero<>0) then
graf[c1,c2]:=chr(armazena[c1,c2].numero)
;
if (armazena[c1,c2].tembandeira=true) then
graf[c1,c2]:='X';
;
if (armazena[c1,c2].stat=true) then
graf[c1,c2]:=' ';
;
if (armazena[c1,c2].tembomba=true) then
minas:=minas+1
;
end;
end;
for c1:=1 to linhas do
begin
for c2:=1 to colunas do
begin
gotoxy(20+c2,5+c1);
write(graf[c2,c1]);
end;
end;
TextColor(black);
gotoxy(20+c1,5+c2);
close(arquivo);
jogar(colunas,linhas,minas,diff,armazena); {chama o jogo}
end;
end;
{Fim do procedimento de arquivo.}
{PROGRAMA PRINCIPAL}
begin
randomize;
Textbackground(white);
Textcolor(black);
clrscr;
gotoxy(5,5);
writeln('Pressione a tecla da funcao desejada: ');
writeln;
gotoxy(5,7);
writeln('N - Novo Jogo');
gotoxy(5,8);
writeln('A - Abrir jogo salvo');
cmd:=readkey;
case upcase(cmd) of
'N' : novojogo(camp);
'A' : abrir();
end;
end.