• Print

Author Topic: CIRCLE command bugs - More info  (Read 182 times)

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2276
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
CIRCLE command bugs - More info
« on: February 02, 2013, 12:33:59 PM »
Ok, previously I reported that the CIRCLE command was not closing negative radians properly.  Upon further investigation I've found that it's actually not calculating ending radians correctly.  The code I have below is a maze generator for an upcoming PacMan game I creating for the game programming class.  You can clearly see where the arcs are not ending in their proper place.  This becomes even more pronounced if you increase the thickness of the walls, or make the maze cells smaller.

Code: [Select]
'**
'** PacMan Ritchie Style! V1.0
'**

CONST FALSE = 0, TRUE = NOT FALSE ' boolean truth testers
CONST MOUTHMOTION = 10 '            number of mouth increments on PacMan
CONST PI = 3.1415926 '              would you like a piece?
CONST HCELL = 10 '                  number of horizontal cells in maze
CONST VCELL = 10 '                  number of vertical cells in maze
CONST CELLSIZE = 41 '               the size of each maze cell
CONST THICKNESS = 3 '               the wall thickness of the maze

TYPE CELL
    Xpos AS INTEGER '               the X screen coordinate of this cell
    Ypos AS INTEGER '               the Y screen coordinate of this cell
    Doors AS INTEGER '              the doors that are open in this cell (1-up, 2-right, 4-down, 8-left)
END TYPE

TYPE LOCATION
    Hor AS INTEGER
    Ver AS INTEGER
END TYPE

TYPE MOUTH
    StartRad AS SINGLE
    EndRad AS SINGLE
END TYPE

TYPE STACK
    Xpos AS INTEGER
    Ypos AS INTEGER
END TYPE

DIM Mouth(4, MOUTHMOTION - 1) AS MOUTH
DIM Cell(HCELL, VCELL) AS CELL
DIM Stack(HCELL * VCELL) AS STACK
DIM MouthIncrement!

RANDOMIZE TIMER

MouthIncrement! = .375 * PI / MOUTHMOTION

Mouth(1, 0).StartRad = -.875 * PI
Mouth(1, 0).EndRad = -.125 * PI
Mouth(2, 0).StartRad = -.375 * PI
Mouth(2, 0).EndRad = -1.625 * PI
Mouth(3, 0).StartRad = -1.875 * PI
Mouth(3, 0).EndRad = -1.125 * PI
Mouth(4, 0).StartRad = -1.375 * PI
Mouth(4, 0).EndRad = -.625 * PI

FOR Direction% = 1 TO 4
    FOR Position% = 1 TO MOUTHMOTION - 1
        Mouth(Direction%, Position%).StartRad = Mouth(Direction%, Position% - 1).StartRad + MouthIncrement!
        Mouth(Direction%, Position%).EndRad = Mouth(Direction%, Position% - 1).EndRad - MouthIncrement!
    NEXT Position%
NEXT Direction%

Direction% = 1
MouthCountDir% = 1

SCREEN _NEWIMAGE(900, 900, 32)
_SCREENMOVE _MIDDLE

MAKEMAZE
DRAWMAZE

END

DO
    _LIMIT 60
    CLS
    DRAWCELL 299, 219, 6

    CIRCLE (319, 239), 20, _RGB32(255, 255, 0), Mouth(Direction%, MouthCount%).StartRad, Mouth(Direction%, MouthCount%).EndRad
    MouthCount% = MouthCount% + MouthCountDir%
    IF MouthCount% = MOUTHMOTION - 1 OR MouthCount% = 0 THEN MouthCountDir% = -MouthCountDir%
    a$ = INKEY$
    IF a$ = " " THEN
        Direction% = Direction% + 1
        IF Direction% = 5 THEN Direction% = 1
    END IF
    _DISPLAY
LOOP UNTIL a$ = CHR$(27)



'----------------------------------------------------------------------------------------------------------------------

SUB DRAWMAZE ()

SHARED Cell() AS CELL

FOR v% = 1 TO VCELL
    FOR h% = 1 TO HCELL
        DRAWCELL Cell(h%, v%).Xpos, Cell(h%, v%).Ypos, Cell(h%, v%).Doors
    NEXT h%
NEXT v%

END SUB

'----------------------------------------------------------------------------------------------------------------------

SUB MAKEMAZE ()

'**
'** Creates a braided looping maze
'**

SHARED Stack() AS STACK '     we need access to the LIFO stack array
SHARED Cell() AS CELL '       we need access to the cell array

DIM CurrentCell AS STACK '    the current cell we are working with
DIM Pointer% '                the stack pointer
DIM ValidCells% '             contains the valid adjacent cells we can move to
DIM RandomDir% '              a random direction to move
DIM Forward% '                TRUE if we are moving forward through the maze
DIM CellX% '                  generic counter used to initiate cells
DIM CellY% '                  generic counter used to initiate cells
DIM VisitedCells% '           number of cells visited by subroutine
DIM Remove% '                 TRUE if it's ok to open a looping door

FOR CellY% = 1 TO HCELL
    FOR CellX% = 1 TO VCELL
        Cell(CellX%, CellY%).Xpos = CellX% * CELLSIZE * 2 '                    upper left X location of this cell
        Cell(CellX%, CellY%).Ypos = CellY% * CELLSIZE * 2 '                    upper left Y location of this cell
        Cell(CellX%, CellY%).Doors = 0 '                                       no doors open
    NEXT CellX%
NEXT CellY%
CurrentCell.Xpos = INT(RND(1) * HCELL) + 1 '                                   random cell to start at
CurrentCell.Ypos = INT(RND(1) * VCELL) + 1
VisitedCells% = 1 '                                                            keep track of how many cells visited
Pointer% = 0 '                                                                 initiate the stack pointer
Forward% = FALSE '                                                             not moving forward through maze yet
WHILE VisitedCells% < HCELL * VCELL '                                          make sure we visit all cells
    ValidCells% = 0 '                                                          initiate number of valid neighbor cells
    IF CurrentCell.Ypos <> 1 THEN '                                            are we at top of maze?
        IF Cell(CurrentCell.Xpos, CurrentCell.Ypos - 1).Doors = 0 THEN '       no, does cell above have all doors closed?
            ValidCells% = ValidCells% + 1 '                                    yes, remember this cell
        END IF
    END IF
    IF CurrentCell.Xpos <> HCELL THEN '                                        are we at right side of maze?
        IF Cell(CurrentCell.Xpos + 1, CurrentCell.Ypos).Doors = 0 THEN '       no, does cell to right have all doors closed?
            ValidCells% = ValidCells% + 2 '                                    yes, remember this cell
        END IF
    END IF
    IF CurrentCell.Ypos <> VCELL THEN '                                        are we at bottom of maze?
        IF Cell(CurrentCell.Xpos, CurrentCell.Ypos + 1).Doors = 0 THEN '       no, does cell below have all doors closed?
            ValidCells% = ValidCells% + 4 '                                    yes, remember this cell
        END IF
    END IF
    IF CurrentCell.Xpos <> 1 THEN '                                            are we at left side of maze?
        IF Cell(CurrentCell.Xpos - 1, CurrentCell.Ypos).Doors = 0 THEN '       no, does cell to left have all doors closed?
            ValidCells% = ValidCells% + 8 '                                    yes, remember this cell
        END IF
    END IF
    IF ValidCells% <> 0 THEN '                                                 did at least one cell have all doors closed?
        DO '                                                                   yes, one or more of the cells have all doors closed
            RandomDir% = INT(RND(1) * 4) '                                     choose a random cell direction
        LOOP UNTIL ValidCells% AND 2 ^ RandomDir% '                            continue if this is a valid move
        Stack(Pointer%) = CurrentCell '                                        push our current location into the LIFO stack
        Pointer% = Pointer% + 1 '                                              increment the stack pointer
        VisitedCells% = VisitedCells% + 1 '                                    increment the number of cells visited so far
        Forward% = TRUE '                                                      we are moving forward in the maze
        OPENDOORS CurrentCell.Xpos, CurrentCell.Ypos, RandomDir% '             open current and adjacent cell doors
        SELECT CASE RandomDir% '                                               which direction did we move forward?
            CASE 0 '                                                           up/north
                CurrentCell.Ypos = CurrentCell.Ypos - 1 '                      make this the new current cell
            CASE 1 '                                                           right/east
                CurrentCell.Xpos = CurrentCell.Xpos + 1 '                      make this the new current cell
            CASE 2 '                                                           down/south
                CurrentCell.Ypos = CurrentCell.Ypos + 1 '                      make this the new current cell
            CASE 3 '                                                           left/west
                CurrentCell.Xpos = CurrentCell.Xpos - 1 '                      make this the new current cell
        END SELECT
    ELSE '                                                                     no, all adjacent cells had at least one door open
        IF Forward% THEN '                                                     were we previously moving forward in the maze?
            Forward% = FALSE '                                                 yes, we are not any longer
            IF INT(RND(1) * 2) = 1 THEN '                                      flip a coin to see if a loop structure built here
                Remove% = FALSE '                                              assume no doors will be opened
                SELECT CASE RandomDir% '                                       which direction were we traveling in?
                    CASE 0 '                                                   up/north
                        IF CurrentCell.Ypos <> 1 THEN Remove% = TRUE '         if not at top of maze upper door can be opened
                    CASE 1 '                                                   right/east
                        IF CurrentCell.Xpos <> HCELL THEN Remove% = TRUE '     if not at right side of maze right door can be opened
                    CASE 2 '                                                   down/south
                        IF CurrentCell.Ypos <> VCELL THEN Remove% = TRUE '     if not at bottom of maze bottom door can be opened
                    CASE 3 '                                                   left/west
                        IF CurrentCell.Xpos <> 1 THEN Remove% = TRUE '         if not at left side of maze left door can be opened
                END SELECT
                IF Remove% THEN '                                              is it ok to open a door?
                    OPENDOORS CurrentCell.Xpos, CurrentCell.Ypos, RandomDir% ' yes, open current and adjacent cell doors
                END IF
            END IF
        END IF
        Pointer% = Pointer% - 1 '                                              decrement the stack pointer
        CurrentCell = Stack(Pointer%) '                                        pop the previous cell position from the LIFO stack
    END IF
