Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local modem = peripheral.wrap("bottom")
- local chessFreq = 4632
- modem.open(chessFreq)
- local chat = peripheral.wrap("back")
- local moni = peripheral.wrap("left")
- local f = fs.open("board","r")
- local board = textutils.unserialize(f.readAll())
- f.close()
- local player1,player2
- local useTouch1,useTouch2=true,true
- local pos1
- local whiteTurn=true
- local turtlesBusy={}
- function reset()
- local startPos = {{"rw","pw","","","","","pb","rb"},{"hw","pw","","","","","pb","hb"},{"bw","pw","","","","","pb","bb"},{"qw","pw","","","","","pb","qb"},{"kw","pw","","","","","pb","kb"},{"bw","pw","","","","","pb","bb"},{"hw","pw","","","","","pb","hb"},{"rw","pw","","","","","pb","rb"}}
- for i=1,8 do
- for j=1,8 do
- if board[i][j]~=startPos[i][j] and board[i][j]~="" then
- sendMove(i,j,false,board[i][j])
- board[i][j]=""
- end
- end
- end
- for i=1,8 do
- for j=1,8 do
- if board[i][j]~=startPos[i][j] then
- sendMove(i,j,true,startPos[i][j])
- board[i][j]=startPos[i][j]
- end
- end
- end
- player1= nil
- player2= nil
- useTouch1,useTouch2=true,true
- whiteTurn=true
- save()
- end
- function save()
- local f = fs.open("board","w")
- f.write(textutils.serialize(board))
- f.close()
- end
- moni.setBackgroundColor(colors.lightBlue)
- moni.setTextColor(colors.gray)
- moni.clear()
- function drawBoard()
- for i=1,8 do
- for k=0,1 do
- moni.setCursorPos(2,i*2+k)
- for j=1,8 do
- moni.setBackgroundColor((pos1~=nil and pos1[1]==i and pos1[2]==j and colors.red) or ((i+j)%2==0 and colors.black) or colors.white)
- moni.setTextColor(board[i][j]:sub(2,2)=="w" and colors.lightGray or colors.gray)
- moni.write(board[i][j]~="" and k==1 and " "..board[i][j]:sub(1,1):upper().." " or " ")
- end
- end
- end
- end
- local moves = {p={{0,1}},h={{2,-1},{2,1},{1,2},{1,-2},{-2,1},{-2,-1},{-1,2},{-1,-2}},k={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{-1,-1},{1,-1}}}
- local directions = {r={{1,0},{-1,0},{0,1},{0,-1}},b={{1,1},{-1,1},{-1,-1},{1,-1}},q={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{-1,-1},{1,-1}}}
- function couldMove(sx,sy,tx,ty)
- if sx<1 or sx>8 or sy<1 or sy>8 or tx<1 or tx>8 or ty<1 or ty>8 then
- return false
- end
- if moves[board[sx][sy]:sub(1,1)] then
- for i,j in pairs(moves[board[sx][sy]:sub(1,1)]) do
- if sx+j[1]==tx and (board[sx][sy]:sub(2,2)=="w" and sy+j[2] or sy-j[2])==ty and (board[tx][ty]=="" or board[sx][sy]:sub(1,1)~="p") then
- return true
- end
- end
- end
- if directions[board[sx][sy]:sub(1,1)] then
- for i,j in pairs(directions[board[sx][sy]:sub(1,1)]) do
- local k=1
- while sx+k*j[1]<=8 and sx+k*j[1] >=1 and sy+k*j[2]<=8 and sy+k*j[2]>=1 and board[sx+k*j[1]][sy+k*j[2]]=="" and sx+k*j[1]~=tx and sy+k*j[2]~=ty do
- k=k+1
- end
- if sx+k*j[1]==tx and sy+k*j[2]==ty then
- return true
- end
- end
- end
- --spezial moves
- --[[pawn moves
- if (board[sx][sy]=="pw" and sy==2 and ty==4 and board[sx][3]=="" and board[sx][4]=="") or (board[sx][sy]=="pb" and sy==7 and ty==5 and board[sx][6]=="" and board[sx][5]=="") and sx==tx then
- return true
- end
- if board[tx][ty]~="" and board[tx][ty]:sub(2,2)~=board[sx][sy]:sub(2,2) and (sx+1==tx or sx-1==tx) and (((board[sx][sy]:sub(2,2)=="w" and 1 or -1)+sy==ty) or ((board[sx][sy]:sub(2,2)=="w" and 5 or 4)==sy and ty==sy)) then
- return true
- end
- --Castling
- if board[sx][sy]:sub(1,1)=="k" and sx==5 and ((tx==3 and board[tx][1]:sub(1,1)=="r" and board[2][ty]=="" and board[3][ty]=="" and board[4][ty]=="") or (tx==7 and board[8][ty]:sub(1,1)=="r" and board[7][ty]=="" and board[6][ty]=="")) and sy==ty and (board[sx][sy]:sub(2,2)=="w" and 1 or 8)==sy then
- return true
- end
- return false]]--
- end
- function isCheck(color)
- local kx,ky=0,0
- for i=1,8 do
- for j=1,8 do
- if board[i][j]==("k"..color) then
- kx,ky=i,j
- end
- end
- end
- for i=1,8 do
- for j=1,8 do
- if board[i][j]:sub(2,2)~=color and couldMove(i,j,kx,ky) then
- chat.tell(color=="w" and player1 or player2 or "Nobody","Check!")
- return true
- end
- end
- end
- return false
- end
- function canMove(sx,sy,tx,ty)
- if not couldMove(sx,sy,tx,ty) then
- return false
- end
- if not isCheck(board[sx][sy]:sub(2,2)) then
- return couldMove(sx,sy,tx,ty)
- end
- local altBoard = {}
- for i=1,8 do
- altBoard[i] = {}
- for j=1,8 do
- altBoard[i][j] = board[i][j]
- end
- end
- noteMove(sx,sy,tx,ty)
- local result = isCheck(board[sx][sy]:sub(2,2))
- for i=1,8 do
- for j=1,8 do
- board[i][j] = altBoard[i][j]
- end
- end
- save()
- return not result
- end
- function noteMove(sx,sy,tx,ty)
- --[[if board[sx][sy]:sub(1,1)=="k" and sy==5 and ((ty==3) or (ty==7)) and sx==tx and (board[sx][sy]:sub(2,2)=="w" and 1 or 8)==sx then
- board[sx][ty==3 and 4 or 6]=board[sx][ty==3 and 1 or 8]
- board[sx][ty==3 and 1 or 8]=""
- board[sx][ty]=board[sx][sy]
- board[sx][sy]=""
- else]]--
- board[tx][ty]=board[sx][sy]
- board[sx][sy]=""
- --[[if board[tx][ty]:sub(1,1)=="p" and (board[tx][ty]:sub(2,2)=="w" and 8 or 1)==tx then
- board[tx][ty]="q"..board[tx][ty]:sub(2,2)
- end
- end ]]--
- save()
- end
- function sendMove(sx,sy,build,piece)
- if not turtlesBusy[string.char(sx+64)..tostring(sy)] then
- modem.transmit(chessFreq,chessFreq,string.char(sx+64)..tostring(sy)..(build and " build " or " break ")..piece)
- turtlesBusy[string.char(sx+64)..tostring(sy)]={}
- end
- table.insert(turtlesBusy[string.char(sx+64)..tostring(sy)],string.char(sx+64)..tostring(sy)..(build and " build " or " break ")..piece)
- end
- function move(sx,sy,tx,ty)
- if board[sx][sy]:sub(1,1)=="k" and sy==5 and ((ty==3) or (ty==7)) and sx==tx and (board[sx][sy]:sub(2,2)=="w" and 1 or 8)==sx then
- sendMove(sx,sy,false,board[sx][sy])
- sendMove(sx,ty==3 and 1 or 8,false,board[sx][(ty==3 and 1 or 8)])
- sendMove(sx,ty,true,board[sx][sy])
- sendMove(sx,ty==3 and 4 or 6,true,board[sx][(ty==3 and 1 or 8)])
- --elseif board[tx][ty]:sub(1,1)=="p" and (board[tx][ty]:sub(2,2)=="w" and 8 or 1)==tx then
- -- modem.transmit(chessFreq,chessFreq,string.char(sy+64)..tostring(sx).." break "..board[sx][sy])
- -- modem.transmit(chessFreq,chessFreq,string.char(sy+64)..tostring(sx).." build q"..board[sx][sy]:sub(2,2))
- else
- if board[tx][ty]~="" then
- sendMove(tx,ty,false,board[tx][ty])
- end
- sendMove(sx,sy,false,board[sx][sy])
- sendMove(tx,ty,true,board[sx][sy])
- end
- noteMove(sx,sy,tx,ty)
- end
- function findMove(piece,tx,ty)
- for i=1,8 do
- for j=1,8 do
- if board[i][j]==piece and canMove(i,j,tx,ty) then
- whiteTurn = not whiteTurn
- move(i,j,tx,ty)
- return true
- end
- end
- end
- return false
- end
- local short={pawn="p",queen="q",knight="h",horse="h",bishop="b",rook="r",tower="r",king="k"}
- while true do
- drawBoard()
- local event = {os.pullEvent()}
- if event[1]=="monitor_touch" and ((whiteTurn and useTouch1) or (not whiteTurn and useTouch2)) then
- if not pos1 then
- pos1={math.min(math.floor((event[4]-2)/2)+1,8),math.min(math.floor((event[3]-2)/3)+1,8)}
- if board[pos1[1]][pos1[2]]:sub(2,2)==(whiteTurn and "b" or "w") then
- chat.say("It is "..(whiteTurn and "white" or "black").."'s turn!")
- pos1=nil
- elseif board[pos1[1]][pos1[2]]=="" then
- chat.say("That place is empty")
- pos1=nil
- end
- else
- local step={math.min(math.floor((event[4]-2)/2)+1,8),math.min(math.floor((event[3]-2)/3)+1,8)}
- if canMove(pos1[1],pos1[2],step[1],step[2]) then
- move(pos1[1],pos1[2],step[1],step[2])
- whiteTurn = not whiteTurn
- else
- chat.say("Invalid Move")
- end
- pos1 = nil
- end
- end
- if event[1]=="key" and event[2]==59 then
- reset()
- end
- if event[1]=="key" and event[2]==63 then
- for i,j in pairs(turtlesBusy) do
- for o,p in ipairs(j) do
- print(p)
- end
- end
- end
- if event[1]=="chat" then
- if player1 and player2 then
- if (whiteTurn and event[2]==player1 or event[2]==player2) then
- local spot = event[3]:find("[ABCDEFGH][12345678]")
- local spot2= event[3]:find("[ABCDEFGH][12345678]",(spot or 0)+2)
- if spot2 then
- if canMove(string.byte(event[3]:sub(spot,spot))-64,tonumber(event[3]:sub(spot+1,spot+1)),
- string.byte(event[3]:sub(spot2,spot2))-64,tonumber(event[3]:sub(spot2+1,spot2+1))) then
- whiteTurn = not whiteTurn
- move(string.byte(event[3]:sub(spot,spot))-64,tonumber(event[3]:sub(spot+1,spot+1)),
- string.byte(event[3]:sub(spot2,spot2))-64,tonumber(event[3]:sub(spot2+1,spot2+1)))
- end
- else
- for i,j in pairs(short) do
- if event[3]:find(i) and spot then
- if not findMove(j..(whiteTurn and "w" or "b"),string.byte(event[3]:sub(spot,spot))-64,tonumber(event[3]:sub(spot+1,spot+1))) then
- chat.tell(whiteTurn and player1 or player2,"Invalid Move")
- end
- end
- end
- end
- end
- if event[3]=="toggle monitor" and (event[2]==player1 or event[2]==player2) then
- if event[2]==player1 then
- useTouch1 = not useTouch1
- chat.tell(player1,"Touchscreen usage on monitor "..(useTouch1 and "enabled!" or "disabled!"))
- else
- useTouch2 = not useTouch2
- chat.tell(player2,"Touchscreen usage on monitor "..(useTouch2 and "enabled!" or "disabled!"))
- end
- end
- if event[3]=="surrender" and (event[2]==player1 or event[2]==player2) then
- chat.say((event[2]==player1 and player2 or player1).." won the game!")
- reset()
- end
- else
- if event[3]=="offer chess party" then
- chat.say("Answer 'accept' to play")
- player1 = event[2]
- end
- if event[3]=="accept" and player1~=event[2] then
- player2 = event[2]
- chat.say(player2.." accepted! Maybe the game begin. Say 'A2 to A3' or 'pawn to A3' to move. Say 'surrender' to surrender!")
- end
- end
- end
- if event[1]=="modem_message" and #event[5]==7 then
- table.remove(turtlesBusy[event[5]:sub(1,2)],1)
- if #turtlesBusy[event[5]:sub(1,2)]==0 then
- turtlesBusy[event[5]:sub(1,2)]=nil
- else
- modem.transmit(chessFreq,chessFreq,turtlesBusy[event[5]:sub(1,2)])
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment