Author Topic: Evolving RI (Robot Intelligence) for a room vacuum  (Read 9276 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Evolving RI (Robot Intelligence) for a room vacuum
« on: February 28, 2022, 08:46:23 pm »
I am developing an Agent in AI lingo that is able to act on it's own without human intervention in real time

Here is first crude effort. You press spacebar for each step, or just lean on it to run through process. There is no stop signal, it just keeps on sweeping the random room.

What surprises the heck out of me is that it always, eventually, covers the whole room! So far I've not seen it fail. True  there is a lot of redundant over sweeps of cells but eventually it covers the room.

The sweeper only moves up/down or left/right each step and can only sense if there is an obstacle in these directions.

Code: QB64: [Select]
  1. _Title "I Robot - Room Mapper 1 (IR-RM1)" ' b+ 2022-02-11
  2. ' 2022-02-23 started writing code
  3. ' The little guy, say a vaccum cleaner, is plopped down somewhere in it's new home.
  4. ' The first order of business is to map out it's area of duty,
  5. ' say sweep the whole floor without getting stuck or wasting allot of moves.
  6. ' It is square and can sense, resistence on any of its edges.
  7. ' It is allowed to go N,S,E,W - the four directions
  8. ' If something is sensed on one side it is forbidden to
  9. ' enter that square from that direction.
  10. ' Rule of economy - don't reenter a square already occupied
  11. ' unless that is the only way to go.
  12. ' Do we have enough spelled out to map a room?
  13.  
  14. ' A room is a grid of squares, we don't know the dimensions
  15. ' and there are objects in many of the middle squares or along
  16. ' the walls. Later we may encounter objects that move around
  17. ' like pets or results of fickle home decorators.
  18.  
  19. ' God provides a room with objetcs and randomly drops the robot
  20. ' into it.
  21.  
  22. ' 2022-02-23 first goal is to get an edges mapped. so make up a room
  23. ' Upon some more thinking and just to get the ball rolling, I will
  24. ' allow robot vaccum sweeper to use the room map and mark it with it's
  25. ' own numbers, so now the walls are -1, empty areas 0, places visited
  26. ' are positive numbers, everytime the vacuum reoccupies the square
  27. ' the number is increased.
  28. ' OK the room setup seems satisfactory onto RI = Robot Intelligence
  29.  
  30. ' OK first run it does eventually cover the whole room.
  31. ' Need to know when it has done the whole room. There are some
  32. ' places that have to be left 0
  33.  
  34. Const SW = 601, SH = 601
  35. Screen _NewImage(SW, SH, 32)
  36. _ScreenMove 200, 70
  37.  
  38. ReDim Shared As Integer dx(3), dy(3)
  39. dx(0) = 0: dy(0) = -1
  40. dx(1) = 1: dy(1) = 0
  41. dx(2) = 0: dy(2) = 1
  42. dx(3) = -1: dy(3) = 0
  43.  
  44. ReDim Shared As Long Room(1 To 20, 1 To 20) ' 0 = empty -1 = wall see MakeRoom
  45. Dim Shared As Long rx, ry ' robot location
  46. rx = 10: ry = 10 ' starts here in middle of room should be clear
  47. MakeRoom
  48.     drawRoom 'ok the middle of room is staying clear of stuff
  49.     _Display
  50.     RI ' ok roby make your move
  51.     Sleep
  52.     Cls
  53.  
  54. Sub RI ' the robot appraises it's current postition rx, ry in Room(20x20) and makes a move changing rx, ry and that ends the sub
  55.  
  56.     ' I was here!
  57.     Room(rx, ry) = Room(rx, ry) + 1 ' sweeps the spot
  58.     Dim d(3)
  59.     d(0) = Room(rx, ry - 1)
  60.     d(1) = Room(rx + 1, ry)
  61.     d(2) = Room(rx, ry + 1)
  62.     d(3) = Room(rx - 1, ry)
  63.  
  64.     If d(0) = 0 Then ' one must have ones priorities
  65.         ry = ry - 1: Exit Sub
  66.     ElseIf d(1) = 0 Then
  67.         rx = rx + 1: Exit Sub
  68.     ElseIf d(2) = 0 Then
  69.         ry = ry + 1: Exit Sub
  70.     ElseIf d(3) = 0 Then
  71.         rx = rx - 1: Exit Sub
  72.     End If
  73.  
  74.     ' still here ?  where is min number of visits?
  75.     Dim As Long min, saveI
  76.     min = 10000000
  77.     For i = 0 To 3
  78.         If d(i) <> -1 Then
  79.             If d(i) < min Then min = d(i): saveI = i
  80.         End If
  81.     Next
  82.     rx = rx + dx(saveI)
  83.     ry = ry + dy(saveI)
  84.  
  85. Sub drawRoom
  86.     drawGridSq 0, 0, 30, 30
  87.     For x = 1 To 20
  88.         For y = 1 To 20
  89.             If Room(x, y) = -1 Then
  90.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), , BF
  91.             ElseIf Room(x, y) > 0 Then
  92.                 s$ = _Trim$(Str$(Room(x, y)))
  93.                 _PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  94.             End If
  95.         Next
  96.     Next
  97.     ' and robot
  98.     Line ((rx - 1) * 30, (ry - 1) * 30)-Step(30, 30), &HFFFFFF00, BF
  99.  
  100. Sub MakeRoom
  101.     ReDim As Long Room(1 To 20, 1 To 20) ' 0 = empty -1 = wall
  102.     ' Here are the walls
  103.     For x = 1 To 20
  104.         For y = 1 To 2
  105.             If y = 2 Then z = 20 Else z = 1
  106.             Room(x, z) = -1
  107.             Room(z, x) = -1
  108.         Next
  109.     Next
  110.  
  111.     ' add random rectangles around the edges
  112.     For i = 1 To 20
  113.         rw = Int(Rnd * 4) + 1: rh = Int(Rnd * 4) + 1
  114.         wall = Int(Rnd * 4)
  115.         Select Case wall
  116.             Case 0 ' top
  117.                 If Rnd < .5 Then ys = 1 Else ys = 4
  118.                 xs = Int(Rnd * (20 - rw)) + 1
  119.                 For y = ys To ys + rh - 1
  120.                     For x = xs To xs + rw - 1
  121.                         Room(x, y) = -1
  122.                     Next
  123.                 Next
  124.             Case 1 'right
  125.                 If Rnd < .5 Then xs = 20 - rw + 1 Else xs = 16 - rw + 1
  126.                 ys = Int(Rnd * (20 - rh)) + 1
  127.                 For y = ys To ys + rh - 1
  128.                     For x = xs To xs + rw - 1
  129.                         Room(x, y) = -1
  130.                     Next
  131.                 Next
  132.             Case 2 ' bottom
  133.                 If Rnd < .5 Then ys = 20 - rh + 1 Else ys = 16 - rh + 1
  134.                 xs = Int(Rnd * (20 - rw)) + 1
  135.                 For y = ys To ys + rh - 1
  136.                     For x = xs To xs + rw - 1
  137.                         Room(x, y) = -1
  138.                     Next
  139.                 Next
  140.             Case 3 'left
  141.                 If Rnd < .5 Then xs = 1 Else xs = 4
  142.                 ys = Int(Rnd * (20 - rh)) + 1
  143.                 For y = ys To ys + rh - 1
  144.                     For x = xs To xs + rw - 1
  145.                         Room(x, y) = -1
  146.                     Next
  147.                 Next
  148.         End Select
  149.     Next
  150.  
  151.  
  152. Sub drawGridSq (x, y, sq, n)
  153.     Dim d As Long, i As Long
  154.     d = sq * n
  155.     For i = 0 To n
  156.         Line (x + sq * i, y)-(x + sq * i, y + d)
  157.         Line (x, y + sq * i)-(x + d, y + sq * i)
  158.     Next
  159.  
  160.  

BTW don't expect the vacuum to access sections that are completely walled off by room obstacles. A bit of a problem picking up on those isolated areas so the code knows when everything that could be swept has been as seen in next code reply.
« Last Edit: February 28, 2022, 08:59:05 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #1 on: February 28, 2022, 08:55:02 pm »
Here's how it looks after I've added a path finding tool and allowed it to magically find the next empty square when it is surrounded with obstacles or cells it's already vacuumed.

It runs quite well on it's own, random room after random room, complete coverage occurs much quicker with smaller amount of redundant sweeping cells.

