// This program runs in RobotBASIC, a FREE language that can
// be downloaded from www.RobotBASIC.org Main: gosub Initialization Flip ON // Eliminates Screen Flicker when ON (set to OFF to see flicker) while true repeat gosub MoveBall gosub MoveRobot delay 30 until by>=550 gosub DrawRobot if not HitWall if (hv>0 and predicted>bx) or (hv<0 and predicted<bx) c*=.95 else c*=1.05 endif endif HitWall=0 vv=-vv // make the robot bump the ball randomly to show it can handle various ball flights // add vertical randomness if vv>-20 then vv=-30 +random(10) // add horizontal randomness if random(100)<40 then hv=random(20)-10 wend
end Initialization: r=5 // radius of ball g=1.0 // accel of gravity rx = 650 // robot's position ry = 570 rv=0 // robot's velocity px=0 // predicted position of where the ball will land c=.075 // starting value for fudge factor // change value of c to make robot have to learn // Any value will work, but if the number is too large or too small // then the learning will take longer. Try .25 for example and note // how the line (showing predicted impact) is wrong at first // Low numbers seem to work, but if you look closely, the robot is // not anticipating, just tracking the ball. When properly trained // watch the line at the bottom of the screen - it will show the // projected impact position fairly accurately and it will move // to the proper place before the robot does HitWall=false // Don't try to correct the Fudge Factor when a wall is hit // because the calulations don't always work right when the ball changes directions Gosub DrawSlingShot linewidth 3 gosub DrawRobot Gosub ShootBall
return DrawSlingShot: LineWidth 5 line 100,550,100,500 lineto 90,450 line 100,500,110,450 gosub DrawRobot print print " Move mouse to ball and hold left button down." print " Pull ball back and release button to launch ball." SaveScr // for easy restore during ball launch
return ShootBall: bx=100.0 by=450.0 LineWidth 2 Circle bx-r,by-r,bx+r,by+r Line 110,450,bx-r,by+r gosub DrawRobot repeat ReadMouse x,y,b until b=1 repeat restorescr ReadMouse bx,by,b if bx<5 then bx=5 if by>590 then by=590 if y<450 then y=450 Line 90,450,bx-r,by Circle bx-r,by-r-5,bx+r,by+r-5 Line 110,450,bx-r,by linewidth 3 //circle rx-20,ry-20,rx+20,ry+20,blue,red until b=0 hv=(100-bx)/6.0 // horz vel vv=(450-by)/6.0 // vert vel restorescr bx=100 by=450 Circle bx-r,by-r,bx+r,by+r ClearScr print print " A line at the bottom of the screen shows where the robot predicts" print " the ball to land. This prediction will improve over time a the" print " Fudge Factor is improved based on past results. The current value" print " of the Factor is: " print " (Notice how the robot moves to the predicted spot" print " even though the ball's movements are random.)" SaveScr
return MoveBall: restorescr // alter the ball's vertical velocity by the acceleration of gravity // to create a realistic ball flight vv=vv+g // calculate new ball position bx=bx+hv by=by+vv if by>550 then by=550 // limit ball's movement downward // and make it bounce of the end walls if bx>799 bx=799 hv=-hv HitWall=1 endif if bx<0 bx=0 hv=-hv HitWall=1 endif // now draw the ball at its new position Circle bx-r,by-r,bx+r,by+r
return MoveRobot: // predict x-position where ball will land px = bx+c*hv*(550-by) // save this value when the ball starts to decend if vv>0 and vv<15 then predicted=px // this saved value will be used when the ball lands to make // corrections to the fudge factor line px,585,px,600 // show where the ball is expected to land // now calculate a robot velocity to move toward ball lastrv = abs(rv) rv = (px-rx) // distance from the expected ball landing (gives direction) //now limit the robot's maximum speed to 15 if rv>15 then rv = 15 if rv<-15 then rv = -15 // and move the robot rx += rv if rx>780 then rx=780 if rx<20 then rx=20 gosub DrawRobot // and show current Fudge Factor on screen xyString 270,68,c;"" flip // redraws screen without flicker if FLIP is ON (see HELP)
return DrawRobot: // draw the robot at the current rx,ry position rL=rx-20 rR=rx+20 linewidth 2 circle rL-20,ry-6,rR+20,ry+6,Black,blue circle rL-10,ry-10,rL+10,ry+10,Black,red // draw wheel // then a line on the wheel to make it look like it turns wa=DtoR(2*3.14*rx/3.6) // wheel angle in radians Line rL,ry,rL-6*cos(wa),ry-6*sin(wa),3,white // again for the right wheel circle rR-10,ry-10,rR+10,ry+10,Black,red Line rR,ry,rR-6*cos(wa),ry-6*sin(wa),3,white line rx,ry-6,rx,ry-20,5,Black line rx-20,ry-20,rx+20,ry-20,5,Black return