MultiMode 101
From Robot Battle Wiki
Contents |
[edit] Introduction
Multi-Mode robots have two or more separate modes that they can switch between. A good multi-mode robot will attempt to learn which mode is better. In this tutorial we will be merging two simple robots together. Here are the source robots:
Init{
name("SittingDuck")
author("GNU FDL")
regcore(core)
regdtcrobot(FoundBot, 1)
regascan(autoscan, 2)
lockgun(_true) //Lock the gun to the radar
}
Core{
bodyleft(5)
}
FoundBot{
stop()
fire(5)
continue()
}
autoscan{
scan()
}
Init{
name("CookieGuy")
author("GNU FDL")
regcore(core)
regdtccookie(FoundCookie, 1)
regascan(autoscan, 2)
}
Core{
radarleft(5)
}
FoundCookie{
stop()
syncall()
ahead(_scandist+5)
continue()
}
AutoScan{
scan()
}
[edit] Rename Sections
Because were are merging the robots into one file, rename the sections. There are a few advantages to this but mostly it's so you can identify which sections come from which robot. Don't do the init section yet. We'll come to that in a minute. For this example:
SittingDuck
- Core becomes Duck_Core
- FoundBot becomes Duck_FoundBot
CookieGuy
- Core becomes Guy_Core
- FoundCookie becomes Guy_FoundCookie
Since both autoscan procedures are identical we only need one copy.
- AutoScan stays the same.
[edit] Merge the inits
Next we need to merge the two inits together. Basically we need to create a switch between the two init procedures. We can do this with an if statement:
init{
if(switch)
//First init
else
//Second init
endif
}
Now, if switch is true then the first init will be run and if it is false the second will be run. Here it is for the example robots:
init{
name("MultiMode 101")
if (switch)
//SittingDuck Init
regcore(Duck_core)
regdtcrobot(Duck_FoundBot, 1)
regascan(autoscan, 2)
lockgun(_true) //Lock the gun to the radar
else
//CookieGuy Init
regcore(Guy_core)
regdtccookie(Guy_FoundCookie, 1)
regascan(autoscan, 2)
endif
}
Things to remember when doing this:
- Make sure you update the register commands so they point to the renamed sections
- You can only call name, version and author once per bot, so you don't need to include those commands.
- As well as the register commands remember to include any other setup commands you used such as lockgun, blocking etc.
[edit] Switching Modes and Learning
Right, now we have a robot that can switch between two modes. But how does your robot decide which mode to use? Well, you are going to have to write a learning routine. The following example is a very basic learning routine, but you can improve it once you know what it does. We are going to write this routine in the dead section. This section gets called if your robot gets killed or wins the game. This simple example figures out if we won or lost:
dead{
if (_energy > 0)
//If we still have energy left, we must of won or drew the game
else
//If we have no energy, we lost the game
endif
}
[edit] Learning
What we are going to do is keep track of the wins and losses of each mode. Then we are going to make the robot choose the mode with the most wins. Do you remember the switch variable? We are going to need to use it again. Remember, if it's true, we're in SittingDuck mode, if it's false we're in CookieGuy mode.
dead{
if (switch)
//SittingDuck Mode
if (_energy > 0)
DuckScore= DuckScore + 1 //Increase the score
else
DuckScore= DuckScore - 1 //Decrease the score
endif
else
//CookieGuy Mode
if (_energy > 0)
GuyScore= GuyScore + 1 //Increase the score
else
GuyScore= GuyScore - 1 //Decrease the score
endif
endif
}
[edit] Switching Modes
So, DuckScore and GuyScore represent how well each mode has done. We can now select between them:
if (GuyScore > DuckScore) //CookieGuy has the high score switch = _false else //SittingDuck has the high score switch = _true endif
[edit] Storing Variables
We have one last problem: Normally at the end of a game all your robots variables are reset to zero. We can avoid this by using the store command on variables we need to keep:
store(switch) store(GuyScore) store(DuckScore)
[edit] The finished product
That's it! Finally here's the combined example robot in all it's glory:
init{
name("MultiMode 101")
author("GNU FDL")
if (switch)
//SittingDuck Init
regcore(Duck_core)
regdtcrobot(Duck_FoundBot, 1)
regascan(autoscan, 2)
lockgun(_true) //Lock the gun to the radar
else
//CookieGuy Init
regcore(Guy_core)
regdtccookie(Guy_FoundCookie, 1)
regascan(autoscan, 2)
endif
}
dead{
if (switch)
//SittingDuck Mode
if (_energy > 0)
DuckScore= DuckScore + 1 //Increase the score
else
DuckScore= DuckScore - 1 //Decrease the score
endif
else
//CookieGuy Mode
if (_energy > 0)
GuyScore= GuyScore + 1 //Increase the score
else
GuyScore= GuyScore - 1 //Decrease the score
endif
endif
if (GuyScore > DuckScore)
//CookieGuy has the high score
switch = _false
else
//SittingDuck has the high score
switch = _true
endif
store(switch)
store(GuyScore)
store(DuckScore)
}
Duck_Core{
bodyleft(5)
}
Duck_FoundBot{
stop()
fire(5)
continue()
}
Guy_Core{
radarleft(5)
}
Guy_FoundCookie{
stop()
syncall()
ahead(_scandist+5)
continue()
}
autoscan{
scan()
}