Code: QB64: [Select]
  1. _Title "I Robot - Room Mapper 2 (IR-RM2)" ' b+ 22-02-11
  2. ' 22-02-23 started writing code
  3. ' The little guy, say a vaccum cleaner, is plopped down somewhere in it's new home.
  4. ' The first order of business is to map out it's area of duty,
  5. ' say sweep the whole floor without getting stuck or wasting allot of moves.
  6. ' It is square and can sense, resistence on any of its edges.
  7. ' It is allowed to go N,S,E,W - the four directions
  8. ' If something is sensed on one side it is forbidden to
  9. ' enter that square from that direction.
  10. ' Rule of economy - don't reenter a square already occupied
  11. ' unless that is the only way to go.
  12. ' Do we have enough spelled out to map a room?
  13.  
  14. ' A room is a grid of squares, we don't know the dimensions
  15. ' and there are objects in many of the middle squares or along
  16. ' the walls. Later we may encounter objects that move around
  17. ' like pets or results of fickle home decorators.
  18.  
  19. ' God provides a room with objetcs and randomly drops the robot
  20. ' into it.
  21.  
  22. ' 22-02-23 first goal is to get an edges mapped. so make up a room
  23. ' Upon some more thinking and just to get the ball rolling, I will
  24. ' allow robot vaccum sweeper to use the room map and mark it with it's
  25. ' own numbers, so now the walls are -1, empty areas 0, places visited
  26. ' are positive numbers, everytime the vacuum reoccupies the square
  27. ' the number is increased.
  28. ' OK the room setup seems satisfactory onto RI = Robot Intelligence
  29.  
  30. ' OK first run it does eventually cover the whole room.
  31. ' Need to know when it has done the whole room. There are some
  32. ' places that have to be left 0
  33.  
  34. ' IR-RM2 next mod
  35. ' 2022-02-24 what I need is path finder, then I can see which squares are
  36. ' accessible to robot from middle of the room, so I can mark and then
  37. ' I will be able to tell when Robot has visited all spaces it can.
  38. ' ALSO I can use pathfinder to get at next closest enpty square.
  39. ' OK the subs from PathFinder 3a are loaded and working with Option _Explicit.
  40.  
  41. ' Next job is to mark all places vacuum can access checks, so we can then
  42. ' have a check to see if all areas covered by vac.
  43.  
  44. ' 2022-02-26 Got the bug causing once in a blue moon problem with room fills
  45. ' ie leaving empty spaces not accessible to vacuum. Could the other once in a blue
  46. ' moon problem be similar. RI is trying to path to target at 0,0.
  47. ' Ho, ho yes! very likely the same problem!!!
  48.  
  49. Const SW = 1021, SH = 721 ' cell @30 max 34x24
  50. Const Cell = 30
  51. Const MapW = 27, MapH = 17 ' min @30 cell is 17, 17
  52. Screen _NewImage(SW, SH, 12)
  53. _ScreenMove 150, 20
  54.  
  55. Dim Shared As Long BeeLine, Done ' Roby is in beeLine Mode heading to closet empty (unvac'd) cell using steps from Path Finder app
  56. ReDim Shared As Long StepMap(1 To MapW, 1 To MapH) ' for making paths that you step through
  57. Dim Shared As Long StepI, StepDist
  58. ReDim Shared As Long StepX(1 To MapW * MapH), StepY(1 To MapW * MapH)
  59.  
  60. ReDim Shared As Long Room(1 To MapW, 1 To MapH) ' 0 = empty -1 = wall see MakeRoom
  61. Dim Shared As Long rx, ry ' robot location
  62. Dim As Long sweeps
  63.     Done = 0: rx = Int(MapW / 2 + .5): ry = Int(MapH / 2 + .5) ' starts here in middle of room should be clear
  64.     MakeRoom
  65.     Do
  66.         drawRoom 'ok the middle of room is staying clear of stuff
  67.  
  68.         ' debug check path works
  69.         'path rx, ry, 5, 5 'does this still work  OH YEAH! Better than ever!
  70.         '_Display
  71.  
  72.         RI ' ok roby make your move
  73.         _Display
  74.         _Limit 10
  75.         If Done Then Cls: drawRoom: Exit Do
  76.  
  77.         ' debug just checking rooms made right
  78.         'Sleep
  79.         'Cls
  80.         'Exit Do
  81.     Loop
  82.     'Print "Finished press any for next run   zzz..."
  83.     'Sleep
  84.     sweeps = sweeps + 1
  85.     _Title "I Robot - Room Mapper 2 (IR-RM2) " + Str$(sweeps) + " successful rooms swept."
  86.     _Display
  87.     _Delay 1
  88.  
  89. Sub RI ' the robot appraises it's current postition rx, ry in Room(x) and makes a move changing rx, ry and that ends the sub
  90.     Dim As Long mini, x, y, saveX, saveY
  91.     ' I was here!  sweeps the spot (again?)
  92.     'If rx > 0 And rx <= MapW And ry > 0 And ry <= MapH Then
  93.     Room(rx, ry) = Room(rx, ry) + 1 ' put roby's presense on map
  94.     'End If
  95.  
  96.     ' after marking current spot see if we have swept all possible
  97.     If swept% Then Done = -1: Exit Sub
  98.  
  99.     If BeeLine = 0 Then ' normal sweeping pattern, hey try up/down then right/left see if leaves less spots
  100.         If Room(rx, ry - 1) = 0 Then ' one must have ones priorities
  101.             ry = ry - 1: Exit Sub
  102.         ElseIf Room(rx + 1, ry) = 0 Then
  103.             rx = rx + 1: Exit Sub
  104.         ElseIf Room(rx, ry + 1) = 0 Then
  105.             ry = ry + 1: Exit Sub
  106.         ElseIf Room(rx - 1, ry) = 0 Then
  107.             rx = rx - 1: Exit Sub
  108.         End If
  109.  
  110.         ' still here ?  ========== Decide to make a BeeLine - find the closet empty and make a bee-line to it
  111.         BeeLine = -1 'put us into BeeLine Mode
  112.         prepStepMap rx, ry
  113.         mini = 10000000
  114.         For y = 1 To MapH ' now run through step map and find the mini closest empty room
  115.             For x = 1 To MapW
  116.                 If StepMap(x, y) > 1 Then ' has to be > 1 because 0 is robot and 1 the robot will detect!
  117.                     If StepMap(x, y) < mini And Room(x, y) = 0 Then mini = StepMap(x, y): saveX = x: saveY = y
  118.                 End If
  119.             Next
  120.         Next
  121.  
  122.         'OK we have our target not find a clear short path to it from roby
  123.         path rx, ry, saveX, saveY ' path sets stepI, stepX(i), stepY(I) that are shared
  124.         StepI = 1 ' roby is on it's way to closet empty cell
  125.  
  126.         'debug
  127.         'Print StepI, StepX(StepI), StepY(StepI)
  128.         '_display
  129.         'Beep
  130.         'Sleep ' let me see that path we made
  131.  
  132.         rx = StepX(StepI): ry = StepY(StepI)
  133.     Else
  134.         ' beeline mode
  135.         StepI = StepI + 1 ' roby is on it's way to closet empty cell
  136.         rx = StepX(StepI): ry = StepY(StepI)
  137.  
  138.         'turn of beeLine mode when we have hit target
  139.         If StepI = StepDist - 1 Then BeeLine = 0 ' we have arrived at our target turn off beeLine mode
  140.     End If
  141.  
  142. Sub drawRoom
  143.     Dim As Long x, y
  144.     Dim s$
  145.     Cls
  146.     drawGridSq
  147.     For y = 1 To MapH
  148.         For x = 1 To MapW
  149.             If Room(x, y) = -1 Then
  150.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), 8, BF
  151.             ElseIf Room(x, y) = -2 Then
  152.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), 0, BF
  153.             ElseIf Room(x, y) < -2 Then
  154.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), Abs(Room(x, y)) - 15, BF
  155.             ElseIf Room(x, y) > 0 Then
  156.                 s$ = _Trim$(Str$(Room(x, y)))
  157.                 _PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  158.             End If
  159.         Next
  160.     Next
  161.     ' and robot
  162.     Line ((rx - 1) * 30, (ry - 1) * 30)-Step(30, 30), 14, BF
  163.  
  164. Sub MakeRoom
  165.     ReDim As Long Room(1 To MapW, 1 To MapH) ' 0 = empty, -1 = wall, -2 = area vac can't access because walled out
  166.     Dim As Long x, y, i, rw, rh, wall, ys, xs, clr
  167.     ' Here are the walls
  168.     For x = 1 To MapW
  169.         Room(x, 1) = -1
  170.         Room(x, MapH) = -1
  171.     Next
  172.     For y = 1 To MapH
  173.         Room(1, y) = -1
  174.         Room(MapW, y) = -1
  175.     Next
  176.  
  177.     ' add random rectangles around the edges
  178.     For i = 1 To Int(Sqr(1.5 * MapW * MapH))
  179.         rw = Int(Rnd * 4) + 1: rh = Int(Rnd * 4) + 1: clr = -1 * ((Int(Rnd * 13) + 1) + 15)
  180.         wall = Int(Rnd * 4)
  181.         Select Case wall
  182.             Case 0 ' top
  183.                 If Rnd < .5 Then ys = 2 Else ys = 4
  184.                 xs = irnd&(2, MapW - 1 - rw)
  185.                 For y = ys To ys + rh - 1
  186.                     For x = xs To xs + rw - 1
  187.                         Room(x, y) = clr
  188.                     Next
  189.                 Next
  190.             Case 1 'right
  191.                 If Rnd < .5 Then xs = MapW - 1 - rw Else xs = (MapW - 3) - rw
  192.                 ys = irnd(2, MapH - 1 - rh)
  193.                 For y = ys To ys + rh - 1
  194.                     For x = xs To xs + rw - 1
  195.                         Room(x, y) = clr
  196.                     Next
  197.                 Next
  198.             Case 2 ' bottom
  199.                 If Rnd < .5 Then ys = MapH - rh - 1 Else ys = (MapH - 2) - rh - 1
  200.                 xs = irnd(2, MapW - 1 - rw)
  201.                 For y = ys To ys + rh - 1
  202.                     For x = xs To xs + rw - 1
  203.                         Room(x, y) = clr
  204.                     Next
  205.                 Next
  206.             Case 3 'left
  207.                 If Rnd < .5 Then xs = 2 Else xs = 5
  208.                 ys = irnd(2, MapH - rh - 1)
  209.                 For y = ys To ys + rh - 1
  210.                     For x = xs To xs + rw - 1
  211.                         Room(x, y) = clr
  212.                     Next
  213.                 Next
  214.         End Select
  215.     Next
  216.  
  217.     ' before make map make sure rx, ry is set or reset
  218.     prepStepMap rx, ry ' see what cells not accessible to vac mark them -1
  219.     For y = 1 To MapH
  220.         For x = 1 To MapW
  221.             If Room(x, y) = 0 Then
  222.                 If StepMap(x, y) = 0 Then Room(x, y) = -2
  223.             End If
  224.         Next
  225.     Next
  226.     Room(rx, ry) = 0 ' not a -2 room!
  227.  
  228. Sub drawGridSq
  229.     Dim As Long x, y
  230.     For x = 0 To Cell * MapW Step Cell
  231.         Line (x, 0)-Step(0, Cell * MapH)
  232.     Next
  233.     For y = 0 To Cell * MapH Step Cell
  234.         Line (0, y)-Step(Cell * MapW, 0)
  235.     Next
  236.  
  237. Function swept%
  238.     Dim As Long x, y
  239.     For y = 1 To MapH
  240.         For x = 1 To MapW
  241.             If Room(x, y) = 0 Then Exit Function 'not swept
  242.         Next
  243.     Next
  244.     swept% = -1 ' all clean!
  245.  
  246. Sub path (sx As Long, sy As Long, tx As Long, ty As Long) ' start x, y to target x, y
  247.     Dim As Long dist, cx, cy, cf, y, x
  248.     prepStepMap tx, ty
  249.     dist = StepMap(sx, sy) 'STEPMAP is DIM SHARED as INTEGER
  250.     StepDist = dist
  251.     If dist = 0 Or Room(tx, ty) = -1 Then
  252.         StepI = 0
  253.         ' Beep
  254.         Color 0, 15
  255.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  256.         _Display
  257.         Sleep
  258.         End
  259.     End If
  260.     'refresh
  261.     ReDim As Long StepX(1 To MapW * MapH), StepY(1 To MapW * MapH)
  262.     StepI = 0 'DIM SHARED error signal
  263.     cx = sx: cy = sy
  264.     While dist >= 2
  265.         'LOCATE 2, 1: PRINT "cx, cy: "; cx, cy '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< debug
  266.         cf = 0
  267.         For y = cy - 1 To cy + 1
  268.             For x = cx - 1 To cx + 1
  269.                 'PRINT "x, y, STEPMAP(x, y) "; x, y, STEPMAP(x, y)
  270.                 If StepMap(x, y) = dist - 1 Then
  271.                     StepI = StepI + 1
  272.                     StepX(StepI) = x: StepY(StepI) = y
  273.                     Line ((StepX(StepI) - 1) * 30 + 4, (StepY(StepI) - 1) * 30 + 4)-Step(30 - 8, 30 - 8), 6, BF
  274.                     cf = 1: Exit For
  275.                 End If
  276.             Next
  277.             If cf = 1 Then Exit For
  278.         Next
  279.         If cf = 0 Then 'lost path
  280.             Exit Sub
  281.         Else
  282.             cx = StepX(StepI): cy = StepY(StepI)
  283.             dist = dist - 1
  284.         End If
  285.     Wend
  286.     _Display
  287.     _Delay .25
  288.  
  289. Sub prepStepMap (tx As Long, ty As Long) ' ========================================== no more diagonal steps
  290.     Dim As Long x, y, tick, changes, ystart, ystop, xstart, xstop
  291.     Dim s$ 'debug
  292.  
  293.     ReDim As Long StepMap(1 To MapW, 1 To MapH)
  294.     If tx > 0 And tx <= MapW And ty > 0 And ty <= MapH Then
  295.         StepMap(tx, ty) = 1: tick = 1: changes = 1
  296.         While changes
  297.             tick = tick + 1: changes = 0
  298.             ystart = max(ty - tick, 1): ystop = min(ty + tick, MapH)
  299.             For y = ystart To ystop
  300.                 xstart = max(tx - tick, 1): xstop = min(tx + tick, MapW)
  301.                 For x = xstart To xstop
  302.                     'check out the neighbors
  303.                     If Room(x, y) >= 0 Then ' places OK to go
  304.                         'cf = 0
  305.                         ' ============================================================= new >>> path finder  that won't take diagonal steps
  306.                         'need to check 4 cells around x, y for parent
  307.                         If StepMap(x - 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  308.                             StepMap(x, y) = tick
  309.                             ' 2 line debug  =====================================================
  310.                             's$ = _Trim$(Str$(StepMap(x, y)))
  311.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  312.                             changes = 1: GoTo skip
  313.                         End If
  314.                         If StepMap(x + 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  315.                             StepMap(x, y) = tick
  316.                             ' debug
  317.                             's$ = _Trim$(Str$(StepMap(x, y)))
  318.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  319.                             changes = 1: GoTo skip
  320.                         End If
  321.                         If StepMap(x, y - 1) = tick - 1 And StepMap(x, y) = 0 Then
  322.                             StepMap(x, y) = tick
  323.                             ' debug
  324.                             's$ = _Trim$(Str$(StepMap(x, y)))
  325.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  326.                             changes = 1: GoTo skip
  327.                         End If
  328.                         If StepMap(x, y + 1) = tick - 1 And StepMap(x, y) = 0 Then
  329.                             StepMap(x, y) = tick
  330.                             ' debug
  331.                             's$ = _Trim$(Str$(StepMap(x, y)))
  332.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  333.                             changes = 1
  334.                         End If
  335.                         skip:
  336.                     End If
  337.                 Next
  338.             Next
  339.         Wend
  340.     Else
  341.         'Beep
  342.         Color 0, 13
  343.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  344.         _Display
  345.         Sleep
  346.         End
  347.     End If
  348.  
  349. Function min (n1, n2)
  350.     If n1 > n2 Then min = n2 Else min = n1
  351.  
  352. Function max (n1, n2)
  353.     If n1 < n2 Then max = n2 Else max = n1
  354.  
  355. Function irnd& (n1, n2) 'return an integer between 2 numbers
  356.     Dim l%, h%
  357.     If n1 > n2 Then l% = n2: h% = n1 Else l% = n1: h% = n2
  358.     irnd& = Int(Rnd * (h% - l% + 1)) + l%
  359.  
  360.  

Next step I think I need to give the RI a stack to save locations of empty cells as it passes them by, so no magic is called upon to know where they are. Hopefully it will get to missed sections a little faster, instead of jumping across room from one incomplete section to next after most the room is finished.
« Last Edit: February 28, 2022, 09:01:05 pm by bplus »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #2 on: February 28, 2022, 09:11:00 pm »
this impresses me
You're not done when it works, you're done when it's right.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #3 on: February 28, 2022, 09:35:14 pm »
bump n' go cars 2.0
Shuwatch!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #4 on: March 01, 2022, 02:19:47 am »
Well neither a FIFO nor FILO Stack worked, at least not the way I coded it. Gave up and just created another array for the RI to "remember" all the places that had empty cells as it rolled by, array called mt. When RI rolls over one of these remembers to mark it as no longer mt. Turns out that was easier to code and with less lines.

So it's true no magic is needed to find the nearest mt cell, the RI always seems to have one in memory to goto. What makes me groan is as it's going to the closest one it sometimes misses royally the opportunity to take a bunch of mt's along the way. Gotta fix that! This is because the mt as the crow flies is closest but getting there can be quite round about because of obstacles... hmm maybe I should check path lengths for shortest one to an empty cell. Yeah that's tomorrow.

Anyway here's proof no magic is needed to find an empty cell because RI has rolled by and memorized plenty enough.
The cells marked with a star are cells the RI has recorded in it's memory as empty.

Code: QB64: [Select]
  1. _Title "I Robot - Room Mapper 4 (IR-RM4)" ' b+ 22-02-11
  2. ' 22-02-23 started writing code
  3. ' The little guy, say a vaccum cleaner, is plopped down somewhere in it's new home.
  4. ' The first order of business is to map out it's area of duty,
  5. ' say sweep the whole floor without getting stuck or wasting allot of moves.
  6. ' It is square and can sense, resistence on any of its edges.
  7. ' It is allowed to go N,S,E,W - the four directions
  8. ' If something is sensed on one side it is forbidden to
  9. ' enter that square from that direction.
  10. ' Rule of economy - don't reenter a square already occupied
  11. ' unless that is the only way to go.
  12. ' Do we have enough spelled out to map a room?
  13.  
  14. ' A room is a grid of squares, we don't know the dimensions
  15. ' and there are objects in many of the middle squares or along
  16. ' the walls. Later we may encounter objects that move around
  17. ' like pets or results of fickle home decorators.
  18.  
  19. ' God provides a room with objetcs and randomly drops the robot
  20. ' into it.
  21.  
  22. ' 22-02-23 first goal is to get an edges mapped. so make up a room
  23. ' Upon some more thinking and just to get the ball rolling, I will
  24. ' allow robot vaccum sweeper to use the room map and mark it with it's
  25. ' own numbers, so now the walls are -1, empty areas 0, places visited
  26. ' are positive numbers, everytime the vacuum reoccupies the square
  27. ' the number is increased.
  28. ' OK the room setup seems satisfactory onto RI = Robot Intelligence
  29.  
  30. ' OK first run it does eventually cover the whole room.
  31. ' Need to know when it has done the whole room. There are some
  32. ' places that have to be left 0
  33.  
  34. ' IR-RM2 next mod
  35. ' 2022-02-24 what I need is path finder, then I can see which squares are
  36. ' accessible to robot from middle of the room, so I can mark and then
  37. ' I will be able to tell when Robot has visited all spaces it can.
  38. ' ALSO I can use pathfinder to get at next closest enpty square.
  39. ' OK the subs from PathFinder 3a are loaded and working with Option _Explicit.
  40.  
  41. ' Next job is to mark all places vacuum can access checks, so we can then
  42. ' have a check to see if all areas covered by vac.
  43.  
  44. ' 2022-02-26 Got the bug causing once in a blue moon problem with room fills
  45. ' ie leaving empty spaces not accessible to vacuum. Could the other once in a blue
  46. ' moon problem be similar. RI is trying to path to target at 0,0.
  47. ' Ho, ho yes! very likely the same problem!!!
  48. ' 2022-02-27 fix some things color the furniture, debug the way the furniture
  49. ' was supposed to be placed around the room ie not into the walls!
  50.  
  51. ' IR-RM3 next mod,
  52. ' 2022-02-28  give RI a stack to save locations of empty cells it passes by.
  53. ' I think that might improve performance because it will get unswept sections
  54. ' while it's still nearby? That is the hypothesis, now for the experiment.
  55. ' Stack is NOT WORKING this code is dead end!
  56.  
  57. ' IR_RM4 next mod
  58. ' Every space the RI occupies, update the 4 cell neighbor status as empty or not
  59. ' in an empty cell array, then when RI needs to know closest empty use that map.
  60.  
  61. Const SW = 1021, SH = 721 ' cell @30 max 34x24
  62. Const Cell = 30
  63. Const MapW = 17, MapH = 17 ' min @30 cell is 17, 17
  64. Screen _NewImage(SW, SH, 12)
  65. _ScreenMove 150, 20
  66.  
  67. ReDim Shared As Long mt(1 To MapW, 1 To MapH)
  68. Dim Shared As Long MagicRequired ' this is to signal that RI could not find the next empty cell without appeal to Gods
  69.  
  70. Dim Shared As Long BeeLine, Done ' Roby is in beeLine Mode heading to closet empty (unvac'd) cell using steps from Path Finder app
  71. ReDim Shared As Long StepMap(1 To MapW, 1 To MapH) ' for making paths that you step through
  72. Dim Shared As Long StepI, StepDist
  73. ReDim Shared As Long StepX(1 To MapW * MapH), StepY(1 To MapW * MapH)
  74.  
  75. ReDim Shared As Long Room(1 To MapW, 1 To MapH) ' 0 = empty -1 = wall see MakeRoom
  76. Dim Shared As Long rx, ry ' robot location
  77. Dim As Long sweeps
  78.     Done = 0
  79.     rx = Int(MapW / 2 + .5): ry = Int(MapH / 2 + .5) ' starts here in middle of room should be clear
  80.     ReDim Shared As Long mt(1 To MapW, 1 To MapH)
  81.     MakeRoom
  82.     Do
  83.         drawRoom 'ok the middle of room is staying clear of stuff
  84.  
  85.         ' debug check path works
  86.         'path rx, ry, 5, 5 'does this still work  OH YEAH! Better than ever!
  87.         '_Display
  88.  
  89.         RI ' ok roby make your move
  90.         _Display
  91.         _Limit 5
  92.         If Done Then Cls: drawRoom: Exit Do
  93.  
  94.         ' debug just checking rooms made right
  95.         'Sleep
  96.         'Cls
  97.         'Exit Do
  98.     Loop
  99.     'Print "Finished press any for next run   zzz..."
  100.     'Sleep
  101.     sweeps = sweeps + 1
  102.     _Title "I Robot - Room Mapper 2 (IR-RM2) " + Str$(sweeps) + " successful rooms swept, magic needed" + Str$(MagicRequired) + " times."
  103.     _Display
  104.     _Delay 1
  105.  
  106. Sub RI ' the robot appraises it's current postition rx, ry in Room(x) and makes a move changing rx, ry and that ends the sub
  107.     Dim As Long mini, x, y, saveX, saveY, mtDist, delayFlag
  108.  
  109.     ' I was here!  sweeps the spot (again?)
  110.     Room(rx, ry) = Room(rx, ry) + 1 ' put roby's presense on map
  111.     mt(rx, ry) = 0 'no longer mt
  112.  
  113.     ' remember what we found here when we need an empty cell loaction
  114.     If Room(rx, ry - 1) = 0 Then mt(rx, ry - 1) = -1
  115.     If Room(rx + 1, ry) = 0 Then mt(rx + 1, ry) = -1
  116.     If Room(rx, ry + 1) = 0 Then mt(rx, ry + 1) = -1
  117.     If Room(rx - 1, ry) = 0 Then mt(rx - 1, ry) = -1
  118.  
  119.  
  120.     ' after marking current spot see if we have swept all possible
  121.     If swept% Then Done = -1: Exit Sub
  122.  
  123.     If BeeLine = 0 Then ' normal sweeping pattern, hey try up/down then right/left see if leaves less spots
  124.         If Room(rx, ry - 1) = 0 Then ry = ry - 1: Exit Sub
  125.         If Room(rx + 1, ry) = 0 Then rx = rx + 1: Exit Sub
  126.         If Room(rx, ry + 1) = 0 Then ry = ry + 1: Exit Sub
  127.         If Room(rx - 1, ry) = 0 Then rx = rx - 1: Exit Sub
  128.  
  129.         ' still here ?  ========== Decide to make a BeeLine - find the closet empty and make a bee-line to it
  130.         BeeLine = -1 'put us into BeeLine Mode
  131.         'do we have an empty cell location in the stack
  132.         mini = 10000000: delayFlag = 0
  133.         For y = 1 To MapH ' now run through step map and find the mini closest empty room
  134.             For x = 1 To MapW
  135.                 If mt(x, y) = -1 Then ' a known empty cell we passed
  136.                     mtDist = Abs(rx - x) + Abs(ry - y)
  137.                     If mtDist < mini And mtDist > 1 Then mini = mtDist: saveX = x: saveY = y
  138.                 End If
  139.             Next
  140.         Next
  141.  
  142.         If mini = 10000000 Then 'we did not find an empty cell we passed by not a single one!?!?
  143.             ' I hope we never have to here!!!  I am betting we never should unless a really odd perfect storm
  144.             Beep ' signal we had to resort to magically finding and empty cell
  145.             MagicRequired = MagicRequired + 1 'set flag, no the amount of times
  146.             delayFlag = -1 ' I want to see where I had to use magic
  147.             prepStepMap rx, ry
  148.             For y = 1 To MapH ' now run through step map and find the mini closest empty room
  149.                 For x = 1 To MapW
  150.                     If StepMap(x, y) > 1 Then ' has to be > 1 because 0 is robot and 1 the robot will detect!
  151.                         If StepMap(x, y) < mini And Room(x, y) = 0 Then mini = StepMap(x, y): saveX = x: saveY = y
  152.                     End If
  153.                 Next
  154.             Next
  155.         End If
  156.  
  157.         'OK we have our target not find a clear short path to it from roby
  158.         path rx, ry, saveX, saveY ' path sets stepI, stepX(i), stepY(I) that are shared
  159.  
  160.         If delayFlag Then Sleep ' let's get a good look at the empty cell we had to magically find
  161.  
  162.         StepI = 1 ' roby is on it's way to closet empty cell
  163.  
  164.         'debug
  165.         'Print StepI, StepX(StepI), StepY(StepI)
  166.         '_display
  167.         'Beep
  168.         'Sleep ' let me see that path we made
  169.  
  170.         rx = StepX(StepI): ry = StepY(StepI)
  171.     Else
  172.         ' beeline mode
  173.         StepI = StepI + 1 ' roby is on it's way to closet empty cell
  174.         rx = StepX(StepI): ry = StepY(StepI)
  175.  
  176.         'turn of beeLine mode when we have hit target
  177.         If StepI = StepDist - 1 Then BeeLine = 0 ' we have arrived at our target turn off beeLine mode
  178.     End If
  179.  
  180. Sub drawRoom
  181.     Dim As Long x, y
  182.     Dim s$
  183.     Cls
  184.     drawGridSq
  185.     For y = 1 To MapH
  186.         For x = 1 To MapW
  187.             If Room(x, y) = -1 Then
  188.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), 8, BF
  189.             ElseIf Room(x, y) = -2 Then
  190.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), 0, BF
  191.             ElseIf Room(x, y) < -2 Then
  192.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), Abs(Room(x, y)) - 15, BF
  193.             ElseIf Room(x, y) > 0 Then
  194.                 s$ = _Trim$(Str$(Room(x, y)))
  195.                 _PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  196.             ElseIf Room(x, y) = 0 Then ' i want to see if the room is listed in the stack between pull and stack
  197.                 If mt(x, y) = -1 Then 'signal an mt cell that is known to RI
  198.                     _PrintString ((x - 1) * 30 + (30 - 8) / 2, (y - 1) * 30 + 7), "*"
  199.                 End If
  200.             End If
  201.         Next
  202.     Next
  203.     ' and robot
  204.     Line ((rx - 1) * 30, (ry - 1) * 30)-Step(30, 30), 14, BF
  205.  
  206. Sub MakeRoom
  207.     ReDim As Long Room(1 To MapW, 1 To MapH) ' 0 = empty, -1 = wall, -2 = area vac can't access because walled out
  208.     Dim As Long x, y, i, rw, rh, wall, ys, xs, clr
  209.     ' Here are the walls
  210.     For x = 1 To MapW
  211.         Room(x, 1) = -1
  212.         Room(x, MapH) = -1
  213.     Next
  214.     For y = 1 To MapH
  215.         Room(1, y) = -1
  216.         Room(MapW, y) = -1
  217.     Next
  218.  
  219.     ' add random rectangles around the edges
  220.     For i = 1 To Int(Sqr(1.5 * MapW * MapH))
  221.         rw = Int(Rnd * 4) + 1: rh = Int(Rnd * 4) + 1: clr = -1 * ((Int(Rnd * 13) + 1) + 15)
  222.         wall = Int(Rnd * 4)
  223.         Select Case wall
  224.             Case 0 ' top
  225.                 If Rnd < .5 Then ys = 2 Else ys = 4
  226.                 xs = irnd&(2, MapW - 1 - rw)
  227.                 For y = ys To ys + rh - 1
  228.                     For x = xs To xs + rw - 1
  229.                         Room(x, y) = clr
  230.                     Next
  231.                 Next
  232.             Case 1 'right
  233.                 If Rnd < .5 Then xs = MapW - 1 - rw Else xs = (MapW - 3) - rw
  234.                 ys = irnd(2, MapH - 1 - rh)
  235.                 For y = ys To ys + rh - 1
  236.                     For x = xs To xs + rw - 1
  237.                         Room(x, y) = clr
  238.                     Next
  239.                 Next
  240.             Case 2 ' bottom
  241.                 If Rnd < .5 Then ys = MapH - rh - 1 Else ys = (MapH - 2) - rh - 1
  242.                 xs = irnd(2, MapW - 1 - rw)
  243.                 For y = ys To ys + rh - 1
  244.                     For x = xs To xs + rw - 1
  245.                         Room(x, y) = clr
  246.                     Next
  247.                 Next
  248.             Case 3 'left
  249.                 If Rnd < .5 Then xs = 2 Else xs = 5
  250.                 ys = irnd(2, MapH - rh - 1)
  251.                 For y = ys To ys + rh - 1
  252.                     For x = xs To xs + rw - 1
  253.                         Room(x, y) = clr
  254.                     Next
  255.                 Next
  256.         End Select
  257.     Next
  258.  
  259.     ' before make map make sure rx, ry is set or reset
  260.     prepStepMap rx, ry ' see what cells not accessible to vac mark them -1
  261.     For y = 1 To MapH
  262.         For x = 1 To MapW
  263.             If Room(x, y) = 0 Then
  264.                 If StepMap(x, y) = 0 Then Room(x, y) = -2
  265.             End If
  266.         Next
  267.     Next
  268.     Room(rx, ry) = 0 ' not a -2 room!
  269.  
  270. Sub drawGridSq
  271.     Dim As Long x, y
  272.     For x = 0 To Cell * MapW Step Cell
  273.         Line (x, 0)-Step(0, Cell * MapH)
  274.     Next
  275.     For y = 0 To Cell * MapH Step Cell
  276.         Line (0, y)-Step(Cell * MapW, 0)
  277.     Next
  278.  
  279. Function swept%
  280.     Dim As Long x, y
  281.     For y = 1 To MapH
  282.         For x = 1 To MapW
  283.             If Room(x, y) = 0 Then Exit Function 'not swept
  284.         Next
  285.     Next
  286.     swept% = -1 ' all clean!
  287.  
  288. Sub path (sx As Long, sy As Long, tx As Long, ty As Long) ' start x, y to target x, y
  289.     Dim As Long dist, cx, cy, cf, y, x
  290.     prepStepMap tx, ty
  291.     dist = StepMap(sx, sy) 'STEPMAP is DIM SHARED as INTEGER
  292.     StepDist = dist
  293.     If dist = 0 Or Room(tx, ty) = -1 Then
  294.         StepI = 0
  295.         ' Beep
  296.         Color 0, 15
  297.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  298.         _Display
  299.         Sleep
  300.         End
  301.     End If
  302.     'refresh
  303.     ReDim As Long StepX(1 To MapW * MapH), StepY(1 To MapW * MapH)
  304.     StepI = 0 'DIM SHARED error signal
  305.     cx = sx: cy = sy
  306.     While dist >= 2
  307.         'LOCATE 2, 1: PRINT "cx, cy: "; cx, cy '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< debug
  308.         cf = 0
  309.         For y = cy - 1 To cy + 1
  310.             For x = cx - 1 To cx + 1
  311.                 'PRINT "x, y, STEPMAP(x, y) "; x, y, STEPMAP(x, y)
  312.                 If StepMap(x, y) = dist - 1 Then
  313.                     StepI = StepI + 1
  314.                     StepX(StepI) = x: StepY(StepI) = y
  315.                     Line ((StepX(StepI) - 1) * 30 + 1, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 1), 13, B
  316.                     Line ((StepX(StepI) - 1) * 30 + 2, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 2), 13, B
  317.                     Line ((StepX(StepI) - 1) * 30 + 3, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 3), 13, B
  318.                     cf = 1: Exit For
  319.                 End If
  320.             Next
  321.             If cf = 1 Then Exit For
  322.         Next
  323.         If cf = 0 Then 'lost path
  324.             Exit Sub
  325.         Else
  326.             cx = StepX(StepI): cy = StepY(StepI)
  327.             dist = dist - 1
  328.         End If
  329.     Wend
  330.     _Display
  331.     _Delay .6
  332.  
  333. Sub prepStepMap (tx As Long, ty As Long) ' ========================================== no more diagonal steps
  334.     Dim As Long x, y, tick, changes, ystart, ystop, xstart, xstop
  335.     Dim s$ 'debug
  336.  
  337.     ReDim As Long StepMap(1 To MapW, 1 To MapH)
  338.     If tx > 0 And tx <= MapW And ty > 0 And ty <= MapH Then
  339.         StepMap(tx, ty) = 1: tick = 1: changes = 1
  340.         While changes
  341.             tick = tick + 1: changes = 0
  342.             ystart = max(ty - tick, 1): ystop = min(ty + tick, MapH)
  343.             For y = ystart To ystop
  344.                 xstart = max(tx - tick, 1): xstop = min(tx + tick, MapW)
  345.                 For x = xstart To xstop
  346.                     'check out the neighbors
  347.                     If Room(x, y) >= 0 Then ' places OK to go
  348.                         'cf = 0
  349.                         ' ============================================================= new >>> path finder  that won't take diagonal steps
  350.                         'need to check 4 cells around x, y for parent
  351.                         If StepMap(x - 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  352.                             StepMap(x, y) = tick
  353.                             ' 2 line debug  =====================================================
  354.                             's$ = _Trim$(Str$(StepMap(x, y)))
  355.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  356.                             changes = 1: GoTo skip
  357.                         End If
  358.                         If StepMap(x + 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  359.                             StepMap(x, y) = tick
  360.                             ' debug
  361.                             's$ = _Trim$(Str$(StepMap(x, y)))
  362.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  363.                             changes = 1: GoTo skip
  364.                         End If
  365.                         If StepMap(x, y - 1) = tick - 1 And StepMap(x, y) = 0 Then
  366.                             StepMap(x, y) = tick
  367.                             ' debug
  368.                             's$ = _Trim$(Str$(StepMap(x, y)))
  369.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  370.                             changes = 1: GoTo skip
  371.                         End If
  372.                         If StepMap(x, y + 1) = tick - 1 And StepMap(x, y) = 0 Then
  373.                             StepMap(x, y) = tick
  374.                             ' debug
  375.                             's$ = _Trim$(Str$(StepMap(x, y)))
  376.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  377.                             changes = 1
  378.                         End If
  379.                         skip:
  380.                     End If
  381.                 Next
  382.             Next
  383.         Wend
  384.     Else
  385.         'Beep
  386.         Color 0, 13
  387.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  388.         _Display
  389.         Sleep
  390.         End
  391.     End If
  392.  
  393. Function min (n1, n2)
  394.     If n1 > n2 Then min = n2 Else min = n1
  395.  
  396. Function max (n1, n2)
  397.     If n1 < n2 Then max = n2 Else max = n1
  398.  
  399. Function irnd& (n1, n2) 'return an integer between 2 numbers
  400.     Dim l%, h%
  401.     If n1 > n2 Then l% = n2: h% = n1 Else l% = n1: h% = n2
  402.     irnd& = Int(Rnd * (h% - l% + 1)) + l%
  403.  
  404.  

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #5 on: March 01, 2022, 05:05:41 am »
This is a very interesting experiment! I think the trip has been effective!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #6 on: March 01, 2022, 07:21:36 am »
This is a very interesting experiment! I think the trip has been effective!

Thank you sir! I am getting much better feedback here than at Liberty Forum :)

You all are just smarter I guess ;-))

