Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Is my Logic wrong or QB64's ?
#1
I am doing a demo of setting up Conways Game of Life at other forum and run into a problem getting proper neighbor counts of a cell with this code:
Code: (Select All)
nc = 0
            For yy = y - 1 To y + 1
                For xx = x - 1 To x + 1
                    If (xx <> x) And (yy <> y) Then 'dont count cell(x, y) the cell whose neighbors we are counting
                        If Cells(xx, yy) Then nc = nc + 1 ' : Beep ' debug OK
                    End If
                Next
            Next
x and y are just in outer loops scanning the whole array to display on screen.


If I rework that first IF line to this:
Code: (Select All)
nc = 0
            For yy = (y - 1) To (y + 1)
                For xx = (x - 1) To (x + 1)
                    If xx = x And yy = y Then
                        'dont count cell(x, y) the cell whose neighbors we are counting
                    Else
                        If Cells(xx, yy) Then nc = nc + 1: Beep ' debug OK
                    End If
                Next
            Next

All is well! Fine I can get the code to work as expected with 2nd block but I am not understanding what is going wrong with the first code example?

A professional Basic coder (non QB64 fan) said the logic is correct, has QB64 another glitch?
BTW he showed a much better method to do count without IF.

If anyone a connoisseur of methods it was this:
Code: (Select All)
nc = 0
            For yy = y - 1 To y + 1
                For xx = x - 1 To x + 1
                    nc = nc + Cells(xx, yy) ' no ifs
                Next
            Next
            nc = nc - Cells(x, y)
I switched from using -1's to using 1's for live cell (0 for dead)

As I recall my debug checks with the first block of code was messing up neighbor counts of live cells not that it should matter but with either -1 or 1 for live cell signal.

oh wait, I see it now, the logic is wrong because if I break the first IF line into 2 it becomes obvious why the counts were failing:
Code: (Select All)
nc = 0
For yy = y - 1 To y + 1
    For xx = x - 1 To x + 1
        If (xx <> x) Then
            If (yy <> y) Then
                'dont count cell(x, y) the cell whose neighbors we are counting
                If Cells(xx, yy) Then nc = nc + 1 ' : Beep ' debug OK
            End If
        End If
    Next
Next

OK never mind, I got it now Smile
b = b + ...
Reply
#2
Aren't you reversing logic?

If x = 1 AND y = 1....

*magic revertso!!*

If x <> 1 OR y <> 1 Then DON'T...

Don't forget to reverse the middle AND/OR as well.
Reply
#3
Yep! here is a case where Charlie's DoNothing comes into play because it is so much clearer (the 2nd code block) to this tiny human brain if we list the one case to exclude and then do something for all the other ELSE cases.
b = b + ...
Reply
#4
Because BASIC never had a "boolean" type, and because so many programmers relied so much on "0 is false, non-zero is true", I have come across this situation with being able to write a condition, but needing to execute something when that condition is false, and not caring at all about when it's true. Something like this:

Code: (Select All)
if x = 1 and y = 2 then
'do nothing
else
'a lot of code
end if

This is just an example but the condition could be a bit mind boggling. I simply do the "block if" and put "do nothing" comment on a line by itself. I do this programming in Lua as well. Even though in that scripting language, it's possible to assign a variable to "true" or "false" and the "if" statement responds to that. Smile
Reply
#5
If x <> 1 OR y <> 2 THEN
'A lot of code
End If



Why is basic logic hard in BASIC?
Reply
#6
Y'all did see the code that skipped the IF test altogether, just added in everything and then subtracted out the one thing not wanted. Time wise, BIG savings!
b = b + ...
Reply
#7
(10-15-2023, 11:50 AM)bplus Wrote: Y'all did see the code that skipped the IF test altogether, just added in everything and then subtracted out the one thing not wanted. Time wise, BIG savings!

Code: (Select All)
nc = 0
FOR i = -1 TO 1
    FOR j = -1 TO 1
        nc = nc + Cells(x + j, y + i)
    NEXT
