Rem Project: PriDe Rem Created: 3/26/2006 10:27:53 AM Rem ***** Main Source File ***** `Initialize Neural Net Rem Project: ANNTM ("Auntie Em"): Artificial Neural Network Through Memblocks Rem Created: 12/30/2005 7:15:12 PM #Constant G_Curve 0 #Constant G_Weight 1 #Constant G_Threshold 2 `Each "Cluster" memblock is a group of 32 neurons. One cluster can be attached to a second cluster. `That second cluster can be attached to a third cluster, and so on. `Each neuron in a cluster can be "linked" to any or all of the 32 neurons in the attached cluster. `End Clusters: Clusters do not have to be assigned a target cluster. If this is the case, the neurons in the cluster will never fire. `Neurons that do not fire, do not lose their charge (and will eventually max out). It is advisable to read an End Cluster periodically `and do something with the charges in the neurons, then set all the neurons in that cluster to 0 (see Clear_Charges) `Neurons have 5 parts: Charge, Threshold, Curve, Weight, and Links. ` Charge: This is how much "electricity" the neuron is holding, represented as a value between 0 and 15 ` Threshold: This is at what point the neuron will release it's charge. If the Charge value => Threshold, then the neuron "fires". ` Curve: This is used to scale the input values coming into a neuron. ` Weight: This is the amount of "charge" a neuron releases when it fires. ` Links: 4 bytes long. Each bit represents a link to a relative neuron in a linked cluster of neurons. The 3rd bit would represent the 3rd neuron. Global AI_Score Global AI_Average Global Epoch_Timer as DWord Global Epoch_Counter as DWord `Epoch_Length is how many frames make a single Epoch Global Epoch_Length = 4 `Pain is an offset from 0 to 14 which adjusts each neuron's charge by -Pain `Basically: this mathematically reflects negative "pain" values without storing negative values (which requires an extra bit) `Remember that this value lowers the maximum output as well. Global Pain = 7 `Set up initial clusters (read about clusters above). `Some arrays are based on how many cluster there are, so it is important to initialize all the clusters first. `Also, clusters must be sequential and start with Memblock 1. The Make_Free_Cluster function handles this automatically. `If you need to create other memblocks, you should start those at a much higher value (like Memblock 100). Global Mem1 Global Mem2 Mem1=Make_Free_Cluster Mem2=Make_Free_Cluster Type Genes Curve as Integer Weight as Integer Threshold as Integer Endtype `Gene is the learning "genetic code". Typically, the "genetic code" would record and consider the population `of all AI of the same type. `In this case though, we only have one AI, and that type of evolution would take a really long time. `So we are going to take the population of possibilities and use those instead. Since a neuron can hold a value of `0 to 15, we will track how well each setting does and keep track over many Epochs. `We are tracking: # of Clusters, 32 neurons (0-31), and 16 possible settings (0-15). `So our Dim is: `Dim Gene( Clusters ,31, 15) as Genes `The BestGenes array records which single Gene setting (0-15) is the best. Dim BestGenes( Clusters ,31 ) as Genes `Note: A future update would be to convert this to a memblock as well. `LinkCrawler is a genetic array that handles the evolution of the neuron links, one at a time per cluster. `The crawler stays with each neuron for specific number of epochs, and then moves on to the next neuron. Dim LinkCrawler( Clusters , 33 ) as Integer `=============Prime the Neural Net AI================= If File Exist("PrideNet1.ann") Open To Read 1,"PrideNet1.ann" Read Memblock 1,Mem1 Close File 1 Open To Read 1,"PrideNet2.ann" Read Memblock 1,Mem2 Close File 1 Else ` Create and Attach two Neuron Clusters Assign_Cluster(Mem1,Mem2) Initialize_Links() For i =0 to 7 For j = 0 to 5 Link_Neuron(Mem1,i,j) Next j Next i For i =8 to 11 Link_Neuron(Mem1,i,0) Link_Neuron(Mem1,i,1) Next i Epoch_Timer=Epoch_Length+1 Epoch() `Increase all the 1st cluster's neuron charges by 2. Pump_Charges(Mem1) Endif `=====================================================GAME===================================================== `Gambling game called PriDe Game: Game_SetUp: Set Display Mode 800,600,32 CLS Print "Welcome to PRIDE" Print Print "Pride is a thinking gambling game." Print "The object is to outwit your opponent on several levels." Print Print "First, is the Player Selection: Choose either the" Print "Alpha Player (Red), or the Numeric Player (White)" Print "(Note: there is no advantage to either player)" Print "[1] Alpha (Red)" Print "[2] Numeric (White)" Global Player Global Player$ Player$="Numeric (White)" Do Input "Select: ",Player If Player = 1 Player$="Alpha (Red)" Exit Endif If Player = 2 Then exit Loop CLS Print Print "Next, you will see the game board." Print "Like this:" Print " 1 2" Print "A [ ][ ]" Print "B [ ][ ]" Print Print "The Game:" Print "Dealing: Each section will have a red or white number from 1 to 5 in it." Print Print "Betting: Each player reviews the board and bets to Win or Lose." Print " You can bet 1 minimum to 5 maximum. This will not be the whole bet amount." Print " Bets are kept secret until the Payout phase." Print Print "Select Row/Column: The Alpha Player selects either row A or B." Print " The Numeric Player selects either column 1 or 2." Print Print "Playing: Both player's reveal their selections simultaniously." Print " The color/number selected is value in the row and column selected by" Print " the players." Print Print "Scoring: If the selected value is Red, the Alpha player 'wins'. Numeric 'loses'." Print " If the selected value is White, the Numeric player 'wins'. Alpha 'loses'." Print " Each initial bet amount is multiplied by the selected value and the results" Print " are added together. This amount is deducted from each player's funds and" Print " added to to the pot." Print Print "Payout: If no player bets correctly (to win or lose), the total amount remains in" Print " the 'pot'. If one player bet correctly, that player wins the total pot." Print " If both players bet correctly, the total amount remains in the 'pot'." Print Print "Press any key to continue" Wait Key Cls Print "Strategies to consider:" Print Print "Your bet is 50% controlled by you and 50% controlled by your opponent. Consider your" Print "bet carefully. If you think you have a good chance to win, you will probably want to" Print "force the highest bet you can. Otherwise, you may want to limit the bet as much as" Print "possible. The dilemma comes when it appears you have a 50% chance of winning." Print Print "You can try to trick your opponent. One option may look like a sure win, but it may" Print "also have a lower bet multiplier. Consider the possibility of going against the sure" Print "bet in order to get the higher payout. Of course, your opponent might consider this" Print "as well." Print Print "If you have a 50-50 chance of winning a hand, consider the payout strategies. Which" Print "choice you make will have the most potential and the least risk. Consider what your" Print "opponent might think is a great strategy as well. And then throw in the possibility" Print "that your opponent is taking what you are thinking into consideration as well." Print Print "Press any key to continue." Wait Key Dim board(3) Global Pot Global Funds1 Funds1=500 Global Funds2 Funds2=500 Global Bet1 Global BetType1 Global Bet2 Global BetType2 Do `Save Neural Net If File Exist("PrideNet1.ann") Delete File "PrideNet1.ann" Endif Open To Write 1,"PrideNet1.ann" Write Memblock 1,Mem1 Close File 1 If File Exist("PrideNet2.ann") Delete File "PrideNet2.ann" Endif Open To Write 1,"PrideNet2.ann" Write Memblock 1,Mem2 Close File 1 Epoch() `Deal phase Deal `Bet Phase Set_All_Charges(Mem2,0) Fire_Neurons(Mem1) b=Read_Charge(Mem2,0)+Read_Charge(Mem2,1) b=Sigmoidal(b-(b*.5),1)*4+1 Bet2=b t1=Read_Charge(Mem2,2):t2=Read_Charge(Mem2,3) t=(t2>t1)+1 BetType2=t Set Cursor 0,110 Ink Rgb(200,200,255),0 Do Input "Bet to [1]Win or [2]Lose? :",BetType1 `BetType1=rnd(1)+1 If BetType1=1 or BetType1=2 then Exit Loop Do Input "Amount to bet (1-5)? :",Bet1 `Bet1=Rnd(4)+5 If Bet1=>1 and Bet1<=5 then Exit Loop `Select Phase a1=Read_Charge(Mem2,4):a2=Read_Charge(Mem2,5) a=(a2>a1)+1 If Player=1 Do Input "Select Row ([1]Row A or [2]Row B): ",Row `Row=Rnd(1)+1 If Row = 1 or Row=2 Then exit Loop Col=a ABet=Bet1:AType=BetType1 NBet=Bet2:NType=BetType2 Else Do Input "Select Column ([1]Col 1 or [2]Col 2): ",Col `Col=Rnd(1)+1 If Col = 1 or Col=2 Then exit Loop Row=a NBet=Bet1:NType=BetType1 ABet=Bet2:AType=BetType2 Endif `Play Phase Print "Bets and selections are made. Press any key to continue." Wait Key Print Print "Alpha Player bet ";ABet;" to "; If AType=1 Then Print "Win." Else Print "Lose." Print "Alpha Player selected Row "; If Row=1 Then Print "A." Else Print "B." Print Print "Numeric Player bet ";NBet;" to "; If NType=1 Then Print "Win." Else Print "Lose." Print "Numeric Player selected Col ";Col Print s=(row-1)*2+(col-1) Print "The selected Value is ";Abs(Board(s));"-"; If Board(s)>0 Print "White." Else Print "Red." Endif totalbet=(Abs(Board(s))*Bet1+Abs(Board(s))*Bet2)*2 Print "Total Bet = ";totalbet;". Pot = ";pot+totalbet*2;"." Print "Press any key to continue." Wait Key `Scoring phase Funds1=Funds1-totalbet Funds2=Funds2-totalbet pot=pot+totalbet*2 win1=0 win2=0 `Scoring if player=1 If Board(s)<0 If AType=1 Then Win1=1 If NType=2 then Win2=1 Endif If Board(s)>0 If AType=2 Then Win1=1 If NType=1 then Win2=1 Endif `Flip win values if Player=2 If Player=2 Win1=(Win1=0) Win2=(Win2=0) Endif `Payout phase If Win1<>Win2 If Win1=1 Print "You have won the pot for ";pot;"!" Funds1=Funds1+pot AI_Score=AI_Score-pot Else Print "The AI has won the pot for ";pot;"." Funds2=Funds2+pot AI_Score=AI_Score+pot Endif pot=0 Else If Win1=0 Print "You have both bet incorrectly. This hand is a draw." Else Print "You have both bet correctly. This hand is a draw." Endif Endif Print Print "Press any key to deal the next hand." Wait key If Funds1<0 Then Funds1=Funds1+300 If Funds1>1000 Then Funds1=Funds1-300 If Funds2<0 Then Funds2=Funds2+300 If Funds2>1000 Then Funds2=Funds2-300 Loop End #Constant Deal Deal() Function Deal() Cls Ink Rgb(50,50,255),0 Box 30,30,60,60 Box 70,30,100,60 Box 30,70,60,100 Box 70,70,100,100 Ink Rgb(255,255,255),0 Center Text 45,5,"1" Center Text 85,5,"2" Ink Rgb(255,0,0),0 Center Text 10,40,"A" Center Text 10,80,"B" For i = 0 to 3 board(i)=(rnd(4)+1)*(Rnd(1)*2-1) if Player=1 c=board(i)+5 Else c=5-board(i) Endif Set_Charge(Mem1,i,c) if Player=1 c=5-board(i) Else c=board(i)+5 Endif Set_Charge(Mem1,i+4,c) t=t+board(i) Next i t=Sigmoidal(t,1)*15 Set_Charge(Mem1,8,t) if board(0)>0 Then Ink RGB(255,255,255),0 Else Ink Rgb(255,0,0),0 Center Text 45,40,Str$(Abs(board(0))) if board(1)>0 Then Ink RGB(255,255,255),0 Else Ink Rgb(255,0,0),0 Center Text 85,40,Str$(Abs(board(1))) if board(2)>0 Then Ink RGB(255,255,255),0 Else Ink Rgb(255,0,0),0 Center Text 45,80,Str$(Abs(board(2))) if board(3)>0 Then Ink RGB(255,255,255),0 Else Ink Rgb(255,0,0),0 Center Text 85,80,Str$(Abs(board(3))) Ink Rgb(200,200,255),0 Text 120,5,"Pot = "+Str$(Pot) c=Sigmoidal(Pot-(pot*.5),75)*15 Set_Charge(Mem1,9,c) Text 120,20,"Player has "+Str$(Funds1) c=Sigmoidal(Funds1-(Funds1*.5),250)*15 Set_Charge(Mem1,10,c) Text 120,35,"AI has "+Str$(Funds2) c=Sigmoidal(Funds2-(Funds2*.5),250)*15 Set_Charge(Mem1,11,c) Text 120,55,"Player is "+Player$ Endfunction `=========================================================ANNTM================================================== Charges: `Set_Charge is used to set a neuron's charge to a specific value between 0 and 15 Function Set_Charge(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) Byt=Set_Right_Nibble(0,rit) If Value>15 then Value=15 Byt=Set_Left_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Add_Charge is used to add a "charge" value to the neuron's existing charge. Function Add_Charge(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Right_Nibble(0,rit) Value=lft+Value If Value>15 then Value=15 Byt=Set_Left_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Deduct_Charge is used to subtract a charge value from the neuron's existing charge. Function Deduct_Charge(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Right_Nibble(0,rit) If lft>Value Value=lft-Value Else Value=0 Endif If Value>15 then Value=15 Byt=Set_Left_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction Function Read_Charge(Memblock, Neuron) If Neuron>31 then ExitFunction 0 If Memblock Exist(Memblock)=0 Then ExitFunction 0 NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) lft=Get_Left_Nibble(Byt)-Pain Endfunction lft `Clear_Charges: sets all the neuron charges to the provided Value in the given cluster. Function Set_All_Charges(Memblock,Value) For i = 0 to 31 Set_Charge(Memblock,i,Value) Next i Endfunction `Drain_Charges: Subtracts 1 from all the neuron charges in the given cluster. Useful for a timer or score drain. Function Drain_Charges(Memblock) For i = 0 to 31 Deduct_Charge(Memblock,i,1) Next i Endfunction `Pump_Charges: Adds 1 to all the neuron charges in the given cluster. Useful for a timer or score boost. Function Pump_Charges(Memblock) For i = 0 to 31 Add_Charge(Memblock,i,1) Next i Endfunction Clusters: `Fire_Neurons runs through all a cluster's neurons and checks if they should be fired or not. `If a neuron is fired, it's Weight is applied to all linked neurons in the target cluster `and the firing neuron's charge is set to 0. `If the Cluster does not have a Target Cluster Assigned to it, then the neurons are not fired. Function Fire_Neurons(SourceMem) If SourceMem=0 Then ExitFunction If Memblock Exist(SourceMem)=0 Then ExitFunction TargetMem=Cluster_Link(SourceMem) If TargetMem=0 Then ExitFunction If Memblock Exist(TargetMem)=0 Then ExitFunction Link as DWord For i = 0 to 31 Charge=Read_Charge(SourceMem,i) Threshold=Read_Threshold(SourceMem,i) If Charge=>Threshold : `Fire Neuron Weight#=Read_Weight(SourceMem,i) Link = Neuron_Link_Dword(SourceMem,i) For j=0 to 31 If (Link && 2^j) <> 0 Curve#=Read_Curve(TargetMem,j) Result=Sigmoidal(Weight#-7.5,Curve#*.5)*5 Add_Charge(TargetMem,j,Result) Endif Next j Set_Charge(SourceMem,i,0) Endif Next i Endfunction `Assign_Cluster: `Assigns a Target Memblock Cluster to a Source Memblock Cluster (recorded in the source). `When the Source Neurons fire, the Target Neurons will receive the resulting charges. `This function can also be used to create the memblocks. `A Source Cluster can only be assigned a single Target Cluster. However, a Target Cluster can be `the target of one or more Source Clusters. Function Assign_Cluster(Source,Target) If Memblock Exist(Source)=0 Make Memblock Source,200 Endif If Memblock Exist(Target)=0 Make Memblock Target,200 Endif t as word t=Target Write Memblock Word Source,198,t Endfunction Function Cluster_Link(Source) If Memblock Exist(Source)=0 Then Exitfunction 0 target=Memblock Word(Source,198) Endfunction target Links: `====================================================== `=======================Links========================== `====================================================== `Link_Neuron: `Links a single Source Neuron to a single Target Neuron. A Neuron can have up to 32 targets. `The target neurons are also determined by the Source neuron's cluster target (see Assign_Cluster). `Memblock must be a valid Memblock Cluster. Source must be a byte <= 31. Target must be a byte <= 31. Function Link_Neuron(Memblock, Source as Byte, Target as Byte) If Memblock Exist(Memblock)=0 Then ExitFunction If Source>31 Then ExitFunction If Target>31 then ExitFunction Link as Dword Link = Neuron_Link_Dword(Memblock,Source) Link = Link || 2^Target Write_Neuron_Link_Dword(Memblock,Source,Link) Endfunction Function DeLink_Neuron(Memblock, Source as Byte, Target as Byte) If Memblock Exist(Memblock)=0 Then ExitFunction If Source>31 Then ExitFunction If Target>31 then ExitFunction Link as Dword Link=Neuron_Link_DWord(Memblock,Source) Link = Link .. Link :`Invert Link Link = Link || 2^Target :`OR the appropriate bit Link = Link .. Link : `Invert Link back to the original settings Write_Neuron_Link_Dword(Memblock,Source,Link) Endfunction Function Neuron_Link_Dword(Memblock,Neuron) zero as dword = 0 If Memblock Exist(Memblock)=0 Then ExitFunction zero Links=Neuron*6+2 DW as DWord DW=Memblock Dword(Memblock,Links) Endfunction DW Function Write_Neuron_Link_DWord(Memblock,Neuron,DW as DWord) If Memblock Exist(Memblock)=0 Then ExitFunction Links=Neuron*6+2 Write Memblock DWord Memblock,Links,DW Endfunction `====================================================== `=====================Thresholds======================= `====================================================== Thresholds: `Set_Threshold is used to set a neuron's threshold to a specific value between 0 and 15 Function Set_Threshold(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) lft=Get_Left_Nibble(Byt) Byt=Set_Left_Nibble(0,lft) If Value>15 then Value=15 Byt=Set_Right_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Add_Threshold is used to add to the to the neuron's existing threshold value. Function Add_Threshold(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Left_Nibble(0,lft) Value=rit+Value If Value>15 then Value=15 Byt=Set_Right_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Deduct_Threshold is used to subtract a value from the neuron's existing threshold value. Function Deduct_Threshold(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Left_Nibble(0,lft) If rit>Value Value=rit-Value Else Value=0 Endif If Value>15 then Value=15 Byt=Set_Right_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction Function Read_Threshold(Memblock, Neuron) If Neuron>31 then ExitFunction 0 If Memblock Exist(Memblock)=0 Then ExitFunction 0 NOff=Neuron*6 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt)-Pain Endfunction rit `Set_All_Thresholds: sets all the neuron thresholds to the specified Value in the given cluster. Function Set_All_Thresholds(Memblock,Value) For i = 0 to 31 Set_Threshold(Memblock,i,Value) Next i Endfunction `Drain_Thresholds: Subtracts 1 from all the neuron thresholds in the given cluster. Function Drain_Thresholds(Memblock) For i = 1 to 31 Deduct_Threshold(Memblock,i,1) Next i Endfunction `Pump_Thresholds: Adds 1 to all the neuron thresholds in the given cluster. Function Pump_Thresholds(Memblock) For i = 1 to 31 Add_Threshold(Memblock,i,1) Next i Endfunction `====================================================== `=======================Curves========================= `====================================================== Curves: `Set_Curve is used to set a neuron's Curve to a specific value between 0 and 15 Function Set_Curve(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) Byt=Set_Right_Nibble(0,rit) If Value>15 then Value=15 Byt=Set_Left_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Add_Curve is used to add a value to the neuron's existing Curve. Function Add_Curve(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Right_Nibble(0,rit) Value=lft+Value If Value>15 then Value=15 Byt=Set_Left_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Deduct_Curve is used to subtract a Curve value from the neuron's existing Curve. Function Deduct_Curve(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Right_Nibble(0,rit) If lft>Value Value=lft-Value Else Value=0 Endif If Value>15 then Value=15 Byt=Set_Left_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction Function Read_Curve(Memblock, Neuron) If Neuron>31 then ExitFunction 0 If Memblock Exist(Memblock)=0 Then ExitFunction 0 NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) lft=Get_Left_Nibble(Byt) Endfunction lft `Clear_Curves: sets all the neuron Curves to the specified Value. Function Set_All_Curves(Memblock,Value) For i = 0 to 31 Set_Curve(Memblock,i,Value) Next i Endfunction `Drain_Curves: Subtracts 1 from all the neuron Curves in the given cluster. Useful for a timer or score drain. Function Drain_Curves(Memblock) For i = 1 to 31 Deduct_Curve(Memblock,i,1) Next i Endfunction `Pump_Curves: Adds 1 to all the neuron Curves in the given cluster. Useful for a timer or score boost. Function Pump_Curves(Memblock) For i = 1 to 31 Add_Curve(Memblock,i,1) Next i Endfunction `====================================================== `=======================Weights======================== `====================================================== Weights: `Set_Weight is used to set a neuron's Weight to a specific value between 0 and 15 Function Set_Weight(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) lft=Get_Left_Nibble(Byt) Byt=Set_Left_Nibble(0,lft) If Value>15 then Value=15 Byt=Set_Right_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Add_Weight is used to add to the to the neuron's existing Weight value. Function Add_Weight(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Left_Nibble(0,lft) Value=rit+Value If Value>15 then Value=15 Byt=Set_Right_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction `Deduct_Weight is used to subtract a value from the neuron's existing Weight value. Function Deduct_Weight(Memblock, Neuron, Value as Byte) If Neuron>31 then ExitFunction If Memblock Exist(Memblock)=0 Then ExitFunction NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) lft=Get_Left_Nibble(Byt) Byt=Set_Left_Nibble(0,lft) If rit>Value Value=rit-Value Else Value=0 Endif If Value>15 then Value=15 Byt=Set_Right_Nibble(Byt,Value) Write Memblock Byte Memblock,NOff,Byt Endfunction Function Read_Weight(Memblock, Neuron) If Neuron>31 then ExitFunction 0 If Memblock Exist(Memblock)=0 Then ExitFunction 0 NOff=Neuron*6+1 Byt as Byte Byt=Memblock Byte(Memblock,NOff) rit=Get_Right_Nibble(Byt) Endfunction rit `Set_All_Weights: sets all the neuron Weights to the specified Value in the given cluster. Function Set_All_Weights(Memblock,Value) For i = 0 to 31 Set_Weight(Memblock,i,Value) Next i Endfunction `Drain_Weights: Subtracts 1 from all the neuron Weights in the given cluster. Function Drain_Weights(Memblock) For i = 1 to 31 Deduct_Weight(Memblock,i,1) Next i Endfunction `Pump_Weights: Adds 1 to all the neuron Weights in the given cluster. Function Pump_Weights(Memblock) For i = 1 to 31 Add_Weight(Memblock,i,1) Next i Endfunction `This function is added to set, or reset, our neurons randomly. Function Initialize_AI() dw as DWord For i = 1 to Clusters For j=0 to 31 Set_Threshold(i,j,Rnd(14)+1) Set_Weight(i,j,Rnd(14)+1) Set_Curve(i,j,Rnd(14)+1) Next j Next i Endfunction `This function is added to set, or reset, our neuron links randomly. Function Initialize_Links() dw as DWord For i = 1 to Clusters For j=0 to 31 d1=Rnd(255):d2=rnd(255):d3=Rnd(255):d4=Rnd(255) dw=d1+(d2 << 8) + (d3 << 16) + (d4 << 24) Write_Neuron_Link_DWord(i,j,dw) Next j Next i Endfunction Function Epoch() Inc Epoch_Timer If Epoch_Timer<Epoch_Length Then ExitFunction `Here's where we score our neuron settings and store them for later: For i = 1 to Clusters For j = 0 to 31 n=Read_Curve(i,j) curve=Int(Sigmoidal((AI_Score-AI_Average)+(Get_Gene(i,j,n,G_Curve)*10),500)*10) Write_Gene(i,j,n,G_Curve,curve) n=Read_Weight(i,j) weight=Int(Sigmoidal((AI_Score-AI_Average)+(Get_Gene(i,j,n,G_Weight)*10),500)*10) Write_Gene(i,j,n,G_Weight,weight) n=Read_Threshold(i,j) threshold=Int(Sigmoidal((AI_Score-AI_Average)+(Get_Gene(i,j,n,G_Threshold)*10),500)*10) Write_Gene(i,j,n,G_Theshold,threshold) Next j Next i `Initialize the AI with some random values. Initialize_AI() `Now populate the AI with some best scores. The more Epochs that go by, the less mutation occurs. `Note: this is sort of an inverse mutation function. The gene starts off by default as mutated. ` Then if the random selection comes up, the mutation is replaced by a successful gene. ` The more Epochs that go by, the more likely the mutations will be replaced, but never 100%. Get_Best_Genes() For i = 1 to Clusters For j = 0 to 31 If Rnd(20+Epoch_Counter)<Epoch_Counter Set_Curve(i,j,BestGenes(i,j).curve) Endif If Rnd(20+Epoch_Counter)<Epoch_Counter Set_Weight(i,j,BestGenes(i,j).weight) Endif If Rnd(20+Epoch_Counter)<Epoch_Counter Set_Threshold(i,j,BestGenes(i,j).threshold) Endif Next j Link_Learning() Next i `Calculate the new average score Inc Epoch_Counter `Weighted average so the current performance is based on past performance. AI_Average=((AI_Average * (Epoch_Counter-1))+AI_Score)/Epoch_Counter AI_Score=0 Epoch_Timer=0 Endfunction `This function chooses the "best" genes, the genes with the highest scores. `A feature has been added to typically select 1 of the best 3 (usually) to avoid getting stuck in a niche. Function Get_Best_Genes() For i = 1 to Clusters For j = 0 to 31 best_curve=-9999 best_weight=-9999 best_threshold=-9999 For k=0 to 15 If best_curve<=Get_Gene(i,j,n,G_Curve) and rnd(3)=1 :`Typically will choose one of the best 3, but not always. best_curve=Get_Gene(i,j,n,G_Curve) BC=k Endif If best_weight<Get_Gene(i,j,n,G_Weight) and rnd(3)=1 best_weight=Get_Gene(i,j,n,G_Weight) BW=k Endif If best_threshold<Get_Gene(i,j,n,G_Threshold) and rnd(3)=1 best_threshold=Get_Gene(i,j,n,G_Threshold) BT=k Endif Next k BestGenes(i,j).curve=BC BestGenes(i,j).weight=BW BestGenes(i,j).threshold=BT Next j Next i Endfunction `Returns the Gene Setting score value from the cluster Function Get_Gene(Cluster,Neuron as byte,Score as byte,Gene as byte) zero as dword = 0 If Gene>2 Then Exitfunction zero If Score>15 Then Exitfunction zero If Neuron>31 Then Exitfunction zero r as Dword rbyte=200+Neuron*24+Int(Score/2)+(Gene*8) r=Memblock Byte(Cluster,rbyte) If Int(Score/2)*2=Score r=Get_Left_Nibble(r) Else r=Get_Right_Nibble(r) Endif Endfunction r `Write the Gene Setting score value to the cluster Function Write_Gene(Cluster,Neuron as byte,Score as byte,Gene as byte, Value as Byte) zero as dword = 0 If Gene>2 Then Exitfunction zero If Score>15 Then Exitfunction zero If Neuron>31 Then Exitfunction zero If Value>15 Then Value=15 r as Dword rbyte=200+Neuron*24+Int(Score/2)+(Gene*8) r=Memblock Byte(Cluster,rbyte) If Int(Score/2)*2=Score r=Get_Left_Nibble(r) Else r=Get_Right_Nibble(r) Endif Endfunction r Function Link_Learning() links as Dword For i = 1 to Clusters `The "Crawling" part Inc LinkCrawler(i,33) If LinkCrawler(i,33)>100 LinkCrawler(i,33)=0 Inc LinkCrawler(i,32) If LinkCrawler(i,32)>31 then LinkCrawler(i,32)=0 links = Neuron_Link_Dword(i,LinkCrawler(i,32)) For j = 0 to 31 bit=(Get_Bit(links,j)*2)-1 LinkCrawler(i,j)=5*bit Next j Endif links=Neuron_Link_Dword(i,LinkCrawler(i,32)) EC=Epoch_Counter-(LinkCrawler(i,32)*100) For j = 0 to 31 sign=Get_Bit(links,j)*2-1 LinkCrawler(i,j)=LinkCrawler(i,j)+((Int(Sigmoidal(AI_Score-AI_Average,500)*11)-5)*sign) If Rnd(20+EC)<EC If LinkCrawler(i,j)>0 Link_Neuron(i,LinkCrawler(i,32),j) Else DeLink_Neuron(i,LinkCrawler(i,32),j) Endif Else if rnd(1) Link_Neuron(i,LinkCrawler(i,32),j) Else DeLink_Neuron(i,LinkCrawler(i,32),j) Endif Endif Next j Next i Endfunction #Constant Clusters Count_Memblocks() Function Count_Memblocks() i=0 Do If Memblock Exist(i+1)=0 Exit Endif inc i Loop EndFunction i #Constant Free_Cluster Free_Memblock() Function Free_Memblock() i=1 Do If Memblock Exist(i)=0 Then Exit inc i Loop Endfunction i #Constant Make_Free_Cluster Free_Cluster() Function Free_Cluster() mb=Free_Memblock() Make Memblock mb,1240 Endfunction mb Function Sigmoidal(value#,curve#) `the sigmoidal formula. Graph this on a spreadsheet to see how it works. result#=1.0/(1.0+2.04541^-((value#)/(curve#*.1))) `The result# is a value between >0 and <1. Curve is the number standard deviations in a normal distribution. Endfunction result# `Simple Nibble Functions. Function Set_Nibble(bt as byte, value as byte, nibble as byte) if nibble=0 then bt = Set_Right_Nibble(bt,value) if nibble=1 then bt = Set_Left_Nibble(bt,value) Endfunction bt Function Set_Left_Nibble(bt as byte,value as byte) value = value << 4 bt = bt || value Endfunction bt Function Set_Right_Nibble(bt as byte,value as byte) value = value << 4 value = value >> 4 bt = bt || value Endfunction bt Function Get_Nibble(bt as byte, nibble as byte) if nibble=0 then bt=Get_Right_Nibble(bt) if nibble=1 then bt=Get_Left_Nibble(bt) Endfunction bt Function Get_Left_Nibble(bt as byte) bt = bt >> 4 Endfunction bt Function Get_Right_Nibble(bt as byte) bt = bt << 4 bt = bt >> 4 Endfunction bt Function Get_Bit(value as DWord, bt as byte) bit as Dword bit= 2^bt r=Value && bit r=(r>0) Endfunction r