Zerosquare Posted August 6, 2018 Share Posted August 6, 2018 Mersenne twisters have a better randomness indeed, but they're slower. I don't think it's worth it for games Quote Link to comment Share on other sites More sharing options...
Christos Posted August 6, 2018 Share Posted August 6, 2018 It depends on the game though. On a turn based rpg it wouldnt matter Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted August 7, 2018 Share Posted August 7, 2018 I now have it pulling from the numbers stored into the array from the (not actually random) random generator (I'll worry about that later) with a counter assigned so that each time it passes (I depress a key, it allows the playback to cycle plus 1), it increases by one and will go up to 8, 16, 32 and displays accordingly on-screen to match the corresponding colors. That's just swell... However, I still don't know how to read from the Jaguar port as an INPUT and wait for user input to check against what is stored in the array. Normally it would be INPUT A$ whatnot and in this case I can't replace that with the jagpad_1 BAND whatever because it obviously doesn't work. Or am I supposed to only look at this system as a constant input and build around that only? Probably overtired and overthinking it as if it should be in a separate subroutine, but maybe not? Also, is there a trick to negative counters? I was trying to have the program display 1, 2, 3 sequence from memory but deduct from a separate counter so that as long as it matched 1 from the main counter for seq1 and was 1 for the input counter, it would display. The main counter is working just fine. I've tried a dozen things with the negative counter but can't seem to get it to work in conjunction with. More or less I'm asking to make sure there's no known issues or bugs going into a negative as it cycles, may it be from sub routines or user inputs? Quote Link to comment Share on other sites More sharing options...
ggn Posted August 7, 2018 Share Posted August 7, 2018 However, I still don't know how to read from the Jaguar port as an INPUT and wait for user input to check against what is stored in the array. Normally it would be INPUT A$ whatnot and in this case I can't replace that with the jagpad_1 BAND whatever because it obviously doesn't work. Or am I supposed to only look at this system as a constant input and build around that only? Probably overtired and overthinking it as if it should be in a separate subroutine, but maybe not? So when you type INPUT A$ in common basic dialects, what they actually do is freeze the main program and wait for user input before giving control back. So let's just do that here: dim pad as LONG ZEROPAD() pad=zero_left_pad do until (pad band 0xffbefbf)<>0 ZEROPAD() pad=zero_left_pad loop So what this does is: a) do an initial read of the pad values, b) go into an infinite loop checking if any button was pressed, and only then break the loop. You might wonder what's that dark arts "pad band 0xffbefbf" about? Normally to check if anything was pressed we'd simply have to do something like (pad<>0) since no button press would mean zero, right? Well, it turns out that there are some "hidden" buttons on each jagpad (which IIRC have to do with teamtaps) that are set at all times. Our condition then has to be rewritten to "(pad band -Input_Pad_C1<>0) band (pad band -Input_Pad_C2<>0) band (pad band -Input_Pad_C3<>0)" or something like that (haven't tested this!), which is a bit long! So instead using boolean math we can convert this to "pad band -(Input_Pad_C1 bor Input_Pad_C2 bor Input_Path_C3)". In turn this boils down to the magic value of 0xffbefbf. Also, is there a trick to negative counters? I was trying to have the program display 1, 2, 3 sequence from memory but deduct from a separate counter so that as long as it matched 1 from the main counter for seq1 and was 1 for the input counter, it would display. The main counter is working just fine. I've tried a dozen things with the negative counter but can't seem to get it to work in conjunction with. More or less I'm asking to make sure there's no known issues or bugs going into a negative as it cycles, may it be from sub routines or user inputs? There are a couple of ways to count down negatively. If I understand you correctly you want to do a for/next counting down? Then you can use any of these for i=10 to 0 step -1 ... next i for i=0 to 10 counter=10-i 'use this variable, not i! ... next i 3 Quote Link to comment Share on other sites More sharing options...
Zerosquare Posted August 7, 2018 Share Posted August 7, 2018 Careful, that minus sign in your expression should be a NOT. In other words, to mask out bits, you need one's complement, not two's complement. 2 Quote Link to comment Share on other sites More sharing options...
ggn Posted August 7, 2018 Share Posted August 7, 2018 Careful, that minus sign in your expression should be a NOT. In other words, to mask out bits, you need one's complement, not two's complement. (haven't tested this!) Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted August 7, 2018 Share Posted August 7, 2018 dim pad as LONG ZEROPAD() pad=zero_left_pad do until (pad band 0xffbefbf)<>0 ZEROPAD() pad=zero_left_pad loop Awesome, thanks. So two questions with this (you answer one then I ask two, sorry) 1. This loop can be in its own sub routine and loop endlessly within itself... 2. ...loop until counter condition = x number then jump back to main game OR if x value = xx THEN go gameover (I'm wording this very loosely I know) I'm realizing there's multiple ways to go about this now and don't really care which is longer or harder just as long as I can do it. So, it would probably just be easier to set it up all as counter based instead of waiting for input? As in - pull random numbers from array, each cycle have it deduct or add to that specific color, have computer check to see if value has been met with that each subsequent depress otherwise gameover. I feel like reading the joystick and writing it into its own array in sequence then reading back and checking it against random generated array may be more difficult than just doing counters in any given direction based on the 4 colors. I'll mess around some more over this next week and see if I can't get it. Thanks again for the help! Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 7, 2018 Share Posted August 7, 2018 You'd normally have a game loop and call the pad reading once per screen update, rather than having it sit and wait for some kind of input, as usually there's more going on than all stop and idling until someone presses B or whatever. 1 Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted August 12, 2018 Share Posted August 12, 2018 I've spent the night on a dead end and I just don't get it. While this is very obviously the hardest way to do it (subjectively so, if it works it works) and obviously it doesn't because I'm here again haha... but, how come this doesn't work or what do I have to do to make this work: SUB CHECKSIM ZEROPAD() pad=zero_left_pad do until (pad band 0xffbefbf)<>0 IF simonvalues[1]=1 AND pad band Input_Pad_Right THEN CALL RIGHT ENDIF IF simonvalues[1]=1 AND pad band Input_Pad_Down THEN CALL GAMELOSE ENDIF IF simonvalues[1]=1 AND pad band Input_Pad_Up THEN CALL GAMELOSE ENDIF IF simonvalues[1]=1 AND pad band Input_Pad_Left THEN CALL GAMELOSE ENDIF IF simonvalues[1]=2 AND pad band Input_Pad_Right THEN CALL GAMELOSE ENDIF IF simonvalues[1]=2 AND pad band Input_Pad_Down THEN CALL DOWN ENDIF IF simonvalues[1]=2 AND pad band Input_Pad_Up THEN CALL GAMELOSE ENDIF IF simonvalues[1]=2 AND pad band Input_Pad_Left THEN CALL GAMELOSE ENDIF IF simonvalues[1]=3 AND pad band Input_Pad_Right THEN CALL GAMELOSE ENDIF IF simonvalues[1]=3 AND pad band Input_Pad_Down THEN CALL GAMELOSE ENDIF IF simonvalues[1]=3 AND pad band Input_Pad_Up THEN CALL GAMELOSE ENDIF IF simonvalues[1]=3 AND pad band Input_Pad_Left THEN CALL LEFT ENDIF IF simonvalues[1]=4 AND pad band Input_Pad_Right THEN CALL GAMELOSE ENDIF IF simonvalues[1]=4 AND pad band Input_Pad_Down THEN CALL GAMELOSE ENDIF IF simonvalues[1]=4 AND pad band Input_Pad_Up THEN CALL UP ENDIF IF simonvalues[1]=4 AND pad band Input_Pad_Left THEN CALL GAMELOSE ENDIF IF FRCOUNT=2 THEN CALL gamestart ENDIF **here I would repeat the top portion pulling from simonvalues 2 - 8+ and continue to increase the FRCOUNT variable by +1 (which is added each time the game plays back an array loop) so it'll match that of the playback on-screen. and then, if FRCOUNT=8 goes to winscreen (which I would later change with X DIM variable so that it can increase to 16, 32, etc.)** IF FRCOUNT=8 CALL GAMEWIN ENDIF loop Quote Link to comment Share on other sites More sharing options...
ggn Posted August 12, 2018 Share Posted August 12, 2018 (edited) dim correctmask[4] as long correctmask[1]=Input_Pad_Right correctmask[2]=Input_Pad_Down correctmask[3]=Input_Pad_Left correctmask[4]=Input_Pad_Up if pad band correctmask[simon[1]] then call direction_dispatch(pad) else call gamelose endif function direction_dispatch(direction as int) select case (direction band (Input_Pad_Right bor Input_Pad_Left bor Input_Pad_Down bor Input_Pad_Up)) case Input_Pad_Right case Input_Pad_Left case Input_Pad_Down case Input_Pad_Up end select end function This should work! (I'm on vacation so I'll refrain from posting lengthy explanations for now) Edited August 12, 2018 by ggn 3 Quote Link to comment Share on other sites More sharing options...
ggn Posted August 27, 2018 Share Posted August 27, 2018 Ok, so here's the bit more elaborate explanation for the source above: What I essentially tried to do was to convert that huge block of if/call statements you had in the code you posted into something more compact. So let's examine a small part of your code: IF simonvalues[1]=1 AND pad band Input_Pad_Right THEN CALL RIGHT ENDIF IF simonvalues[1]=1 AND pad band Input_Pad_Down THEN CALL GAMELOSE ENDIF IF simonvalues[1]=1 AND pad band Input_Pad_Up THEN CALL GAMELOSE ENDIF IF simonvalues[1]=1 AND pad band Input_Pad_Left THEN CALL GAMELOSE ENDIF So this essentially calls RIGHT if and only if simonvalues[1]=1 and pad has Input_Pad_Right, else it calls GAMELOSE. Right? So we can rewrite this code as: IF simonvalues[1]=1 then IF pad band Input_Pad_Right THEN CALL RIGHT ELSE CALL GAMELOSE ENDIF ENDIF Have another read at it, as it should be directly equivalent to the code above. The second 'if' executes only when simonvalues[1]=1. So then we only have to check if pad contains the Input_Pad_Right bitmask. Otherwise it doesn't so the player loses. This way we can compress all 4 blocks of your code in 4 times my block of code above. IF simonvalues[1]=1 then IF pad band Input_Pad_Right THEN CALL RIGHT ELSE CALL GAMELOSE ENDIF ENDIF IF simonvalues[1]=2 then IF pad band Input_Pad_Down THEN CALL RIGHT ELSE CALL GAMELOSE ENDIF ENDIF IF simonvalues[1]=3 then IF pad band Input_Pad_Left THEN CALL RIGHT ELSE CALL GAMELOSE ENDIF ENDIF IF simonvalues[1]=4 then IF pad band Input_Pad_Up THEN CALL RIGHT ELSE CALL GAMELOSE ENDIF ENDIF But still that's a lot of code! So, we notice that the 4 if/endif blocks are nearly the same. The only thing that changes is simonvalues[1], the Pad_Input____ value and which subroutine to call (RIGHT/DOWN/LEFT/UP). That's where correctmask table comes in. dim correctmask[4] as long correctmask[1]=Input_Pad_Right correctmask[2]=Input_Pad_Down correctmask[3]=Input_Pad_Left correctmask[4]=Input_Pad_Up if pad band correctmask[simonvalues[1]] then call direction_dispatch(pad) else call gamelose endif Let's step through the revised if block, from innermost compexity to outermost. First of all, we assume simonvalues will evaluate to 1,2,3 or 4. This will be used as an index to correctmask table, which will give us the value Input_Pad_Right/Down/Left/Up. Then we band it with pad and call direction_dispatch if it's true (non-zero). Why does is this equivalent to the above code? Each of the 4 rewritten if blocks above only has one shot at not calling GAMELOSE. If simonvalues[1]=1 then the only mask to band and would yield a correct result is Input_Pad_Right. And this is the value correctmask[simonvalues[1]] will give us in this case! So we cut down on the checks this way. Finally, when we reach direction_dispatch we know that we have a correct answer so we simply check the pad value and call the appropriate subroutine depending on input. Hopefully this explanation makes things more clear! Explaining the code here made me realise I made a few oopsies: a) dim correctmask[4] should be dim correctmask[5] - dim is 0 indexed so it counts as an index. We use 1-4 but 0 is unused but still takes up memory! b) I don't check if simonvalues[1] is between 1 and 4 inclusive. That could also lead to problems if it's (for example) 5! c) If the player hits any other button than up/down/left/right (for example the C button) this code will also call gamelose. Not sure if you want this behaviour or not. d) Diagonal movement can also lead to correct guess (for example if the correct answer is up and the player does up-left on the d-pad) Hopefully all this makes sense now. 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.