|
Post by sketcz on Jul 17, 2024 11:29:53 GMT
It's a simple game where you move, it makes a hole after you move, if you move onto a hole you die. But it keeps making holes on top of the player, or just freezing!
It's meant to detect if it creates a hole in an existing hole, and redo that bit. And if it makes a hole on top of the player it redoes it.
I have been toiling for hours, and I cannot work out why. Any ideas? 1) the death blocks still appear on top of the cross 2) it freezes after about 14 steps --- CLS : CLEAR SCREEN 7 RANDOMIZE TIMER COLOR 8, 15 DIM mazex$(500) DIM mazey$(500) LOCATE 5, 5: PRINT "лллллллллллллл" FOR j% = 1 TO 10 PRINT TAB(5); "л"; TAB(18); "л" NEXT j% PRINT TAB(5); "лллллллллллллл" LOCATE 1, 2: PRINT "5 up, 2 dwn, 1 lft, 3 rght" x% = INT(RND * 9) + 6 y% = INT(RND * 11) + 6
DO LOCATE 3, 2: PRINT "score:"; S LOCATE x%, y% PRINT "+" IF mazex$(x%) = "1" AND mazey$(y%) = "1" THEN GOTO death
SELECT CASE INKEY$ CASE CHR$(0) + "H": drx% = -1 CASE CHR$(0) + "P": drx% = 1 CASE CHR$(0) + "K": dry% = -1 CASE CHR$(0) + "M": dry% = 1 CASE CHR$(27): END END SELECT
IF drx% <> 0 THEN GOSUB mover IF dry% <> 0 THEN GOSUB mover
LOOP UNTIL INKEY$ = CHR$(27) END
mover: LOCATE x%, y%: PRINT " " x% = x% + drx% y% = y% + dry% drx% = 0 dry% = 0
redoz: newx% = x% + INT(RND * 3) - 1 IF newx% = x% THEN GOTO redoz newy% = y% + INT(RND * 3) - 1 IF newy% = y% THEN GOTO redoz
IF mazex$(newx%) = "1" AND mazey$(newy%) = "1" THEN GOTO redoz
mazex$(newx%) = "1" mazey$(newy%) = "1" IF mazex$(x%) = "1" AND mazey$(y%) = "1" THEN mazex$(x%) = "0" mazey$(y%) = "0" GOTO redoz END IF
LOCATE newx%, newy%: PRINT "л"
S = S + 1 RETURN
death: LOCATE x%, y%: PRINT "л" LOCATE 20, 10: PRINT "you died" END
|
|
|
Post by bplus on Jul 17, 2024 15:01:03 GMT
What is this really? ascii number?
PRINT "лллллллллллллл"
update the code works in QB64 BUT isn't the "+" supposed to go where you were?
what is the meaning of this instruction? Locate 1, 2: Print "5 up, 2 dwn, 1 lft, 3 rght" the keypad numbers don't work nor the normal numbers along top but arrow keys work fine.
|
|
|
Post by bplus on Jul 17, 2024 17:17:22 GMT
Thankyou sketcz that was fun but tricky to update! I think I have jist of game here: _Title "Simple Game Update" ' bplus 2024-07-17
' remember Locate works backwards from all graphics commands ' Y vertical is listed first then x horizontal. ' I call it Row, Col to distinguish from graphics (x, y)
DefInt A-Z ' using default screen 0, simplest of all screen commands is none! Randomize Timer ' so we start in differnt places on board Dim maze(1 To 14, 1 To 12) 'this is our game board
For x = 1 To 14 ' marks board borders and draws them y = 1 maze(x, y) = 1 Locate y, x: Print "#"; y = 12 maze(x, y) = 1 Locate y, x: Print "#"; Next For y = 2 To 11 x = 1 maze(x, y) = 1 Locate y, x: Print "#"; x = 14 maze(x, y) = 1 Locate y, x: Print "#"; Next x = Int(Rnd * 7) + 3 ' set a random place to start y = Int(Rnd * 5) + 3
Do
Locate 15, 2: Print "score:"; S ' udate score and player Locate y, x Print Chr$(1); ' this draw a cute little face If maze(x, y) = 1 Then Locate y, x: Print "*"; Locate 18, 1: Print "Wall! Game Over!" End End If If maze(x + 1, y) = 1 Then ' is there a place to move If maze(x - 1, y) = 1 Then If maze(x, y + 1) = 1 Then If maze(x, y - 1) = 1 Then Locate 18, 1: Print "Trapped! Game Over!": End End If End If End If End If kh& = _KeyHit Select Case kh& Case 18432: dry = -1 Case 20480: dry = 1 Case 19200: drx = -1 Case 19712: drx = 1 Case 27: End End Select If drx <> 0 Or dry <> 0 Then GoSub mover _Limit 30 Loop
mover: Locate y, x: Print " "; x = x + drx y = y + dry drx = 0 dry = 0
tryAgain: newx = x + Int(Rnd * 3) - 1 newy = y + Int(Rnd * 3) - 1 If newy = y And newx = x Then GoTo tryAgain If maze(newx, newy) = 1 Then GoTo tryAgain maze(newx, newy) = 1 Locate newy, newx: Print "#"; ' mark new block S = S + 1 ' increase score Return When you use Inkey$ for multiple selections best to set ky$ = Inkey$ and select case on ky$ Also I used a 2 dim array to track the walls of the maze. Plus Locate does y or row first and x or column 2nd. All graphics use (x, y) and for 2 Dim arrays I recommend x first and y 2nd to match. Locate has been replaced bettered by _Printstring(x, y), text$ which is far superior to Locate but old habits die hard.
|
|
|
Post by sketcz on Jul 17, 2024 19:14:49 GMT
Wow, that was quick! I will go over it now - I want to see where I went wrong and try to learn from my mistakes. I'm already seeing that you did a better job tracking the two arrays. Thank you! what is the meaning of this instruction? Locate 1, 2: Print "5 up, 2 dwn, 1 lft, 3 rght" the keypad numbers don't work nor the normal numbers along top but arrow keys work fine.
Oh, this was old code. I was actually trying to convert Trap for the ZX81, from ZX81 BASIC to QB64. The original I found in a book, and it was only 19 lines and it looked fun, but it just kept going wrong. They used PEEK statements, which I don't like, and they needed converting. But clearly I messed up somewhere.
Here's the original:
Not sure where you can see the code without me taking a photo of the book.
I'll have a read of your fix and reply. Thanks again!
|
|
|
Post by sketcz on Jul 17, 2024 19:43:07 GMT
OK, wow. You are a genius. I've gone through this and it was so simple and elegant!
I even went back to my old version and changed the way DIM was handled, and it worked flawlessly!
These are the key fixes:
Dim maze(1 To 14, 1 To 12)
If maze(x, y) = 1 Then Locate y, x: Print "*"; Locate 18, 1: Print "Wall! Game Over!" End End If
If newy = y And newx = x Then GoTo tryAgain If maze(newx, newy) = 1 Then GoTo tryAgain maze(newx, newy) = 1 I went and just changed it to DIM Maze(15, 15) and it still worked.
My question though is, why did my version, with two separate arrays, mazex and mazey, go so horribly wrong?
Going back to what I posted at the start, and changing the way the array is handled, with just one, but two numbers inside, fixed it. I can see what works, but I don't quite grasp or understand the reasons why?
I'm looking over this, and I can't quite figure out why sometimes the blocks would be drawn on top of the player and you'd get an instant Game Over when moving. Your version is much better - you're only supposed to lose when trapped or when walking into a pre-existing wall.
I would have thought this prevented that: newx% = x% + INT(RND * 3) - 1 newy% = y% + INT(RND * 3) - 1 IF newx% = x% and newy% = y% THEN GOTO redoz It should prevents the hole being drawn on top of the player.
Anyway, you've fixed it and I've learned something new, so I am very happy! THANK YOU!
|
|
|
Post by bplus on Jul 17, 2024 22:40:06 GMT
Using 2 arrays for x and y can be done but very awkwardly. Each cell on the board would need an index number to use for both x array and y array, then you would need to convert a row and col to an index number, it could be done if your Basic never allowed 2d arrays.
for 3 by 5 = 15 cells or locations, indexs might look like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
you would need functions to go from index to row and column and vice versa. Imagine checking the 4 directions from one index number to see if walls (holes) or free walking space for trap.
Hmm... actually you still just need one array for the board using one index number to get the value 1 or 0 for wall/hole or free space.
It is just way more natural to "locate" a cell with an (x,y) coodinate like we do with mathematical graphs, ie for every (x,y) value there is a potential for player to move, maze array = 0 at x, y OR a wall (you call hole which works too) maze array = 1.
|
|