NEXT
nc = nc - Cells(x, y)
Reply
#8
Thumbs Up 
(10-15-2023, 12:13 PM)SMcNeill Wrote:
(10-15-2023, 11:50 AM)bplus Wrote: Y'all did see the code that skipped the IF test altogether, just added in everything and then subtracted out the one thing not wanted. Time wise, BIG savings!

Code: (Select All)
nc = 0
FOR i = -1 TO 1
    FOR j = -1 TO 1
        nc = nc + Cells(x + j, y + i)
    NEXT
NEXT
nc = nc - Cells(x, y)

Yeah I like how yours takes the calc's out of the For loop and puts them in the counting line.

Part of what makes Steve amazing is that he is also a connoisseur of coding method.
b = b + ...
Reply
#9
(10-15-2023, 11:50 AM)bplus Wrote: Y'all did see the code that skipped the IF test altogether, just added in everything and then subtracted out the one thing not wanted. Time wise, BIG savings!

I like.    I similar in a  life-like program. (and yes I have a honking load of if thens) 

Code: (Select All)
Sub update_cell (sx, sy)
    'check each cell for neighbors and update life
    _Source s0
    _Dest s1
    ds = -1 'set to -1 because we are going to count the cell itself and ignore it this way
    If sx > 1 Then x0 = sx - 1 Else x0 = 0
    If sy > 1 Then y0 = sy - 1 Else y0 = 0
    If sx < xmax - 1 Then x1 = sx + 1 Else x1 = xmax - 1
    If sy < ymax - 1 Then y1 = sy + 1 Else y1 = ymax - 1
    For y = y0 To y1
        For x = x0 To x1
            If Point(x, y) <> _RGB32(0, 0, 0) Then ds = ds + 1
        Next
    Next
    Select Case ds
        Case 0, 1
            PSet (sx, sy), _RGB32(0, 0, 0)
        Case 2
            PSet (sx, sy), klr
        Case 3
            If Point(sx, sy) = _RGB32(0, 0, 0) Then PSet (sx, sy), klr Else PSet (sx, sy), klr
        Case Is > 3
            PSet (sx, sy), _RGB32(0, 0, 0)
    End Select
End Sub
Reply
#10
(10-15-2023, 04:07 PM)James D Jarvis Wrote:
(10-15-2023, 11:50 AM)bplus Wrote: Y'all did see the code that skipped the IF test altogether, just added in everything and then subtracted out the one thing not wanted. Time wise, BIG savings!

I like.    I similar in a  life-like program. (and yes I have a honking load of if thens) 

Code: (Select All)
Sub update_cell (sx, sy)
    'check each cell for neighbors and update life
    _Source s0
    _Dest s1
    ds = -1 'set to -1 because we are going to count the cell itself and ignore it this way
    If sx > 1 Then x0 = sx - 1 Else x0 = 0
    If sy > 1 Then y0 = sy - 1 Else y0 = 0
    If sx < xmax - 1 Then x1 = sx + 1 Else x1 = xmax - 1
    If sy < ymax - 1 Then y1 = sy + 1 Else y1 = ymax - 1
    For y = y0 To y1
        For x = x0 To x1
            If Point(x, y) <> _RGB32(0, 0, 0) Then ds = ds + 1
        Next
    Next
    Select Case ds
        Case 0, 1
            PSet (sx, sy), _RGB32(0, 0, 0)
        Case 2
            PSet (sx, sy), klr
        Case 3
            If Point(sx, sy) = _RGB32(0, 0, 0) Then PSet (sx, sy), klr Else PSet (sx, sy), klr
        Case Is > 3
            PSet (sx, sy), _RGB32(0, 0, 0)
    End Select
End Sub

Oh man, you can do this without... well case 2 should be checking if cell is alive so it can stay alive.

You can avoid border IF checking by allowing x, y to go only as close as 1 pixels away from border (but what does a screen return for a point outside it's border?)

Funny!
Case 3 : Pset(sx, sy), klr ' no if's, ands, or buts!!!

Hey maybe your Pixel Life isn't exactly by Conway's Life Rules but it sure is pretty!
b = b + ...
Reply




Users browsing this thread: 7 Guest(s)