WEND

END SUB

'----------------------------------------------------------------------------------------------------------------------

SUB OPENDOORS (x%, y%, d%)

'**
'** Opens a door in the current cell and the corresponding door in the adjacent cell
'**

SHARED Cell() AS CELL '   we need access to the cell array

SELECT CASE d% '                                                               which direction are we going?
    CASE 0 '                                                                   up/north
        Cell(x%, y%).Doors = Cell(x%, y%).Doors + 1 '                          open the current cell's up door
        Cell(x%, y% - 1).Doors = Cell(x%, y% - 1).Doors + 4 '                  open the adjacent cell's south door
    CASE 1 '                                                                   right/east
        Cell(x%, y%).Doors = Cell(x%, y%).Doors + 2 '                          open the current cell's right door
        Cell(x% + 1, y%).Doors = Cell(x% + 1, y%).Doors + 8 '                  open the adjacent cell's left door
    CASE 2 '                                                                   down/south
        Cell(x%, y%).Doors = Cell(x%, y%).Doors + 4 '                          open the current cell's down door
        Cell(x%, y% + 1).Doors = Cell(x%, y% + 1).Doors + 1 '                  open the adjacent cell's up door
    CASE 3 '                                                                   left/west
        Cell(x%, y%).Doors = Cell(x%, y%).Doors + 8 '                          open this cell's left door
        Cell(x% - 1, y%).Doors = Cell(x% - 1, y%).Doors + 2 '                  open the adjacent cell's right door
END SELECT

END SUB

'----------------------------------------------------------------------------------------------------------------------

SUB DRAWCELL (x%, y%, n%)

'**
'** Draws a maze cell
'**

DIM xc% '                    center X coordinate of cell
DIM yc% '                    center Y coordiante of cell
DIM Radius! '                radius of various maze corners

xc% = x% + CELLSIZE \ 2 '    calculate center X coordinate of cell
yc% = y% + CELLSIZE \ 2 '    calculate center Y coordinate of cell

SELECT CASE n% '                                                                                             which cell to draw?
    CASE 1 '                                                                                                 up door open
        FOR Radius! = CELLSIZE / 2 + 1 TO CELLSIZE / 2 + THICKNESS STEP .5
            CIRCLE (xc%, yc%), Radius!, _RGB32(0, 0, 255), 3.1415926, 0
        NEXT Radius!
        LINE (x% - 1, yc%)-(x% - THICKNESS, yc% - CELLSIZE), _RGB32(0, 0, 255), BF
        LINE (x% + CELLSIZE, yc%)-(x% + CELLSIZE% + THICKNESS - 1, yc% - CELLSIZE), _RGB32(0, 0, 255), BF
    CASE 2 '                                                                                                 right door open
        FOR Radius! = CELLSIZE / 2 + 1 TO CELLSIZE / 2 + THICKNESS STEP .5
            CIRCLE (xc%, yc%), Radius!, _RGB32(0, 0, 255), 1.5707963, 4.7123889
        NEXT Radius!
        LINE (xc%, y% - 1)-(xc% + CELLSIZE%, y% - THICKNESS), _RGB32(0, 0, 255), BF
        LINE (xc%, y% + CELLSIZE)-(xc% + CELLSIZE, y% + CELLSIZE + THICKNESS - 1), _RGB32(0, 0, 255), BF
    CASE 3 '                                                                                                 up and right doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% + CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 3.1415926, 4.7123889
        NEXT Radius!
        FOR Radius! = CELLSIZE * 1.5 + THICKNESS TO CELLSIZE * 1.5 + 1 STEP -.5
            CIRCLE (xc% + CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 3.1415926, 4.7123889
        NEXT Radius!
    CASE 4 '                                                                                                 down door open
        FOR Radius! = CELLSIZE / 2 + 1 TO CELLSIZE / 2 + THICKNESS STEP .5
            CIRCLE (xc%, yc%), Radius!, _RGB32(0, 0, 255), 0, 3.1415926
        NEXT Radius!
        LINE (x% - 1, yc%)-(x% - THICKNESS%, yc% + CELLSIZE), _RGB32(0, 0, 255), BF
        LINE (x% + CELLSIZE, yc%)-(x% + CELLSIZE + THICKNESS - 1, yc% + CELLSIZE), _RGB32(0, 0, 255), BF
    CASE 5 '                                                                                                 up and down doors open
        LINE (x% - 1, yc% - CELLSIZE)-(x% - THICKNESS, yc% + CELLSIZE), _RGB32(0, 0, 255), BF
        LINE (x% + CELLSIZE, yc% - CELLSIZE)-(x% + CELLSIZE + THICKNESS - 1, yc% + CELLSIZE), _RGB32(0, 0, 255), BF
    CASE 6 '                                                                                                 down and right doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% + CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 1.5707963, 3.1415926
        NEXT Radius!
        FOR Radius! = CELLSIZE * 1.5 + THICKNESS TO CELLSIZE * 1.5 + 1 STEP -.5
            CIRCLE (xc% + CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 1.5707963, 3.1415926
        NEXT Radius!
    CASE 7 '                                                                                                 up and down and right doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% + CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 3.1415926, 4.7123889
            CIRCLE (xc% + CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 1.5707963, 3.1415926
        NEXT Radius!
        LINE (x% - 1, yc% - CELLSIZE)-(x% - THICKNESS, yc% + CELLSIZE), _RGB32(0, 0, 255), BF
    CASE 8 '                                                                                                 left door open
        FOR Radius! = CELLSIZE / 2 + 1 TO CELLSIZE / 2 + THICKNESS STEP .5
            CIRCLE (xc%, yc%), Radius!, _RGB32(0, 0, 255), 4.7123889, 1.5707963
        NEXT Radius!
        LINE (xc% - CELLSIZE, y% - 1)-(xc%, y% - THICKNESS), _RGB32(0, 0, 255), BF
        LINE (xc% - CELLSIZE, y% + CELLSIZE)-(xc%, y% + CELLSIZE + THICKNESS - 1), _RGB32(0, 0, 255), BF
    CASE 9 '                                                                                                 up and left doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% - CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 4.7123889, 0
        NEXT Radius!
        FOR Radius! = CELLSIZE * 1.5 + THICKNESS TO CELLSIZE * 1.5 + 1 STEP -.5
            CIRCLE (xc% - CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 4.7123889, 0
        NEXT Radius!
    CASE 10 '                                                                                                left and right doors open
        LINE (xc% - CELLSIZE, y% - 1)-(xc% + CELLSIZE, y% - THICKNESS), _RGB32(0, 0, 255), BF
        LINE (xc% - CELLSIZE, y% + CELLSIZE)-(xc% + CELLSIZE, y% + CELLSIZE + THICKNESS - 1), _RGB32(0, 0, 255), BF
    CASE 11 '                                                                                                up and left and right doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% - CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 4.7123889, 0
            CIRCLE (xc% + CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 3.1415926, 4.7123889
        NEXT Radius!
        LINE (xc% - CELLSIZE, y% + CELLSIZE)-(xc% + CELLSIZE, y% + CELLSIZE + THICKNESS - 1), _RGB32(0, 0, 255), BF
    CASE 12 '                                                                                                down and left doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% - CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 0, 1.5707963
        NEXT Radius!
        FOR Radius! = CELLSIZE * 1.5 + THICKNESS TO CELLSIZE * 1.5 + 1 STEP -.5
            CIRCLE (xc% - CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 0, 1.5707963
        NEXT Radius!
    CASE 13 '                                                                                                up and down and left doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% - CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 0, 1.5707963
            CIRCLE (xc% - CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 4.7123889, 0
        NEXT Radius!
        LINE (x% + CELLSIZE, yc% - CELLSIZE)-(x% + CELLSIZE + THICKNESS - 1, yc% + CELLSIZE), _RGB32(0, 0, 255), BF
    CASE 14 '                                                                                                down and left and right doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% - CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 0, 1.5707963
            CIRCLE (xc% + CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 1.5707963, 3.1415926
        NEXT Radius!
        LINE (xc% - CELLSIZE, y% - 1)-(xc% + CELLSIZE, y% - THICKNESS), _RGB32(0, 0, 255), BF
    CASE 15 '                                                                                                all doors open
        FOR Radius! = CELLSIZE / 2 - THICKNESS TO CELLSIZE / 2 STEP .5
            CIRCLE (xc% - CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 4.7123889, 0
            CIRCLE (xc% - CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 0, 1.5707963
            CIRCLE (xc% + CELLSIZE, yc% - CELLSIZE), Radius!, _RGB32(0, 0, 255), 3.1415926, 4.7123889
            CIRCLE (xc% + CELLSIZE, yc% + CELLSIZE), Radius!, _RGB32(0, 0, 255), 1.5707963, 3.1415926
        NEXT Radius!
    CASE ELSE
END SELECT

END SUB

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: CIRCLE command bugs - More info
« Reply #1 on: February 02, 2013, 12:38:51 PM »
Yeah it is missing the horizontal starts and ends. Same thing with your other program. Vertical seems OK.
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2276
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: CIRCLE command bugs - More info
« Reply #2 on: February 02, 2013, 12:41:52 PM »
I'm going to investigate the CIRCLE routine Mcalkins created for Unseen's GDK as a replacement for now. Can anyone verify this behavior in the GL version of QB64?

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: CIRCLE command bugs - More info
« Reply #3 on: February 02, 2013, 02:38:05 PM »
Yes it is happening in GL too.
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2276
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: CIRCLE command bugs - More info
« Reply #4 on: February 02, 2013, 04:23:50 PM »
I could have swore that Mcalkins said there was a circle routine in Unseen's GDK?  Looking through the code I can't seem to locate one.

Never mind, it was Codeguy and he was referring to Unseen's visual library.
« Last Edit: February 02, 2013, 04:37:06 PM by TerryRitchie »

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2276
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: CIRCLE command bugs - More info
« Reply #5 on: February 02, 2013, 06:18:17 PM »
I now have a CIRCLE command replacement to use for now:

http://www.qb64.net/forum/index.php?topic=10593.0

  • Print