![]() |
||
Obrigado a Julio Marchi pelo espaço cedido na MSX All |
||
![]() Basic English Essa versão tem como objetivo apresentar uma versão mais simples do jogo feita em Basic, com as rotinas principais do jogo. O programa a seguir cria um mapa de 8x8 das minas, sorteia a posição das 10 minas e por fim notifica os vizinhos da presenças das bombas. 5 ' MarMSX 2018 10 COLOR15,1,1:SCREEN0:WIDTH40:KEYOFF 20 DIM MA$(8,8) 30 GOSUB 500:GOSUB 800 40 END 500 ' 501 ' Cria minas 502 ' 510 GOSUB 600 520 FOR M=1 TO 10 530 X=INT(8*RND(-TIME))+1 540 Y=INT(8*RND(-TIME))+1 550 IF MA$(X,Y)="*" THEN 530 ELSE MA$(X,Y)="*" 560 NEXT M 570 GOSUB 700:RETURN 600 ' 601 ' Limpa minas 602 ' 610 FOR X=1 TO 8:FOR Y=1 TO 8 620 MA$(X,Y)="0" 630 NEXT Y,X 640 RETURN 700 ' 701 ' Mapa da vizinhanca 702 ' 710 FOR X=1 TO 8:FOR Y=1 TO 8 720 IF MA$(X,Y)="*" THEN GOSUB 750 730 NEXT Y,X 740 RETURN 750 ' 751 ' Notifica vizinhos 752 ' 760 FOR VX=X-1 TO X+1:FOR VY=Y-1 TO Y+1 770 IF VX<1 OR VX>8 OR VYX<1 OR VY>8 THEN 780 ELSE IF MA$(VX,VY)="*" THEN 780 775 MA$(VX,VY)=RIGHT$(STR$(VAL(MA$(VX,VY))+1),1) 780 NEXT VY,VX 790 RETURN 800 ' 801 ' Imprime mapa 802 ' 810 FOR X=16 TO 23:FOR Y=2 TO 9 820 LOCATE X,Y:PRINT MA$(X-15,Y-1); 830 NEXT Y,X 840 RETURN O capítulo 4 do manual de desenvolvimento do jogo explica como esse mapa é criado. Nessa nova etapa, o mapa do usuário "MU" é criado para indicar quais as coordenadas do mapa o usuário já abriu. A regra de impressão é a seguinte: caso não tenha aberto uma determinada coordenada do mapa, imprime o caractere "."; caso haja uma bandeira, imprime o caractere "+"; por fim, imprime a informação de acordo com o mapa do jogo "MA$". Para imprimir o mapa inicial do jogo, podemos inserir direto o caractere ".". Conforme o usuário vai abrindo o mapa, seguiremos a regra acima. 5 ' MarMSX 2018 10 COLOR15,1,1:SCREEN0:WIDTH40:KEYOFF 20 DIM MA$(8,8) Valores de MU:
Essa rotina irá controlar as ações do jogador. 40 CX=16:CY=2 50 LOCATE CX,CY:A$=INPUT$(1):A=ASC(A$) 60 IF A=29 THEN CX=CX-1:IF CX<16 THEN CX=16 70 IF A=28 THEN CX=CX+1:IF CX>23 THEN CX=23 80 IF A=30 THEN CY=CY-1:IF CY<2 THEN CY=2 90 IF A=31 THEN CY=CY+1:IF CY>9 THEN CY=9 100 IF A=13 THEN IF MU(CX-15,CY-1)<>1 THEN MU(CX-15,CY-1)=-(MU(CX-15,CY-1)=0)*2: GOSUB 850 110 IF A=32 THEN IF MU(CX-15,CY-1)=0 THEN MU(CX-15,CY-1)=1:GOSUB 850 120 GOTO 50 ... 850 ' 851 ' Imprime posicao 852 ' 860 LOCATE CX,CY 870 IF MU(CX-15,CY-1)=0 THEN PRINT".":RETURN 875 IF MU(CX-15,CY-1)=2 THEN PRINT"+":RETURN 880 IF MA$(CX-15,CY-1)="0" THEN PRINT" " ELSE PRINT MA$(CX-15,CY-1) 890 RETURN Quando o usuário abre um local do mapa, se nesse local há uma mina, ela estoura e o jogo termina. Entretanto, se todos os espaços que não são minas são abertos, o jogo termina com a vitória do jogador. 40 CX=16:CY=2 Um pequeno truque permite verificar se todas os locais "limpos" do jogo foram abertos: basta contar as casas limpas abertas e quando atingir o valor de 54, o jogo termina com vitória para o jogador. Dica: para verificar o funcionamento do código, adicione a seguinte linha e veja o mapa do jogo: 825 LOCATE X-16,Y+10:PRINT MA$(X-15,Y-1) O algoritmo de flood-fill pode ser utilizado para abrir as casas vazias automaticamente. Uma vez que o Basic não possui chamadas à funções como no Pascal e C, vamos utilizar o flood-fill com pilha. Pseudo-código para vizinhança de 4: var pilha : vetor [1..M, 1..N] de inteiro; p : inteiro; procedimento flood_fill(x, y : inteiro) inicio p ← 0; empilha(x,y); enquanto (p>0) desempilha(); se teste_condicao(X,Y) = verdadeiro então faz_algo(); empilha(x+1,y); empilha(x-1,y); empilha(x,y+1); empilha(x,y-1); fim_se fim_enquanto fim_procedimento Mudanças no jogo com flood-fill de 8 vizinhos: 20 DIM MA$(8,8):DIM MU(8,8) Nota: embora estejamos abrindo o local corrente incondicionalmente, somente espalhamos novas coordenadas se o local atual for "0". Controle:
5 ' MarMSX 2018 10 COLOR15,1,1:SCREEN0:WIDTH40:KEYOFF 20 DIM MA$(8,8):DIM MU(8,8):DEFINT S:DIM S(64,2) 30 GOSUB 500:GOSUB 800 40 CX=16:CY=2:LA=0 50 LOCATE CX,CY:A$=INPUT$(1):A=ASC(A$) 60 IF A=29 THEN CX=CX-1:IF CX<16 THEN CX=16 70 IF A=28 THEN CX=CX+1:IF CX>23 THEN CX=23 80 IF A=30 THEN CY=CY-1:IF CY<2 THEN CY=2 90 IF A=31 THEN CY=CY+1:IF CY>9 THEN CY=9 100 IF A=13 THEN IF MU(CX-15,CY-1)<>1 THEN MU(CX-15,CY-1)=-(MU(CX-15,CY-1)=0)*2 :GOSUB 850 110 IF A=32 THEN IF MU(CX-15,CY-1)=0 THEN GOSUB 1000:GOSUB900 120 GOTO 50 500 ' 501 ' Cria minas 502 ' 510 GOSUB 600 520 FOR M=1 TO 10 530 X=INT(8*RND(-TIME))+1 540 Y=INT(8*RND(-TIME))+1 550 IF MA$(X,Y)="*" THEN 530 ELSE MA$(X,Y)="*" 560 NEXT M 570 GOSUB 700:RETURN 600 ' 601 ' Limpa minas 602 ' 610 FOR X=1 TO 8:FOR Y=1 TO 8 620 MA$(X,Y)="0":MU(X,Y)=0 630 NEXT Y,X 640 RETURN 700 ' 701 ' Mapa da vizinhanca 702 ' 710 FOR X=1 TO 8:FOR Y=1 TO 8 720 IF MA$(X,Y)="*" THEN GOSUB 750 730 NEXT Y,X 740 RETURN 750 ' 751 ' Notifica vizinhos 752 ' 760 FOR VX=X-1 TO X+1:FOR VY=Y-1 TO Y+1 770 IF VX<1 OR VX>8 OR VY<1 OR VY>8 THEN 780 ELSE IF MA$(VX,VY)="*" THEN 780 775 MA$(VX,VY)=RIGHT$(STR$(VAL(MA$(VX,VY))+1),1) 780 NEXT VY,VX 790 RETURN 800 ' 801 ' Imprime mapa 802 ' 810 FOR X=16 TO 23:FOR Y=2 TO 9 820 LOCATE X,Y:PRINT"." 830 NEXT Y,X 840 RETURN 850 ' 851 ' Imprime posicao 852 ' 860 LOCATE CX,CY 870 IF MU(CX-15,CY-1)=0 THEN PRINT".":RETURN 875 IF MU(CX-15,CY-1)=2 THEN PRINT"+":RETURN 880 IF MA$(CX-15,CY-1)="0" THEN PRINT" " ELSE PRINT MA$(CX-15,CY-1) 890 RETURN 900 ' 901 ' Verifica o fim do jogo 902 ' 910 IF MA$(CX-15,CY-1)="*" THEN LOCATE 0,12:PRINT"Voce estourou uma bomba. Fim de jogo.":END 920 IF LA>53 THEN LOCATE 0,12:PRINT"Parabens. Voce limpou as minas.":END 930 RETURN 1000 ' 1001 ' Flood-fill 1002 ' 1010 P=0:SX=CX:SY=CY 1020 P=P+1:S(P,1)=CX:S(P,2)=CY 1030 CX=S(P,1):CY=S(P,2):P=P-1 1040 IF CX<16 OR CX>23 OR CY<2 OR CY>9 THEN 1110 1045 IF MU(CX-15,CY-1)=1 THEN 1110 1050 MU(CX-15,CY-1)=1:GOSUB 850:LA=LA+1 1060 IF MA$(CX-15,CY-1)<>"0" THEN 1110 1070 P=P+1:S(P,1)=CX+1:S(P,2)=CY 1075 P=P+1:S(P,1)=CX+1:S(P,2)=CY+1 1080 P=P+1:S(P,1)=CX:S(P,2)=CY+1 1085 P=P+1:S(P,1)=CX-1:S(P,2)=CY+1 1090 P=P+1:S(P,1)=CX-1:S(P,2)=CY 1095 P=P+1:S(P,1)=CX-1:S(P,2)=CY-1 1100 P=P+1:S(P,1)=CX:S(P,2)=CY-1 1105 P=P+1:S(P,1)=CX+1:S(P,2)=CY-1 1110 IF P>0 THEN 1030 1120 CX=SX:CY=SY:RETURN |
||