Implemented Powerups & 1ups

* Include powerups to fitness calculation. (as antagonist to the damage counter)
* Give bonus for received 1-Ups.
* Option to start with specific powerup.
This commit is contained in:
wts42 2018-04-07 22:59:55 +02:00
parent 9f30fd2d4b
commit 10278e7302
4 changed files with 81 additions and 16 deletions

View file

@ -1,17 +1,37 @@
local _M = {}
--
-- Change BizhawkDir to your BizHawk directory.
--
--[[
Change BizhawkDir to your BizHawk directory.
--]]
--_M.BizhawkDir = "C:/Users/mmill/Downloads/BizHawk-2.2/"
_M.BizhawkDir = "X:/BizHawkLab/BizHawk-2.2.2/"
_M.BizhawkDir = "X:/B2_BizHawkLab/BizHawk-2.2.2/"
_M.StateDir = _M.BizhawkDir .. "Lua/SNES/neat-mario/state/"
_M.PoolDir = _M.BizhawkDir .. "Lua/SNES/neat-mario/pool/"
--[[
At the moment the first in list will get loaded.
Rearrange for other savestates. (will be redone soon)
--]]
_M.State = {
"DP1.state", -- Donut Plains 1
"YI1.state", -- Yoshi's Island 1
"YI2.state", -- Yoshi's Island 2
}
--[[
Start game with specific powerup.
0 = No powerup
1 = Mushroom
2 = Feather
3 = Flower
Comment out to disable.
--]]
_M.StartPowerup = 0
_M.NeatConfig = {
--Filename = "DP1.state",
Filename = _M.PoolDir .. "DP1.state",
Filename = _M.PoolDir .. _M.State[1],
Population = 300,
DeltaDisjoint = 2.0,
DeltaWeights = 0.4,

View file

@ -26,6 +26,25 @@ function _M.getScore()
return score
end
function _M.getLives()
local lives = memory.readbyte(0x0DBE) + 1
return lives
end
function _M.writeLives(lives)
memory.writebyte(0x0DBE, lives - 1)
end
function _M.getPowerup()
local powerup = memory.readbyte(0x0019)
return powerup
end
function _M.writePowerup(powerup)
memory.writebyte(0x0019, powerup)
end
function _M.getMarioHit(alreadyHit)
local timer = memory.readbyte(0x1497)
if timer > 0 then
@ -150,4 +169,4 @@ function _M.clearJoypad()
joypad.set(controller)
end
return _M
return _M

View file

@ -641,15 +641,20 @@ end
function initializeRun()
savestate.load(config.NeatConfig.Filename);
if config.StartPowerup ~= NIL then
game.writePowerup(config.StartPowerup)
end
rightmost = 0
pool.currentFrame = 0
timeout = config.NeatConfig.TimeoutConstant
game.clearJoypad()
startCoins = game.getCoins()
startScore = game.getScore()
startLives = game.getLives()
checkMarioCollision = true
marioHitCounter = 0
powerUpCounter = 0
powerUpBefore = game.getPowerup()
local species = pool.species[pool.currentSpecies]
local genome = species.genomes[pool.currentGenome]
generateNetwork(genome)
@ -1015,8 +1020,10 @@ FitnessLabel = forms.label(form, "Fitness: " .. "", 5, 30)
MaxLabel = forms.label(form, "Max: " .. "", 130, 30)
CoinsLabel = forms.label(form, "Coins: " .. "", 5, 65)
ScoreLabel = forms.label(form, "Score: " .. "", 130, 65)
DmgLabel = forms.label(form, "Damage: " .. "", 230, 65)
ScoreLabel = forms.label(form, "Score: " .. "", 130, 65, 90, 14)
LivesLabel = forms.label(form, "Lives: " .. "", 130, 80, 90, 14)
DmgLabel = forms.label(form, "Damage: " .. "", 230, 65, 110, 14)
PowerUpLabel = forms.label(form, "PowerUp: " .. "", 230, 80, 110, 14)
startButton = forms.button(form, "Start", flipState, 155, 102)
@ -1064,6 +1071,16 @@ while true do
checkMarioCollision = true
end
powerUp = game.getPowerup()
if powerUp > 0 then
if powerUp ~= powerUpBefore then
powerUpCounter = powerUpCounter+1
powerUpBefore = powerUp
end
end
Lives = game.getLives()
timeout = timeout - 1
local timeoutBonus = pool.currentFrame / 4
@ -1080,8 +1097,16 @@ while true do
end
local hitPenalty = marioHitCounter * 100
local fitness = coinScoreFitness - hitPenalty + rightmost - pool.currentFrame / 2
local powerUpBonus = powerUpCounter * 100
local fitness = coinScoreFitness - hitPenalty + powerUpBonus + rightmost - pool.currentFrame / 2
if startLives < Lives then
local ExtraLiveBonus = (Lives - startLives)*1000
fitness = fitness + ExtraLiveBonus
console.writeline("ExtraLiveBonus added " .. ExtraLiveBonus)
end
if rightmost > 4816 then
fitness = fitness + 1000
console.writeline("!!!!!!Beat level!!!!!!!")
@ -1126,7 +1151,9 @@ while true do
forms.settext(MeasuredLabel, "Measured: " .. math.floor(measured/total*100) .. "%")
forms.settext(CoinsLabel, "Coins: " .. (game.getCoins() - startCoins))
forms.settext(ScoreLabel, "Score: " .. (game.getScore() - startScore))
forms.settext(LivesLabel, "Lives: " .. Lives)
forms.settext(DmgLabel, "Damage: " .. marioHitCounter)
forms.settext(PowerUpLabel, "PowerUp: " .. powerUpCounter)
pool.currentFrame = pool.currentFrame + 1

View file

@ -10,7 +10,6 @@ _M.Sprites = {}
-- Make sure this list is sorted before initialization.
_M.NeutralSprites = {
0x0E, -- Keyhole.
0x21, -- Moving coin.
0x2C, -- Yoshi egg Red/Blue/Yellow/Blue (X&3).
0x2D, -- Baby green Yoshi.
0x2F, -- Portable spring board.
@ -19,9 +18,6 @@ _M.NeutralSprites = {
0x41, -- Dolphin, horizontal.
0x42, -- Dolphin2, horizontal.
0x43, -- Dolphin, vertical.
0x45, -- Directional coins, no time limit.
0x47, -- Swimming/Jumping fish, doesn't need water. (!)
0x48, -- Diggin' Chuck's rock.
0x49, -- Growing/shrinking pipe end.
0x4A, -- Goal Point Question Sphere.
0x52, -- Moving ledge hole in ghost house.
@ -49,7 +45,6 @@ _M.NeutralSprites = {
0x6D, -- Invisible solid block.
0x79, -- Growing Vine.
0x7C, -- ???
0x7D, -- Balloon.
0x80, -- Key.
0x81, -- Changing item from a translucent block.
0x87, -- Lakitu's cloud, no time limit. (!)
@ -71,6 +66,8 @@ _M.NeutralSprites = {
-- Make sure this list is sorted before initialization.
_M.GoodSprites = {
0x21, -- Moving coin.
0x45, -- Directional coins, no time limit.
0x74, -- Mushroom.
0x75, -- Flower.
0x76, -- Star.
@ -148,6 +145,8 @@ _M.BadSprites = {
0x3F, -- Para-Goomba.
0x40, -- Para-Bomb.
0x44, -- Torpedo Ted.
0x47, -- Swimming/Jumping fish, doesn't need water. (!)
0x48, -- Diggin' Chuck's rock.
0x46, -- Diggin' Chuck.
0x4B, -- Pipe dwelling Lakitu.
0x4C, -- Exploding Block, fish/goomba/Koopa/Koopa with shell (X&3).