Lion4ever

chess

Aug 30th, 2013
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.71 KB | None | 0 0
  1. local modem = peripheral.wrap("bottom")
  2. local chessFreq = 4632
  3. modem.open(chessFreq)
  4. local chat = peripheral.wrap("back")
  5. local moni = peripheral.wrap("left")
  6. local f = fs.open("board","r")
  7. local board = textutils.unserialize(f.readAll())
  8. f.close()
  9. local player1,player2
  10. local useTouch1,useTouch2=true,true
  11. local pos1
  12. local whiteTurn=true
  13. local turtlesBusy={}
  14.  
  15. function reset()
  16.     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"}}
  17.     for i=1,8 do
  18.         for j=1,8 do
  19.             if board[i][j]~=startPos[i][j] and board[i][j]~="" then
  20.                 sendMove(i,j,false,board[i][j])
  21.                 board[i][j]=""
  22.             end
  23.         end
  24.     end
  25.     for i=1,8 do
  26.         for j=1,8 do
  27.             if board[i][j]~=startPos[i][j] then
  28.                 sendMove(i,j,true,startPos[i][j])
  29.                 board[i][j]=startPos[i][j]
  30.             end
  31.         end
  32.     end
  33.     player1= nil
  34.     player2= nil
  35.     useTouch1,useTouch2=true,true
  36.     whiteTurn=true
  37.     save()
  38. end
  39. function save()
  40.     local f = fs.open("board","w")
  41.     f.write(textutils.serialize(board))
  42.     f.close()
  43. end
  44. moni.setBackgroundColor(colors.lightBlue)
  45. moni.setTextColor(colors.gray)
  46. moni.clear()
  47. function drawBoard()
  48.     for i=1,8 do
  49.         for k=0,1 do
  50.             moni.setCursorPos(2,i*2+k)
  51.             for j=1,8 do
  52.                 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)
  53.                 moni.setTextColor(board[i][j]:sub(2,2)=="w" and colors.lightGray or colors.gray)
  54.                 moni.write(board[i][j]~="" and k==1 and " "..board[i][j]:sub(1,1):upper().." " or "   ")
  55.             end
  56.         end
  57.     end
  58. end
  59. 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}}}
  60. 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}}}
  61. function couldMove(sx,sy,tx,ty)
  62.     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
  63.         return false
  64.     end
  65.     if moves[board[sx][sy]:sub(1,1)] then
  66.         for i,j in pairs(moves[board[sx][sy]:sub(1,1)]) do
  67.             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
  68.                 return true
  69.             end
  70.         end
  71.     end
  72.     if directions[board[sx][sy]:sub(1,1)] then
  73.         for i,j in pairs(directions[board[sx][sy]:sub(1,1)]) do
  74.             local k=1
  75.             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
  76.                 k=k+1
  77.             end
  78.             if sx+k*j[1]==tx and sy+k*j[2]==ty then
  79.                 return true
  80.             end
  81.         end
  82.     end
  83.     --spezial moves
  84.     --[[pawn moves
  85.     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
  86.         return true
  87.     end
  88.     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
  89.         return true
  90.     end
  91.     --Castling
  92.     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
  93.         return true
  94.     end
  95.     return false]]--
  96. end
  97. function isCheck(color)
  98.     local kx,ky=0,0
  99.     for i=1,8 do
  100.         for j=1,8 do
  101.             if board[i][j]==("k"..color) then
  102.                 kx,ky=i,j
  103.             end
  104.         end
  105.     end
  106.     for i=1,8 do
  107.         for j=1,8 do
  108.             if board[i][j]:sub(2,2)~=color and couldMove(i,j,kx,ky) then
  109.                 chat.tell(color=="w" and player1 or player2 or "Nobody","Check!")
  110.                 return true
  111.             end
  112.         end
  113.     end
  114.     return false
  115. end
  116. function canMove(sx,sy,tx,ty)
  117.     if not couldMove(sx,sy,tx,ty) then
  118.         return false
  119.     end
  120.     if not isCheck(board[sx][sy]:sub(2,2)) then
  121.         return couldMove(sx,sy,tx,ty)
  122.     end
  123.     local altBoard = {}
  124.     for i=1,8 do
  125.         altBoard[i] = {}
  126.         for j=1,8 do
  127.             altBoard[i][j] = board[i][j]
  128.         end
  129.     end
  130.     noteMove(sx,sy,tx,ty)
  131.     local result = isCheck(board[sx][sy]:sub(2,2))
  132.     for i=1,8 do
  133.         for j=1,8 do
  134.             board[i][j] = altBoard[i][j]
  135.         end
  136.     end
  137.     save()
  138.     return not result
  139. end
  140. function noteMove(sx,sy,tx,ty)
  141.     --[[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
  142.         board[sx][ty==3 and 4 or 6]=board[sx][ty==3 and 1 or 8]
  143.         board[sx][ty==3 and 1 or 8]=""
  144.         board[sx][ty]=board[sx][sy]
  145.         board[sx][sy]=""
  146.     else]]--
  147.         board[tx][ty]=board[sx][sy]
  148.         board[sx][sy]=""
  149.         --[[if board[tx][ty]:sub(1,1)=="p" and (board[tx][ty]:sub(2,2)=="w" and 8 or 1)==tx then
  150.             board[tx][ty]="q"..board[tx][ty]:sub(2,2)
  151.         end
  152.     end ]]--
  153.     save()
  154. end
  155. function sendMove(sx,sy,build,piece)
  156.     if not turtlesBusy[string.char(sx+64)..tostring(sy)] then
  157.         modem.transmit(chessFreq,chessFreq,string.char(sx+64)..tostring(sy)..(build and " build " or " break ")..piece)
  158.         turtlesBusy[string.char(sx+64)..tostring(sy)]={}
  159.     end
  160.     table.insert(turtlesBusy[string.char(sx+64)..tostring(sy)],string.char(sx+64)..tostring(sy)..(build and " build " or " break ")..piece)
  161. end
  162. function move(sx,sy,tx,ty)
  163.     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
  164.         sendMove(sx,sy,false,board[sx][sy])
  165.         sendMove(sx,ty==3 and 1 or 8,false,board[sx][(ty==3 and 1 or 8)])
  166.         sendMove(sx,ty,true,board[sx][sy])
  167.         sendMove(sx,ty==3 and 4 or 6,true,board[sx][(ty==3 and 1 or 8)])
  168.     --elseif board[tx][ty]:sub(1,1)=="p" and (board[tx][ty]:sub(2,2)=="w" and 8 or 1)==tx then
  169.     --  modem.transmit(chessFreq,chessFreq,string.char(sy+64)..tostring(sx).." break "..board[sx][sy])
  170.     --  modem.transmit(chessFreq,chessFreq,string.char(sy+64)..tostring(sx).." build q"..board[sx][sy]:sub(2,2))
  171.     else
  172.         if board[tx][ty]~="" then
  173.             sendMove(tx,ty,false,board[tx][ty])
  174.         end
  175.         sendMove(sx,sy,false,board[sx][sy])
  176.         sendMove(tx,ty,true,board[sx][sy])
  177.     end
  178.     noteMove(sx,sy,tx,ty)
  179. end
  180. function findMove(piece,tx,ty)
  181. for i=1,8 do
  182.     for j=1,8 do
  183.         if board[i][j]==piece and canMove(i,j,tx,ty) then
  184.             whiteTurn = not whiteTurn
  185.             move(i,j,tx,ty)
  186.             return true
  187.         end
  188.     end
  189. end
  190. return false
  191. end
  192. local short={pawn="p",queen="q",knight="h",horse="h",bishop="b",rook="r",tower="r",king="k"}
  193. while true do
  194.     drawBoard()
  195.     local event = {os.pullEvent()}
  196.     if event[1]=="monitor_touch" and ((whiteTurn and useTouch1) or (not whiteTurn and useTouch2)) then
  197.         if not pos1 then
  198.             pos1={math.min(math.floor((event[4]-2)/2)+1,8),math.min(math.floor((event[3]-2)/3)+1,8)}
  199.             if board[pos1[1]][pos1[2]]:sub(2,2)==(whiteTurn and "b" or "w") then
  200.                 chat.say("It is "..(whiteTurn and "white" or "black").."'s turn!")
  201.                 pos1=nil
  202.             elseif board[pos1[1]][pos1[2]]=="" then
  203.                 chat.say("That place is empty")
  204.                 pos1=nil
  205.             end
  206.         else
  207.             local step={math.min(math.floor((event[4]-2)/2)+1,8),math.min(math.floor((event[3]-2)/3)+1,8)}
  208.             if canMove(pos1[1],pos1[2],step[1],step[2]) then
  209.                 move(pos1[1],pos1[2],step[1],step[2])
  210.                 whiteTurn = not whiteTurn
  211.             else
  212.                 chat.say("Invalid Move")
  213.             end
  214.             pos1 = nil
  215.         end
  216.     end
  217.     if event[1]=="key" and event[2]==59 then
  218.         reset()
  219.     end
  220.     if event[1]=="key" and event[2]==63 then
  221.         for i,j in pairs(turtlesBusy) do
  222.             for o,p in ipairs(j) do
  223.                 print(p)
  224.             end
  225.         end
  226.     end
  227.     if event[1]=="chat" then
  228.         if player1 and player2 then
  229.             if (whiteTurn and event[2]==player1 or event[2]==player2) then
  230.                 local spot = event[3]:find("[ABCDEFGH][12345678]")
  231.                 local spot2= event[3]:find("[ABCDEFGH][12345678]",(spot or 0)+2)
  232.                 if spot2 then              
  233.                     if canMove(string.byte(event[3]:sub(spot,spot))-64,tonumber(event[3]:sub(spot+1,spot+1)),
  234.                         string.byte(event[3]:sub(spot2,spot2))-64,tonumber(event[3]:sub(spot2+1,spot2+1))) then
  235.                         whiteTurn = not whiteTurn
  236.                         move(string.byte(event[3]:sub(spot,spot))-64,tonumber(event[3]:sub(spot+1,spot+1)),
  237.                         string.byte(event[3]:sub(spot2,spot2))-64,tonumber(event[3]:sub(spot2+1,spot2+1)))
  238.                     end
  239.                 else
  240.                     for i,j in pairs(short) do
  241.                         if event[3]:find(i) and spot then
  242.                             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
  243.                                 chat.tell(whiteTurn and player1 or player2,"Invalid Move")
  244.                             end
  245.                         end
  246.                     end
  247.                 end
  248.             end
  249.             if event[3]=="toggle monitor" and (event[2]==player1 or event[2]==player2) then
  250.                 if event[2]==player1 then
  251.                     useTouch1 = not useTouch1
  252.                     chat.tell(player1,"Touchscreen usage on monitor "..(useTouch1 and "enabled!" or "disabled!"))
  253.                 else
  254.                     useTouch2 = not useTouch2
  255.                     chat.tell(player2,"Touchscreen usage on monitor "..(useTouch2 and "enabled!" or "disabled!"))
  256.                 end
  257.             end
  258.             if event[3]=="surrender" and (event[2]==player1 or event[2]==player2) then
  259.                 chat.say((event[2]==player1 and player2 or player1).." won the game!")
  260.                 reset()
  261.             end
  262.         else
  263.             if event[3]=="offer chess party" then
  264.                 chat.say("Answer 'accept' to play")
  265.                 player1 = event[2]
  266.             end
  267.             if event[3]=="accept" and player1~=event[2] then
  268.                 player2 = event[2]
  269.                 chat.say(player2.." accepted! Maybe the game begin. Say 'A2 to A3' or 'pawn to A3' to move. Say 'surrender' to surrender!")
  270.             end
  271.         end
  272.     end
  273.     if event[1]=="modem_message" and #event[5]==7 then
  274.         table.remove(turtlesBusy[event[5]:sub(1,2)],1)
  275.         if #turtlesBusy[event[5]:sub(1,2)]==0 then
  276.             turtlesBusy[event[5]:sub(1,2)]=nil
  277.         else
  278.             modem.transmit(chessFreq,chessFreq,turtlesBusy[event[5]:sub(1,2)])
  279.         end
  280.     end
  281. end
Advertisement
Add Comment
Please, Sign In to add comment