Advertisement
billysback

PacMan

Dec 3rd, 2012
1,839
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.06 KB | None | 0 0
  1.  
  2. local function compare(table1, table2, icap)
  3.     local ok = true
  4.     for j=1,#table1 do
  5.         local yes = true
  6.         local table = table1[j]
  7.         for i=1,icap do
  8.             if table[i] ~= table2[i] then yes = false end
  9.         end
  10.         if yes then ok = false end
  11.     end
  12.     return ok
  13. end
  14.  
  15. local function findPath(s, e, map)
  16.     local done = {}
  17.     local todo = {{s[1], s[2], nil}}
  18.     local result = nil
  19.     local ok = true
  20.     local n = 0
  21.     while ok do
  22.         local temp = {}
  23.         if #todo > 0 then
  24.             local p = 1
  25.             for i=1,#todo do
  26.                 local cur = todo[i]
  27.                 local new = { {cur[1]+1, cur[2]}, {cur[1]-1, cur[2]}, {cur[1], cur[2]+1}, {cur[1], cur[2]-1} }
  28.                 for i=1,#new do
  29.                     local pos = new[i]
  30.                     pos[3] = cur[3]
  31.                     if compare(done, pos, 2) then
  32.                         local typ = map:getBlock(pos[1], pos[2])
  33.                         if typ == 0 then
  34.                             temp[#temp + 1] = {pos[1], pos[2], {cur[1], cur[2], cur[3]}}
  35.                         end
  36.                     end
  37.                 end
  38.                 local newDone = {cur[1], cur[2], cur[3]}
  39.                 done[#done + 1] = newDone
  40.                 if cur[1] == e[1] and cur[2] == e[2] then
  41.                     result = newDone
  42.                     ok = false
  43.                 end
  44.                 p = p + 1
  45.                 if p > 50 then
  46.                     sleep(0)
  47.                 end
  48.             end
  49.             todo = {}
  50.             for i=1,#temp do todo[#todo + 1] = temp[i] end
  51.         else
  52.             ok = false
  53.         end
  54.         if n > 20 then
  55.             sleep(0)
  56.         end
  57.         term.setCursorPos(1,1)
  58.     end
  59.    
  60.     local path = {}
  61.     if result ~= nil then
  62.         local cur = {result[1], result[2], result[3]}
  63.         while cur ~= nil do
  64.             path[#path + 1] = {cur[1], cur[2]}
  65.             cur = cur[3]
  66.         end
  67.     end
  68.     return path
  69. end
  70.  
  71. local function flipTable(table)
  72.     local ntable = {}
  73.     for i=1,#table do
  74.         local index = (#table - i) + 1
  75.         ntable[i] = table[index]
  76.     end
  77.     return ntable
  78. end
  79.  
  80. local function createMap(lines, mapping)
  81.     local info = {}
  82.     local map = {
  83.         getBlock = function(self, x, y)
  84.             local xtab = self[y]
  85.             if xtab ~= nil then
  86.                 local n = xtab[x]
  87.                 if n == nil then n = 1 end
  88.                 return n
  89.             end
  90.             return 1
  91.         end,
  92.         draw = function(self, ox, oy, mapping, scale)
  93.             for y=1,#self do
  94.                 local xtab = self[y]
  95.                 if xtab ~= nil then
  96.                     for x=1,#xtab do
  97.                         local n = xtab[x]
  98.                         local data = mapping[tostring(n)]
  99.                         local o = 1
  100.                         if scale == 1 then o = 0 end
  101.                         local nx = (x * scale) - o
  102.                         local ny = (y * scale) - o
  103.                         for wx = 0,(scale-1) do
  104.                             for wy = 0,(scale-1) do
  105.                                 term.setCursorPos(nx+wx+ox,ny+wy+oy)
  106.                                 if data ~= nil then
  107.                                     term.setBackgroundColor(data[1])
  108.                                     term.setTextColor(data[2])
  109.                                     term.write(data[3])
  110.                                 end
  111.                             end
  112.                         end
  113.                     end
  114.                 end
  115.             end
  116.         end,
  117.     }
  118.     for y=1,#lines do
  119.         local xtab = {}
  120.         local line = lines[y]
  121.         for x=1,string.len(line) do
  122.             local ch = string.sub(line, x, x)
  123.             local n = tonumber(ch)
  124.             for i=1,#mapping do
  125.                 local mapp = mapping[i]
  126.                 if mapp[2] == n then
  127.                     n = mapp[3]
  128.                     info[mapp[1]] = {x, y}
  129.                 end
  130.             end
  131.             xtab[x] = n
  132.         end
  133.         map[y] = xtab
  134.     end
  135.    
  136.     return map, info
  137. end
  138.  
  139. local function createPlayer(sx, sy)
  140.     local player = {
  141.         x = sx,
  142.         y = sy,
  143.         dir = {0,0},
  144.         draw = function(self, scale)
  145.             local o = 1
  146.             if scale == 1 then o = 0 end
  147.             local x = (self.x * scale) - o
  148.             local y = (self.y * scale) - o
  149.             for w = 0,scale-1 do
  150.                 for h = 0,scale-1 do
  151.                     term.setCursorPos(x+w, y+h)
  152.                     term.setBackgroundColor(colors.white)
  153.                     term.setTextColor(colors.red)
  154.                     term.write("@")
  155.                 end
  156.             end
  157.         end,
  158.         checkForGhost = function(self, gs)
  159.             for i=1,#gs do
  160.                 local ghost = gs[i]
  161.                 if ghost.x == self.x and ghost.y == self.y then
  162.                     return true
  163.                 end
  164.             end
  165.             return false
  166.         end,
  167.         update = function(self, map, gs)
  168.             local nx = self.x + self.dir[1]
  169.             local ny = self.y + self.dir[2]
  170.             local b = map:getBlock(nx, ny)
  171.             if b == 0 then
  172.                 self.x = nx
  173.                 self.y = ny
  174.             end
  175.             return self:checkForGhost(gs)
  176.         end,
  177.     }
  178.     return player
  179. end
  180. local map, info = createMap({
  181. "111111111",
  182. "100000001",
  183. "101101101",
  184. "101000101",
  185. "100010001",
  186. "111030111",
  187. "100010001",
  188. "101000101",
  189. "101101101",
  190. "100020001",
  191. "111111111"
  192. },
  193. {{"player", 2, 0}, {"ghost", 3, 0}}
  194. )
  195. local cmaps = {
  196.     ["0"] = {colors.white, colors.black, " "},
  197.     ["1"] = {colors.black, colors.white, "+"}
  198. }
  199.  
  200.  
  201. local player = createPlayer(info.player[1], info.player[2])
  202.  
  203. local function createGhost(sx, sy, smap, sid)
  204.     local gpath = flipTable(findPath({sx, sy}, {player.x, player.y}, smap))
  205.     local ghost = {
  206.         x = sx,
  207.         y = sy,
  208.         id = sid,
  209.         map = smap,
  210.         path = gpath,
  211.         cur = 1,
  212.         getPath = function(self, play)
  213.             local gpath = flipTable(findPath({self.x, self.y}, {play.x, play.y}, self.map))
  214.             if #gpath == 0 or math.random(100) <= 25 then
  215.                 local rloc = nil
  216.                 local sov = 0
  217.                 while rloc == nil and sov < 100 do
  218.                     local cloc = {math.random(#self.map[1]), math.random(#self.map)}
  219.                     if self.map:getBlock(cloc[1], cloc[2], self.map) == 0 then rloc = cloc end
  220.                     sov = sov + 1
  221.                 end
  222.                 if rloc == nil then rloc = {2,2} end
  223.                 gpath = flipTable(findPath({self.x, self.y}, {play.x, play.y}, self.map))
  224.             end
  225.             return gpath
  226.         end,
  227.         checkForGhosts = function(self, gs)
  228.             for i=1,#gs do
  229.                 local ghost = gs[i]
  230.                 if ghost.x == self.x and ghost.y == self.y and self.id ~= ghost.id then
  231.                     return true
  232.                 end
  233.             end
  234.             return false
  235.         end,
  236.         checkForIntersect = function(self)
  237.             local n = 0
  238.             local new = { {self.x+1, self.y}, {self.x-1, self.y}, {self.x, self.y+1}, {self.x, self.y-1} }
  239.             for i=1,#new do
  240.                 local n = self.map:getBlock(new[i][1], new[i][2])
  241.                 if n == 0 then n = n + 1 end
  242.             end
  243.             return (n > 2)
  244.         end,
  245.         update = function(self, gs, play)
  246.            
  247.             if self.cur > #self.path then
  248.                 self.path = self:getPath(play)
  249.                 self.cur = 1
  250.             end
  251.             if self.cur <= #self.path then
  252.                 local nloc = self.path[self.cur]
  253.                 local oloc = {self.x, self.y}
  254.                 self.x = nloc[1]
  255.                 self.y = nloc[2]
  256.                 if self:checkForGhosts(self, gs) then
  257.                     self.x = oloc[1]
  258.                     self.y = oloc[2]
  259.                 elseif self.x == play.x and self.y == play.y then return true
  260.                 elseif self:checkForIntersect() and math.random(10) < 5 then
  261.                     self.path = self:getPath(play)
  262.                 else
  263.                     self.cur = self.cur + 1
  264.                 end
  265.             else
  266.                 self.cur = self.cur + 1
  267.             end
  268.             return false
  269.         end,
  270.         draw = function(self, scale)
  271.             local o = 1
  272.             if scale == 1 then o = 0 end
  273.             local x = (self.x * scale) - o
  274.             local y = (self.y * scale) - o
  275.             for w = 0,scale-1 do
  276.                 for h = 0,scale-1 do
  277.                     term.setCursorPos(x+w, y+h)
  278.                     term.setBackgroundColor(colors.white)
  279.                     term.setTextColor(colors.red)
  280.                     term.write("O")
  281.                 end
  282.             end
  283.         end,   
  284.     }
  285.     return ghost
  286. end
  287.  
  288. local ghosts = {
  289.     createGhost(info.ghost[1], info.ghost[2], map, 1)
  290. }
  291.  
  292. local on = true
  293. local interval = 0.2
  294.  
  295. local scale = 2
  296.  
  297. local stuff = {...}
  298. if #stuff == 1 then
  299.     scale = tonumber(stuff[1])
  300. elseif #stuff == 2 then
  301.     scale = tonumber(stuff[1])
  302.     interval = tonumber(stuff[2])
  303. end
  304.  
  305. local tick = 0
  306.  
  307. local timer = os.startTimer(0)
  308. local score = 0
  309. while on do
  310.     local event,p1 = os.pullEvent()
  311.     if event == "timer" and p1 == timer then
  312.         term.setBackgroundColor(colors.black)
  313.         term.setTextColor(colors.white)
  314.         term.clear()
  315.         term.setCursorPos(1,1)
  316.         map:draw(0, 0, cmaps, scale)
  317.         if player:update(map, ghosts) then
  318.             on = false
  319.         end
  320.         for i=1,#ghosts do
  321.             if ghosts[i]:update(ghosts, player) then on = false end
  322.             ghosts[i]:draw(scale)
  323.         end
  324.         player:draw(scale)
  325.         if #ghosts < 4 then
  326.             tick = tick + 1
  327.             if tick > 50 then
  328.                 ghosts[#ghosts + 1] = createGhost(info.ghost[1], info.ghost[2], map, #ghosts+1)
  329.                 tick = 0
  330.             end
  331.         end
  332.         score = score + 1
  333.         timer = os.startTimer(interval)
  334.     elseif event == "key" then
  335.         local key = p1
  336.         if key == 200 then -- up
  337.             player.dir = {0, -1}
  338.         elseif key == 203 then -- left
  339.             player.dir = {-1, 0}
  340.         elseif key == 208 then -- down
  341.             player.dir = {0, 1}
  342.         elseif key == 205 then -- right
  343.             player.dir = {1, 0}
  344.         elseif key == 29 then
  345.             on = false
  346.         end
  347.     end
  348. end
  349. term.setBackgroundColor(colors.black)
  350. term.setTextColor(colors.white)
  351. term.setCursorPos(1, (#map*scale) + 2)
  352. print("!!! !!! GAME OVER !!! !!!")
  353. print("!!! SCORE: "..score)
  354. print("!!! !!! !!!! !!!! !!! !!!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement