Zapic's Blog
用HP 39gII写一个简单的小游戏 (2048)
2020-10-04
编程
查看标签

今天摸了一天的鱼,在计算器上写了一个小游戏.
2048.gif

EXPORT ZM0;
Flush() BEGIN
 BLIT_P(G0,G9);
END;

ClrG() BEGIN
 RECT_P(G9,130,5,246,121,0,3);
 LINE_P(G9,159,5,159,121,0);
 LINE_P(G9,188,5,188,121,0);
 LINE_P(G9,217,5,217,121,0);
 LINE_P(G9,130,34,246,34,0);
 LINE_P(G9,130,63,246,63,0);
 LINE_P(G9,130,92,246,92,0);

 RECT_P(G9,31,51,89,64,3,3);
 RECT_P(G9,31,81,89,94,3,3);
END;

DMain() BEGIN
 DIMGROB_P(G9,256,127);
 ClrG();
 RECT_P(G9,30,35,90,95,0,3);
 RECT_P(G9,30,35,90,50,0,0);
 RECT_P(G9,30,65,90,80,0,0);
 RECT_P(G9,19,105,38,115,1,1);
 TEXTOUT_P("F6",G9,24,105,1,3);
 TEXTOUT_P("Save & Exit",
  G9,43,105,1
 );
 TEXTOUT_P("2048",G9,43,18,2,0);
 TEXTOUT_P("SCORE",G9,43,37,1,3);
 TEXTOUT_P("STEP",G9,48,67,1,3);
END;

DBlk(X,Y,N) BEGIN
 LOCAL Bc,Fc,Fx;
 IFTE(N<64,0,IFTE(N<1024,1,2))►Bc;
 IFTE(N<1024,3,0)►Fc;
 101+29X►X;
 -24+29Y►Y;
 IFTE(N<10,11,
  IFTE(N<100,7,
   IFTE(N<1000,6,
    IFTE(N<10000,3,1)
   )
  )
 )►Fx; RECT_P(G9,X+1,Y+1,X+28,Y+28,3,Bc);
 TEXTOUT_P(N,G9,X+Fx,
  Y+IFTE(N<100,7,9),
 IFTE(N<100,2,1),Fc,26);
END;

PrB() BEGIN
 LOCAL E,P,L,X,Y;
 {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4}►L;
 0►P;
 0►E;
 REPEAT
 FOR X FROM 1 TO 4 DO
 FOR Y FROM 1 TO 4 DO
 IF ZM0(X,Y)==0 THEN
 E+1►E;
 IF RANDOM(0,13)≤E THEN
 L(CEILING(
  RANDOM(1,SIZE(L))
 ))►ZM0(X,Y);
 1►P;
 BREAK;
 END;
 END;
 END;
 IF P THEN BREAK; END;
 END;
 UNTIL P OR E==0;
END;

MInit() BEGIN
 IFERR ZM0(5,4) THEN
  MAKEMAT(0,5,4)►ZM0;
  PrB(); PrB();
 ELSE
  IF ZM0(5,3)==0 THEN
   MAKEMAT(0,5,4)►ZM0;
   PrB(); PrB();
  END;
 END;
 0►ZM0(5,3);
END;

CheckM() BEGIN
 LOCAL X,Y,M;
 IF ZM0(4,4)==0 THEN
  RETURN 1;
 END;
 FOR X FROM 1 TO 4 DO
  FOR Y FROM 1 TO 3 DO
   IF ZM0(X,Y)==0
    OR ZM0(X,Y)==ZM0(X,Y+1)
   THEN
    1►M;
    BREAK 2;
   END;
  END;
 END;
 IF M THEN
  RETURN M; 
 END;
 FOR Y FROM 1 TO 4 DO
  FOR X FROM 1 TO 3 DO
   IF ZM0(X,Y)==0
    OR ZM0(X,Y)==ZM0(X+1,Y)
   THEN
    1►M;
    BREAK 2;
   END;
  END;
 END;
 RETURN M;
END;

ShowDie() BEGIN
 INVERT_P(G9);
 RECT_P(G9,82,47,172,77,2,2);
 RECT_P(G9,80,45,170,75,0,3);
 TEXTOUT_P("GAME OVER",
  G9,86,53,2
 );
END;

DrawM() BEGIN
 ClrG();
 LOCAL X,Y;
 FOR X FROM 1 TO 4 DO
  FOR Y FROM 1 TO 4 DO
   ABS(ZM0(X,Y))►ZM0(X,Y);
   IF ZM0(X,Y)≠0 THEN 
    DBlk(X,Y,ZM0(X,Y));
   END;
  END;
 END;
 TEXTOUT_P(ZM0(5,1),G9,34,52,1,0);
 TEXTOUT_P(ZM0(5,2),G9,34,82,1,0);
END;

