console.clear()
local column={"a","b","c","d","e","f","g","h"}
local piece={"P", "N", "B", "R", "Q", "K"}
local values={a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,["1"]=1,["2"]=2,["3"]=3,["4"]=4,["5"]=5,["6"]=6,["7"]=7,["8"]=8}
--4BE-4FD (chessboard a8 b8 ...)
--0 empty 1 pawn 2 knight 3 bishop 4 rook 5 queen 6 king +0x80 black
--1fe can move? 20 yes anything else no
--3ea cpu thinking? 1 yes 0 no
--7d cursor 0-7 file a-h
--7e cursor 0-7 rank8-rank1
memory.usememorydomain("RAM")
local mbyte=memory.read_u8
local function nothing()
end
local hndl=forms.newform(400,800,"Battle Chess")
local label=forms.label(hndl,"hello",0,200,300,50)
local tb=forms.textbox(hndl,"e2e4",100,20,nil,30,30)
local automove_phase=0
local qq=forms.button(hndl,"Auto move",function()
--client.unpause()
forms.settext(label,"Auto-move start (unpause to continue)")
--need to savestate and loadstate to avoid losing a frame?
savestate.saveslot(7)
automove_phase=1
end,0,60,100,20)
local pacm_phase=0
local xx=forms.button(hndl,"Get next CPU move and pause",function()
client.unpause()
forms.settext(label,"Waiting for cpu's turn")
pacm_phase=1
end,0,90,300,20)
event.unregisterbyname("exit")
event.onexit(function()
forms.destroyall()
end, "exit")
local board = {}
local startx, starty, endx, endy, movingpiece, diffbyte
local cursorx,cursory, xoffset, yoffset
local cpumovetime=0
local key={}
while true do
if pacm_phase~=0 then
--monitor 3ea
if pacm_phase==1 then
local x=mbyte(0x3ea)
if x==1 then
pacm_phase=2
forms.settext(label,"CPU's turn")
cpumovetime=0
--get board
for i=0,63 do
board[i]=mbyte(0x4be+i)
end
end
elseif pacm_phase==2 then
local x=mbyte(0x3ea)
cpumovetime=cpumovetime+1
if x==0 then
pacm_phase=3
forms.settext(label,"CPU moving")
--find which piece was picked up
for i=0,63 do
if board[i]~=mbyte(0x4be+i) then
diffbyte=board[i]
startx=i%8+1
starty=8-math.floor(i/8)
movingpiece=diffbyte%0x80
end
end
end
elseif pacm_phase==3 then
local x=mbyte(0x1fe)
if x==20 then
--find where piece was moved
for i=0,63 do
if board[i]~=mbyte(0x4be+i) then
if mbyte(0x4be+i)==diffbyte then
endx=i%8+1
endy=8-math.floor(i/8)
end
end
end
forms.settext(label,"Done\nThe move was "..piece[movingpiece]..column[startx]..starty.."-"..column[endx]..endy.."\nCPU thinking time was "..cpumovetime.." frames")
pacm_phase=0
client.pause()
end
end
end
if automove_phase~=0 then
--check string validity
if automove_phase==1 then
--need to savestate and loadstate to avoid losing a frame?
savestate.loadslot(7)
local str=forms.gettext(tb)
if string.len(str)~=4 then
automove_phase=0
forms.settext(label,"Format should be something like e2e4 or 5254")
else
startx=values[string.sub(str,1,1)]
starty=values[string.sub(str,2,2)]
endx=values[string.sub(str,3,3)]
endy=values[string.sub(str,4,4)]
if not (startx and starty and endx and endy) then
automove_phase=0
forms.settext(label,"Format should be something like e2e4 or 5254")
else --OK
local x=mbyte(0x1fe)
if x~=20 then
automove_phase=0
forms.settext(label,"It's not your turn!")
else
automove_phase=2
end
end
end
end
if automove_phase==2 then
cursorx=mbyte(0x7d)+1
cursory=8-mbyte(0x7e)
xoffset = cursorx-startx
if xoffset>4 then xoffset=xoffset-8
elseif xoffset<-3 then xoffset=xoffset+8 end --between -3 and 4
yoffset = cursory-starty
if yoffset>4 then yoffset=yoffset-8
elseif yoffset<-3 then yoffset=yoffset+8 end
key.Left="False"
key.Right="False"
key.Down="False"
key.Up="False"
key.A="False"
if xoffset>0 then key.Left="True" end --need to go left
if xoffset<0 then key.Right="True" end --need to go right
if yoffset>0 then key.Down="True" end --need to go down
if yoffset<0 then key.Up="True" end --need to go up
automove_phase=3
if xoffset==0 and yoffset==0 then
key.A="True"
automove_phase=5
end --correct
joypad.set(key,1)
elseif automove_phase==3 then
automove_phase=2
elseif automove_phase==4 then
cursorx=mbyte(0x7d)+1
cursory=8-mbyte(0x7e)
xoffset = cursorx-endx
if xoffset>4 then xoffset=xoffset-8
elseif xoffset<-3 then xoffset=xoffset+8 end --between -3 and 4
yoffset = cursory-endy
if yoffset>4 then yoffset=yoffset-8
elseif yoffset<-3 then yoffset=yoffset+8 end
key.Left="False"
key.Right="False"
key.Down="False"
key.Up="False"
key.A="False"
if xoffset>0 then key.Left="True" end --need to go left
if xoffset<0 then key.Right="True" end --need to go right
if yoffset>0 then key.Down="True" end --need to go down
if yoffset<0 then key.Up="True" end --need to go up
automove_phase=5
if xoffset==0 and yoffset==0 then
key.A="True"
forms.settext(label,"Done auto move")
automove_phase=0
end --correct
joypad.set(key,1)
elseif automove_phase==5 then
automove_phase=4
end
end
emu.frameadvance()
end