Advertisement
zigwin

#connect4

Jul 14th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.39 KB | None | 0 0
  1. -- #connect4 - lua script by Zigwin
  2.  
  3. -- ! magic do not touch !
  4. -- ! магия . не трогать !
  5. do local _,name = pcall(nil) admin = string.match(name, "(.-)%.") end
  6.  
  7. --[[ Settings / Настройки --]]
  8.  
  9. -- "ru" - Русский
  10. -- "en" - English
  11. local language = tfm.get.room.playerList[admin].community
  12.  
  13. -- If you sure you can change these
  14. -- Если уверены можете изменить опции ниже
  15.  
  16. -- Debug mode
  17. -- Режим отладки
  18. local debug = false
  19.  
  20. -- Amount of people that can play at once
  21. -- Should NOT be greather than 8. Recommended to play with 2 players
  22. -- Количество людей которые могут играть одновременно
  23. -- НЕ должно превышать 8. Рекомендуется играть вдвоем
  24. local maximumPlayers = 2
  25.  
  26. -- 1 or 2
  27. -- 1 или 2
  28. local turnsPerPlayer = 1
  29.  
  30.  
  31. -- ! magic do not touch anything below !
  32.  
  33. -- Init Values
  34.  
  35. -- Vars
  36. local grid = {}
  37. local playerData = {}
  38. local queue = {}
  39. local players = {}      -- Players that in game
  40. local isGameOn = false
  41. local turn = 1
  42.  
  43. -- Const
  44.  
  45. local colors = {
  46.     [1] = 0xb13e53, -- Red
  47.     [2] = 0x3b5dc9, -- Blue
  48.     [3] = 0x5d275d, -- Magenta
  49.     [4] = 0xef7d57, -- Orange
  50.     [5] = 0x41a6f6, -- Cyan
  51.     [6] = 0xa7f070, -- Green
  52.     [7] = 0xf4f4f4, -- White
  53.     [8] = 0x1a1c2c, -- Black
  54. }
  55. local colors2 = {
  56.     [1] = "#b13e53", -- Red
  57.     [2] = "#3b5dc9", -- Blue
  58.     [3] = "#5d275d", -- Magenta
  59.     [4] = "#ef7d57", -- Orange
  60.     [5] = "#41a6f6", -- Cyan
  61.     [6] = "#a7f070", -- Green
  62.     [7] = "#f4f4f4", -- White
  63.     [8] = "#1a1c2c", -- Black
  64. }
  65.  
  66. text = {
  67.     ru = {
  68.         join = "Присоединиться",
  69.         cancel = "Отмена",
  70.         queue = "Очередь",
  71.     },
  72.     en = {
  73.         join = "Join",
  74.         cancel = "Cancel",
  75.         queue = "Queue",
  76.     }
  77. }
  78.  
  79. if not text[language] then
  80.     language = "en"
  81. end
  82.  
  83. --[[ Main --]]
  84.  
  85. -- Init player
  86.  
  87. function eventNewPlayer(playerName, _)
  88.     playerData[playerName] = {
  89.         team = 0,
  90.         isPlaying = false,
  91.         inQueue = false
  92.     }
  93.  
  94.     if not _ then
  95.         -- Draw things if new player comes to room
  96.         drawQueue()
  97.         drawTurns()
  98.         drawGrid()
  99.         -- Map name
  100.         ui.setMapName("<j>#connect4</j> <bl>- Zigwin</bl>")
  101.         -- Respawn
  102.         tfm.exec.respawnPlayer(playerName)
  103.     end
  104. end
  105.  
  106. for playerName in next, tfm.get.room.playerList do
  107.     eventNewPlayer(playerName, true)
  108. end
  109.  
  110. function initGame()
  111.     -- Set game on and init settings
  112.     isGameOn = true
  113.  
  114.     for i = 1, maximumPlayers do
  115.         players[i] = queue[i]
  116.         playerData[players[i]].team = i
  117.         playerData[players[i]].isPlaying = true
  118.         playerData[players[i]].inQueue = false
  119.     end
  120.     for i = 1, maximumPlayers do
  121.         table.remove(queue, 1)
  122.     end
  123.     -- Remove winner text
  124.     ui.removeTextArea(100)
  125.     ui.removeTextArea(101)
  126.     -- Clear grid
  127.     for x = 1, 7 do
  128.         grid[x] = {}
  129.         for y = 1, 6 do
  130.             grid[x][y] = 0
  131.             -- Remove circles
  132.             tfm.exec.removePhysicObject(100+x*10+y)
  133.         end
  134.     end
  135.     -- Draw for new players
  136.     for x = 1, 7 do
  137.         for y = 1, 6 do
  138.             tfm.exec.addPhysicObject(x..y, 200 + x * 50, y * 50 + 70, {
  139.                 type            = 13,
  140.                 width           = 20,
  141.                 color           = 0x6A7495,
  142.                 miceCollision   = false,
  143.                 groundCollision = false
  144.             })
  145.         end
  146.     end
  147.     -- First turn to random player
  148.     turn = math.random(1, #players)
  149.  
  150.     -- Draw UI
  151.     drawQueue()
  152.     drawTurns()
  153.     drawGrid()
  154. end
  155.  
  156. function eventChatCommand(playerName, command)
  157.     if not playerData[playerName].isPlaying then
  158.         -- Queue System
  159.         if command == "join" then
  160.             -- Add
  161.             if not playerData[playerName].inQueue then
  162.                 playerData[playerName].inQueue = true
  163.                 queue[#queue + 1] = playerName
  164.                 print("\n"..playerName.." join queue :"..table.concat(queue, "\n"))
  165.                 drawQueue()
  166.             end
  167.         elseif command == "cancel" then
  168.             -- Remove
  169.             if playerData[playerName].inQueue then
  170.                 playerData[playerName].inQueue = false
  171.                 for index, name in next, queue do
  172.                     if name == playerName then
  173.                         table.remove(queue, index)
  174.                         print("\n"..playerName.." left queue :"..table.concat(queue, "\n"))
  175.                         drawQueue()
  176.                         break
  177.                     end
  178.                 end
  179.             end
  180.         end
  181.     end
  182. end
  183.  
  184. --[[
  185.  
  186. 0 - Empty
  187. 1 - 1 Team
  188. 2 - 2 Team
  189.  
  190. --]]
  191.  
  192. function drawGrid()
  193.     if debug then
  194.         for x = 1, 7 do
  195.             for y = 1, 6 do
  196.                 local color = colors[grid[x][y]]
  197.                 ui.addTextArea(x..y, "", nil, 180 + x * 50, y * 50 + 50, 40, 40, nil, color, 0.5)
  198.             end
  199.         end
  200.     end
  201.     for x = 1, 7 do
  202.         ui.addTextArea(x, "<a href='event:grid'>\t\t\t\n\t\t\t\n\t\t\t\n", nil, 180 + x * 50, 50, 40, 40, 0x00ff00, 0x00ff00, 0.25)
  203.     end
  204. end
  205.  
  206. function drawQueue()
  207.     --"<b><v><p align='center'>Queue</p></v></b>\n<j>1. <b>Tigrounette#0001</b></j>\n<u><j>2. <b>Hilnova#1234</b></j></u>\n3. Bolodefchoco#5678\n4. Lobezito#9012\n5. Ubitfm#3456\n6. Akuch#7890\n7. Istopetri#1234"
  208.     local out, c = {"<b><v><p align='center'>"..text[language].queue.."</p></v></b>\n"}, 2
  209.  
  210.     for index, playerName in next, queue do
  211.         if c > 3 then
  212.             out[c] = (c-1)..". "..playerName.."\n"
  213.         elseif c == 2 then
  214.             out[c] = "<j>"..(c-1)..". <b>"..playerName.."</b></j>\n"
  215.         elseif c == 3 then
  216.             out[c] = "<u><j>"..(c-1)..". <b>"..playerName.."</b></j></u>\n"
  217.         end
  218.         c = c + 1
  219.     end
  220.     for playerName, Data in next, playerData do
  221.         print(playerName)
  222.         print("que: "..tostring(Data.inQueue))
  223.         print("pla: "..tostring(Data.isPlaying))
  224.         if Data.inQueue then
  225.             out[c] = "\n<a href='event:quecancel'><p align='center'><r>["..text[language].cancel.."]</r></p></a>"
  226.             ui.addTextArea(102, table.concat(out), playerName, 15, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
  227.         elseif not Data.isPlaying then
  228.             out[c] = "\n<a href='event:quejoin'><p align='center'><vp>["..text[language].join.."]</vp></p></a>"
  229.             ui.addTextArea(102, table.concat(out), playerName, 15, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
  230.         else
  231.             ui.addTextArea(102, table.concat(out), playerName, 15, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
  232.         end
  233.     end
  234. end
  235.  
  236. function drawTurns()
  237.     --"<font color='#ff0000'><b><u>●</u></b></font> <vp><b>Zigwin#0000</b></vp>\n<font color='#0000ff'><b><u>●</u></b></font> Mapchest#0000"
  238.     local out, c = {}, 1
  239.     for index, playerName in next, players do
  240.         local team = playerData[playerName].team
  241.         local color = colors2[team]
  242.         if math.floor(turn) == team then
  243.             out[c] = "<font color='"..color.."' size='8'>●</font> <vp><b>"..playerName.."</b></vp>\n"
  244.         else
  245.             out[c] = "<font color='"..color.."' size='8'>●</font> "..playerName.."\n"
  246.         end
  247.         c = c + 1
  248.     end
  249.     ui.addTextArea(103, table.concat(out), nil, 15, 240, 160, 0, 0x000000, 0x333333, 0.5, true)
  250. end
  251.  
  252. function checkGrid()
  253.     -- Check Y (Vertical)
  254.     --[0][_][0][_][_][_][_]
  255.     --[0][_][2][_][_][_][_]
  256.     --[1][_][2][_][_][_][_]
  257.     --[1][_][1][_][_][_][_]
  258.     --[1][_][1][_][_][_][_]
  259.     --[1][_][1][_][_][_][_]
  260.     local previousValue = 0
  261.     local amount = 0
  262.     for x = 1, 7 do
  263.         for y = 1, 6 do
  264.             local value = grid[x][y]
  265.             if value ~= 0 and value == previousValue then
  266.                 amount = amount + 1
  267.                 if amount == 3 then
  268.                     print("Vertical Y")
  269.                     return players[value]
  270.                 end
  271.             else
  272.                 amount = 0
  273.             end
  274.             previousValue = value
  275.         end
  276.         amount = 0
  277.         previousValue = 0
  278.     end
  279.  
  280.     -- Check X (Horisontal)
  281.     amount = 0
  282.     previousValue = 0
  283.  
  284.     for y = 1, 6 do
  285.         for x = 1, 7 do
  286.             local value = grid[x][y]
  287.             if value ~= 0 and value == previousValue then
  288.                 amount = amount + 1
  289.                 if amount == 3 then
  290.                     print("Horisontal X")
  291.                     return players[value]
  292.                 end
  293.             else
  294.                 amount = 0
  295.             end
  296.             previousValue = value
  297.         end
  298.         amount = 0
  299.         previousValue = 0
  300.     end
  301.     -- Check (Positive X) Diagonal
  302.     amount = 0
  303.     previousValue = 0
  304.     --[0][0][0][x][>][>][x]
  305.     --[0][0][x][v][>][>][x]
  306.     --[0][x][#][>][>][>][x]
  307.     --[x][#][x][#][#][x][0]
  308.     --[#][x][#][#][x][0][0]
  309.     --[x][#][#][x][0][0][0]
  310.     for x = 4, 7 do
  311.         for y = 1, 3 do
  312.             for i = 0, 3 do
  313.                 local value = grid[x - i][y + i]
  314.                 if value ~= 0 and value == previousValue then
  315.                     amount = amount + 1
  316.                     if amount == 3 then
  317.                         print("Diagonal X")
  318.                         return players[value]
  319.                     end
  320.                 else
  321.                     amount = 0
  322.                 end
  323.                 previousValue = value
  324.             end
  325.             amount = 0
  326.             previousValue = 0
  327.         end
  328.     end
  329.  
  330.     -- Check (Negative X) Diagonal
  331.     --[1][2][3][4][_][_][_]
  332.     --[2][1][2][3][4][_][_]
  333.     --[3][2][1][2][3][4][_]
  334.     --[_][3][2][1][2][3][4]
  335.     --[_][_][3][2][_][_][_]
  336.     --[_][_][_][3][_][_][_]
  337.     amount = 0
  338.     previousValue = 0
  339.     for x = 1, 4 do
  340.         for y = 1, 3 do
  341.             for i = 0, 3 do
  342.                 local value = grid[x + i][y + i]
  343.                 if value ~= 0 and value == previousValue then
  344.                     amount = amount + 1
  345.                     if amount == 3 then
  346.                         print("Diagonal -X")
  347.                         return players[value]
  348.                     end
  349.                 else
  350.                     amount = 0
  351.                 end
  352.                 previousValue = value
  353.             end
  354.             amount = 0
  355.             previousValue = 0
  356.         end
  357.     end
  358.  
  359.     return false
  360. end
  361.  
  362. function eventTextAreaCallback(textAreaId, playerName, eventName)
  363.     if eventName:sub(1,3) == 'que' then
  364.         eventChatCommand(playerName, eventName:sub(4))
  365.     end
  366.  
  367.     if isGameOn then
  368.         local Data = playerData[playerName]
  369.         if debug then
  370.             turn = Data.team
  371.         end
  372.         if eventName == "grid" and Data.isPlaying and Data.team == math.floor(turn) then
  373.             local x = textAreaId
  374.  
  375.             -- Check that cell empty
  376.             if grid[x][1] ~= 0 then
  377.                 return
  378.             end
  379.  
  380.             -- Move Circle Down
  381.  
  382.             local i = 1
  383.             repeat
  384.                 grid[x][i-1] = 0
  385.                 grid[x][i] = Data.team
  386.                 i = i + 1
  387.             until not grid[x][i] or grid[x][i] ~= 0
  388.  
  389.             -- Draw Circle
  390.  
  391.             local y = i - 1
  392.             tfm.exec.addPhysicObject(100 + (x * 10) + y, 200 + x * 50, y * 50 + 70, {
  393.                 type            = 13,
  394.                 width           = 20,
  395.                 color           = colors[Data.team],
  396.                 miceCollision   = true,
  397.                 groundCollision = false
  398.             })
  399.  
  400.             -- Draw particles and arrow
  401.  
  402.             tfm.exec.addShamanObject(0, 200 + x * 50, 50)
  403.             for i = 1, 5 do
  404.                 tfm.exec.displayParticle(3, 200 + x * 50, y * 50 + 70, math.random(-10, 10)/10, math.random(-10, 10)/10)
  405.             end
  406.  
  407.             -- Next Turn
  408.             if not debug then
  409.                 turn = turn + (1 / turnsPerPlayer)
  410.                 if math.floor(turn) > #players then
  411.                     turn = 1
  412.                 end
  413.                 drawTurns()
  414.             end
  415.             -- Check for winner
  416.             local winner = checkGrid()
  417.             if checkGrid() then
  418.                 print(winner.." won!")
  419.                 -- Give some score to winner
  420.                 tfm.exec.setPlayerScore(winner, 10, true)
  421.  
  422.                 -- Set some values to default
  423.                 isGameOn = false
  424.                 for index, playerName in next, players do
  425.                     playerData[playerName].isPlaying = false
  426.                     playerData[playerName].team = 0
  427.                 end
  428.                 players = {}
  429.                 -- Draw queue to players that played
  430.                 drawQueue()
  431.  
  432.                 -- Draw particles and some text for winner
  433.                 local x, y = tfm.get.room.playerList[winner].x, tfm.get.room.playerList[winner].y
  434.                 for i = 1, 20 do
  435.                     --[[redConfetti : 21
  436.                     greenConfetti : 22
  437.                     blueConfetti : 23
  438.                     yellowConfetti : 24--]]
  439.                     tfm.exec.playEmote(winner, 9)
  440.                     tfm.exec.displayParticle(math.random(21,24), x, y, math.random(-10, 10)/10, math.random(-10, 10)/10, math.random(-10, 10)/100, math.random(-10, 10)/100)
  441.  
  442.                     ui.addTextArea(101, "<font face='Courier New' size='24' color='#000000'><p align='center'><b>"..winner.." won!", nil, 2, 102, 800, 0, nil, nil, 0)
  443.                     ui.addTextArea(100, "<font face='Courier New' size='24'><p align='center'><j><b>"..winner.." won!", nil, 0, 100, 800, 0, nil, nil, 0)
  444.                 end
  445.             end
  446.  
  447.             -- Update Grid
  448.             drawGrid()
  449.         end
  450.     end
  451. end
  452.  
  453. function eventLoop(elapsedTime, remainingTime)
  454.     if not isGameOn then
  455.         if #queue >= maximumPlayers then
  456.             initGame()
  457.         else
  458.             print("Not enough players in queue")
  459.         end
  460.     end
  461. end
  462.  
  463. function eventPlayerDied(playerName)
  464.     tfm.exec.respawnPlayer(playerName)
  465. end
  466.  
  467. -- Init map & game settings
  468.  
  469. tfm.exec.disableAutoNewGame(true)
  470. tfm.exec.disableAutoScore(true)
  471. tfm.exec.disableAutoShaman(true)
  472. tfm.exec.disableAutoTimeLeft(true)
  473. tfm.exec.disableAfkDeath(true)
  474.  
  475. for playerName in next, tfm.get.room.playerList do
  476.     tfm.exec.setPlayerScore(playerName, 0)
  477. end
  478.  
  479. --
  480.  
  481. local xml = [[<C><P /><Z><S><S P="0,0,0.3,0.2,0,0,0,0" H="320" L="380" o="202020" X="400" c="4" Y="240" T="12" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="250" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="300" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="350" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="400" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="450" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="500" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="20" o="6a7495" X="550" c="4" Y="70" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" L="800" o="324650" H="80" X="400" Y="440" T="12" /><S P="0,0,0.3,0.2,0,0,0,0" X="220" L="20" H="320" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" H="320" L="10" X="275" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" X="325" L="10" H="320" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" H="320" L="10" X="375" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" X="425" L="10" H="320" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" H="320" L="10" X="475" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" X="525" L="10" H="320" c="1" Y="240" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" H="320" L="20" X="580" c="1" Y="240" T="14" /></S><D><DS Y="385" X="100" /></D><O /></Z></C>]]
  482. tfm.exec.newGame(xml)
  483. ui.setMapName("<j>#connect4</j> <bl>- Zigwin</bl>")
  484.  
  485. -- Draw map grounds
  486.  
  487. for x = 1, 7 do
  488.     for y = 1, 6 do
  489.         tfm.exec.addPhysicObject(x..y, 200 + x * 50, y * 50 + 70, {
  490.             type            = 13,
  491.             width           = 20,
  492.             color           = 0x6A7495,
  493.             miceCollision   = false,
  494.             groundCollision = false
  495.         })
  496.     end
  497. end
  498.  
  499. -- Draw Interface
  500.  
  501. drawQueue()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement