User File #638045376344965016

Upload All User Files

#638045376344965016 - Battle Chess Lua form (actually uses forms!)

battlechessform.lua
Game: Battle Chess ( NES, see all files )
116 downloads
Uploaded 11/20/2022 10:40 AM by FractalFusion (see all 87)
Just a small script to reduce the tedium of entering moves and waiting for CPU to move (especially on the hardest difficulty).
  • Auto move allows to enter the move and the script will execute the move optimally (type in move like "e2e4"; "5254" is also acceptable). Must be run when it is your turn.
  • Option to go forward until CPU finishes moving (to the beginning of your turn), then pauses. Will also return information such as what the CPU's move was, as well as CPU thinking time for the move. Must be run during your turn (before or during your move).
Script may be buggy; may not recognize CPU pawn promotion moves. The script is dumb and cannot tell when captures, castling, pawn promotion and/or en passant has occurred. All it cares about is the starting square and the ending square.
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