Talk:Robots
From WikiManual
- this is version 2.4.A ...
- modified by Eric in a couple of places on mr 19th.
- these 'fixed' a console bug and the DNA activation tables.
- this version of Robots.bas may be downloaded from the DB forum here:
- Robot.bas 19Mar06
- placed here for the time being until i can format
- it and make a separate page for 2.4.A Robot.bas Griztalk 13:19, 19 Mar 2006 (MST)
Attribute VB_Name = "Robots" Option Explicit ' ' robot system locations constants ' Public Const dirup As Integer = 1 Public Const dirdn As Integer = 2 Public Const dirdx As Integer = 3 Public Const dirsx As Integer = 4 Public Const aimdx As Integer = 5 Public Const aimsx As Integer = 6 Public Const shoot As Integer = 7 Public Const shootval As Integer = 8 Public Const robage As Integer = 9 Public Const masssys As Integer = 10 Public Const maxvelsys As Integer = 11 Public Const timersys As Integer = 12 Public Const AimSys As Integer = 18 Public Const SetAim As Integer = 19 Public Const bodgain As Integer = 194 Public Const bodloss As Integer = 195 Public Const velscalar As Integer = 196 Public Const velsx As Integer = 197 Public Const veldx As Integer = 198 Public Const veldn As Integer = 199 Public Const velup As Integer = 200 Public Const vel As Integer = 200 Public Const hit As Integer = 201 Public Const shflav As Integer = 202 Public Const pain As Integer = 203 Public Const pleas As Integer = 204 Public Const hitup As Integer = 205 Public Const hitdn As Integer = 206 Public Const hitdx As Integer = 207 Public Const hitsx As Integer = 208 Public Const shup As Integer = 210 Public Const shdn As Integer = 211 Public Const shdx As Integer = 212 Public Const shsx As Integer = 213 Public Const Fixed As Integer = 216 Public Const Kills As Integer = 220 Public Const Repro As Integer = 300 Public Const mrepro As Integer = 301 Public Const sexrepro As Integer = 302 Public Const energy As Integer = 310 Public Const BODY As Integer = 311 Public Const fdbody As Integer = 312 Public Const strbody As Integer = 313 Public Const setboy As Integer = 314 Public Const rdboy As Integer = 315 Public Const mtie As Integer = 330 Public Const stifftie As Integer = 331 Public Const mkvirus As Integer = 335 Public Const DnaLenSys As Integer = 336 Public Const Vtimer As Integer = 337 Public Const VshootSys As Integer = 338 Public Const GenesSys As Integer = 339 Public Const DelgeneSys As Integer = 340 Public Const thisgene As Integer = 341 Public Const LandM As Integer = 400 Public Const trefbody As Integer = 437 Public Const trefxpos As Integer = 438 Public Const trefypos As Integer = 439 Public Const trefvelmysx As Integer = 440 Public Const trefvelmydx As Integer = 441 Public Const trefvelmydn As Integer = 442 Public Const trefvelmyup As Integer = 443 Public Const trefvelscalar As Integer = 444 Public Const trefvelyoursx As Integer = 445 Public Const trefvelyourdx As Integer = 446 Public Const trefvelyourdn As Integer = 447 Public Const trefvelyourup As Integer = 448 Public Const trefshell As Integer = 449 Public Const tieport1 As Integer = 450 Public Const tieloc As Integer = 452 Public Const tieval As Integer = 453 Public Const tienum As Integer = 455 Public Const trefnrg As Integer = 456 Public Const readtiesys As Integer = 471 Public Const EyeStart As Integer = 500 Public Const EyeEnd As Integer = 510 Public Const refmulti = 686 Public Const refshell = 687 Public Const refbody = 688 Public Const refxpos = 689 Public Const refypos = 690 Public Const refvelscalar As Integer = 695 Public Const refvelsx As Integer = 696 Public Const refveldx As Integer = 697 Public Const refveldn As Integer = 698 Public Const refvelup As Integer = 699 Public Const occurrstart As Integer = 700 Public Const out1 As Integer = 800 Public Const out2 As Integer = 801 Public Const out3 As Integer = 802 Public Const out4 As Integer = 803 Public Const out5 As Integer = 804 Public Const in1 As Integer = 810 Public Const in2 As Integer = 811 Public Const in3 As Integer = 812 Public Const in4 As Integer = 813 Public Const in5 As Integer = 814 Public Const poison As Integer = 827 Public Const backshot As Integer = 900 Public Const aimshoot As Integer = 901 ' robot structure Private Type robot Exist As Boolean ' the robot exists? radius As Single Shape As Integer ' shape of the robot, how many sides Veg As Boolean ' is it a vegetable? Wall As Boolean ' is it a wall? Corpse As Boolean Fixed As Boolean ' is it blocked? View As Boolean ' has this bot ever tried to see? NewMove As Boolean ' is the bot using the new physics paradigms? ' physics pos As vector BucketPos As vector vel As vector ImpulseInd As vector ' independant forces vector ImpulseRes As vector ' Resistive forces vector ImpulseStatic As Single ' static force scalar (always opposes current forces) AddedMass As Single 'From fluid displacement aim As Single ' aim angle aimvector As vector ' the unit vector for aim oaim As Single ' old aim angle ma As Single ' angular momentum mt As Single ' torch Ties(10) As tie ' array of ties order As Integer 'order in the roborder array occurr(20) As Integer ' array with the ref* values nrg As Single ' energy onrg As Single ' old energy BODY As Single ' Body points. A corpse still has a body after all obody As Single ' old body points, for use with pain pleas versions for body vbody As Single ' Virtual Body used to calculate body functions of MBs mass As Single ' mass of robot Shell As Single ' Hard shell. protection from shots 1-100 reduces each cycle Slime As Single ' slime layer. protection from ties 1-100 reduces each cycle Waste As Single ' waste buildup in a robot. Too much and he dies. some can be removed by various methods Pwaste As Single ' Permanent waste. cannot be removed. Builds up as waste is removed. poison As Single ' How poisonous is robot venom As Single ' How venomous is robot Paralyzed As Boolean ' true when robot is paralyzed Paracount As Single ' countdown until paralyzed robot is free to move again Numties As Single ' the number of ties attached to a robot Multibot As Boolean ' Is robot part of a multi-bot Poisoned As Boolean ' Is robot poisoned and confused Poisoncount As Single ' Countdown till poison is out of his system Bouyancy As Single ' Does robot float or sink DecayTimer As Integer ' controls decay cycle Kills As Long ' How many other robots has it killed? Might not work properly Dead As Boolean ' Allows program to define a robot as dead after a certain operation Ploc As Integer ' Location for custom poison to strike Vloc As Integer ' Location for custom venom to strike Vval As Integer ' Value to insert into venom location Vtimer As Integer ' Count down timer to produce a virus vars(50) As var '| vnum As Integer '| about private variables maxusedvars As Integer '| usedvars(1000) As Integer '| used memory cells ' virtual machine mem(1000) As Integer ' memory array DNA() As block ' program array lastopp As Long ' last robot in eye5 AbsNum As Long ' absolute robot number 'Mutation related Mutables As mutationprobs PointMutCycle As Long ' Next cycle to point mutate (expressed in cycles since birth. ie: age) PointMutBP As Long ' the base pair to mutate condnum As Integer ' number of conditions (used for cost calculations) console As Consoleform ' console object associated to the robot ' informative SonNumber As Integer ' number of sons Mutations As Integer ' total mutations LastMut As Integer ' last mutations parent As Long ' parent absolute number age As Long ' age in cycles BirthCycle As Long ' birth cycle genenum As Integer ' genes number generation As Integer ' generation LastOwner As String ' last internet owner's name fname As String ' species name DnaLen As Integer ' dna length LastMutDetail As String ' description of last mutations ' aspetto Skin(13) As Integer ' skin definition OSkin(13) As Integer ' Old skin definition color As Long ' colour highlight As Boolean ' is it highlighted? virusshot As Integer ' the viral shot being stored End Type Public Badwastelevel As Integer Public Const RobSize As Integer = 120 ' rob diameter Public Const half As Integer = 60 ' and so on... Public Const CubicTwipPerBody As Long = 905 'seems like a random number, I know. 'It's cube root of volume * some constants to give 'radius of 60 for a bot of 1000 body Public Const RobArrayMax As Integer = 5000 'robot array must be an array for swift retrieval times. Public rob(RobArrayMax) As robot ' array of robots Public rep(RobArrayMax) As Integer ' array for pointing to robots attempting reproduction Dim rp As Integer Public kil(RobArrayMax) As Integer ' array of robots to kill Dim kl As Integer Public MaxRobs As Integer ' max used robots array index Public robfocus As Integer ' the robot which has the focus (selected) Public TotalRobots As Integer ' total robots in the sim Public MaxAbsNum As Long ' robots born (used to assign unique code) Public MaxMem As Integer ' EricL March 15, 2006 Public ga() As Boolean ' Used to store gene activation state for robot with the current focus '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' ' R O B O T S M A N A G E M E N T ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Public Function FindRadius(ByVal bodypoints As Single) As Single If bodypoints < 1 Then bodypoints = 1 FindRadius = (bodypoints * CubicTwipPerBody * 3 / 4 / PI) ^ (1 / 3) End Function ' returns an absolute acceleration, given up-down, ' left-right values and aim Public Function absx(aim As Single, ByVal up As Integer, ByVal dn As Integer, ByVal sx As Integer, ByVal dx As Integer) As Integer On Error Resume Next up = up - dn sx = sx - dx absx = Cos(aim) * up + Sin(aim) * sx End Function Public Function absy(aim As Single, ByVal up As Integer, ByVal dn As Integer, ByVal sx As Integer, ByVal dx As Integer) As Integer On Error Resume Next up = up - dn sx = sx - dx absy = -Sin(aim) * up + Cos(aim) * sx End Function Private Function SetAimFunc(t As Integer) As Single 'ByVal aim As Single, ByVal sx As Long, ByVal dx As Long, Optional ByVal setittothis As Single = 32000) As Single With rob(t) If .mem(SetAim) = Round(.aim * 200, 0) Then SetAimFunc = (.aim * 200 + .mem(aimsx) - .mem(aimdx)) Else SetAimFunc = .mem(SetAim) End If SetAimFunc = SetAimFunc Mod (1256) If SetAimFunc < 0 Then SetAimFunc = SetAimFunc + 1256 SetAimFunc = SetAimFunc / 200 .aim = SetAimFunc .aimvector = VectorSet(Cos(.aim), Sin(.aim)) .mem(aimsx) = 0 .mem(aimdx) = 0 .mem(AimSys) = .aim * 200 .mem(SetAim) = .mem(AimSys) End With End Function ' updates positions, transforming calculated accelerations ' in velocities, and velocities in new positions Public Sub UpdatePosition(ByVal n As Integer) Dim t As Integer Dim vt As Single With rob(n) .mass = (.BODY / 1000) + (.Shell / 200) 'set value for mass If .mass + .AddedMass < 0.25 Then .mass = 0.25 - .AddedMass ' a fudge since Euler approximation can't handle it when mass -> 0 If Not .Fixed Then ' speed normalization .vel = VectorAdd(.vel, VectorScalar(.ImpulseInd, 1 / (.mass + .AddedMass))) .ImpulseInd = VectorSet(0, 0) .ImpulseRes = .ImpulseInd .ImpulseStatic = 0 vt = VectorMagnitudeSquare(.vel) If vt > SimOpts.MaxVelocity * SimOpts.MaxVelocity Then .vel = VectorScalar(VectorUnit(.vel), SimOpts.MaxVelocity) vt = SimOpts.MaxVelocity * SimOpts.MaxVelocity End If .pos = VectorAdd(.pos, .vel) Else .vel = VectorSet(0, 0) End If If SimOpts.ZeroMomentum = True Then .vel = VectorSet(0, 0) 'UpdateBotBucket n ' if it's time, sends a robot on the net If IntOpts.Active And IntOpts.LastUploadCycle = 0 Then VerificaPosizione n .mem(dirup) = 0 .mem(dirdn) = 0 .mem(dirdx) = 0 .mem(dirsx) = 0 .mem(velscalar) = iceil(Sqr(vt)) .mem(vel) = iceil(Cos(.aim) * .vel.x + Sin(.aim) * .vel.y * -1) .mem(veldn) = .mem(vel) * -1 .mem(veldx) = iceil(Sin(.aim) * .vel.x + Cos(.aim) * .vel.y) .mem(velsx) = .mem(veldx) * -1 .mem(masssys) = .mass .mem(maxvelsys) = SimOpts.MaxVelocity End With End Sub Private Function iceil(x As Single) As Integer If (Abs(x) > 32000) Then x = Sgn(x) * 32000 iceil = x End Function Private Sub makeshell(n) Dim oldshell As Integer Dim cost As Single With rob(n) oldshell = .Shell .Shell = .Shell + .mem(822) If .Shell > 32000 Then .Shell = 32000 If .Shell < 0 Then .Shell = 0 cost = (.Shell - oldshell) * SimOpts.Costs(SHELLCOST) If cost < 0 Then cost = 0 .nrg = .nrg - cost / (.Numties + 1) .Waste = .Waste + cost / 10 .mem(822) = 0 .mem(823) = .Shell End With End Sub Private Sub makeslime(n) Dim oldslime As Integer Dim cost As Single With rob(n) oldslime = .Slime .Slime = .Slime + .mem(820) If .Slime > 32000 Then .Slime = 32000 If .Slime < 0 Then .Slime = 0 cost = (.Slime - oldslime) * SimOpts.Costs(SLIMECOST) If cost < 0 Then cost = 0 .nrg = .nrg - cost / (.Numties + 1) 'lower cost for multibot .Waste = .Waste + cost / 10 .mem(820) = 0 .mem(821) = .Slime End With End Sub Private Sub altzheimer(n As Integer) 'makes robots with high waste act in a bizarre fashion. Dim loc As Integer, val As Integer Dim loops As Integer Dim t As Integer loops = (rob(n).Pwaste + rob(n).Waste - Badwastelevel) / 4 With rob(n) For t = 1 To loops loc = fRnd(1, 1000) val = fRnd(-32000, 32000) .mem(loc) = val Next t End With End Sub Private Sub Upkeep(n As Integer) With rob(n) 'BODY UPKEEP .nrg = .nrg - .BODY * SimOpts.Costs(BODYUPKEEP) 'DNA upkeep cost .nrg = .nrg - (.DnaLen - 1) * SimOpts.Costs(BPCYCCOST) 'degrade slime .Slime = .Slime * 0.98 End With End Sub Public Function genelength(n As Integer, p As Integer) 'measures the length of gene p in robot n Dim k As Long, genes As Long Dim i As Integer Dim f As Integer k = 1 With rob(n) While True If .DNA(k).tipo = 10 And .DNA(k).value = 1 Then Exit Function If .DNA(k).tipo = 9 And .DNA(k).value <> 1 And .DNA(k).value <> 4 Then genes = genes + 1 End If If genes = p Then f = NextStop(rob(n).DNA, k + 1) genelength = f - k Exit Function End If k = k + 1 Wend End With End Function Private Sub BotDNAManipulation(n As Integer) With rob(n) 'count down If .Vtimer > 1 Then .Vtimer = .Vtimer - 1 End If .mem(Vtimer) = .Vtimer 'Viruses If .mem(mkvirus) > 0 And .Vtimer = 0 Then Dim shot As Integer 'make the virus If MakeVirus(n, .mem(mkvirus)) Then .Vtimer = genelength(n, .mem(mkvirus)) * 2 End If End If 'shoot it! If .mem(VshootSys) > 0 And .Vtimer = 1 Then Vshoot n, .virusshot .mem(VshootSys) = 0 .mem(Vtimer) = 0 .mem(mkvirus) = 0 .Vtimer = 0 End If 'Other stuff .mem(DnaLenSys) = .DnaLen .mem(GenesSys) = CountGenes(.DNA) If .mem(DelgeneSys) > 0 Then delgene n, .mem(DelgeneSys) .mem(DelgeneSys) = 0 End If End With End Sub Private Sub Poisons(n As Integer) With rob(n) 'Paralyzed means venomized If .Paralyzed Then .mem(.Vloc) = .Vval If .Paralyzed Then .Paracount = .Paracount - 1 .mem(837) = .Paracount If .Paracount < 1 Then .Paralyzed = False: .Vloc = 0: .Vval = 0 End If If .Poisoned Then .mem(.Ploc) = 0 If .Poisoned Then .Poisoncount = .Poisoncount - 1 .mem(838) = .Poisoncount If .Poisoncount < 1 Then .Poisoned = False: .Ploc = 0: .Poisoncount = 0 End If End With End Sub Private Sub UpdateCounters(n As Integer) With rob(n) TotalRobots = TotalRobots + 1 If .Veg Then totvegs = totvegs + 1 ElseIf .Corpse Then totcorpse = totcorpse + 1 Decay n ElseIf .Wall Then Else totnvegs = totnvegs + 1 End If End With End Sub Private Sub MakeStuff(n As Integer) With rob(n) If .mem(824) <> 0 Then storevenom n If .mem(826) <> 0 Then storepoison n If .mem(822) <> 0 Then makeshell n If .mem(820) <> 0 Then makeslime n End With End Sub Private Sub HandleWaste(n As Integer) With rob(n) If .Waste > 0 And .Veg Then feedveg2 n If Badwastelevel = 0 Then Badwastelevel = 400 If Badwastelevel <> -1 And .Pwaste + .Waste > Badwastelevel Then altzheimer n If .Waste > 32000 Then defacate n If .Pwaste > 32000 Then .Pwaste = 32000 If .Waste < 0 Then .Waste = 0 .mem(828) = .Waste .mem(829) = .Pwaste End With End Sub Private Sub Ageing(n As Integer) With rob(n) 'aging .age = .age + 1: If .age > 32000 Then .age = 32000 .mem(robage) = .age 'line added to copy robots age into a memory location .mem(timersys) = .mem(timersys) + 1 'update epigenetic timer If .mem(timersys) > 32000 Then .mem(timersys) = -32000 End With End Sub Private Sub Shooting(n As Integer) 'shooting If rob(n).mem(shoot) Then robshoot n rob(n).mem(shoot) = 0 End Sub Private Sub ManageBody(n As Integer) With rob(n) 'body management .obody = .BODY 'replaces routine above If .mem(strbody) > 0 Then storebody n If .mem(fdbody) > 0 Then feedbody n If .Wall Then .BODY = 1 If .BODY > 32000 Then .BODY = 32000 .mem(BODY) = .BODY .radius = FindRadius(.BODY) End With End Sub Private Sub Shock(n As Integer) With rob(n) 'shock code: 'later make the shock threshold based on body and age If Not .Veg And .nrg > 3000 Then Dim temp As Double temp = .onrg - .nrg If temp > (.onrg / 2) Then .nrg = 0 .BODY = .BODY + (.nrg / 10) If .BODY > 32000 Then .BODY = 32000 .radius = FindRadius(.BODY) End If End If End With End Sub Private Sub ManageDeath(n As Integer) With rob(n) If .nrg < 1 And Not SimOpts.CorpseEnabled Then .Dead = True End If If SimOpts.CorpseEnabled Then If Not .Corpse Then If .nrg < 1 And .age > 1 Then .Corpse = True .fname = "Corpse" delallties n Erase .occurr .color = vbWhite .Veg = False .Fixed = False If SimOpts.Bouyancy Then .Bouyancy = -1.5 End If End If If .Corpse = True Then .nrg = 0 End If Else If .nrg < 1 Then .Dead = True End If If .BODY < 1 Then .Dead = True End If If .Dead Then kil(kl) = n kl = kl + 1 End If End With End Sub Private Sub ManageBouyancy(n As Integer) With rob(n) 'Bouyancy 'obsolete, so how to fix? If .mem(setboy) > 2000 Or .mem(setboy) < -2000 Then .mem(setboy) = 2000 * Sgn(.mem(setboy)) If SimOpts.Bouyancy Then .Bouyancy = .mem(setboy) / 1000 Else .Bouyancy = 0 End If .mem(rdboy) = .Bouyancy * 1000 End With End Sub Private Sub ManageFixed(n As Integer) With rob(n) 'Fixed/ not fixed If .mem(216) > 0 Then .Fixed = True Else .Fixed = False End If End With End Sub Private Sub ManageReproduction(n As Integer) With rob(n) If .mem(Repro) > 0 Or .mem(mrepro) > 0 Then rep(rp) = n rp = rp + 1 End If If .mem(sexrepro) > 0 Then If .lastopp > 0 And rob(.lastopp).mem(sexrepro) > 0 Then rep(rp) = -n rep(rp + 1) = -.lastopp rp = rp + 2 End If End If End With End Sub Private Sub FireTies(n As Integer) With rob(n) If .mem(mtie) > 0 Then If .View = False Then BasicProximity n, True If .lastopp > 0 And Not SimOpts.DisableTies Then '2 robot lengths Dim lengthsquare As Long, maxlengthsquare As Long lengthsquare = VectorMagnitudeSquare(VectorSub(rob(.lastopp).pos, .pos)) maxlengthsquare = (CLng(RobSize) * CLng(RobSize) * CLng(4)) If lengthsquare <= maxlengthsquare Then 'maketie auto deletes existing ties for you maketie n, rob(n).lastopp, rob(n).radius + rob(rob(n).lastopp).radius + RobSize * 2, -20, rob(n).mem(mtie) End If End If .mem(mtie) = 0 End If End With End Sub 'The heart of the robots to simulation interfacing Public Sub UpdateBots() Dim t As Integer Dim k As Integer Dim c As Integer Dim z As Integer Dim q As Integer Dim ti As Single Dim x As Integer rp = 1 kl = 1 kil(1) = 0 rep(1) = 0 TotalEnergy = 0 totwalls = 0 totcorpse = 0 TotalRobots = 0 totnvegs = 0 totvegs = 0 If ContestMode Then F1count = F1count + 1 If F1count = SampFreq And Contests <= Maxrounds Then Countpop End If 'this loops if for pre update For t = 1 To MaxRobs If rob(t).Exist Then Upkeep t Poisons t EraseSenses t ManageFixed t NetForces t 'calculate forces on all robots tieportcom t 'transfer data through ties readtie t 'reads all of the tref variables from a given tie number UpdateCounters t End If Next t DoEvents For t = 1 To MaxRobs With rob(t) If .Exist Then Update_Ties t ' Carries out all tie routines SetAimFunc t 'Setup aiming BotDNAManipulation t UpdatePosition t 'updates robot's position End If End With Next t DoEvents For t = 1 To MaxRobs With rob(t) If .Exist Then If .nrg > 32000 Then .nrg = 32000 If .nrg < 0 Then .nrg = 0 If .poison > 32000 Then .poison = 32000 If .poison < 0 Then .poison = 0 If .venom > 32000 Then .venom = 32000 If .venom < 0 Then .venom = 0 If .Waste > 32000 Then .Waste = 32000 If .Waste < 0 Then .Waste = 0 End If End With Next t For t = 1 To MaxRobs With rob(t) If Not .Corpse And Not .Wall And .Exist Then Mutate t MakeStuff t HandleWaste t Ageing t Shooting t ManageBody t Shock t ManageBouyancy t ManageReproduction t WriteSenses t FireTies t End If If .Exist Then ManageDeath t End With Next t DoEvents ReproduceAndKill 'restart If totnvegs = 0 And RestartMode Then totnvegs = 1 Contests = Contests + 1 ReStarts = ReStarts + 1 Form1.StartSimul End If End Sub Private Sub ReproduceAndKill() Dim t As Integer t = 1 While t < rp If rep(t) > 0 Then Dim temp As Long temp = rob(rep(t)).mem(mrepro) temp = temp + rob(rep(t)).mem(Repro) If temp > 32000 Then temp = 32000 If temp < -32000 Then temp = -32000 Reproduce rep(t), temp rob(rep(t)).mem(Repro) = 0 rob(rep(t)).mem(mrepro) = 0 ElseIf rep(t) < 0 Then 'SexReproduce -rep(t), -rep(t + 1) rob(-rep(t)).mem(sexrepro) = 0 rob(-rep(t + 1)).mem(sexrepro) = 0 t = t + 1 End If t = t + 1 Wend t = 1 'kill robots While t < kl KillRobot kil(t) t = t + 1 Wend End Sub Private Sub storebody(t As Integer) If rob(t).mem(313) > 100 Then rob(t).mem(313) = 100 rob(t).nrg = rob(t).nrg - rob(t).mem(313) rob(t).BODY = rob(t).BODY + rob(t).mem(313) / 10 If rob(t).BODY > 32000 Then rob(t).BODY = 32000 rob(t).radius = FindRadius(rob(t).BODY) rob(t).mem(313) = 0 End Sub Private Sub feedbody(t As Integer) If rob(t).mem(fdbody) > 100 Then rob(t).mem(fdbody) = 100 rob(t).nrg = rob(t).nrg + rob(t).mem(fdbody) rob(t).BODY = rob(t).BODY - rob(t).mem(fdbody) / 10 If rob(t).nrg > 32000 Then rob(t).nrg = 32000 rob(t).radius = FindRadius(rob(t).BODY) rob(t).mem(fdbody) = 0 End Sub ' here we catch the attempt of a robot to shoot, ' and actually build the shot Private Sub robshoot(n As Integer) Dim shtype As Integer Dim value As Long Dim multiplier As Single Dim cost As Long Dim rngmultiplier As Single Dim valmode As Boolean shtype = rob(n).mem(shoot) value = rob(n).mem(shootval) If value < 0 Then multiplier = 1 rngmultiplier = -value ElseIf value > 0 Then multiplier = value rngmultiplier = 1 valmode = True Else multiplier = 1 rngmultiplier = 1 End If If rngmultiplier > 4 Then cost = rngmultiplier * SimOpts.Costs(SHOTCOST) rngmultiplier = Log(rngmultiplier / 2) / Log(2) ElseIf valmode = False Then rngmultiplier = 1 cost = (SimOpts.Costs(SHOTCOST) / (rob(n).Numties + 1)) End If If multiplier > 4 Then cost = multiplier * SimOpts.Costs(SHOTCOST) multiplier = Log(multiplier / 2) / Log(2) ElseIf valmode = True Then multiplier = 1 cost = (SimOpts.Costs(SHOTCOST) / (rob(n).Numties + 1)) End If If cost > rob(n).nrg And cost > 2 And rob(n).nrg > 2 And valmode Then cost = rob(n).nrg multiplier = Log(rob(n).nrg / SimOpts.Costs(SHOTCOST)) / Log(2) End If If cost > rob(n).nrg And cost > 2 And rob(n).nrg > 2 And Not valmode Then cost = rob(n).nrg rngmultiplier = Log(rob(n).nrg / SimOpts.Costs(SHOTCOST)) / Log(2) End If '''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''' Select Case shtype Case Is >= -1 shtype = shtype Mod MaxMem If shtype = -1 Then If rob(n).Multibot Then value = 20 + (rob(n).BODY / 5) * (rob(n).Numties + 1) Else value = 20 + (rob(n).BODY / 5) End If value = value * multiplier rob(n).nrg = rob(n).nrg - cost Else rngmultiplier = 1 End If newshot n, shtype, value, rngmultiplier Case -2 value = Abs(value) If rob(n).nrg < value Then value = rob(n).nrg If value = 0 Then value = rob(n).nrg / 100 'default energy shot. Very small. rob(n).nrg = rob(n).nrg - value - SimOpts.Costs(SHOTCOST) / (rob(n).Numties + 1) newshot n, shtype, value, 1 Case -3 'shoot venom value = Abs(value) If value > rob(n).venom Then value = rob(n).venom If value = 0 Then value = rob(n).venom / 20 'default venom shot. Not too small. rob(n).venom = rob(n).venom - value rob(n).mem(825) = rob(n).venom rob(n).nrg = rob(n).nrg - SimOpts.Costs(SHOTCOST) / (rob(n).Numties + 1) newshot n, shtype, value, 1 Case -4 'shoot waste value = Abs(value) If value > rob(n).Waste Then value = rob(n).Waste rob(n).Waste = rob(n).Waste - value If value < 0 Then value = rob(n).Waste / 10 'default waste shot. rob(n).Pwaste = rob(n).Pwaste + value / 100 rob(n).nrg = rob(n).nrg - SimOpts.Costs(SHOTCOST) / (rob(n).Numties + 1) newshot n, shtype, value, 1 ' no -5 shot here as poison can only be shot in response to an attack Case -6 'shoot body If rob(n).Multibot Then value = 10 + (rob(n).BODY / 2) * (rob(n).Numties + 1) Else value = 10 + Abs(rob(n).BODY) / 2 End If rob(n).nrg = rob(n).nrg - cost value = value * multiplier newshot n, shtype, value, rngmultiplier End Select rob(n).mem(shoot) = 0 rob(n).mem(shootval) = 0 End Sub Public Sub shareslime(t As Integer, k As Integer) 'robot shares slime with others in the same multibot structure Dim totslime As Integer With rob(t) If .mem(833) > 99 Then .mem(833) = 99 If .mem(833) < 0 Then .mem(833) = 0 totslime = .Slime + rob(.Ties(k).pnt).Slime If totslime * (.mem(833) / 100) < 32000 Then .Slime = totslime * (.mem(833) / 100) Else .Slime = 32000 End If If totslime * ((100 - .mem(833)) / 100) < 32000 Then rob(.Ties(k).pnt).Slime = totslime * ((100 - .mem(833)) / 100) Else rob(.Ties(k).pnt).Slime = 32000 End If End With End Sub Public Sub sharewaste(t As Integer, k As Integer) Dim totwaste As Long With rob(t) If .mem(831) > 99 Then .mem(831) = 99 If .mem(831) < 0 Then .mem(831) = 0 totwaste = .Waste + rob(.Ties(k).pnt).Waste If totwaste * (.mem(831) / 100) < 32000 Then .Waste = totwaste * (.mem(831) / 100) Else .Waste = 32000 End If If totwaste * ((100 - .mem(831)) / 100) < 32000 Then rob(.Ties(k).pnt).Waste = totwaste * ((100 - .mem(831)) / 100) Else rob(.Ties(k).pnt).Waste = 32000 End If End With End Sub Public Sub shareshell(t As Integer, k As Integer) Dim totshell As Long With rob(t) If .mem(832) > 99 Then .mem(832) = 99 If .mem(832) < 0 Then .mem(832) = 0 totshell = .Shell + rob(.Ties(k).pnt).Shell If totshell * ((100 - .mem(832)) / 100) < 32000 Then rob(.Ties(k).pnt).Shell = totshell * ((100 - .mem(832)) / 100) Else rob(.Ties(k).pnt).Shell = 32000 End If If totshell * (.mem(832) / 100) < 32000 Then .Shell = totshell * (.mem(832) / 100) Else .Shell = 32000 End If End With End Sub Public Sub sharenrg(t As Integer, k As Integer) Dim totnrg As Long With rob(t) If .mem(830) > 99 Then .mem(830) = 99 If .mem(830) < 0 Then .mem(830) = 0 totnrg = .nrg + rob(.Ties(k).pnt).nrg If totnrg * ((100 - .mem(830)) / 100) < 32000 Then rob(.Ties(k).pnt).nrg = totnrg * ((100 - .mem(830)) / 100) Else rob(.Ties(k).pnt).nrg = 32000 End If If totnrg * (.mem(830) / 100) < 32000 Then .nrg = totnrg * (.mem(830) / 100) Else .nrg = 32000 End If End With End Sub 'Robot n converts some of his energy to venom Public Sub storevenom(n As Integer) Dim cost As Single With rob(n) cost = .mem(824) * SimOpts.Costs(VENOMCOST) If cost > .nrg And cost > 0 Then .mem(824) = (.nrg / 2) / SimOpts.Costs(VENOMCOST) cost = .mem(824) * SimOpts.Costs(VENOMCOST) .venom = .venom + .mem(824) If .mem(824) > 0 Then .nrg = .nrg - cost .Waste = .Waste + .mem(824) / 100 If .venom > 32000 Then .venom = 32000 Else If .venom < 0 Then .venom = 0 'this line below can potentially make waste just disappear! Fix it! .Waste = .Waste - .mem(824) / 100 End If .mem(825) = .venom .mem(824) = 0 End With End Sub ' Robot n converts some of his energy to poison Public Sub storepoison(n As Integer) Dim cost As Single With rob(n) cost = .mem(826) * SimOpts.Costs(POISONCOST) If cost > .nrg And cost > 0 Then .mem(826) = (.nrg / 2) / SimOpts.Costs(VENOMCOST) cost = .mem(826) * SimOpts.Costs(POISONCOST) .poison = .poison + .mem(826) If .mem(826) > 0 Then .nrg = .nrg - .mem(826) .Waste = .Waste + .mem(826) / 100 If .poison > 32000 Then .poison = 32000 Else If .poison < 0 Then .poison = 0 'this line can potentially just make waste vanish! Fix it! .Waste = .Waste - .mem(826) / 100 End If .mem(827) = .poison .mem(826) = 0 End With End Sub ' Reproduction ' makes some tests regarding the available space for ' spawning a new robot, the position (not off the field, nor ' on the internet d/l gate), the energy of the parent, ' then finally copies the dna and most of the two data ' structures (with some modif. - for example generation), ' sends the newborn rob to the mutation division, ' reanalizes the resulting dna (usedvars, condlist, and so on) ' ties parent and son, and the miracle of birth is accomplished Public Sub Reproduce(n As Integer, ByVal per As Integer) Dim sondist As Long Dim nuovo As Integer Dim nnrg As Long, nwaste As Long, npwaste As Long Dim nbody As Integer Dim nx As Long Dim ny As Long Dim t As Integer Dim tests As Boolean tests = False If n = -1 Then n = robfocus If rob(n).BODY <= 2 Then Exit Sub 'bot is too small to reproduce If rob(n).Veg = True And totvegs > SimOpts.MaxPopulation Then 't = Random(0, totvegs - SimOpts.MaxPopulation) 'totvegs = totvegs + 1 'If t > 0 Then Exit Sub 'attempt to stop veg overpopulation but will it work? ElseIf rob(n).Veg = True Then 'totvegs = totvegs + 1 End If If per < 1 Then per = 1 If per > 99 Then per = 99 sondist = FindRadius(rob(n).BODY * (per / 100)) + FindRadius(rob(n).BODY * ((100 - per) / 100)) nnrg = (rob(n).nrg / 100) * per nbody = (rob(n).BODY / 100) * per 'rob(n).nrg = rob(n).nrg - DNALength(n) * 3 If rob(n).nrg > 0 Then nx = rob(n).pos.x + absx(rob(n).aim, sondist, 0, 0, 0) ny = rob(n).pos.y + absy(rob(n).aim, sondist, 0, 0, 0) tests = tests Or simplecoll(nx, ny, n) tests = tests Or (rob(n).Fixed And IsInSpawnArea(nx, ny)) If Not tests Then nuovo = posto() SimOpts.TotBorn = SimOpts.TotBorn + 1 ReDim rob(nuovo).DNA(UBound(rob(n).DNA)) For t = 1 To UBound(rob(nuovo).DNA) rob(nuovo).DNA(t) = rob(n).DNA(t) Next t rob(nuovo).DnaLen = rob(n).DnaLen rob(nuovo).Mutables = rob(n).Mutables rob(nuovo).Mutations = rob(n).Mutations rob(nuovo).LastMut = 0 rob(nuovo).LastMutDetail = rob(n).LastMutDetail For t = 1 To rob(n).maxusedvars rob(nuovo).usedvars(t) = rob(n).usedvars(t) Next t For t = 0 To 12 rob(nuovo).Skin(t) = rob(n).Skin(t) Next t rob(nuovo).maxusedvars = rob(n).maxusedvars Erase rob(nuovo).mem Erase rob(nuovo).Ties rob(nuovo).pos.x = rob(n).pos.x + absx(rob(n).aim, sondist, 0, 0, 0) rob(nuovo).pos.y = rob(n).pos.y + absy(rob(n).aim, sondist, 0, 0, 0) 'UpdateBotBucket nuovo rob(nuovo).vel = rob(n).vel rob(nuovo).color = rob(n).color rob(nuovo).aim = rob(n).aim + PI If rob(nuovo).aim > 6.28 Then rob(nuovo).aim = rob(nuovo).aim - 2 * PI rob(nuovo).aimvector = VectorSet(Cos(rob(nuovo).aim), Sin(rob(nuovo).aim)) rob(nuovo).mem(SetAim) = rob(nuovo).aim * 200 rob(nuovo).mem(468) = 32000 rob(nuovo).mem(480) = 32000 rob(nuovo).mem(481) = 32000 rob(nuovo).mem(482) = 32000 rob(nuovo).mem(483) = 32000 rob(nuovo).Exist = True rob(nuovo).Corpse = False rob(nuovo).Dead = False rob(nuovo).NewMove = rob(n).NewMove rob(nuovo).generation = rob(n).generation + 1 rob(nuovo).BirthCycle = SimOpts.TotRunCycle rob(nuovo).vnum = 1 nnrg = (rob(n).nrg / 100) * per nwaste = rob(n).Waste / 100 * per npwaste = rob(n).Pwaste / 100 * per rob(n).nrg = rob(n).nrg - nnrg rob(n).Waste = rob(n).Waste - nwaste rob(n).Pwaste = rob(n).Pwaste - npwaste rob(n).BODY = rob(n).BODY - nbody rob(n).radius = FindRadius(rob(n).BODY) rob(nuovo).BODY = nbody rob(nuovo).radius = FindRadius(nbody) rob(nuovo).Waste = nwaste rob(nuovo).Pwaste = npwaste rob(n).mem(energy) = rob(n).nrg rob(n).mem(311) = rob(n).BODY rob(n).SonNumber = rob(n).SonNumber + 1 rob(nuovo).nrg = nnrg rob(nuovo).onrg = nnrg rob(nuovo).mem(energy) = nnrg rob(nuovo).Poisoned = False rob(nuovo).parent = rob(n).AbsNum rob(nuovo).fname = rob(n).fname rob(nuovo).LastOwner = rob(n).LastOwner rob(nuovo).Veg = rob(n).Veg rob(nuovo).Fixed = rob(n).Fixed If rob(nuovo).Fixed Then rob(nuovo).mem(Fixed) = 1 rob(nuovo).Shape = rob(n).Shape 'BucketsProximity n, 12 'BucketsProximity nuovo, 12 If rob(n).mem(mrepro) > 0 Then Dim temp As mutationprobs temp = rob(nuovo).Mutables For t = 0 To 20 rob(nuovo).Mutables.mutarray(t) = rob(nuovo).Mutables.mutarray(t) / 10 If rob(nuovo).Mutables.mutarray(t) = 0 Then rob(nuovo).Mutables.mutarray(t) = 1000 Next t Mutate nuovo, True rob(nuovo).Mutables = temp Else 'Mutate n, True 'mutate parent and child, note that these mutations are independant of each other. Mutate nuovo, True End If makeoccurrlist nuovo rob(nuovo).DnaLen = DnaLen(rob(nuovo).DNA()) maketie n, nuovo, sondist, 100, 0 'birth ties last 100 cycles rob(n).onrg = rob(n).nrg 'saves parent from dying from shock after giving birth rob(nuovo).mass = nbody / 1000 + rob(nuovo).Shell / 200 rob(nuovo).mem(timersys) = rob(n).mem(timersys) 'epigenetic timer End If End If End Sub ' hot hot: sex reproduction ' same as above, but: dna comes from two parents, is crossed-over, ' and the resulting dna is then mutated. Public Sub SexReproduce(robA As Integer, robB As Integer) Dim perA As Integer, perB As Integer Dim nrgA As Long, nrgB As Long Dim bodyA As Long, bodyB As Long Dim sondist As Long Dim nuovo As Integer Dim nnrg As Long Dim nbody As Long Dim nx As Long Dim ny As Long Dim t As Integer Dim tests As Boolean tests = False sondist = RobSize * 1.3 If Sqr((rob(robA).pos.x - rob(robB).pos.x) ^ 2 + (rob(robA).pos.y - rob(robB).pos.y) ^ 2) >= RobSize * 2 Then Exit Sub perA = rob(robA).mem(sexrepro) perB = rob(robB).mem(sexrepro) If perA < 1 Then perA = 1 If perA > 99 Then perA = 99 If perB < 1 Then perB = 1 If perB > 99 Then perB = 99 nrgA = (rob(robA).nrg / 100) * perA nrgB = (rob(robB).nrg / 100) * perB nnrg = nrgA + nrgB If nnrg > 32000 Then nnrg = 32000 nrgA = 32000 * (perA / 100) nrgB = 32000 * (perB / 100) End If bodyA = (rob(robA).BODY / 100) * perA bodyB = (rob(robB).BODY / 100) * perB nbody = bodyA + bodyB If nbody > 32000 Then nbody = 32000 bodyA = 32000 * (perA / 100) bodyB = 32000 * (perB / 100) End If rob(perA).nrg = rob(perA).nrg - rob(robA).DnaLen * 1.5 rob(perB).nrg = rob(perB).nrg - rob(robB).DnaLen * 1.5 If rob(perA).nrg > 0 And rob(perB).nrg > 0 Then nx = rob(perA).pos.x + absx(rob(perA).aim, sondist, 0, 0, 0) ny = rob(perA).pos.y + absy(rob(perA).aim, sondist, 0, 0, 0) 'tests = tests Or simplecoll(nx, ny, n) tests = tests Or (rob(robA).Fixed And IsInSpawnArea(nx, ny)) If Not tests Then nuovo = posto() SimOpts.TotBorn = SimOpts.TotBorn + 1 ReDim rob(nuovo).DNA(100) 'Reimplement below! 'DNA is redimed inside a sub function of CrossingOver 'CrossingOver rob(robA).DNA, rob(robB).DNA, rob(nuovo).DNA ScanUsedVars nuovo For t = 0 To 14 rob(nuovo).Mutables.mutarray(t) = (rob(robA).Mutables.mutarray(t) + rob(robB).Mutables.mutarray(t)) / 2 Next t If rob(robA).Mutables.Mutations Or rob(robB).Mutables.Mutations Then rob(nuovo).Mutables.Mutations = True Else rob(nuovo).Mutables.Mutations = False End If For t = 0 To 12 rob(nuovo).Skin(t) = (rob(robA).Skin(t) + rob(robB).Skin(t)) / 2 Next t Erase rob(nuovo).mem Erase rob(nuovo).Ties rob(nuovo).pos.x = rob(robA).pos.x + absx(rob(robA).aim, sondist, 0, 0, 0) rob(nuovo).pos.y = rob(robA).pos.y + absy(rob(robA).aim, sondist, 0, 0, 0) rob(nuovo).vel.x = rob(robA).vel.x rob(nuovo).vel.y = rob(robA).vel.y rob(nuovo).color = rob(robA).color rob(nuovo).aim = rob(robA).aim + PI If rob(nuovo).aim > 6.28 Then rob(nuovo).aim = rob(nuovo).aim - 2 * PI rob(nuovo).aimvector = VectorSet(Cos(rob(nuovo).aim), Sin(rob(nuovo).aim)) rob(nuovo).mem(SetAim) = rob(nuovo).aim * 200 rob(nuovo).mem(468) = 32000 rob(nuovo).mem(480) = 32000 rob(nuovo).mem(481) = 32000 rob(nuovo).mem(482) = 32000 rob(nuovo).mem(483) = 32000 rob(nuovo).Exist = True rob(nuovo).Dead = False rob(nuovo).generation = rob(robA).generation + 1 rob(nuovo).BirthCycle = SimOpts.TotRunCycle rob(nuovo).vnum = 1 rob(robA).nrg = rob(robA).nrg - nrgA rob(robB).nrg = rob(robB).nrg - nrgB rob(robA).mem(energy) = rob(robA).nrg rob(robB).mem(energy) = rob(robB).nrg rob(robA).BODY = rob(robA).BODY - bodyA rob(robA).radius = FindRadius(rob(robA).BODY) rob(robB).BODY = rob(robB).BODY - bodyB rob(robB).radius = FindRadius(rob(robB).BODY) rob(robA).mem(315) = rob(robA).BODY rob(robB).mem(315) = rob(robB).BODY rob(robA).SonNumber = rob(robA).SonNumber + 1 rob(robB).SonNumber = rob(robB).SonNumber + 1 rob(nuovo).nrg = nnrg rob(nuovo).BODY = nbody rob(nuovo).radius = FindRadius(rob(nuovo).BODY) rob(nuovo).Poisoned = False rob(nuovo).parent = rob(robA).AbsNum rob(nuovo).fname = rob(robA).fname rob(nuovo).LastOwner = rob(robA).LastOwner rob(nuovo).Veg = rob(robA).Veg rob(nuovo).NewMove = rob(robA).NewMove rob(nuovo).Fixed = rob(robA).Fixed If rob(nuovo).Fixed Then rob(nuovo).mem(216) = 1 rob(nuovo).Corpse = False rob(nuovo).Mutations = rob(robA).Mutations rob(nuovo).LastMutDetail = rob(robA).LastMutDetail rob(nuovo).Shape = rob(robA).Shape 'UpdateBotBucket nuovo 'BucketsProximity robA 'BucketsProximity robB 'BucketsProximity nuovo Mutate nuovo 'If Not CheckIntegrity(rob(nuovo).DNA) Then ' 'parents aren't suposed to be penalized, ' 'so they need to get their nrg and body back ' 'NOT YET IMPLEMENTED! ' rob(nuovo).nrg = 0 'End If makeoccurrlist nuovo rob(nuovo).DnaLen = DnaLen(rob(nuovo).DNA()) maketie robA, nuovo, RobSize * 1.3, 90, 0 maketie robB, nuovo, RobSize * 1.3, 90, 0 'to prevent shock rob(robA).onrg = rob(robA).nrg rob(robB).onrg = rob(robB).nrg rob(nuovo).mass = nbody / 1000 + rob(nuovo).Shell / 200 End If End If End Sub ' verifies rapidly if a field position is already occupied Public Function simplecoll(x As Long, y As Long, k As Integer) As Boolean Dim t As Integer Dim radius As Long simplecoll = False For t = 1 To MaxRobs If rob(t).Exist Then If Abs(rob(t).pos.x - x) < rob(t).radius + rob(k).radius And _ Abs(rob(t).pos.y - y) < rob(t).radius + rob(k).radius Then If k <> t Then simplecoll = True End If End If Next t If SimOpts.Dxsxconnected = False Then If x < rob(k).radius + smudgefactor Or x + rob(k).radius + smudgefactor > SimOpts.FieldWidth Then simplecoll = True End If If SimOpts.Updnconnected = False Then If y < rob(k).radius + smudgefactor Or y + rob(k).radius + smudgefactor > SimOpts.FieldHeight Then simplecoll = True End If End Function ' searches a free slot in the robots array, to store a new rob Public Function posto() As Integer Dim t As Integer t = 1 While rob(t).Exist And t <= MaxRobs And t < UBound(rob()) t = t + 1 Wend If t > MaxRobs Then MaxRobs = t If t = UBound(rob()) Then MaxRobs = MaxRobs - 1 t = t - 1 End If posto = t 'potential memory leak: I'm not sure if VB will catch and release the dereferenced memory or not Dim blank As robot rob(posto) = blank MaxAbsNum = MaxAbsNum + 1 rob(posto).AbsNum = MaxAbsNum End Function ' Kill Bill Public Sub KillRobot(n As Integer) If n = -1 Then n = robfocus If SimOpts.DBEnable Then If rob(n).Veg And SimOpts.DBExcludeVegs Then Else AddRecord n End If End If If n = MaxRobs Then Dim a As Integer Dim b As Integer For a = 0 To MaxRobs If rob(a).Exist = True Then b = a Next a MaxRobs = b 'b is now the last actual array element End If rob(n).Exist = False rob(n).Wall = False rob(n).Fixed = False rob(n).Veg = False rob(n).View = False rob(n).NewMove = False rob(n).LastOwner = "" rob(n).SonNumber = 0 rob(n).age = 0 'UpdateBotBucket n delallties n If Not MDIForm1.nopoff Then makepoff n End If If Not (rob(n).console Is Nothing) Then rob(n).console.textout "Robot has died." 'EricL 3/19/2006 Indicate robot has died in console End Sub