Using DCS7 BASIC libs, over the weekend I have made a 2048 clone on my calc. I aimed for speed instead of size, so I hard-coded every piece of the recursive movement algorithm. I have worked very hard to get the graphics right, and I like them. Here are some pictures:




And here is the sliding algorithm code:


Code:
DCS6
"7FFE80019C39A2458C459045BE39800180018C399445A439BE45843980017FFE
"rowSwap(thetathetaZZ2048->Str1

//unarchive/create/initialize the savestate
det(0,Str1,5
If "A"=sub(det(0,Str1,7),1,1
det(0,Str1
If 4>det(5,Str1,0
Then
   {4,4->dim([A]
   Fill(0,[A]
   1->[A](randInt(1,4),randInt(1,4
   Repeat not([A](A,B
      randInt(1,4->A
      randInt(1,4->B
   End
   1->[A](A,B
   det(6,Str1,det(1,[A]),1
   det(6,Str1,"0",2
   det(6,Str1,"0",3
End
//load from the savestate
expr(det(5,Str1,1->[A]
expr(det(5,Str1,2->S
expr(det(5,Str1,3->N
[A]->[B]
//draw the game to the screen
real(0,0
real(1,0,0,4,15,7,2,48,0,0,0
real(1,1,17,2,8,7,0,48,0,0,0
real(1,1,31,2,8,7,0,55,0,0,0
//start gaming, [clear] and [mode] exit the loop
Repeat theta=22 or theta=45
   //add a new "2" to the board if a move was made
   If [A]!=[B]
   Then
      Repeat Ans=0
         randInt(1,4->A
         randInt(1,4->B
         [A](A,B
      End
      1->[A](A,B
   End
   //draw the game's tilemap (is there an issue here? it doesn't draw on the last line)
   real(2,0,0,0,4,4,2,6,0,4,7,0,16,0
   //draw that last line (64th row)
   For(A,1,4
      [A](4,A
      real(1,16A+16,63,2,1,7,2(Ans>0),15,0,0,0
   End
   real(6
   //show the scores
   Text(24,1,S
   Text(38,1,N
   Repeat max(Ans={24,25,26,34,22,45
      getKey
   End
   Ans->theta
   //getkey and prep [B] for later comparison
   [A]->[B]
   //Lbl theta contains the code for pressing "up", so the different direction rotate/flip the matrix so that "up" works, applies the "up" move, then rotates the matrix back to the original direction
   If theta=25
   Then
      Goto theta
      Lbl A
   End
   If theta=24
   Then
      [A]^^T->[A]
      Goto theta
      Lbl B
      [A]^^T->[A]
   End
   If theta=34
   Then
      rowSwap([A],1,4->[A]
      rowSwap([A],2,3->[A]
      Goto theta
      Lbl C
      rowSwap([A],1,4->[A]
      rowSwap([A],2,3->[A]
   End
   If theta=26
   Then
      [A]^^T->[A]
      rowSwap([A],1,4->[A]
      rowSwap([A],2,3->[A]
      Goto theta
      Lbl D
      rowSwap([A],1,4->[A]
      rowSwap([A],2,3->[A]
      [A]^^T->[A]
   End
End
//this is where the loop exits to, pressing [clear] clears the board, save for 2 2's, and resets the score counter, while pressing [mode] exits and saves the current board and score
If theta=45
Then
   0->S
   Fill(0,[A]
   1->[A](randInt(1,4),randInt(1,4
   Repeat not([A](A,B
      randInt(1,4->A
      randInt(1,4->B
   End
   1->[A](A,B
End
//store the current board, score, and highscore to thetathetaZZ2048 AppVar
det(8,Str1,det(1,[A]),1
det(8,Str1,det(1,S),2
det(8,Str1,det(1,N),3
real(0,1
ClrHome
//Goto last line, returning to shell/homescreen
Goto AA


//here is the "up" sliding code, it's lenghty, but works. I would like to find a way to make this faster, though, I don't care how large it gets.
Lbl theta
//store the peices of the matrix to 16 variables for faster read/write/readability
[A](1,1->E
[A](1,2->F
[A](1,3->G
[A](1,4->H
[A](2,1->J
[A](2,2->K
[A](2,3->L
[A](2,4->M
[A](3,1->O
[A](3,2->P
[A](3,3->Q
[A](3,4->R
[A](4,1->T
[A](4,2->U
[A](4,3->V
[A](4,4->W
//If the next-to-bottom piece is empty, slide the bottom piece up
If not(O
Then
   T->O
   0->T
End
//If the next-to-top peice is empty, slide the bottom 2 pieces up
If not(J
Then
   O->J
   T->O
   0->T
End
//If the top piece is empty, slide the bottom 3 pieces up
If not(E
Then
   J->E
   O->J
   T->O
   0->T
End
//If the top piece equals the next-to-top piece, add 1 to the top piece, increment the score counter by 2^[resuting number], and slide the bottom 2 pieces up
If E(E=J
Then
   J+1->E
   S+2^Ans->S
   O->J
   T->O
   0->T
End
//If the next-to-top piece equals the next-to-bottom piece, add 1 to the next-to-top piece, increment the score counter by 2^[resuting number], and slide the bottom piece up
If J(J=O
Then
   O+1->J
   S+2^Ans->S
   T->O
   0->T
End
//If the nex-to-bottom piece equals the bottom piece, add 1 to the next-to-bottom piece, increment the scre counter by 2^[resulting number], and set the bottom peice to 0.
If O(O=T
Then
   T+1->O
   S+2^Ans->S
   0->T
End
//repeat 3 more times for the next 3 columns, same algorithm.
If not(P
Then
   U->P
   0->U
End
If not(K
Then
   P->K
   U->P
   0->U
End
If not(F
Then
   K->F
   P->K
   U->P
   0->U
End
If F(F=K
Then
   K+1->F
   S+2^Ans->S
   P->K
   U->P
   0->U
End
If K(K=P
Then
   P+1->K
   S+2^Ans->S
   U->P
   0->U
End
If P(P=U
Then
   U+1->P
   S+2^Ans->S
   0->U
End
If not(Q
Then
   V->Q
   0->V
End
If not(L
Then
   Q->L
   V->Q
   0->V
End
If not(G
Then
   L->G
   Q->L
   V->Q
   0->V
End
If G(G=L
Then
   L+1->G
   S+2^Ans->S
   Q->L
   V->Q
   0->V
End
If L(L=Q
Then
   Q+1->L
   S+2^Ans->S
   V->Q
   0->V
End
If Q(Q=V
Then
   V+1->Q
   S+2^Ans->S
   0->V
End
If not(R
Then
   W->R
   0->W
End
If not(M
Then
   R->M
   W->R
   0->W
End
If not(H
Then
   M->H
   R->M
   W->R
   0->W
End
If H(H=M
Then
   M+1->H
   S+2^Ans->S
   R->M
   W->R
   0->W
End
If M(M=R
Then
   R+1->M
   S+2^Ans->S
   W->R
   0->W
End
If R(R=W
Then
   W+1->R
   S+2^Ans->S
   0->W
End
//store the variables back into the matrix
[[E,F,G,H][J,K,L,M][O,P,Q,R][T,U,V,W->[A]
//if need be, update the highscore
If S>N
S->N
//return back to the loop given what key was pressed
If theta=25
Goto A
If theta=24
Goto B
If theta=34
Goto C
If theta=26
Goto D
Lbl AA


I have implemented the scoring system and highscore, and using Celtic libs, am able to save the score, highscore, and current game state upon exit, given that the program is in RAM and unlocked. I am pleased with the look and feel of my work, but it is still a bit slow.

*It currently take about .75 seconds for the move to be made, slower if there are less blanks and more combining/moving pieces. I would love to shave this time down to .25s, or really anything faster. A bit of slowdown happens because I am drawing a 4x4 tilemap AND For-looping through 4 2-byte sprites, so finding a solution to the "tilemaps don't draw on the 64th row" problem will help. I would love input that could suggest a new algorithm for sliding the board or a new and faster way to implement the one I am already using.

My main questions are:

1) How do I make the sliding algorithm faster?
2) One thing slowing me down is having to draw the last 4 pieces as sprites instead of in the tile map because tilemapping does not draw on the last line. Is there a way to have tilemapping utilize the 64th row of pixels?
3) Does it look good?
4) Are there any other optimizations that could be implemented as far as program flow or speed/size?
5) Should I use an AppVar instead of saving back into the original program? This would allow the original prog to remain locked and archived, but would make the code longer and use more mem on the calc.

Edit:
So, regarding #5, after playing around a bit, saving the level and score to lines at the top of the prog tend to change the program's length, and doing this before the program is finished confuses the TI-OS parser, as it is no longer looking at what it thinks it should be. This add the to con's of needing to have the program unlocked and in RAM, so I will be using an AppVar to save the current game, score, and highscore.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement