PDA

View Full Version : Confused.... Help Please!



UKIkarus
- 27th September 2010, 12:34
Hi,

I am kind of new to programming using PICBasic Pro, my dad who is the hardware guru around here :rolleyes: has made me a board specifically for a little project I am working on but I have hit a hurdle and need some assistance.

Basically what I am trying to make is (if any of you are familiar with it) a clone of the good old Casio calculator game "Digital Invaders" found here Digi Invaders (http://www.widgetbox.com/widget/digi-invaders-casio-mg-880-game)

The scoring system and all that will be fine as I have already planned that part out as a seperate Block, the problem I am having is getting the randomly generated numbers (which I have generated in an array of 30 Bytes on start) to scroll across the screen AND check to see if they are shot...

I can get numbers to scroll across the screen fine using the following example ignore the comments positions...


FOR T = 144 TO 131 STEP -1
'LCDOUT $FE, 1
LCDOUT $FE,T,#NOS[CURNO] 'OUTPUT TO LCD SLIDE
PAUSE 1000
CURNO = CURNO + 1
'IF CURNO >= 31 THEN GOSUB ARRAY 'IN FROM LEFT LINE 1
NEXT


Where T = Var Byte
NOS = Array or []
and CURNO = Var BYTE

This of course adds to the left of the line 1 by 1, which gives me the basic fundamentals for scrolling across the screen however... I need the number to be added behind the existing numbers whilst also checking to see if the first number has been "Shot" and removing it e.g.

"4: 4913827" needs to remove the number 4 on button press and continue adding numbers on the end and shifting left where 9 moves to where 4 was etc etc

how can i go about this? I was thinking of rebuilding the array everytime a number is shot and shifting them all down an index, but i am still stuck on how I continue from where the last number was removed since I need to also check to see if a number has hit the : mark (I have that bit working in a Block of its own)

p.s. by Module I mean blocks of code dedicated to each seperate area of the overall whole I.E. Array: Start: etc etc

Thanks

Edit: forgot to mention I am using a PIC16F627 for the first beta and plan on using 628 for the next 3-4 boards I replicate from this (with the required changes)

Edit2: I have read that PicBasic (non Pro) has STRING support such as Right$ Left$ Mid$ etc? is this the case? what are the differences between the normal version and PRO?

cncmachineguy
- 27th September 2010, 13:19
OMG, I remember playing that game on my friends watch. Lets see, peeling back lots of time the year was 1982/83. On the watch version, the "aim" was the left side of the calc keypad, and "fire" was the right half. If I remember correctly, you had to press aim, which incremented the choice to fire. so if you were aiming at 8 then wanted to shoot 7, you had to press aim 9 times. Are you doing it this way, or do you have a numeric keypad to directly choose the number?

As for you actual question, I think my approach would be to have an array representing the entire string. Starting the game would have that array filled with " ".Then shift the array for every number added, decreasing the delay between shifts as the player gets to a higher level. When the fire button is pressed ( or a number key), search the array for the first match. Shift the remaining parts of the array back 1 place. This will then just over write the match and fill in the last place with a " ".

Does this help any? This sounds like a fun project, I love the old stuff :)

Acetronics2
- 27th September 2010, 13:21
Hi,

May be you could get some ideas here : ;)

http://users.picbasic.org/projects/Space%20Invaders/space_invaders.htm

no comments about the square wheel ... of course !!!

Alain

UKIkarus
- 27th September 2010, 13:55
OMG, I remember playing that game on my friends watch. Lets see, peeling back lots of time the year was 1982/83. On the watch version, the "aim" was the left side of the calc keypad, and "fire" was the right half. If I remember correctly, you had to press aim, which incremented the choice to fire. so if you were aiming at 8 then wanted to shoot 7, you had to press aim 9 times. Are you doing it this way, or do you have a numeric keypad to directly choose the number?

As for you actual question, I think my approach would be to have an array representing the entire string. Starting the game would have that array filled with " ".Then shift the array for every number added, decreasing the delay between shifts as the player gets to a higher level. When the fire button is pressed ( or a number key), search the array for the first match. Shift the remaining parts of the array back 1 place. This will then just over write the match and fill in the last place with a " ".

Does this help any? This sounds like a fun project, I love the old stuff :)

Wait?! are you saying I can shift the text inside a string left or right from a set point? I thought PBP didnt support that?

I couldnt use a string to represent the numbers and remove the first shifting the remaining characters left to replace the empty space as you say, also using your method if i shot a number and it replaced the original first character in the array would that not move the number behind it to its position on the LCD? I want that space to remain blank until another number is added to the end or it would be quite difficult to play dont you think? =D

cncmachineguy
- 27th September 2010, 20:44
I don't know about playing with strings in PBP. I was more just using that as a referance.But if you have an array, say
target var byte(32) then you could step through the array testing if the fired number matches any array values. If/when it comes to a match, you could replace the match with a " ", then update LCD, or shift them as I thought I remember and update the LCD.

UKIkarus
- 28th September 2010, 00:23
Well I am already doing that with the array, the problem lies somewhere in updating the array and continuing the scrolling of the numbers across the lcd from where i left off..

I'm not sure how to go about it since the numbers need to go from right to left with new 1's adding on the far right and removing on the far left without disrupting the current position of the other numbers while doing so

cncmachineguy
- 28th September 2010, 12:02
I have gone and played the game you linked, it is exactly as I remember it! great find, Thank you.

OK on to business here. What I understand of your description seems different then how the game works. heres what I think you are trying to do. You only want to allow the player to shoot the first (or last) number in the line? This will make it VERY hard to play. But maybe thats not what you mean.

Heres what I assumed you wanted to do, If here are 3 sevens in the display, every time i hit fire with my aim number being 7, it will remove the left most occurance of the 7. Then any numbers further to the left will move right. In that way, if the player has 3 sevens, and can press fire 3 times before a new number is added, the targets are now fewer. The orginal game had a preset number of targets to shoot for each level. When all were shot without letting them reach the : level was complete. next level, numbers appear faster.

so here is what I am trying to suggest:
assume we have only 5 elements in the array (make bigger to suit your game but the theory will be the same)

t(0) t(1) t(2) t(3) t(4) t(5) #t(5) is the : if t(5) <>" ", you lose

upon starting the game t(all) = " "
when a new number is added, it comes in at t(0). to do this, first shift everybody right, maybe like this:
t(5)=t(4)
t(4)=t(3)
t(3)=t(2)
t(2)=t(1)
t(1)=t(0)
t(0)=new target
if t(5)<>" " you lose

update LCD

now for the fire check:
scroll through the array checking for equal:

index=4
start check
if t(index)<>bullet
index=index-1
if index<0 then no hit
goto start check
else hit
now lets say t(2) = bullet

for shift = index to 4
t(shift)=t(shift+1)
next shift

now update LCD with new array!
wait in mainloop until either aim is pressed, fire is pressed or scroll timer says add a number

I purposely did not put use code tags because I am not sure this would be compilable code. I am new to PBP and don't have all the syntax in my head yet. I am really just trying to show you ONE way of approaching this. Of course a loop would be much better for the shift, and I'm sure I have left plenty of stuff out, but maybe this will help.

UKIkarus
- 28th September 2010, 12:25
I was unsure as to whether or not you could only shoot down the front number or any number in the line, so long as the number was equal to the target of course.

The problem I am having is actually getting the nubers to scroll across the LCD you see i have a 2 x 16 LCD running on port.B 4 buttons below it running on Port.A 0-3 the 627 and the required resistors etc (my dad built it specifically for this project)

The code I originally found for scrolling text across the screen was this


FOR B0 = 144 TO 128 STEP -1
LCDOUT $FE, 1 ' Clears Screen (not needed)
LCDOUT $FE,B0,"This Is A Test!!" 'OUTPUT TO LCD SLIDE
PAUSE 1000 'IN FROM RIGHT LINE 1
NEXT


The above code simply steps the string in 1 character at a time from the far right of line 1 until it reaches the far left.

Of course this is using a predefined string and isnt suitable for what I need to be doing, since I need to be bringing them in from the right while removing characters from it and maintaining the position of the existing numbers.

If how you describe the game being played is actually as it was (similar to the clone I linked)
then if the below example occured I would need to do the following

5: 4385559271 ---> 5: 438 9271 and continue adding onto the end and shifting the characters from right to left, at the same time I need to be checking to see if a number has reached the ship... I was thinking of possibly using LCDIN on the cell after the "5:" and checking to see if it had a number in it during the loop which adds another.

This would of course allow me to determine whether or not the player is out, since if a number is in that cell and another is being added then it would hit the : ;)

I just dont know how to get them to scroll and remove numbers in between without losing positioning like the example above, I am terrible when it comes to overcomplicating and thus need a little advice for an approach.

cncmachineguy
- 28th September 2010, 13:13
5: 4385559271 ---> 5: 438 9271

It would go from 4385559271 -->4389271. No space in it.

Don't think of scrolling the display. Think of your array like this:

If I have 31 positions for the numbers, They will be T(30) to t(0)
each "scroll" is really just an update to the LCD, sending array positions T(30)-T(0)
with all the elements shifted 1 place to the left. (new targets enter from the right?)
you will be able to do MANY operations before time to scroll again. Those many operations are the checking for hits, adjusting the array and so forth.

Keep this in mind, assuming you are running 4mHz internal clock (no I haven't looked at the datasheet) thats 1 million inscrutions per second. if you want to scroll at a rate of .1 second, you have time left over for 100,00 inscrutions. So the "scrolling" is just a quick task, then done.

Now I have no idea how to actually write to the LCD, but I am assuming you just send it all the characters serially and not address each charater randomly. So your array may need to be 64 bytes instead of 32.

UKIkarus
- 28th September 2010, 14:14
It would go from 4385559271 -->4389271. No space in it.

Don't think of scrolling the display. Think of your array like this:

If I have 31 positions for the numbers, They will be T(30) to t(0)
each "scroll" is really just an update to the LCD, sending array positions T(30)-T(0)
with all the elements shifted 1 place to the left. (new targets enter from the right?)
you will be able to do MANY operations before time to scroll again. Those many operations are the checking for hits, adjusting the array and so forth.

Keep this in mind, assuming you are running 4mHz internal clock (no I haven't looked at the datasheet) thats 1 million inscrutions per second. if you want to scroll at a rate of .1 second, you have time left over for 100,00 inscrutions. So the "scrolling" is just a quick task, then done.

Now I have no idea how to actually write to the LCD, but I am assuming you just send it all the characters serially and not address each charater randomly. So your array may need to be 64 bytes instead of 32.

So would you shift the 438 right to meet the 9271 or the opposite? because if its the opposite then it isnt really helping the player by shooting the middle numbers now is it? since they continue to be in the same position and will just keep adding on... unless of course they then shoot the front numbers

cncmachineguy
- 28th September 2010, 14:27
So would you shift the 438 right to meet the 9271

Yes, that way the player keeps the targets from hitting the ship.

cncmachineguy
- 28th September 2010, 15:04
Ok, Lets establish some basics first.

In your first post, you have a program that scrolls numbers across the screen at a rate of 1 sec per number. correct?

You are reading the numbers from an array, correct?

So if you take out the pause, it will just instantly display the whole array? If yes, this is your LCD update. call this every time you need to change the display.

reasons to update or change:
1. time to scroll
2. aim button pressed so you need to change the aim number
3. fire button pressed AND a hit is made

Now you can forget about the LCD. when you update it, send all 32 characters to it (unless random access is available, but this will take more code and understanding). The game portion of the program will minipulate the array so everytime in update is done, the numbers will be where they should be. Because they will be in the same position as they are in the array.

If none of this makes sense, please tell me where you are lost. This applies to all of my above posts. ;)

cncmachineguy
- 28th September 2010, 15:13
oh yea, one more thing. Ask dad if there is any hardware de-bouncing on the switches. If not, they will be something you will need to deal with in software.

UKIkarus
- 28th September 2010, 15:49
Ok i can rebuild the array as you say and debouncing i have done in the software, the problem i have is that the scrolling text code only is a for next loop which is running cell by cell on the lcd not updating the whole thing.

I could update the whole thing by starting with 14 blank array spaces at start rather than filling it all, and adapt the array 1 by 1 that way until 0-13 are filled with the numbers behind them (coming from the right) that way i can just update the lcd everytime with NOS[1-14] which will be the only onscreen values since 1-2 are taken by the number followed by a colon.

cncmachineguy
- 28th September 2010, 16:16
I think you are following me now. the LCD is really static, not scrolling, the array is what scrolls. Yes, as I posted in the beginning, start with the array filled with blank spaces or " " if you will.

try it out at first with just adding a number to the array every second, then updating the LCD. it should have the scroll effect you are looking for. The number you add to the array should be a random number, I don't recall if PBP has a random number generator, but you could just increment the number for now.

Once you have that worked out, move on to making the aim change as you press the aim button. from there its all just logic and playing with the array.

UKIkarus
- 28th September 2010, 23:54
I think you are following me now. the LCD is really static, not scrolling, the array is what scrolls. Yes, as I posted in the beginning, start with the array filled with blank spaces or " " if you will.

try it out at first with just adding a number to the array every second, then updating the LCD. it should have the scroll effect you are looking for. The number you add to the array should be a random number, I don't recall if PBP has a random number generator, but you could just increment the number for now.

Once you have that worked out, move on to making the aim change as you press the aim button. from there its all just logic and playing with the array.

Indeed, I continue to underestimate the speed of 20Mhz.

I will be able to use the array manipulation as you say in a for next loop easily ;)

I think i will first start with the shooting the far left number only for now and then move onto numbers anywhere later on since that will require that I scn the array and adjust it many times.

I do have the number changing figured out and also the "n" character and I can also shoot thats no problem ... I have the debounce and all that sorted it was just the scrolling i wasnt sure about since I was thinking of another approach.

Unfortunately since pbp does not support that approach directly its alot easier to just as you say manipulate the array, I will get on with programming it tomorrow.

cncmachineguy
- 29th September 2010, 01:24
That's great! Will you be sharing? Just curious cuz I like this application. As someone who played this when it was new, it just seems cool to have.

Are you willing to share your LCD hookup? And your actual part number for it? I would like to play with LCD's, but never seem to find time to hunt one down. No worries if you don't want to, you ARE NOT obligated to in any way.

I have had fun helping with this, you are required to share a pic or video though. ;)

UKIkarus
- 29th September 2010, 12:28
That's great! Will you be sharing? Just curious cuz I like this application. As someone who played this when it was new, it just seems cool to have.

Are you willing to share your LCD hookup? And your actual part number for it? I would like to play with LCD's, but never seem to find time to hunt one down. No worries if you don't want to, you ARE NOT obligated to in any way.

I have had fun helping with this, you are required to share a pic or video though. ;)

Of course!

I will be happy to share any information with you regarding the board and my dad can provide you with the part numbers and all.

I have just gone back over the notes for this program before I began writing it and I have noticed that the array is made up of "Bytes" meaning I cannot enter a space or " " since it sees it as a string or char and converts it to the decimal value any ideas?

I suppose I could just get the decimal value and check to see if the vallue in the array is equal to that value and just override it for the lcd printing a space, it is just awquard to do it that way and means more code hehe

cncmachineguy
- 29th September 2010, 14:08
I have just gone back over the notes for this program before I began writing it and I have noticed that the array is made up of "Bytes" meaning I cannot enter a space or " " since it sees it as a string or char and converts it to the decimal value any ideas?


Always keep this in mind, everything is made up of bytes, strings and things are just converted for our convinence to read. So you are correct, the " " IS repersented by some number, that is the number to check against.

But I would have thought using PBP, you could have a statement like t(2)=" ". that should be no different then t(3)="3".Of course this is different then T(3)=3 with no quotes. Am I wrong? good chance of that, but either way assuming I am not wrong, will work just fine.t(2)=" " means PBP will convert " " to some byte. then your check would be IF T(2) = " ". the key here may be in the quotes.

UKIkarus
- 29th September 2010, 15:20
The issue is that a space is equal to the decimal value of 3 as you stated above, since the decimal numbers 0-9 are being used already it will remove any cells filled with 3 if i were to check that.

When an array is created and all the cells are empty they are literally empty right? filled with nothing? is there a way to empty a cell or delete its contents? I cannot seem to find any information on array manipulation in the manual (im guessing its old)

This includes shifting values in cells too, all i can find is a section about creating the array.

It does have ArrayRead and ArrayWrite but those are for strings.

cncmachineguy
- 29th September 2010, 16:47
How do you send a space to the LCD? In fact, How do you send any character to the LCD? keep in mind, I don't think the number 3 is the same as "3". The number 3 is an interger, and "3" is a string. I assume the string is really converted to its UNICODE equal. So I THINK (i am not sure) these would be 2 different arrays:


t(0)=1
t(1)=3
t(2)=9

t(0)="1"
t(1)="3"
t(2)="9"

the problem you are facing, is there is NO integer space. there are only numbers 0-infinety. BTW there is also no n. the target after 9. So it should be as big a problem as the space if you are using an array of intergers.

If you use an array of strings, each element is only 1 charater big, the space is no problem. It sounds to me like you are trying to mix numbers and strings. That is a big NO-NO!

If you can post some or all of your code, I may understand better. I have no inclination to write it for you (and I don't think you want me to), but I find I am having trouble figuring out how to make sense to you.

maybe just post the array and the LCD update part. Or get the LCD part number from your dad so I can look at the data sheet and understand how to talk to it. Or better yet, attach the datasheet here.

UKIkarus
- 29th September 2010, 21:26
How do you send a space to the LCD? In fact, How do you send any character to the LCD? keep in mind, I don't think the number 3 is the same as "3". The number 3 is an interger, and "3" is a string. I assume the string is really converted to its UNICODE equal. So I THINK (i am not sure) these would be 2 different arrays:


t(0)=1
t(1)=3
t(2)=9

t(0)="1"
t(1)="3"
t(2)="9"

the problem you are facing, is there is NO integer space. there are only numbers 0-infinety. BTW there is also no n. the target after 9. So it should be as big a problem as the space if you are using an array of intergers.

If you use an array of strings, each element is only 1 charater big, the space is no problem. It sounds to me like you are trying to mix numbers and strings. That is a big NO-NO!

If you can post some or all of your code, I may understand better. I have no inclination to write it for you (and I don't think you want me to), but I find I am having trouble figuring out how to make sense to you.

maybe just post the array and the LCD update part. Or get the LCD part number from your dad so I can look at the data sheet and understand how to talk to it. Or better yet, attach the datasheet here.

You are correct, the code used to fill the array (for testing purposes) is the following



FOR I = 0 TO 29
RANDOM RAND
B0 = RAND // 10 ' Gives me numbers 0-9
NOS[I] = B0
NEXT

And the LCD...


CMCON = 7
DEFINE OSC 20 '20MHZ XTAL
DEFINE LCD_DREG PORTB 'PORT B LOW 4 BITS
DEFINE LCD_DBIT 0 'DATA BITS 0-3
DEFINE LCD_RSREG PORTA 'RS REG PORTA
DEFINE LCD_RSBIT 4 'RS BIT 4 PORT A
DEFINE LCD_LINES 4 '4 LIN LCD SET
DEFINE LCD_EREG PORTB 'EREG (ENABLE)
DEFINE LCD_EBIT 4 'PORTB BIT 4
DEFINE LCD_BITS 4 'LCD IN 4 BIT MODE
PAUSE 1000 'INITIALIZE LCD

how can I generate a random number as a string? as that would as you say save me alot of problems... as far as the manual goes PBP has limited support for strings, is there a ToString equivalent for PBP?

To write to the lcd I simply use LCDOUT found on the pbp manual but at the moment since the randomly generated numbers are int's i can only go 0-infinity as you say.

I need a way to generate random numbers as string values since spaces gave a Unicode value of 3 again as you stated.

As for shifting the values within the array I cannot find any functions specifically for this in the manual so I will just have to resort to using a for next loop to shift the values around.

mackrackit
- 29th September 2010, 21:42
how can I generate a random number as a string?
Not what you want but you could use a LOOKUP table after the random number is generated.

cncmachineguy
- 29th September 2010, 22:21
Thanks Dave, Glad someone is watching "me". I am always worried I will misguide him, and no one will be watching.

Anyway, Go back and look at post 7 I think. Now that you and I both understand you will be using strings, (I assumed this the whole time, my bad), it may make more sense to you. The first part shows the quickest way I know of to shift the array. And at the same time check for losing. in my example, only t(0)-t(4) are displayed. t(5) is the you lose check.

The second part shows 1 way to check for a hit, then adjust the array.

I agree with Dave, use a lookup to match a number with a string.

UKIkarus
- 29th September 2010, 23:14
Not what you want but you could use a LOOKUP table after the random number is generated.

Ahhh good point, I didnt think of that! and I have them in another file =)

UKIkarus
- 7th October 2010, 12:53
Hey guys, thanks for the support before...

I was indeed heading down the wrong path with my approaches :o in the end I just put the Ascii equivilents of the numbers 0-9 and "n" into the array instead of trying to tell the LCD to display the Decimal values...

MUCH EASIER :)

Timing is a bit of a pain, since the main loop counts and GoSub's to other areas (this adds about half a second to the count sometimes) but I'm working on that.

Guess my main problem is my habit of keep looking at "visual" syntax as a reference, since everything appears to run simultaniously... where as on this its loops in loops all the time hehe.


EDIT: Now that I have that sorted, once the code is working and bugs ironed out I will rename the variables to something that makes sense to others reading it and upload the source with the hardware layout for those interested.

mackrackit
- 7th October 2010, 13:15
COOL!!!
I am looking forward to seeing/playing it. could use a little fun!

UKIkarus
- 7th October 2010, 14:58
Hi,

I seem to have hit a bit of a problem, when I compile the code everything is fine it shows 0 errors 0 warnings but 2 suppressed (cant seem to get any output on these).

However when I go to program the PIC with the compiled code it just loops forever on programming and will not actually write to the PIC.

I have checked all settings including con bits all is fine, I had an issue like this before when i placed a return in the code without anything to return to but that is no longer the case... I am stuck :confused:

EDIT: Nevermind power ran out on the pack powering the board ;)

UKIkarus
- 7th October 2010, 17:31
Hi Guys,

According to the manual, the "BUTTON" function acts as a "GOTO" to a defined label (the last argument) with the added bonus of disabling auto-repeat and or debounce... does anybody know if the same can be used to GOSUB?

or know of a solution to do the same?

Since I have loops within loops the button presses keep being registered, but I cannot use the BUTTON function to GOTO since it will reset the count on the main loop


MAIN:
FOR CNT2 = 1 TO CNT
IF PORTA.3 = 1 THEN GOSUB SHIP
IF PORTA.0 = 1 THEN GOSUB FIRE
IF CNT2 == CNT THEN GOSUB ADD
GOSUB LCDUPDATE
PAUSE 5
NEXT
GOTO MAIN

As you can see I am using GOSUB as to not interrupt the "for..next" loop doing the count, but I need a way of stopping auto repeat on the button checks... (without pausing since this messes up the count timing) unless there is another way to have a definitive count?

(watchdog timer perhaps? never used it)

Basically so that when the user presses the button it will only increment by 1 and not auto repeat (due to the instructions per second) and increment by about 70 per press :D

Any help will be greatly appreciated!

cncmachineguy
- 7th October 2010, 18:25
To make the button gosub instead of goto to, 1 solution is :


main
button goto no_ship 'if button is NOT pressed, skip the gosub
gosub ship ' if button was pressed gosub and return
no_ship
button goto no_fire
gosub fire
no_fire
....
goto main


As for the multi press and the way you are doing it, you have to check for when the button is released also. So when you have a button press, set a flag, then next time through the loop, if the flag is set, ignore the press. when the button is released, clear the flag.

If cnt2==cnt gosub add

you can move this line outside of the for next loop. It will be true each time the loop counts to cnt. so just process it before jumping back to main.

as for the counting, you could use a timer setup as a counter. Just load it with a number, then in your mainloop check for an overflow. If it did, call your add. This way, as the levels get harder, just change the preload for the timer.

UKIkarus
- 7th October 2010, 18:34
ahhh yes of course... *facepalms*

I will go about adding a flag in there now, seems I had a bit of a well I dunno what to call it actually lol :rolleyes:

That will solve the final few problems and a first draft version will be ready =)

I havnt added the "n" bit yet or proper scoring system (it just counts the ammount you shot) but it does have lives, levels, shooting anywhere, etc etc etc...

just a matter of time :)

UKIkarus
- 22nd November 2010, 14:39
Forgot about this thread,

First version is complete and has basic scoring with increasing difficulty and levels, will be adding proper scoring, motherships (n) and sound when I can get the bits. :)