Calculator Community > Axe

Looping Through an Array in Axe

(1/3) > >>

Ki1o:
Hey all,
So I'm current working on a roguelike project but I have hit an annoying stumbling block that I'm not sure how to solve.
I'm implementing a mob system where I can add mobs to various map coordinates and display them on the screen. I'm also using their position to determine whether or not they should be drawn as well as for collision. The array that I've set up works perfectly and I can draw them to the screen, but I am encountering a weird bug(?) when I loop over the array in a for loop to compare values. Here is the full code that I have written so far:

--- Code: ---.A
./front frames
[FFC1C3E7C33E23FB]→Pic0
[C1C3E7C33E62F3FF]
[FFC1C3E7C37CC4DF]
[C1C3E7C37C46CFFF]
./right frames
[FFC1E1EBA13E22DB]
[C1E1EBE1DF9393E7]
[FFC1E1EBE19F93DB]
[C1E1EBE1BE2223E7]
./left frames
[FF8387D7857C44DB]
[8387D787FBC9C9E7]
[FF8387D787F9C9DB]
[8387D7877D44C4E7]
./back frames
[FF83C3FFA3223BF3]
[83C3FFA3227AF3FF]
[FF83C3FFC544DCCF]
[83C3FFC5445ECFFF]
./slime frames
[FFFFFFC7A3410183]→Pic2
[FFFFC7A3A38383C7]
[FFFFFFC7A3410183]
[FFFFFFFF81600081]
./wall tile, 00
[45FF11FF45FF11FF]→Pic1
./ground tile, 01
[FFFFFFFFFFEFFFFF]
./tile map
[00000000000000000000000000000000000000000000000000000000000000000000000000]→GDB0
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000010101010100000000000000000000000000000101010101000000000000]
[00000000000000010101010100000000000000000000000000000101010101000000000000]
[00000000000000010101010100000000000000000000000000000101010101000000000000]
[00000000000000010101010100000000000000000000000000000101010101000000000000]
[00000000000000010101010101010101010101010101010101010101010101000000000000]
[00000000000000000000000000000000000101010101010100000101010101000000000000]
[00000000000000000000000000000000000101010101010100000101010101000000000000]
[00000000000000000000000000000000000101010101010100000101010101000000000000]
[00000000000000000000000000000101010101010101010100000101010101000000000000]
[00000000000000000000000000000100000101010101010100000000010000000000000000]
[00000000000000000000000000000100000000000000000000000000010000000000000000]
[00000000000000000000000000000100000000000000000000000000010000000000000000]
[00000000000000000000000000000100000000000000000000000000010000000000000000]
[00000000000000000000000000000100000000000101010101010101010000000000000000]
[00000000000000000000000000000100000000000101010101010000000000000000000000]
[00000000000000000000000000000101010101010101010101010000000000000000000000]
[00000000000000000000000000000000000001000101010101010000000000000000000000]
[00000000000000000000000000000000000001000101010101010000000000000000000000]
[00000000000000000000000000000000000001000000000100000000000000000000000000]
[00000000000000000000000000000000000001000000000100000000000000000000000000]
[00000000000000000000000000000000000001000000000100000000000000000000000000]
[00000000000000000000000000000000000001000000000100000000000000000000000000]
[00000000000000000000000000000000000001000000000000000000000000000000000000]
[00000000000000010101010101010101000001000000000000000000000000000000000000]
[00000000000000010101010101010101010101000000000000000000000000000000000000]
[00000000000000010101010101010101000000000000000000000000000000000000000000]
[00000000000000010101010101010101000000000000000000000000000000000000000000]
[00000000000000010101010101010101010101010101010101010101010101000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
[00000000000000000000000000000000000000000000000000000000000000000000000000]
0->Q->P→V->H→I→J→F→S→L->K->T
Fix 5
AddMob(1,0)
AddMob(2,2)
AddMob(15,9)
AddMob(2,26)
ClrDraw
Repeat getKey(15)
  ./192 is the offset from the beginning of GDB0
  Q*37+P+192→Z
  If getKey(3) and (I=0) and (J=0) and ({Z+1+GDB0}=1)
    If Z+1≠M
      1→I
      32→S
    End
  End
  If getKey(2) and (I=0) and (J=0) and ({Z-1+GDB0}=1)
    If Z-1≠M
      0-1→I
      64→S
    End
  End
  If getKey(1) and (I=0) and (J=0) and ({Z+37+GDB0}=1)
    If Z+37≠M
      1→J
      0→S
    End
  End
  If getKey(4) and (I=0) and (J=0) and ({Z-37+GDB0}=1)
    If Z-37≠M
      0-1→J
      96→S
    End
  End
  F++
  H+I+I→H
  V+J+J→V
  If (H-8=0) or (H+8=0)
    P+I→P
    0→H→I
  End
  If (V-8=0) or (V+8=0)
    Q+J→Q
    0→V→J
  End
  DrawMap()
  DrawMob()
  Pt-Off(44,28,Pic0+(F/3^4*8)+S)
  ...Text(0,0,Z►Dec)
  For(E,1,L)
    E*4+L₁-4→G
    Text(0,E*6,{G+2}ʳ►Dec)
  End
  ...
  DispGraph
End
ClrDraw
Fix 4
Lbl AddMob
  ./r1 = x, r2 = y
  ./creates an array [x,y,y*37+x+192]
  If L<18
    r₂*37+r₁+192→{r₂→{r₁→{L+1→L*4+L₁-4}+1}+1}ʳ
  End
Return
Lbl DrawMob
  For(E,1,L)
    E*4+L₁-4→G
    {E*4+L₁-2}ʳ→M
    Text(0,0,M►Dec)
    ./If ((M-192≤Z) and (M+192≥Z))
      ./Text(0,E*6,"Drawn")
      {G}-P*8→r₁
      {G+1}-Q*8→r₂
      ./Text(0,0,M►Dec)
      Pt-Off(44+r₁-H,28+r₂-V,Pic2+(F/3^4*8))
      ./Else
      ./Text(0,E*6,"Not Drawn")
    ./End
  End
Return
Lbl DrawMap
  Q*37+P→T
  ClrDraw
  For(B,0,10)
    For(A,0,14)
      A-1*8-4-H→C
      B-1*8-4-V→D
      Pt-On(C,D,{B*37+A+T+GDB0}*8+Pic1)
    End
  End
Return
--- End code ---
The problem occurs at the line If (M-192≤Z) and (M+192≥Z) because it is not checking for all values of M, only the last value of M. At first I thought I was doing something incorrectly, so I made a test program that compares a given value with a set of values in a variable length array:

--- Code: ---.ARRAY
ClrHome
0→L
193→A
AddEntry(1156)
AddEntry(193)
AddEntry(208)
AddEntry(447)
Repeat getKey(15)
  CheckArray()
End
ClrHome
Lbl AddEntry
  r₁→{L+1→L*2+L₁-2}ʳ
Return
Lbl CheckArray
  For(I,1,L)
    {I*2+L₁-2}ʳ→B
    If A=B
      Output(0,0,"EQUAL")
      Pause 1800
      ClrHome
      Else
      Output(0,0,"NOT EQUAL")
      Pause 1800
      ClrHome
    End
  End
Return
--- End code ---

This code runs perfectly. I've been commenting out various parts of my original code to see where I am going wrong, but I can't quite solve it on my own. I'm hoping a fresh pair of eyes might give some insight as to why it is not working. Thanks.
Cross-posting from Cemetech to see if anyone here might know.

Xeda112358:
If M  is less than 192, then M-192 will wrap back around to be >=65344.

Is that possibly the issue ? If so, and if Z is small enough, then you can probably change it to compare M with Z+128 instead.

Ki1o:
Hey Xeda, thanks for replying. Initially I suspected that was the case, so I wrote in the code to display both the values of Z and M, which I commented out later to test other ideas. However the case of Z being ever less than zero should never happen as Z starts at 192 as that corresponds to the player's position at the top leftmost corner of the map, effectively (0,0). Then I thought maybe the method of accessing and checking M was somehow incorrect, so I wrote another test program that should be similar to the conditions of my original program:

--- Code: ---.ARRAY
ClrHome
0→L
193→A
AddEntry(2,26)
AddEntry(1,0)
AddEntry(15,9)
AddEntry(2,2)
Repeat getKey(15)
  CheckArray()
End
ClrHome
Lbl AddEntry
  r₂*37+[r1]+192→{[r2]->{[r1]->{L+1->L*4+L1-4}+1}+1}ʳ
Return
Lbl CheckArray
  For(I,1,L)
    {I*4+L₁-2}ʳ→B
    If (B-192≤A) and (B+192≥A)
      Output(0,0,"IN BOUNDS")
      Pause 1800
      ClrHome
      Else
      Output(0,0,"OUT OF BOUNDS")
      Pause 1800
      ClrHome
    End
  End
Return
--- End code ---
This code also executes without a hitch and perfectly loops through each value and displays whether it is out of bounds or in bounds based on a given value. I'm not entirely sure what I am overlooking at this point. When I was doing some more debugging, it looked like checking the value in the for loop was not playing nicely with drawing to the screen. I'm attaching a screenshot so I can hopefully better explain what is going on.
Funny thing: In the midst of writing this reply, I went to test the code again, this time I have text that shows whether or not a given mob is drawn, and strangely, it works.

--- Code: ---AddMob(1,0)
AddMob(2,2)
AddMob(15,9)
AddMob(2,26)
AddMob(7,5)
AddMob(8,5)
Lbl DrawMob
  For(E,1,L)
    E*4+L₁-4→G
    {E*4+L₁-2}ʳ→M
    Text(0,0,M►Dec)
  Text(36,0,L►Dec)
  If (M-192≤Z) and (M+192≥Z)
  Text(0,E*6,"Drawn")
    {G}-P*8→r₁
    {G+1}-Q*8→r₂
    Pt-Off(44+r₁-H,28+r₂-V,Pic2+(F/3^4*8))
  Else
  Text(0,E*6,"Not Drawn")
  End
  End
Return
--- End code ---
The AddMob code hasn't changed but I added a few more to the map so I can better gauge what's being drawn and should be/what's being drawn and shouldn't be/what's not being drawn and should be, if that makes sense. I added in what mobs are being placed on the map for reference in the screenshot. So the mobs at (1,0),(2,2) and (7,5) are within the bounds of being drawn and therefore should be. I went ahead counted in the map data where a mob should not be drawn based on the character's starting position and lo and behold, the mob at (8,5) should not be drawn and therefore isn't. All the other mobs are also not drawn which is the behavior I desired. Now what doesn't make sense is that this code literally was not working the day before. All I did was rewrite it by hand in a new file which makes this even more confusing. Actually the only difference between the two is this line:

--- Code: ---If ((M-155≤Z) and (M+155≥Z))
--- End code ---
became this line:

--- Code: ---If (M-155≤Z) and (M+155≥Z)
--- End code ---
In an earlier version of this project instead of "M" I used
--- Code: ---{G+2}ʳ
--- End code ---
which I used in my test program to verify that these were in fact the same values and could be used in comparing values, and it still wasn't working in the original program. So, to be honest, I'm quite lost. I'm going to continue onward with the idea that I can use the same for loop in the collision check for each direction and go from there. This has been a weird 24 hours.

E37:
Just looking through your code, I'd like to point out a few things.

I don't have my calc on me but your line r₂*37+r₁+192→{r₂→{r₁→{L+1→L*4+L₁-4}+1}+1}ʳ may not work the way you want it to. Either x->{L1}->x or x->{L1}r->x doesn't return x but instead returns L1. If it is the latter you are fine but you should keep that mechanic in mind so it doesn't get you later.

You can put your data at the end of your program. No need to scroll through all the lines of [FFC1C3E7C33E23FB]→Pic0. A lot of the Axe code examples aren't up to date at all. They are all valid as far as I know but they aren't very efficient.

I assume you starting your comments with ./ is just for you. You don't need the slash.

At the end of your program, you set Fix 4, ClrDraw, run into AddMob and use its return to quit. That is asking for trouble since you don't know the values of r1 and r2 and is is possible you corrupt memory as you exit. Just return before you get to AddMob. Also, the Fix 4 isn't really needed. Yea, it technically best practice but doesn't really matter.

Much of your code is laughably very unoptimized but if you are having trouble with other bugs I won't confuse you more with optimization. Don't worry, my first code was just as bad. (I'm sorry, I just get really excited when I see Axe code to optimize)

If you are still having trouble, (or have any in the future) upload your .8xp and I'll find out what is wrong. (and have a blast in the progress)

Ki1o:
Thanks for the reply. To your point about the line r₂*37+r₁+192→{r₂→{r₁→{L+1→L*4+L₁-4}+1}+1}ʳ, it works great, actually. I used Deep Thought's array tutorial to write it. I'm actually storing 3 values at a time but the last one can be a 2-byte value. I wrote a lot of smaller test programs to make sure I was getting the behavior I wanted.
I actually didn't realize how I was quitting the program, so thank you for that. Right now I'm focusing more on readability and functionality so yeah my code is... not very optimized. Planning on doing that sometime in the future, but any help in that regard is always appreciated.
Right now my current problem is the collision check. In my mind, I thought I could simply execute a for loop over the array and check the position of a mob in the same manner that I check collision for tiles, but I realized after trying it that this was not the right approach. The thing is, I actually don't know what the right approach is. Here is a quick snippet:

--- Code: ---If getKey(3) and (I=0) and (J=0) and ({Z+1+GDB0}=1)
    If CheckRight()
    1→I
    32→S
    End
  End
Lbl CheckRight
  For(K,1,L)
    {K*4+L₁-2}ʳ→N
    Z+1≠N
  End
Return
--- End code ---
Except I just walk right through the mobs, even in the case where the only mob is the one right next to me. I'm not entirely sure what reason is for this. In the screenshot, Z=192 and N=193. I verified that this was case using the commented out block
--- Code: --- ...Text(0,0,Z►Dec)
  For(E,1,L)
    E*4+L₁-4→G
    Text(0,E*6,{G+2}ʳ►Dec)
  End
  ...
--- End code ---
Z+1 definitely equals 193, so the statement Z+1≠N is false, and I should not be able to move to the right at the start... yet I can. What's the best way to do this?

Navigation

[0] Message Index

[#] Next page

Go to full version