Gekkeiju

Mice Sweeper

Dec 14th, 2015
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.35 KB | None | 0 0
  1. --Mice Sweeper--
  2. --[[
  3. First, please google "mine sweeper" if you don't know that too popular game.
  4. Mice should press Space bar on the cells to open them. If there is a mine under a tile someone has tried to open he is damaged his health. The hearts on a mouse's head show his health. He dies when he has lost all his health and he lose half of his score. Players respawn in 10 seconds after they die.
  5. A mouse gets 10 points whenever he opens a safe tile (without mine)
  6. Tiles are opened not just after a player presses space bar on them. It takes a little bit before a tile is opened so that other players can open it too. After the first player has pressed Space bar on a cell, if another player also presses space bar on the same cell before it is opened, he also get 10 points if that cell is safe.
  7. ]]
  8.  
  9. players = {};
  10. countl = 0;
  11. tiles = {};
  12. checkList = {};
  13. cellsOpened = 0;
  14. ncells = 0;
  15.  
  16. SIZE = 40;
  17. WIDTH = 20;
  18. HEIGHT = 15;
  19. HP = 3;
  20.  
  21. around = {{-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}};
  22. ID = {ncells = 1, help=2};
  23. gd1={
  24.     type=12,
  25.     width=SIZE - 2,
  26.     height=SIZE - 2,
  27.     foreground=false,
  28.     friction=0.3,
  29.     restitution=0.2,
  30.     angle=0,
  31.     color = 0x948f82,
  32.     miceCollision=false,
  33.     groundCollision=true,
  34.     dynamic=false,
  35.     fixedRotation=false,
  36.     mass=0,
  37.     linearDamping=0,
  38.     angularDamping=0
  39. }
  40. gd2 = {
  41.     type=12,
  42.     width=SIZE - 2,
  43.     height=SIZE - 2,
  44.     foreground=false,
  45.     friction=0.3,
  46.     restitution=0.2,
  47.     angle=0,
  48.     color = 0xba8f66,
  49.     miceCollision=false,
  50.     groundCollision=true,
  51.     dynamic=false,
  52.     fixedRotation=false,
  53.     mass=0,
  54.     linearDamping=0,
  55.     angularDamping=0
  56. }
  57. gd3 = {
  58.     type=0,
  59.     width=10,
  60.     height=10,
  61.     foreground=false,
  62.     friction=0.3,
  63.     restitution=0.2,
  64.     angle=45,
  65.     color = 0x948f82,
  66.     miceCollision=true,
  67.     groundCollision=true,
  68.     dynamic=false,
  69.     fixedRotation=false,
  70.     mass=0,
  71.     linearDamping=0,
  72.     angularDamping=0
  73. }
  74. images = {"15199769c74.png", "1519bf78f15.png", "1519bf7c43b.png", "1519bf7f5f0.png", "1519bf90206.png", "1519bf91cc8.png", "1519bf9568c.png", "1519bfa1fb7.png", "1519bfb1049.png"};
  75. hearts = {"1519fffc1f5.png", "151a003b85a.png", "151a00e7417.png"};
  76.  
  77. text = {
  78.     welcome = "Welcome to Mice Sweeper! Type !help for help",
  79.     begin = "The round has begun. Open the tiles avoiding mines",
  80.     help = "Welcome to Mice Sweeper<br/>The rules are simple. There are tiles and some of them have mines buried under them. So, don't open them.<br><li>Press Space Bar to open a tile on it</li><li>You get 10 points for every opening a safe tile</li><li>The number on a tile stands for the number of mines around it</li><li>Your health is 3 at the beginning and when you open a mine tile you lose one.</li><li>You die when your health is all lost. You lose half of your score at the same time.</li>",
  81.     respawn = "You will respawn in 10 seconds"
  82. }
  83.  
  84. function sendChatMessage(message, name, prefix, f)
  85.     if name~=nil then
  86.         message=text[message] or message;
  87.         if prefix then
  88.             message=prefix..message
  89.         end
  90.         if f then
  91.             message=message:format(table.unpack(f))
  92.         end
  93.         tfm.exec.chatMessage(message, name);
  94.     else
  95.         for name,player in pairs(tfm.get.room.playerList) do
  96.             sendChatMessage(message, name, prefix, f)
  97.         end
  98.     end
  99. end
  100.  
  101. function eventLoop(time, remaining)
  102.     countl = countl + 1;
  103.     if remaining < 500 then
  104.         finishRound();
  105.         local s = '<C><P Ca="" L="%d" H="%d"/><Z><S><S X="%d" L="%d" Y="%d" H="%d" P="0,0,0.3,0.2,0,0,0,0" c="2" T="12" o="FFFFFF"/><S X="5" L="10" Y="%d" H="%d" P="0,0,0.3,0.2,0,0,0,0" T="10" /><S X="%d" L="%d" Y="30" H="10" P="0,0,0.3,0.2,0,0,0,0" T="10" /><S X="%d" L="10" Y="%d" H="%d" P="0,0,0.3,0.2,0,0,0,0" T="10" /><S X="%d" L="%d" Y="%d" H="10" P="0,0,0.3,0.2,0,0,0,0" T="10" />%s</S><D><DS X="25" Y="50" /></D><O /></Z></C>';
  106.         local h = SIZE * HEIGHT + 20;
  107.         local w = SIZE * WIDTH + 20;
  108.         local t = {};
  109.         for x = 1, WIDTH do
  110.             for y = 1, HEIGHT do
  111.                 table.insert(t, string.format('<S lua="%d" X="%d" L="%d" Y="%d" H="%d" c="2" T="0" o="948f82"/>', (y - 1) * WIDTH + x, (x - 0.5) * SIZE + 10, SIZE-2, (y - 0.5) * SIZE + 35, SIZE-2));
  112.             end
  113.         end
  114.         for x = 1, WIDTH - 1 do
  115.             for y = 1, HEIGHT - 1 do
  116.                 if (x + 2 * y) % 4 == 0 then
  117.                     table.insert(t, string.format('<S X="%d" L="10" Y="%d" H="10" P="0,0,15,0.2,45,0,0,0" T="4"/>', x * SIZE + 10, y * SIZE + 35));
  118.                 end
  119.             end
  120.         end
  121.         s = string.format(s, w, h + 25,
  122.             w / 2, w, h / 2 + 25, h,
  123.             h / 2 + 25, h,
  124.              w / 2, w,
  125.              w - 5, h / 2 + 25, h,
  126.              w / 2, w, h - 5 + 25,
  127.              table.concat(t, ""));
  128.         tfm.exec.newGame(s);
  129.     else
  130.         local x, y, tile
  131.         for i, t in pairs(checkList) do
  132.             x = (i - 1) % WIDTH + 1;
  133.             y = (i - x) / WIDTH + 1;
  134.             tile = tiles[x][y];
  135.             if tile[2] then --bomb
  136.                 local p;
  137.                 for j, name in pairs(t) do
  138.                     p = players[name];
  139.                     if p.hp == 1 then
  140.                         tfm.exec.killPlayer(name);
  141.                         p.loopRespawn = countl + 20;
  142.                         p.score = math.floor(p.score / 2);
  143.                         tfm.exec.setPlayerScore(name, p.score, false);
  144.                         sendChatMessage("respawn", name);
  145.                     else
  146.                         p.hp = p.hp - 1;
  147.                         tfm.exec.removeImage(p.heartID);
  148.                         p.heartID = addHeart(name);
  149.                     end
  150.                 end
  151.             else
  152.                 for j, name in pairs(t) do
  153.                     players[name].score = players[name].score + 10;
  154.                     tfm.exec.setPlayerScore(name, players[name].score, false);
  155.                 end
  156.             end
  157.             openTile(x, y, true);
  158.         end
  159.         checkList = {};
  160.         if cellsOpened == ncells then
  161.             eventLoop(0, 0);
  162.         end
  163.         for name, player in pairs(players) do
  164.             if player.loopRespawn == countl then
  165.                 tfm.exec.respawnPlayer(name);
  166.                 player.hp = HP;
  167.                 player.heartID = addHeart(name);
  168.             end
  169.         end
  170.     end
  171. end
  172.  
  173. function finishRound()
  174.     if ncells == 0 then return end
  175.     local t = {};
  176.     for name, player in pairs(players)  do
  177.         table.insert(t, {name, player.score});
  178.     end
  179.     table.sort(t, function(a,b)return a[2] > b[2] end);
  180.     for i = 1, #t do
  181.         t[i] = string.format("%d: %s %d", i, t[i][1], t[i][2]);
  182.     end
  183.     local s = (ncells == cellsOpened and "All the mines were sweeped!") or "Time is up";
  184.     sendChatMessage(s .. "\nScores: \n" .. table.concat(t, "\n"));
  185. end
  186.  
  187. function openTile(x, y, autoOpen)
  188.     local tile, sum;
  189.     if tiles[x][y][1] == 0 then return end
  190.     if tiles[x][y][2] then
  191.         sum = 9;
  192.     else
  193.         cellsOpened = cellsOpened + 1;
  194.         ui.addTextArea(ID.ncells, string.format("<font color='#FF0000'><b>%d/%d</b></font>", cellsOpened, ncells), nil, 5, 27, 100, 30, 0, 0, 0, true);
  195.         sum = 0;
  196.         local _x, _y;
  197.         for j, xy in pairs(around) do
  198.             _x, _y = x + xy[1], y + xy[2];
  199.             tile = tiles[_x] and tiles[_x][_y];
  200.             if tile then
  201.                 sum = sum + ((tile[2] and 1) or 0);
  202.             end
  203.         end
  204.     end
  205.     tiles[x][y][3] = sum;
  206.     tiles[x][y][1] = 0;
  207.     tfm.exec.removePhysicObject((y - 1) * WIDTH + x);
  208.     if sum > 0 then
  209.         tfm.exec.addImage(images[sum], "_1000", (x - 1) * SIZE + 10, (y - 1) * SIZE + 35);
  210.     end
  211.     if autoOpen and sum == 0 then
  212.         local _x, _y;
  213.         for j, xy in pairs(around) do
  214.             _x, _y = x + xy[1], y + xy[2];
  215.             tile = tiles[_x] and tiles[_x][_y];
  216.             if tile and tile[1] ~= 0 then
  217.                 openTile(_x, _y, true);
  218.             end
  219.         end
  220.     end
  221. end
  222.  
  223. function eventNewPlayer(name)
  224.     players[name] = {
  225.         name = name,
  226.         score = 0,
  227.         hp = HP;
  228.     };
  229.     system.bindKeyboard(name, 32, true, true);
  230.     system.bindKeyboard(name, 72, true, true);
  231.     if tiles and tiles[1] then
  232.         for x = 1, WIDTH do
  233.             for y = 1, HEIGHT do
  234.                 if tiles[x][y][1] == 0 then
  235.                     tfm.exec.removePhysicObject((y - 1) * WIDTH + x);
  236.                     if tiles[x][y][3] > 0 then
  237.                         tfm.exec.addImage(images[tiles[x][y][3]], "_1000", (x - 1) * SIZE + 10, (y - 1) * SIZE + 35, name);
  238.                     end
  239.                 end
  240.             end
  241.         end
  242.     end
  243.     sendChatMessage("welcome", name);
  244.     players[name].loopRespawn = countl + 20;
  245. end
  246.  
  247. function eventKeyboard(name, code, down, x, y)
  248.     if code == 32 then
  249.         x = math.floor((x - 10) / SIZE) + 1;
  250.         y = math.floor((y - 35) / SIZE) + 1;
  251.         local ind = (y - 1) * WIDTH + x;
  252.         if tiles[x] and tiles[x][y] and tiles[x][y][1] == 1 then
  253.             if checkList[ind] == nil then
  254.                 checkList[ind] = {};
  255.             end
  256.             table.insert(checkList[ind], name);
  257.         end
  258.     elseif code == 72 then
  259.         ui.addPopup(ID.help, 0, text.help, name, 200, 60, 400, true);
  260.     end
  261. end
  262.  
  263. function eventPlayerLeft(name)
  264.     players[name] = nil;
  265. end
  266.  
  267. function eventNewGame()
  268.     tiles = {};
  269.     checkList = {};
  270.     for x = 1, WIDTH do
  271.         tiles[x] = {};
  272.         for y = 1, HEIGHT do
  273.             tiles[x][y] = {1};
  274.         end
  275.     end
  276.  
  277.     local i = 1;
  278.     local nmine = math.floor(WIDTH * HEIGHT * 0.23);
  279.     ncells = HEIGHT * WIDTH - nmine;
  280.     cellsOpened = 0;
  281.     ui.addTextArea(ID.ncells, string.format("<font color='#FF0000'><b>%d/%d</b></font>", cellsOpened, ncells), nil, 5, 27, 100, 30, 0, 0, 0, true);
  282.     local x, y;
  283.     while i <= nmine do
  284.         x = math.random(WIDTH);
  285.         y = math.random(HEIGHT);
  286.         if not tiles[x][y][2] then
  287.             tiles[x][y][2] = true;
  288.             i = i + 1;
  289.         end
  290.     end
  291.    
  292.     for name, player in pairs(players) do
  293.         player.score = 0;
  294.         player.hp = HP;
  295.         tfm.exec.setPlayerScore(name, 0, false);
  296.         player.heartID = addHeart(name);
  297.     end
  298.     tfm.exec.setGameTime(360);
  299. end
  300.  
  301. function addHeart(name, hp)
  302.     hp = hp or players[name].hp;
  303.     return tfm.exec.addImage(hearts[hp], "$"..name, -20, -38);
  304. end
  305.  
  306. function eventChatCommand(name, com)
  307.     if com == "help" then
  308.         ui.addPopup(ID.help, 0, text.help, name, 200, 60, 400, true);
  309.     end
  310. end
  311.  
  312. tfm.exec.disableAutoNewGame(true);
  313. tfm.exec.disableAutoShaman(true);
  314. tfm.exec.disableAutoTimeLeft(true);
  315. tfm.exec.disableAfkDeath(true);
  316. for name, player in pairs(tfm.get.room.playerList) do
  317.     eventNewPlayer(name);
  318. end
  319. math.randomseed(os.time());
  320. eventLoop(0,0)
Advertisement
Add Comment
Please, Sign In to add comment