AdU() BEGIN
 LOCAL M,X,Y,T;
 1►Y;
 REPEAT Y+1►Y;
  FOR X FROM 1 TO 4 DO
   IF ZM0(X,Y)==0 THEN
    CONTINUE; 
   END;
   FOR T FROM 0 TO Y-2 DO
    IF ZM0(X,Y-T-1)==0 THEN 
     ZM0(X,Y-T)►ZM0(X,Y-T-1);
     0►ZM0(X,Y-T);
     M+1►M;
     CONTINUE;     
    END;
    IF ZM0(X,Y-T-1)>0
     AND ZM0(X,Y-T)==ZM0(X,Y-T-1)
    THEN
     -2*ZM0(X,Y-T)►ZM0(X,Y-T-1);
     0►ZM0(X,Y-T);
     -ZM0(X,Y-T-1)
     +ZM0(5,1)►ZM0(5,1);
     M+1►M;
    END;
   END;
  END;
 UNTIL Y==4;
 RETURN M;
END;

AdD() BEGIN
 LOCAL M,X,Y,T;
 4►Y;
 REPEAT Y-1►Y;
  FOR X FROM 1 TO 4 DO
   IF ZM0(X,Y)==0 THEN
    CONTINUE; 
   END;
   FOR T FROM Y TO 3 DO
    IF ZM0(X,T+1)==0 THEN 
     ZM0(X,T)►ZM0(X,T+1);
     0►ZM0(X,T);
     M+1►M;
     CONTINUE;     
    END;
    IF ZM0(X,T+1)>0
     AND ZM0(X,T)==ZM0(X,T+1)
    THEN
     -2*ZM0(X,T)►ZM0(X,T+1);
     0►ZM0(X,T);
     -ZM0(X,T+1)
     +ZM0(5,1)►ZM0(5,1);
     M+1►M;
    END;
   END;
  END;
 UNTIL Y==1;
 RETURN M;
END;



AdL() BEGIN
 LOCAL M,X,Y,T;
 1►X;
 REPEAT X+1►X;
  FOR Y FROM 1 TO 4 DO
   IF ZM0(X,Y)==0 THEN
    CONTINUE; 
   END;
   FOR T FROM 0 TO X-2 DO
    IF ZM0(X-T-1,Y)==0 THEN 
     ZM0(X-T,Y)►ZM0(X-T-1,Y);
     0►ZM0(X-T,Y);
     M+1►M;
     CONTINUE;     
    END;
    IF ZM0(X-T-1,Y)>0
     AND ZM0(X-T,Y)==ZM0(X-T-1,Y)
    THEN
     -2*ZM0(X-T,Y)►ZM0(X-T-1,Y);
     0►ZM0(X-T,Y);
     -ZM0(X-T-1,Y)
     +ZM0(5,1)►ZM0(5,1);
     M+1►M;
    END;
   END;
  END;
 UNTIL X==4;
 RETURN M;
END;

AdR() BEGIN
 LOCAL M,X,Y,T;
 4►X;
 REPEAT X-1►X;
  FOR Y FROM 1 TO 4 DO
   IF ZM0(X,Y)==0 THEN
    CONTINUE; 
   END;
   FOR T FROM X TO 3 DO
    IF ZM0(T+1,Y)==0 THEN 
     ZM0(T,Y)►ZM0(T+1,Y);
     0►ZM0(T,Y);
     M+1►M;
     CONTINUE;     
    END;
    IF ZM0(T+1,Y)>0
     AND ZM0(T,Y)==ZM0(T+1,Y)
    THEN
     -2*ZM0(T,Y)►ZM0(T+1,Y);
     0►ZM0(T,Y);
     -ZM0(T+1,Y)
     +ZM0(5,1)►ZM0(5,1);
     M+1►M;
    END;
   END;
  END;
 UNTIL X==1;
 RETURN M;
END;


WaitK() BEGIN
 LOCAL R,P,Ap;
 {9,10,14,15,5}►Ap;
 REPEAT
  POS(Ap,GETKEY())►P;
  IF NOT P THEN
   CONTINUE;
  ELSE IF P==1 THEN 
   AdU()►R;
  ELSE IF P==2 THEN
   AdR()►R;
  ELSE IF P==3 THEN
   AdL()►R;
  ELSE IF P==4 THEN
   AdD()►R;
  ELSE IF P==5 THEN 
   1►ZM0(5,3);
   BREAK;
  END;END;END;END;END;END;
  IF R>0 THEN
   ZM0(5,2)+1►ZM0(5,2);
   DrawM();
   Flush();
   WAIT(0.1);
   PrB();
   DrawM();
   Flush();
   IF NOT CheckM() THEN
    ShowDie();
    Flush();
    WAIT(3);
    BREAK;
   END;
  ELSE
   INVERT();
   WAIT(0.3);
   INVERT();
   REPEAT UNTIL GETKEY()==-1;
  END;
  0►R;
 UNTIL 0;
END;

EXPORT Z2048() BEGIN
 DMain();
 MInit();
 DrawM();
 Flush();
 WaitK();
 KILL;
END;

就这样.