I really think I will get it improved today when I start measuring path lengths to open / mt (empty) cells RI has memorized. But what a difference since the start!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #7 on: March 01, 2022, 03:59:12 pm »
OK this is selecting the empty cell that has shortest path to it when the RI is surrounded by already passed through cells, as opposed to going to the closest empty cell as the crow flies (rectangularly).

It might be a shade better.
Code: QB64: [Select]
  1. _Title "I Robot - Room Mapper 5 (IR-RM5)" ' b+ 22-02-11
  2. ' 22-02-23 started writing code
  3. ' The little guy, say a vaccum cleaner, is plopped down somewhere in it's new home.
  4. ' The first order of business is to map out it's area of duty,
  5. ' say sweep the whole floor without getting stuck or wasting allot of moves.
  6. ' It is square and can sense, resistence on any of its edges.
  7. ' It is allowed to go N,S,E,W - the four directions
  8. ' If something is sensed on one side it is forbidden to
  9. ' enter that square from that direction.
  10. ' Rule of economy - don't reenter a square already occupied
  11. ' unless that is the only way to go.
  12. ' Do we have enough spelled out to map a room?
  13.  
  14. ' A room is a grid of squares, we don't know the dimensions
  15. ' and there are objects in many of the middle squares or along
  16. ' the walls. Later we may encounter objects that move around
  17. ' like pets or results of fickle home decorators.
  18.  
  19. ' God provides a room with objetcs and randomly drops the robot
  20. ' into it.
  21.  
  22. ' 22-02-23 first goal is to get an edges mapped. so make up a room
  23. ' Upon some more thinking and just to get the ball rolling, I will
  24. ' allow robot vaccum sweeper to use the room map and mark it with it's
  25. ' own numbers, so now the walls are -1, empty areas 0, places visited
  26. ' are positive numbers, everytime the vacuum reoccupies the square
  27. ' the number is increased.
  28. ' OK the room setup seems satisfactory onto RI = Robot Intelligence
  29.  
  30. ' OK first run it does eventually cover the whole room.
  31. ' Need to know when it has done the whole room. There are some
  32. ' places that have to be left 0
  33.  
  34. ' IR-RM2 next mod
  35. ' 2022-02-24 what I need is path finder, then I can see which squares are
  36. ' accessible to robot from middle of the room, so I can mark and then
  37. ' I will be able to tell when Robot has visited all spaces it can.
  38. ' ALSO I can use pathfinder to get at next closest enpty square.
  39. ' OK the subs from PathFinder 3a are loaded and working with Option _Explicit.
  40.  
  41. ' Next job is to mark all places vacuum can access checks, so we can then
  42. ' have a check to see if all areas covered by vac.
  43.  
  44. ' 2022-02-26 Got the bug causing once in a blue moon problem with room fills
  45. ' ie leaving empty spaces not accessible to vacuum. Could the other once in a blue
  46. ' moon problem be similar. RI is trying to path to target at 0,0.
  47. ' Ho, ho yes! very likely the same problem!!!
  48. ' 2022-02-27 fix some things color the furniture, debug the way the furniture
  49. ' was supposed to be placed around the room ie not into the walls!
  50.  
  51. ' IR-RM3 next mod,
  52. ' 2022-02-28  give RI a stack to save locations of empty cells it passes by.
  53. ' I think that might improve performance because it will get unswept sections
  54. ' while it's still nearby? That is the hypothesis, now for the experiment.
  55. ' Stack is NOT WORKING this code is dead end!
  56.  
  57. ' IR_RM4 next mod
  58. ' Every space the RI occupies, update the 4 cell neighbor status as empty or not
  59. ' in an empty cell array, then when RI needs to know closest empty use that map.
  60. ' OK that works but now find the shortest path lengths to an empty cell.
  61.  
  62. ' IR-RM5
  63. ' 2022-03-01 Today we find the mt cell with shortest path to roby.
  64. ' That got working right quick. I want to test another patern for priortizing
  65. ' which empty cell order to use.
  66.  
  67.  
  68. Const SW = 1021, SH = 721 ' cell @30 max 34x24
  69. Const Cell = 30
  70. Const MapW = 17, MapH = 17 ' min @30 cell is 17, 17
  71. Screen _NewImage(SW, SH, 12)
  72. _ScreenMove 150, 20
  73.  
  74. ReDim Shared As Long mt(1 To MapW, 1 To MapH)
  75. Dim Shared As Long MagicRequired ' this is to signal that RI could not find the next empty cell without appeal to Gods
  76.  
  77. Dim Shared As Long BeeLine, Done ' Roby is in beeLine Mode heading to closet empty (unvac'd) cell using steps from Path Finder app
  78. ReDim Shared As Long StepMap(1 To MapW, 1 To MapH) ' for making paths that you step through
  79. Dim Shared As Long StepI, StepDist
  80. ReDim Shared As Long StepX(1 To MapW * MapH), StepY(1 To MapW * MapH)
  81.  
  82. ReDim Shared As Long Room(1 To MapW, 1 To MapH) ' 0 = empty -1 = wall see MakeRoom
  83. Dim Shared As Long rx, ry ' robot location
  84. Dim As Long sweeps
  85.     Done = 0
  86.     rx = Int(MapW / 2 + .5): ry = Int(MapH / 2 + .5) ' starts here in middle of room should be clear
  87.     ReDim Shared As Long mt(1 To MapW, 1 To MapH)
  88.     MakeRoom
  89.     Do
  90.         drawRoom 'ok the middle of room is staying clear of stuff
  91.  
  92.         ' debug check path works
  93.         'path rx, ry, 5, 5 'does this still work  OH YEAH! Better than ever!
  94.         '_Display
  95.  
  96.         RI ' ok roby make your move
  97.         _Display
  98.         _Limit 5
  99.         If Done Then Cls: drawRoom: Exit Do
  100.  
  101.         ' debug just checking rooms made right
  102.         'Sleep
  103.         'Cls
  104.         'Exit Do
  105.     Loop
  106.     'Print "Finished press any for next run   zzz..."
  107.     'Sleep
  108.     sweeps = sweeps + 1
  109.     _Title "I Robot - Room Mapper 2 (IR-RM2) " + Str$(sweeps) + " successful rooms swept, magic needed" + Str$(MagicRequired) + " times."
  110.     _Display
  111.     _Delay 1
  112.  
  113. Sub RI ' the robot appraises it's current postition rx, ry in Room(x) and makes a move changing rx, ry and that ends the sub
  114.     Dim As Long mini, x, y, saveX, saveY, mtDist, delayFlag
  115.  
  116.     ' I was here!  sweeps the spot (again?)
  117.     Room(rx, ry) = Room(rx, ry) + 1 ' put roby's presense on map
  118.     mt(rx, ry) = 0 'no longer mt
  119.  
  120.     ' remember what we found here when we need an empty cell loaction
  121.     If Room(rx, ry - 1) = 0 Then mt(rx, ry - 1) = -1
  122.     If Room(rx + 1, ry) = 0 Then mt(rx + 1, ry) = -1
  123.     If Room(rx, ry + 1) = 0 Then mt(rx, ry + 1) = -1
  124.     If Room(rx - 1, ry) = 0 Then mt(rx - 1, ry) = -1
  125.  
  126.  
  127.     ' after marking current spot see if we have swept all possible
  128.     If swept% Then Done = -1: Exit Sub
  129.  
  130.     If BeeLine = 0 Then ' normal sweeping pattern, hey try up/down then right/left see if leaves less spots
  131.         If Room(rx, ry - 1) = 0 Then ry = ry - 1: Exit Sub
  132.         If Room(rx + 1, ry) = 0 Then rx = rx + 1: Exit Sub
  133.         If Room(rx, ry + 1) = 0 Then ry = ry + 1: Exit Sub
  134.         If Room(rx - 1, ry) = 0 Then rx = rx - 1: Exit Sub
  135.  
  136.         ' still here ?  ========== Decide to make a BeeLine - find the closet empty and make a bee-line to it
  137.         BeeLine = -1 'put us into BeeLine Mode
  138.         'do we have an empty cell location in the stack
  139.  
  140.         prepStepMap rx, ry ' this will get us a map of how far away all accessible cells are
  141.         ' now consult stepMap of x,y
  142.  
  143.         mini = 10000000: delayFlag = 0
  144.         For y = 1 To MapH ' now run through step map and find the mini closest empty room
  145.             For x = 1 To MapW
  146.                 If mt(x, y) = -1 Then ' a known empty cell we passed
  147.                     mtDist = StepMap(x, y)
  148.                     If mtDist < mini And mtDist > 1 Then mini = mtDist: saveX = x: saveY = y
  149.                 End If
  150.             Next
  151.         Next
  152.  
  153.         'from a number of runs with IR-RM4 this should not ever be needed but just in case
  154.         If mini = 10000000 Then 'we did not find an empty cell we passed by, not a single one!?!?
  155.             ' I hope we never have to here!!!  I am betting we never should unless a really odd perfect storm
  156.             Beep ' signal we had to resort to magically finding and empty cell
  157.             MagicRequired = MagicRequired + 1 'set flag, no the amount of times
  158.             delayFlag = -1 ' I want to see where I had to use magic
  159.  
  160.             For y = 1 To MapH ' now run through step map and find the mini closest empty room
  161.                 For x = 1 To MapW
  162.                     If StepMap(x, y) > 1 Then ' has to be > 1 because 0 is robot and 1 the robot will detect!
  163.                         If StepMap(x, y) < mini And Room(x, y) = 0 Then mini = StepMap(x, y): saveX = x: saveY = y
  164.                     End If
  165.                 Next
  166.             Next
  167.         End If
  168.  
  169.         'OK we have our target not find a clear short path to it from roby
  170.         path rx, ry, saveX, saveY ' path sets stepI, stepX(i), stepY(I) that are shared
  171.  
  172.         If delayFlag Then Sleep ' let's get a good look at the empty cell we had to magically find
  173.  
  174.         StepI = 1 ' roby is on it's way to closet empty cell
  175.  
  176.         'debug
  177.         'Print StepI, StepX(StepI), StepY(StepI)
  178.         '_display
  179.         'Beep
  180.         'Sleep ' let me see that path we made
  181.  
  182.         rx = StepX(StepI): ry = StepY(StepI)
  183.     Else
  184.         ' beeline mode
  185.         StepI = StepI + 1 ' roby is on it's way to closet empty cell
  186.         rx = StepX(StepI): ry = StepY(StepI)
  187.  
  188.         'turn of beeLine mode when we have hit target
  189.         If StepI = StepDist - 1 Then BeeLine = 0 ' we have arrived at our target turn off beeLine mode
  190.     End If
  191.  
  192. Sub drawRoom
  193.     Dim As Long x, y
  194.     Dim s$
  195.     Cls
  196.     drawGridSq
  197.     For y = 1 To MapH
  198.         For x = 1 To MapW
  199.             If Room(x, y) = -1 Then
  200.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), 8, BF
  201.             ElseIf Room(x, y) = -2 Then
  202.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), 0, BF
  203.             ElseIf Room(x, y) < -2 Then
  204.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), Abs(Room(x, y)) - 15, BF
  205.             ElseIf Room(x, y) > 0 Then
  206.                 s$ = _Trim$(Str$(Room(x, y)))
  207.                 _PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  208.             ElseIf Room(x, y) = 0 Then ' i want to see if the room is listed in the stack between pull and stack
  209.                 If mt(x, y) = -1 Then 'signal an mt cell that is known to RI
  210.                     _PrintString ((x - 1) * 30 + (30 - 8) / 2, (y - 1) * 30 + 7), "*"
  211.                 End If
  212.             End If
  213.         Next
  214.     Next
  215.     ' and robot
  216.     Line ((rx - 1) * 30, (ry - 1) * 30)-Step(30, 30), 14, BF
  217.  
  218. Sub MakeRoom
  219.     ReDim As Long Room(1 To MapW, 1 To MapH) ' 0 = empty, -1 = wall, -2 = area vac can't access because walled out
  220.     Dim As Long x, y, i, rw, rh, wall, ys, xs, clr
  221.     ' Here are the walls
  222.     For x = 1 To MapW
  223.         Room(x, 1) = -1
  224.         Room(x, MapH) = -1
  225.     Next
  226.     For y = 1 To MapH
  227.         Room(1, y) = -1
  228.         Room(MapW, y) = -1
  229.     Next
  230.  
  231.     ' add random rectangles around the edges
  232.     For i = 1 To Int(Sqr(1.5 * MapW * MapH))
  233.         rw = Int(Rnd * 4) + 1: rh = Int(Rnd * 4) + 1: clr = -1 * ((Int(Rnd * 13) + 1) + 15)
  234.         wall = Int(Rnd * 4)
  235.         Select Case wall
  236.             Case 0 ' top
  237.                 If Rnd < .5 Then ys = 2 Else ys = 4
  238.                 xs = irnd&(2, MapW - 1 - rw)
  239.                 For y = ys To ys + rh - 1
  240.                     For x = xs To xs + rw - 1
  241.                         Room(x, y) = clr
  242.                     Next
  243.                 Next
  244.             Case 1 'right
  245.                 If Rnd < .5 Then xs = MapW - 1 - rw Else xs = (MapW - 3) - rw
  246.                 ys = irnd(2, MapH - 1 - rh)
  247.                 For y = ys To ys + rh - 1
  248.                     For x = xs To xs + rw - 1
  249.                         Room(x, y) = clr
  250.                     Next
  251.                 Next
  252.             Case 2 ' bottom
  253.                 If Rnd < .5 Then ys = MapH - rh - 1 Else ys = (MapH - 2) - rh - 1
  254.                 xs = irnd(2, MapW - 1 - rw)
  255.                 For y = ys To ys + rh - 1
  256.                     For x = xs To xs + rw - 1
  257.                         Room(x, y) = clr
  258.                     Next
  259.                 Next
  260.             Case 3 'left
  261.                 If Rnd < .5 Then xs = 2 Else xs = 5
  262.                 ys = irnd(2, MapH - rh - 1)
  263.                 For y = ys To ys + rh - 1
  264.                     For x = xs To xs + rw - 1
  265.                         Room(x, y) = clr
  266.                     Next
  267.                 Next
  268.         End Select
  269.     Next
  270.  
  271.     ' before make map make sure rx, ry is set or reset
  272.     prepStepMap rx, ry ' see what cells not accessible to vac mark them -1
  273.     For y = 1 To MapH
  274.         For x = 1 To MapW
  275.             If Room(x, y) = 0 Then
  276.                 If StepMap(x, y) = 0 Then Room(x, y) = -2
  277.             End If
  278.         Next
  279.     Next
  280.     Room(rx, ry) = 0 ' not a -2 room!
  281.  
  282. Sub drawGridSq
  283.     Dim As Long x, y
  284.     For x = 0 To Cell * MapW Step Cell
  285.         Line (x, 0)-Step(0, Cell * MapH)
  286.     Next
  287.     For y = 0 To Cell * MapH Step Cell
  288.         Line (0, y)-Step(Cell * MapW, 0)
  289.     Next
  290.  
  291. Function swept%
  292.     Dim As Long x, y
  293.     For y = 1 To MapH
  294.         For x = 1 To MapW
  295.             If Room(x, y) = 0 Then Exit Function 'not swept
  296.         Next
  297.     Next
  298.     swept% = -1 ' all clean!
  299.  
  300. Sub path (sx As Long, sy As Long, tx As Long, ty As Long) ' start x, y to target x, y
  301.     Dim As Long dist, cx, cy, cf, y, x
  302.     prepStepMap tx, ty
  303.     dist = StepMap(sx, sy) 'STEPMAP is DIM SHARED as INTEGER
  304.     StepDist = dist
  305.     If dist = 0 Or Room(tx, ty) = -1 Then
  306.         StepI = 0
  307.         ' Beep
  308.         Color 0, 15
  309.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  310.         _Display
  311.         Sleep
  312.         End
  313.     End If
  314.     'refresh
  315.     ReDim As Long StepX(1 To MapW * MapH), StepY(1 To MapW * MapH)
  316.     StepI = 0 'DIM SHARED error signal
  317.     cx = sx: cy = sy
  318.     While dist >= 2
  319.         'LOCATE 2, 1: PRINT "cx, cy: "; cx, cy '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< debug
  320.         cf = 0
  321.         For y = cy - 1 To cy + 1
  322.             For x = cx - 1 To cx + 1
  323.                 'PRINT "x, y, STEPMAP(x, y) "; x, y, STEPMAP(x, y)
  324.                 If StepMap(x, y) = dist - 1 Then
  325.                     StepI = StepI + 1
  326.                     StepX(StepI) = x: StepY(StepI) = y
  327.                     Line ((StepX(StepI) - 1) * 30 + 1, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 1), 10, B
  328.                     Line ((StepX(StepI) - 1) * 30 + 2, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 2), 10, B
  329.                     Line ((StepX(StepI) - 1) * 30 + 3, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 3), 10, B
  330.                     Line ((StepX(StepI) - 1) * 30 + 4, (StepY(StepI) - 1) * 30 + 2)-Step(30 - 2, 30 - 4), 10, B
  331.                     cf = 1: Exit For
  332.                 End If
  333.             Next
  334.             If cf = 1 Then Exit For
  335.         Next
  336.         If cf = 0 Then 'lost path
  337.             Exit Sub
  338.         Else
  339.             cx = StepX(StepI): cy = StepY(StepI)
  340.             dist = dist - 1
  341.         End If
  342.     Wend
  343.     _Display
  344.     _Delay .6
  345.  
  346. Sub prepStepMap (tx As Long, ty As Long) ' ========================================== no more diagonal steps
  347.     Dim As Long x, y, tick, changes, ystart, ystop, xstart, xstop
  348.     Dim s$ 'debug
  349.  
  350.     ReDim As Long StepMap(1 To MapW, 1 To MapH)
  351.     If tx > 0 And tx <= MapW And ty > 0 And ty <= MapH Then
  352.         StepMap(tx, ty) = 1: tick = 1: changes = 1
  353.         While changes
  354.             tick = tick + 1: changes = 0
  355.             ystart = max(ty - tick, 1): ystop = min(ty + tick, MapH)
  356.             For y = ystart To ystop
  357.                 xstart = max(tx - tick, 1): xstop = min(tx + tick, MapW)
  358.                 For x = xstart To xstop
  359.                     'check out the neighbors
  360.                     If Room(x, y) >= 0 Then ' places OK to go
  361.                         'cf = 0
  362.                         ' ============================================================= new >>> path finder  that won't take diagonal steps
  363.                         'need to check 4 cells around x, y for parent
  364.                         If StepMap(x - 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  365.                             StepMap(x, y) = tick
  366.                             ' 2 line debug  =====================================================
  367.                             's$ = _Trim$(Str$(StepMap(x, y)))
  368.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  369.                             changes = 1: GoTo skip
  370.                         End If
  371.                         If StepMap(x + 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  372.                             StepMap(x, y) = tick
  373.                             ' debug
  374.                             's$ = _Trim$(Str$(StepMap(x, y)))
  375.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  376.                             changes = 1: GoTo skip
  377.                         End If
  378.                         If StepMap(x, y - 1) = tick - 1 And StepMap(x, y) = 0 Then
  379.                             StepMap(x, y) = tick
  380.                             ' debug
  381.                             's$ = _Trim$(Str$(StepMap(x, y)))
  382.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  383.                             changes = 1: GoTo skip
  384.                         End If
  385.                         If StepMap(x, y + 1) = tick - 1 And StepMap(x, y) = 0 Then
  386.                             StepMap(x, y) = tick
  387.                             ' debug
  388.                             's$ = _Trim$(Str$(StepMap(x, y)))
  389.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  390.                             changes = 1
  391.                         End If
  392.                         skip:
  393.                     End If
  394.                 Next
  395.             Next
  396.         Wend
  397.     Else
  398.         'Beep
  399.         Color 0, 13
  400.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  401.         _Display
  402.         Sleep
  403.         End
  404.     End If
  405.  
  406. Function min (n1, n2)
  407.     If n1 > n2 Then min = n2 Else min = n1
  408.  
  409. Function max (n1, n2)
  410.     If n1 < n2 Then max = n2 Else max = n1
  411.  
  412. Function irnd& (n1, n2) 'return an integer between 2 numbers
  413.     Dim l%, h%
  414.     If n1 > n2 Then l% = n2: h% = n1 Else l% = n1: h% = n2
  415.     irnd& = Int(Rnd * (h% - l% + 1)) + l%
  416.  
  417.  

It still makes me cringe when it leaves behind an empty cell or 2 that it will later have to come back to, to cover the room. I don't know maybe like chess we will have to start looking 2 or 3 moves ahead for a smarter bot.

Next is a scoring system (ha maybe again like chess) for evaluating better and worse plans of action.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #8 on: March 01, 2022, 06:22:44 pm »
Another way it could be more like chess would be to replace the yellow square with
a Queen, one  brandishing a broom.

It drops more spies (*) than a C-130.

Will the next version quantum tunnel to isolated rooms?
« Last Edit: March 01, 2022, 06:37:42 pm by Richard Frost »
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #9 on: March 03, 2022, 09:54:59 am »
NOW play the game yourself!

More rework of Room map because it was leaving channel along right and bottom edge.
Remove the RI stuff and just view rooms with spacebar.

See one you want to try yourself press Enter after you have your printer ready.
Code: QB64: [Select]
  1. _Title "Press Enter to Print out Room Map, press space for next room. " ' b+ 22-03-02
  2. ' 2022-03-02 Edit IR-RM6 so I can play around with this puzzle with pencil and paper.
  3.  
  4. Const SW = 1021, SH = 721 ' cell @30 max 34x24
  5. Const Cell = 30
  6. Const MapW = 17, MapH = 17 ' min @30 cell is 17, 17
  7.  
  8. Screen _NewImage(SW, SH, 32)
  9. _ScreenMove 150, 20
  10.  
  11. qb(0) = &HFF000000
  12. qb(1) = &HFF000088
  13. qb(2) = &HFF008800
  14. qb(3) = &HFF008888
  15. qb(4) = &HFF880000
  16. qb(5) = &HFF880088
  17. qb(6) = &HFF888800
  18. qb(7) = &HFFCCCCCC
  19. qb(8) = &HFF888888
  20. qb(9) = &HFF0000FF
  21. qb(10) = &HFF00FF00
  22. qb(11) = &HFF00FFFF
  23. qb(12) = &HFFFF0000
  24. qb(13) = &HFFFF00FF
  25. qb(14) = &HFFFFFF00
  26. qb(15) = &HFFFFFFFF
  27.  
  28. ReDim Shared As Long StepMap(1 To MapW, 1 To MapH) ' for making paths that you step through
  29. ReDim Shared As Long Room(1 To MapW, 1 To MapH) ' 0 = empty -1 = wall see MakeRoom
  30. Dim Shared As Long rx, ry ' robot location
  31. Dim K$
  32. rx = Int(MapW / 2 + .5): ry = Int(MapH / 2 + .5)
  33. Color qb(0), qb(15)
  34.     MakeRoom
  35.     Do
  36.         drawRoom 'ok the middle of room is staying clear of stuff
  37.         _Display
  38.         K$ = InKey$
  39.         While Len(K$) = 0
  40.             K$ = InKey$
  41.             _Limit 30
  42.         Wend
  43.         If Asc(K$) = 13 Then PrintLandscapeView Else Exit Do
  44.     Loop
  45.  
  46. Sub drawRoom
  47.     Dim As Long x, y
  48.     Dim s$
  49.     Cls
  50.     drawGridSq
  51.     For y = 1 To MapH
  52.         For x = 1 To MapW
  53.             If Room(x, y) = -1 Then
  54.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), qb(8), BF
  55.             ElseIf Room(x, y) = -2 Then
  56.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), qb(1), BF
  57.             ElseIf Room(x, y) < -2 Then
  58.                 Line ((x - 1) * 30, (y - 1) * 30)-Step(30, 30), qb(3), BF
  59.             ElseIf Room(x, y) > 0 Then
  60.                 s$ = _Trim$(Str$(Room(x, y)))
  61.                 _PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  62.             End If
  63.         Next
  64.     Next
  65.     _PrintString ((rx - 1) * 30 + 12, (ry - 1) * 30 + 8), "X"
  66.  
  67. Sub MakeRoom
  68.     ReDim As Long Room(1 To MapW, 1 To MapH) ' 0 = empty, -1 = wall, -2 = area vac can't access because walled out
  69.     Dim As Long x, y, i, rw, rh, wall, ys, xs, clr
  70.     ' Here are the walls
  71.     For x = 1 To MapW
  72.         Room(x, 1) = -1
  73.         Room(x, MapH) = -1
  74.     Next
  75.     For y = 1 To MapH
  76.         Room(1, y) = -1
  77.         Room(MapW, y) = -1
  78.     Next
  79.  
  80.     ' add random rectangles around the edges
  81.     For i = 1 To Int(Sqr(1.5 * MapW * MapH))
  82.         rw = Int(Rnd * 4) + 1: rh = Int(Rnd * 4) + 1: clr = -3
  83.         wall = Int(Rnd * 4)
  84.         Select Case wall
  85.             Case 0 ' top
  86.                 If Rnd < .5 Then ys = 2 Else ys = 4
  87.                 xs = irnd&(2, MapW - rw)
  88.                 For y = ys To ys + rh - 1
  89.                     For x = xs To xs + rw - 1
  90.                         Room(x, y) = clr
  91.                     Next
  92.                 Next
  93.             Case 1 'right
  94.                 If Rnd < .5 Then xs = MapW - rw Else xs = (MapW - 2) - rw
  95.                 ys = irnd(2, MapH - rh)
  96.                 For y = ys To ys + rh - 1
  97.                     For x = xs To xs + rw - 1
  98.                         Room(x, y) = clr
  99.                     Next
  100.                 Next
  101.             Case 2 ' bottom
  102.                 If Rnd < .5 Then ys = MapH - rh Else ys = (MapH - 2) - rh
  103.                 xs = irnd(2, MapW - rw)
  104.                 For y = ys To ys + rh - 1
  105.                     For x = xs To xs + rw - 1
  106.                         Room(x, y) = clr
  107.                     Next
  108.                 Next
  109.             Case 3 'left
  110.                 If Rnd < .5 Then xs = 2 Else xs = 4
  111.                 ys = irnd(2, MapH - rh)
  112.                 For y = ys To ys + rh - 1
  113.                     For x = xs To xs + rw - 1
  114.                         Room(x, y) = clr
  115.                     Next
  116.                 Next
  117.         End Select
  118.     Next
  119.  
  120.     ' before make map make sure rx, ry is set or reset
  121.     prepStepMap rx, ry ' see what cells not accessible to vac mark them -1
  122.     For y = 1 To MapH
  123.         For x = 1 To MapW
  124.             If Room(x, y) = 0 Then
  125.                 If StepMap(x, y) = 0 Then Room(x, y) = -2
  126.             End If
  127.         Next
  128.     Next
  129.     Room(rx, ry) = 0 ' not a -2 room!
  130.  
  131. Sub drawGridSq
  132.     Dim As Long x, y
  133.     For x = 0 To Cell * MapW Step Cell
  134.         Line (x, 0)-Step(0, Cell * MapH)
  135.     Next
  136.     For y = 0 To Cell * MapH Step Cell
  137.         Line (0, y)-Step(Cell * MapW, 0)
  138.     Next
  139.  
  140. Function irnd& (n1, n2) 'return an integer between 2 numbers
  141.     Dim l%, h%
  142.     If n1 > n2 Then l% = n2: h% = n1 Else l% = n1: h% = n2
  143.     irnd& = Int(Rnd * (h% - l% + 1)) + l%
  144.  
  145. Sub prepStepMap (tx As Long, ty As Long) ' ========================================== no more diagonal steps
  146.     Dim As Long x, y, tick, changes, ystart, ystop, xstart, xstop
  147.     Dim s$ 'debug
  148.  
  149.     ReDim As Long StepMap(1 To MapW, 1 To MapH)
  150.     If tx > 0 And tx <= MapW And ty > 0 And ty <= MapH Then
  151.         StepMap(tx, ty) = 1: tick = 1: changes = 1
  152.         While changes
  153.             tick = tick + 1: changes = 0
  154.             ystart = max(ty - tick, 1): ystop = min(ty + tick, MapH)
  155.             For y = ystart To ystop
  156.                 xstart = max(tx - tick, 1): xstop = min(tx + tick, MapW)
  157.                 For x = xstart To xstop
  158.                     'check out the neighbors
  159.                     If Room(x, y) >= 0 Then ' places OK to go
  160.                         'cf = 0
  161.                         ' ============================================================= new >>> path finder  that won't take diagonal steps
  162.                         'need to check 4 cells around x, y for parent
  163.                         If StepMap(x - 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  164.                             StepMap(x, y) = tick
  165.                             ' 2 line debug  =====================================================
  166.                             's$ = _Trim$(Str$(StepMap(x, y)))
  167.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  168.                             changes = 1: GoTo skip
  169.                         End If
  170.                         If StepMap(x + 1, y) = tick - 1 And StepMap(x, y) = 0 Then
  171.                             StepMap(x, y) = tick
  172.                             ' debug
  173.                             's$ = _Trim$(Str$(StepMap(x, y)))
  174.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  175.                             changes = 1: GoTo skip
  176.                         End If
  177.                         If StepMap(x, y - 1) = tick - 1 And StepMap(x, y) = 0 Then
  178.                             StepMap(x, y) = tick
  179.                             ' debug
  180.                             's$ = _Trim$(Str$(StepMap(x, y)))
  181.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  182.                             changes = 1: GoTo skip
  183.                         End If
  184.                         If StepMap(x, y + 1) = tick - 1 And StepMap(x, y) = 0 Then
  185.                             StepMap(x, y) = tick
  186.                             ' debug
  187.                             's$ = _Trim$(Str$(StepMap(x, y)))
  188.                             '_PrintString ((x - 1) * 30 + (30 - Len(s$) * 8) / 2, (y - 1) * 30 + 7), s$
  189.                             changes = 1
  190.                         End If
  191.                         skip:
  192.                     End If
  193.                 Next
  194.             Next
  195.         Wend
  196.     Else
  197.         'Beep
  198.         Color 0, 13
  199.         _PrintString (200, 300), "Target:" + Str$(tx) + "," + Str$(ty) + " is bad, fatal error."
  200.         _Display
  201.         Sleep
  202.         End
  203.     End If
  204.  
  205. Function min (n1, n2)
  206.     If n1 > n2 Then min = n2 Else min = n1
  207.  
  208. Function max (n1, n2)
  209.     If n1 < n2 Then max = n2 Else max = n1
  210.  
  211. Sub PrintLandscapeView ' straight from printing calendars  needs _newimage(x, y, 32)
  212.     Dim landscape&
  213.     'printer prep
  214.     landscape& = _NewImage(SH, SW, 32) ' yes reverse x and y
  215.     _MapTriangle (SW, 0)-(0, 0)-(0, SH), 0 To(0, 0)-(0, SW)-(SH, SW), landscape&
  216.     _MapTriangle (SW, 0)-(SW, SH)-(0, SH), 0 To(0, 0)-(SH, 0)-(SH, SW), landscape&
  217.     _PrintImage landscape& '<<<<<<<<<<<<<<<<<<<<<<<<<    debug first before wasting paper and ink
  218.     _Delay 2
  219.     _FreeImage landscape&
  220.  
  221.  

 
image_2022-03-03_095456.png


It's now a pencil and paper puzzle! Goal try to draw one line through all squares backtracking as little as possible.
« Last Edit: March 03, 2022, 01:06:12 pm by bplus »

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #10 on: March 03, 2022, 01:19:58 pm »
what should I do after selecting a room? I may not understand something

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #11 on: March 03, 2022, 01:51:37 pm »
what should I do after selecting a room? I may not understand something

Well it works for my printer, press Enter and get a PrintOut of the room you are viewing. Keep hitting Spacebar (or anything NOT Enter)  for a new room on the screen. I don't know how well other people's printers will handle QB64's: _PrintImage IHandle&

This is just if you want to try a Pencil and Paper Puzzle, draw one continuous line through every square in grid trying not to go over same square more than once, some places you have to go over more than once.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #12 on: March 03, 2022, 04:13:09 pm »
I had to figure out how to get my scanner to work to show an example solution to a puzzle:
 
Room Sweep Puzzle_0001.png


If you can do this room in less than 3 overlap cells then you beat me and the above solution I came up with.

Oops! a blunder at the top (see the missed cell, no line thru it, go thru that instead of repeat), can do that Puzzle in 2 overlaps

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #13 on: March 03, 2022, 07:29:40 pm »
Space filling "curve".

I should mention going diagonally is not allowed as the sweeper wouldn't fit between one rectangular obstacle kitty cornered to another, not even close!

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Evolving RI (Robot Intelligence) for a room vacuum
« Reply #14 on: March 04, 2022, 01:33:32 pm »
ah, I get it now, I think it was a very good idea to do this! I didn't print it out (I don't have a printer), but I think it works for me.