BeeBee: BasicBot frontend and LuaBot. Pretty much stable, afaik.
This commit is contained in:
parent
c6b90a037e
commit
dc97747998
|
@ -1,11 +1,11 @@
|
||||||
-- LuaBot, concept bot for FCEU and ZSnes and any other emu that has compatible Lua engine
|
-- LuaBot, concept bot for FCEU and snes9x and any other emu that has compatible Lua engine
|
||||||
-- qFox, 30 July 2008
|
-- qFox, 30 July 2008
|
||||||
-- version 1.04
|
-- version 1.06
|
||||||
|
|
||||||
-- Botscript data following
|
-- Botscript data following:
|
||||||
-- Rom: ROMNAME
|
-- Rom: -- ROMNAME
|
||||||
-- Comment: COMMENT
|
-- Comment: -- COMMENT
|
||||||
-- Version: VERSION
|
-- Version: -- VERSION
|
||||||
|
|
||||||
local function realcount(t) -- accurately count the number of elements of a table, even if they contain nil values. not fast, but accurate.
|
local function realcount(t) -- accurately count the number of elements of a table, even if they contain nil values. not fast, but accurate.
|
||||||
local n = 0;
|
local n = 0;
|
||||||
|
@ -34,8 +34,12 @@ end;
|
||||||
local loopcounter = 0; -- counts the main loop
|
local loopcounter = 0; -- counts the main loop
|
||||||
local key1 = {}; -- holds the to be pressed keys this frame for player 1
|
local key1 = {}; -- holds the to be pressed keys this frame for player 1
|
||||||
local key2 = {}; -- holds the to be pressed keys this frame for player 2
|
local key2 = {}; -- holds the to be pressed keys this frame for player 2
|
||||||
|
local key3 = {}; -- holds the to be pressed keys this frame for player 3
|
||||||
|
local key4 = {}; -- holds the to be pressed keys this frame for player 4
|
||||||
local lastkey1 = {}; -- keys pressed in previous frame for player 1
|
local lastkey1 = {}; -- keys pressed in previous frame for player 1
|
||||||
local lastkey2 = {}; -- keys pressed in previous frame for player 2
|
local lastkey2 = {}; -- keys pressed in previous frame for player 2
|
||||||
|
local lastkey3 = {}; -- keys pressed in previous frame for player 1
|
||||||
|
local lastkey4 = {}; -- keys pressed in previous frame for player 2
|
||||||
local frame = 0; -- number of frames (current value is current frame count, incremented at the start of a new frame)
|
local frame = 0; -- number of frames (current value is current frame count, incremented at the start of a new frame)
|
||||||
local attempt = 1; -- number of attempts (current value is current attempt, incremented after the end of an attempt)
|
local attempt = 1; -- number of attempts (current value is current attempt, incremented after the end of an attempt)
|
||||||
local segment = 1; -- number of segments (current value is current segment, incremented after the end of a segment)
|
local segment = 1; -- number of segments (current value is current segment, incremented after the end of a segment)
|
||||||
|
@ -53,6 +57,8 @@ local maxsegments = 100;
|
||||||
local playingbest = false; -- when going to the next segment, we need to play the best segment to record, this indicates when we're doing so
|
local playingbest = false; -- when going to the next segment, we need to play the best segment to record, this indicates when we're doing so
|
||||||
local keyrecording1 = {}; -- every key pressed for player 1 is put in here
|
local keyrecording1 = {}; -- every key pressed for player 1 is put in here
|
||||||
local keyrecording2 = {}; -- every key pressed for player 2 is put in here
|
local keyrecording2 = {}; -- every key pressed for player 2 is put in here
|
||||||
|
local keyrecording3 = {}; -- every key pressed for player 3 is put in here
|
||||||
|
local keyrecording4 = {}; -- every key pressed for player 4 is put in here
|
||||||
|
|
||||||
-- some constants/macro's/whatever to make source easier to read
|
-- some constants/macro's/whatever to make source easier to read
|
||||||
local press = maxvalue;
|
local press = maxvalue;
|
||||||
|
@ -365,7 +371,7 @@ local function onInputEnd() -- code ran after getting input (lastkey are still v
|
||||||
-- ONINPUTEND
|
-- ONINPUTEND
|
||||||
end;
|
end;
|
||||||
|
|
||||||
-- the bot starts here..
|
-- the bot starts here.. (nothing is added from the user from this point onwards)
|
||||||
|
|
||||||
onStart(); -- run this code first
|
onStart(); -- run this code first
|
||||||
|
|
||||||
|
@ -373,9 +379,13 @@ segments[segment].savestate = savestate.create(); -- create anonymous save
|
||||||
savestate.save(segments[segment].savestate); -- save current state to it, it will be reloaded at the start of each frame
|
savestate.save(segments[segment].savestate); -- save current state to it, it will be reloaded at the start of each frame
|
||||||
local startkey1 = key1; -- save the last key pressed in the onStart. serves as an anchor for the first segment
|
local startkey1 = key1; -- save the last key pressed in the onStart. serves as an anchor for the first segment
|
||||||
local startkey2 = key2;
|
local startkey2 = key2;
|
||||||
|
local startkey3 = key3; -- save the last key pressed in the onStart. serves as an anchor for the first segment
|
||||||
|
local startkey4 = key4;
|
||||||
local startvars = vars; -- save the vars array (it might have been used by the onStart)
|
local startvars = vars; -- save the vars array (it might have been used by the onStart)
|
||||||
lastkey1 = key1; -- to enter the loop...
|
lastkey1 = key1; -- to enter the loop...
|
||||||
lastkey2 = key2;
|
lastkey2 = key2;
|
||||||
|
lastkey3 = key3;
|
||||||
|
lastkey4 = key4;
|
||||||
--FCEU.speedmode("maximum"); -- uncomment this line to make the bot run faster ("normal","turbo","maximum")
|
--FCEU.speedmode("maximum"); -- uncomment this line to make the bot run faster ("normal","turbo","maximum")
|
||||||
|
|
||||||
onSegmentStart();
|
onSegmentStart();
|
||||||
|
@ -429,8 +439,12 @@ while (rand_if(isRunEnd())) do
|
||||||
segments[segment].best.tie4 = segments[segment].prev.tie4;
|
segments[segment].best.tie4 = segments[segment].prev.tie4;
|
||||||
segments[segment].best.keys1 = keyrecording1; -- backup the recorded keys
|
segments[segment].best.keys1 = keyrecording1; -- backup the recorded keys
|
||||||
segments[segment].best.keys2 = keyrecording2; -- backup the recorded keys player 2
|
segments[segment].best.keys2 = keyrecording2; -- backup the recorded keys player 2
|
||||||
|
segments[segment].best.keys3 = keyrecording3; -- backup the recorded keys
|
||||||
|
segments[segment].best.keys4 = keyrecording4; -- backup the recorded keys player 2
|
||||||
segments[segment].best.lastkey1 = lastkey1; -- backup the lastkey
|
segments[segment].best.lastkey1 = lastkey1; -- backup the lastkey
|
||||||
segments[segment].best.lastkey2 = lastkey2; -- backup the lastkey
|
segments[segment].best.lastkey2 = lastkey2; -- backup the lastkey
|
||||||
|
segments[segment].best.lastkey3 = lastkey3; -- backup the lastkey
|
||||||
|
segments[segment].best.lastkey4 = lastkey4; -- backup the lastkey
|
||||||
segments[segment].best.vars = vars; -- backup the vars table
|
segments[segment].best.vars = vars; -- backup the vars table
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -454,6 +468,8 @@ while (rand_if(isRunEnd())) do
|
||||||
frame = 0;
|
frame = 0;
|
||||||
keyrecording1 = {}; -- reset the recordings :)
|
keyrecording1 = {}; -- reset the recordings :)
|
||||||
keyrecording2 = {};
|
keyrecording2 = {};
|
||||||
|
keyrecording3 = {};
|
||||||
|
keyrecording4 = {};
|
||||||
-- set lastkey to lastkey of previous segment (or start, if first segment)
|
-- set lastkey to lastkey of previous segment (or start, if first segment)
|
||||||
-- also set the vars table to the table of the previous segment
|
-- also set the vars table to the table of the previous segment
|
||||||
if (segment == 1) then
|
if (segment == 1) then
|
||||||
|
@ -463,6 +479,8 @@ while (rand_if(isRunEnd())) do
|
||||||
else
|
else
|
||||||
lastkey1 = segments[segment-1].best.lastkey1;
|
lastkey1 = segments[segment-1].best.lastkey1;
|
||||||
lastkey2 = segments[segment-1].best.lastkey2;
|
lastkey2 = segments[segment-1].best.lastkey2;
|
||||||
|
lastkey3 = segments[segment-1].best.lastkey3;
|
||||||
|
lastkey4 = segments[segment-1].best.lastkey4;
|
||||||
vars = segments[segment-1].best.vars;
|
vars = segments[segment-1].best.vars;
|
||||||
end;
|
end;
|
||||||
-- load the segment savestate to go back to the start of this segment
|
-- load the segment savestate to go back to the start of this segment
|
||||||
|
@ -486,6 +504,8 @@ while (rand_if(isRunEnd())) do
|
||||||
playingbest = false;
|
playingbest = false;
|
||||||
lastkey1 = segments[segment].best.lastkey1;
|
lastkey1 = segments[segment].best.lastkey1;
|
||||||
lastkey2 = segments[segment].best.lastkey2;
|
lastkey2 = segments[segment].best.lastkey2;
|
||||||
|
lastkey3 = segments[segment].best.lastkey3;
|
||||||
|
lastkey4 = segments[segment].best.lastkey4;
|
||||||
vars = segments[segment].best.vars;
|
vars = segments[segment].best.vars;
|
||||||
segment = segment + 1;
|
segment = segment + 1;
|
||||||
segments[segment] = {};
|
segments[segment] = {};
|
||||||
|
@ -495,10 +515,11 @@ while (rand_if(isRunEnd())) do
|
||||||
-- reset vars
|
-- reset vars
|
||||||
frame = 0; -- onSegmentStart and onAttemptStart expect this to be one fewer...
|
frame = 0; -- onSegmentStart and onAttemptStart expect this to be one fewer...
|
||||||
attempt = 1;
|
attempt = 1;
|
||||||
--key1 = {}; -- i dont think this has to be done just for the two events below. they get reset anyways before input.
|
|
||||||
--key2 = {};
|
|
||||||
keyrecording1 = {}; -- reset recordings :)
|
keyrecording1 = {}; -- reset recordings :)
|
||||||
keyrecording2 = {};
|
keyrecording2 = {};
|
||||||
|
keyrecording3 = {};
|
||||||
|
keyrecording4 = {};
|
||||||
-- after this, the next segment starts because playingbest is no longer true
|
-- after this, the next segment starts because playingbest is no longer true
|
||||||
onSegmentStart();
|
onSegmentStart();
|
||||||
onAttemptStart();
|
onAttemptStart();
|
||||||
|
@ -506,6 +527,8 @@ while (rand_if(isRunEnd())) do
|
||||||
else
|
else
|
||||||
key1 = segments[segment].best.keys1[frame]; -- fill keys with that of the best attempt
|
key1 = segments[segment].best.keys1[frame]; -- fill keys with that of the best attempt
|
||||||
key2 = segments[segment].best.keys2[frame];
|
key2 = segments[segment].best.keys2[frame];
|
||||||
|
key3 = segments[segment].best.keys3[frame];
|
||||||
|
key4 = segments[segment].best.keys4[frame];
|
||||||
gui.text(10,10,"Playback best of segment "..segment.."\nFrame: "..frame);
|
gui.text(10,10,"Playback best of segment "..segment.."\nFrame: "..frame);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -526,6 +549,8 @@ while (rand_if(isRunEnd())) do
|
||||||
|
|
||||||
key1 = {};
|
key1 = {};
|
||||||
key2 = {};
|
key2 = {};
|
||||||
|
key3 = {};
|
||||||
|
key4 = {};
|
||||||
|
|
||||||
onInputStart();
|
onInputStart();
|
||||||
|
|
||||||
|
@ -549,18 +574,44 @@ while (rand_if(isRunEnd())) do
|
||||||
if (rand_if(pressKeySelect2())) then key2.select = 1; end;
|
if (rand_if(pressKeySelect2())) then key2.select = 1; end;
|
||||||
if (rand_if(pressKeyStart2())) then key2.start = 1; end;
|
if (rand_if(pressKeyStart2())) then key2.start = 1; end;
|
||||||
|
|
||||||
|
-- player 3
|
||||||
|
if (rand_if(pressKeyUp3()) ) then key3.up = 1; end;
|
||||||
|
if (rand_if(pressKeyDown3())) then key3.down = 1; end;
|
||||||
|
if (rand_if(pressKeyLeft3())) then key3.left = 1; end;
|
||||||
|
if (rand_if(pressKeyRight3())) then key3.right = 1; end;
|
||||||
|
if (rand_if(pressKeyA3())) then key3.A = 1; end;
|
||||||
|
if (rand_if(pressKeyB3())) then key3.B = 1; end;
|
||||||
|
if (rand_if(pressKeySelect3())) then key3.select = 1; end;
|
||||||
|
if (rand_if(pressKeyStart3())) then key3.start = 1; end;
|
||||||
|
|
||||||
|
-- player 2
|
||||||
|
if (rand_if(pressKeyUp4()) ) then key4.up = 1; end;
|
||||||
|
if (rand_if(pressKeyDown4())) then key4.down = 1; end;
|
||||||
|
if (rand_if(pressKeyLeft4())) then key4.left = 1; end;
|
||||||
|
if (rand_if(pressKeyRight4())) then key4.right = 1; end;
|
||||||
|
if (rand_if(pressKeyA4())) then key4.A = 1; end;
|
||||||
|
if (rand_if(pressKeyB4())) then key4.B = 1; end;
|
||||||
|
if (rand_if(pressKeySelect4())) then key4.select = 1; end;
|
||||||
|
if (rand_if(pressKeyStart4())) then key4.start = 1; end;
|
||||||
|
|
||||||
onInputEnd();
|
onInputEnd();
|
||||||
|
|
||||||
lastkey1 = key1;
|
lastkey1 = key1;
|
||||||
lastkey2 = key2;
|
lastkey2 = key2;
|
||||||
|
lastkey3 = key3;
|
||||||
|
lastkey4 = key4;
|
||||||
|
|
||||||
keyrecording1[frame] = key1; -- record these keys
|
keyrecording1[frame] = key1; -- record these keys
|
||||||
keyrecording2[frame] = key2; -- record these keys
|
keyrecording2[frame] = key2; -- record these keys
|
||||||
|
keyrecording3[frame] = key3; -- record these keys
|
||||||
|
keyrecording4[frame] = key4; -- record these keys
|
||||||
end;
|
end;
|
||||||
|
|
||||||
-- actually set the keys here.
|
-- actually set the keys here.
|
||||||
joypad.set(1, key1);
|
joypad.set(1, key1);
|
||||||
joypad.set(2, key2);
|
joypad.set(2, key2);
|
||||||
|
joypad.set(3, key3);
|
||||||
|
joypad.set(4, key4);
|
||||||
|
|
||||||
-- next frame
|
-- next frame
|
||||||
FCEU.frameadvance();
|
FCEU.frameadvance();
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
-- BasicBot, a LuaBot frontend
|
-- BeeBee, BasicBot Frontend v1.06
|
||||||
-- qFox, 30 July 2008
|
|
||||||
-- version 1.04 (unstable load button!)
|
|
||||||
|
|
||||||
-- we need iup, so include it here
|
-- we need iup, so include it here
|
||||||
local iuplua_open = package.loadlib("iuplua51.dll", "iuplua_open");
|
local iuplua_open = package.loadlib("iuplua51.dll", "iuplua_open");
|
||||||
iuplua_open();
|
iuplua_open();
|
||||||
|
@ -37,12 +34,12 @@ function emu.OnCloseIup()
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function createTextareaTab(reftable, tmptable, token, tab, fun, val) -- specific one, at that :)
|
function createTextareaTab(reftable, tmptable, token, tab, fun, val) -- specific one, at that :)
|
||||||
reftable[token] = iup.multiline{title="Contents",expand="YES", border="YES",value=val};
|
reftable[token] = iup.multiline{title="Contents",expand="YES", border="YES" }; -- ,value=val};
|
||||||
tmptable[token] = iup.vbox{iup.label{title="function "..fun.."()\n local result = no;"},reftable[token],iup.label{title=" return result;\nend;"}};
|
tmptable[token] = iup.vbox{iup.label{title="function "..fun.."()\n local result = no;"},reftable[token],iup.label{title=" return result;\nend;"}};
|
||||||
tmptable[token].tabtitle = tab;
|
tmptable[token].tabtitle = tab;
|
||||||
end;
|
end;
|
||||||
function createTextareaTab2(reftable, tmptable, token, fun, arg) -- specific one, at that :) this one generates no return values
|
function createTextareaTab2(reftable, tmptable, token, fun, arg) -- specific one, at that :) this one generates no return values
|
||||||
reftable[token] = iup.multiline{title="Contents",expand="YES", border="YES",value=fun};
|
reftable[token] = iup.multiline{title="Contents",expand="YES", border="YES" }; --,value=fun};
|
||||||
if (arg) then
|
if (arg) then
|
||||||
tmptable[token] = iup.vbox{iup.label{title="function "..fun.."(wasOk) -- wasOk (boolean) is true when the attempt was ok\n"},reftable[token],iup.label{title="end;"}};
|
tmptable[token] = iup.vbox{iup.label{title="function "..fun.."(wasOk) -- wasOk (boolean) is true when the attempt was ok\n"},reftable[token],iup.label{title="end;"}};
|
||||||
else
|
else
|
||||||
|
@ -148,7 +145,7 @@ function createGUI(n)
|
||||||
tabs7.tabtitle = "Selection";
|
tabs7.tabtitle = "Selection";
|
||||||
|
|
||||||
playertabs = iup.tabs{general,tabs1,tabs2,tabs3,tabs4,tabs5,tabs6,tabs7,title};
|
playertabs = iup.tabs{general,tabs1,tabs2,tabs3,tabs4,tabs5,tabs6,tabs7,title};
|
||||||
handles[n] = iup.dialog{playertabs, title="Basic Bot Frontend", size="450x200"}
|
handles[n] = iup.dialog{playertabs, title="BeeBee; BasicBot Frontend", size="450x200"}
|
||||||
handles[n]:showxy(iup.CENTER, iup.CENTER)
|
handles[n]:showxy(iup.CENTER, iup.CENTER)
|
||||||
|
|
||||||
-- now set the callback function for the save button. this will use all the references above.
|
-- now set the callback function for the save button. this will use all the references above.
|
||||||
|
@ -242,22 +239,33 @@ function createGUI(n)
|
||||||
local file = iup.filedlg{allownew="NO",dialogtype="OPEN",directory="./lua",showhidden="YES",title="Save botfile",extfilter="BasicBot (*.bot)|*.bot|All files (*.*)|*.*|"};
|
local file = iup.filedlg{allownew="NO",dialogtype="OPEN",directory="./lua",showhidden="YES",title="Save botfile",extfilter="BasicBot (*.bot)|*.bot|All files (*.*)|*.*|"};
|
||||||
file:popup(iup.ANYWHERE,iup.ANYWHERE);
|
file:popup(iup.ANYWHERE,iup.ANYWHERE);
|
||||||
if (file.status == 1) then -- cancel
|
if (file.status == 1) then -- cancel
|
||||||
|
iup.Message ("Success", "Canceled by you...");
|
||||||
return;
|
return;
|
||||||
end;
|
end;
|
||||||
local nellen = string.len("\n"); -- platform independent
|
local nellen = string.len("\n"); -- platform independent
|
||||||
fh = assert(io.open(file.value,"r"));
|
fh = assert(io.open(file.value,"r"));
|
||||||
print("seek: "..fh:seek());
|
|
||||||
print("version: "..fh:read("*l"));
|
fh:read("*n"); -- version
|
||||||
print("seek: "..fh:seek());
|
fh:read("*l"); -- return
|
||||||
if (true) then return; end;
|
|
||||||
|
local len;
|
||||||
|
local data;
|
||||||
for token,crap in pairs(reftable) do
|
for token,crap in pairs(reftable) do
|
||||||
local len = fh:read("*n"); -- read line (length)
|
len = fh:read("*n"); -- read line (length)
|
||||||
if (not len) then break; end;
|
if (not len) then
|
||||||
fh:seek("set",fh:seek("cur", nellen)); -- remove the aesthetic return
|
iup.Message ("Warning", "End of file reached too soon!");
|
||||||
print(len);
|
break;
|
||||||
reftable[token].value = fh:read(len);
|
end; -- no more data... (should we erase the rest?)
|
||||||
fh:seek("set",fh:seek("cur", nellen)); -- remove the aesthetic return
|
fh:read("*l"); -- return
|
||||||
|
data = fh:read(len);
|
||||||
|
if (not data) then
|
||||||
|
iup.Message ("Warning", "End of file reached too soon!");
|
||||||
|
break;
|
||||||
|
end; -- no more data... (should we erase the rest?)
|
||||||
|
reftable[token].value = data;
|
||||||
|
fh:read("*l"); -- return
|
||||||
end;
|
end;
|
||||||
|
iup.Message ("Success", "Settings loaded!");
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue