Advertisement
qwertyMAN_rus

Cube the game

Jan 4th, 2016 (edited)
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.10 KB | None | 0 0
  1. local os = require("os")
  2. local term = require("term")
  3. local event = require("event")
  4. local component = require("component")
  5. local gpu = component.gpu
  6. math.randomseed(os.time())
  7.  
  8. -- приветствие
  9. term.clear()
  10. print("Cube v0.2")
  11. print("")
  12. print("Target: go to chamber 1")
  13. print("Game 100% passable")
  14. print("Press Q at any time to exit game")
  15. print("Press E to set mark")
  16. print("Press X to remove mark")
  17. print("Press Z to back color mark")
  18. print("Press C to next color mark")
  19. print("")
  20. print("press any key to continue...")
  21. event.pull("key_down")
  22.  
  23. local level = {}
  24. local doors = {}
  25. local nick_player
  26. local markColor = {0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff, 0xffffff}
  27. local playerColor = 7
  28. local sx,sy = gpu.getResolution()
  29. sx, sy = math.modf(sx/4), math.modf(sy/2)   -- точка отступа/координата игрока на экране (статичные)/центр событий
  30. local px,py = 3,3                       -- относительные координаты игрока в комнате
  31. local min_map, max_map = 1, 1000000     -- ограничители номеров комнат, чтобы сильно не запутаться при прохождении
  32. level[1] = {number=1, color = 0xffffff} -- цель игры - попасть в эту комнату
  33.  
  34. local rand_1, rand_2 ,rand_3, rand_4 = math.random(1,3), math.random(-200,200), math.random(1,3), math.random(-200,200)
  35. formula={} -- создаём случайные формулы для дверей
  36. formula[1]=function(n) return n*rand_1 + rand_2 end
  37. formula[-1]=function(n) return (n - rand_2)/rand_1 end
  38. formula[2]=function(n) return n*rand_3 - rand_4 end
  39. formula[-2]=function(n) return (n + rand_4)/rand_3 end
  40.  
  41. function gen_level(i)
  42.     if not level[i] then
  43.         level[i]={number=i, color = math.random(0x000000, 0xffffff), mark=false}
  44.     end
  45.     return level[i]
  46. end
  47.  
  48. function proverka(x,y) -- где x номер формулы, y номер текущей комнаты
  49.     local rezerv_4 = formula[x](y)
  50.     return rezerv_4>=min_map and rezerv_4<=max_map and rezerv_4==math.modf(rezerv_4)
  51. end
  52.  
  53. local rezerv_6 = 1 -- начальная комната/текущая, в программном смысле
  54. local rezerv_7 = -1 -- предыдущая использованная формула
  55. for i=1, 100 do -- делаем максимум 50 ходов из стартовой комнаты, чтобы запутаться
  56.     local rezerv_10 = rezerv_6
  57.     for j=1, 30 do -- если за 30 попыток не будет перехода, то делаем откат на 1 шаг
  58.         -- подбираем формулу
  59.         local rand = math.random(-2,2)
  60.         if rand ~=0 and rezerv_7 ~= rand and proverka(rand,rezerv_6) then -- проверим не обратная ли это формула
  61.             rezerv_6 = formula[rand](rezerv_6)
  62.             rezerv_7 = -rand
  63.             break
  64.         end
  65.     end
  66.     if rezerv_6 == rezerv_10 then -- если нет изменений то шаг назад
  67.         rezerv_6 = formula[rezerv_7](rezerv_6)
  68.         rezerv_7 = -rezerv_7
  69.     end
  70. end
  71. local chamber = gen_level(rezerv_6) -- создаём номер запутанной стартовой комнаты
  72.  
  73. function reload_doors() -- переставляет двери в комнате / данная функция достаточно сложна
  74.     local rezerv={}
  75.     for i=1,4 do -- занесём двери в базу данных, чтобы знать использованные формулы
  76.         if doors[i] then
  77.             rezerv[#rezerv+1]=doors[i]
  78.         end
  79.     end
  80.     for i=1,4 do -- перебираем все 4 двери
  81.         if not doors[i] then
  82.             while true do
  83.                 local rand = math.random(-2,2)
  84.                 local rezerv_2 = 0
  85.                 if rand ~= 0 then
  86.                     if #rezerv > 0 then -- проверка, есть ли комната с такой же формулой
  87.                         for j=1, #rezerv do
  88.                             if rezerv[j] == rand then break else rezerv_2 = rezerv_2 + 1 end
  89.                         end
  90.                     end
  91.                     if rezerv_2 == #rezerv then -- если нет повторяющихся формул, то присваивается данная формула
  92.                         doors[i] = rand
  93.                         rezerv[#rezerv+1]=rand
  94.                         break
  95.                     end
  96.                 end
  97.             end
  98.         end
  99.     end
  100. end
  101.  
  102. function mark_print(nx, ny, number) -- алгоритм рисования меток
  103.     if level[number].mark then
  104.         for i=1, #level[number].mark do
  105.             gpu.setBackground(level[number].mark[i][3])
  106.             gpu.set((level[number].mark[i][1]+nx)*2, level[number].mark[i][2]+ny, "  ")
  107.         end
  108.     end
  109. end
  110.    
  111. function level_print(nx, ny, color, number) -- алгоритм рисования комнаты по координатам
  112.     number = tostring(number)
  113.     gpu.setBackground(color)
  114.     gpu.set(nx*2, ny, "      ")
  115.     gpu.set((nx+4)*2, ny, "      ")
  116.     gpu.set(nx*2, ny+6, "      ")
  117.     gpu.set((nx+4)*2, ny+6, "      ")
  118.    
  119.     gpu.set(nx*2, ny+1, "  ")
  120.     gpu.set(nx*2, ny+2, "  ")
  121.     gpu.set(nx*2, ny+4, "  ")
  122.     gpu.set(nx*2, ny+5, "  ")
  123.     gpu.set((nx+6)*2, ny+1, "  ")
  124.     gpu.set((nx+6)*2, ny+2, "  ")
  125.     gpu.set((nx+6)*2, ny+4, "  ")
  126.     gpu.set((nx+6)*2, ny+5, "  ")
  127.    
  128.     gpu.setBackground(0x000000)
  129.     gpu.set(nx*2+6-math.modf((string.len(number)-1)/2), ny+3, number)
  130. end
  131.  
  132. pxx, pyy = {}, {}
  133. pxx[-1]=function(nx)
  134.     local rezerv_3 = doors[1]
  135.     if proverka(rezerv_3, chamber.number) then
  136.         doors={}
  137.         doors[2] = -rezerv_3
  138.         reload_doors()
  139.         chamber = gen_level(formula[rezerv_3](chamber.number))
  140.         ppx = 6
  141.     else
  142.         ppx = px
  143.     end
  144. end
  145. pxx[7]=function(nx)
  146.     local rezerv_3 = doors[2]
  147.     if proverka(rezerv_3, chamber.number) then
  148.         doors={}
  149.         doors[1] = -rezerv_3
  150.         reload_doors()
  151.         chamber = gen_level(formula[rezerv_3](chamber.number))
  152.         ppx = 0
  153.     else
  154.         ppx = px
  155.     end
  156. end
  157. pyy[-1]=function(ny)
  158.     local rezerv_3 = doors[3]
  159.     if proverka(rezerv_3, chamber.number) then
  160.         doors={}
  161.         doors[4] = -rezerv_3
  162.         reload_doors()
  163.         chamber = gen_level(formula[rezerv_3](chamber.number))
  164.         ppy = 6
  165.     else
  166.         ppy = py
  167.     end
  168. end
  169. pyy[7]=function(ny)
  170.     local rezerv_3 = doors[4]
  171.     if proverka(rezerv_3, chamber.number) then
  172.         doors={}
  173.         doors[3] = -rezerv_3
  174.         reload_doors()
  175.         chamber = gen_level(formula[rezerv_3](chamber.number))
  176.         ppy = 0
  177.     else
  178.         ppy = py
  179.     end
  180. end
  181.  
  182. function player_update(nx,ny)
  183.     ppx, ppy = px+nx, py+ny
  184.     if not ((ppx==0 or ppy==0 or ppx==6 or ppy==6) and ppx~=3 and ppy~=3) then
  185.         if pxx[ppx] then pxx[ppx](ppx)
  186.         elseif pyy[ppy] then pyy[ppy](ppy)
  187.         end
  188.         px,py = ppx,ppy
  189.     end
  190. end
  191.  
  192. function update(nick)
  193.     nick_player = nick
  194.     term.clear() -- очистка экрана
  195.     gpu.setBackground(markColor[playerColor]) -- отобразить текущий цвет
  196.     gpu.set(2, 2, "     ")
  197.    
  198.     ------------- рисуем комнаты -------------
  199.     -- текущая комната
  200.     gen_level(chamber.number)
  201.     mark_print(sx-px,sy-py, chamber.number)
  202.     level_print(sx-px,sy-py,chamber.color, chamber.number)
  203.    
  204.     -- комната слева
  205.     -- проверяет, удовлетворяет ли комната критериям. если да то отрисовывает
  206.     if proverka(doors[1], chamber.number) and px==0 then
  207.         local number = formula[doors[1]](chamber.number)
  208.         gen_level(number)
  209.         mark_print(sx-7-px,sy-py, number)
  210.         level_print(sx-7-px,sy-py,gen_level(formula[doors[1]](chamber.number)).color, gen_level(formula[doors[1]](chamber.number)).number)
  211.     end
  212.    
  213.     -- комната справа
  214.     if proverka(doors[2], chamber.number) and px==6 then
  215.         local number = formula[doors[2]](chamber.number)
  216.         gen_level(number)
  217.         mark_print(sx+7-px,sy-py, number)
  218.         level_print(sx+7-px,sy-py,gen_level(formula[doors[2]](chamber.number)).color, gen_level(formula[doors[2]](chamber.number)).number)
  219.     end
  220.    
  221.     -- комната сверху
  222.     if proverka(doors[3], chamber.number) and py==0 then
  223.         local number = formula[doors[3]](chamber.number)
  224.         gen_level(number)
  225.         mark_print(sx-px,sy-7-py, number)
  226.         level_print(sx-px,sy-7-py,gen_level(formula[doors[3]](chamber.number)).color, gen_level(formula[doors[3]](chamber.number)).number)
  227.     end
  228.    
  229.     -- комната снизу
  230.     if proverka(doors[4], chamber.number) and py==6 then
  231.         local number = formula[doors[4]](chamber.number)
  232.         gen_level(number)
  233.         mark_print(sx-px,sy+7-py, number)
  234.         level_print(sx-px,sy+7-py,gen_level(formula[doors[4]](chamber.number)).color, number)
  235.     end
  236.    
  237.     -- отображение игрока
  238.     gpu.setBackground(0xff0000)
  239.     gpu.set(sx*2, sy, "  ")
  240. end
  241.  
  242. reload_doors()
  243. update(nick)
  244. gpu.setBackground(0x000000)
  245.  
  246. local command={} -- управление
  247. command[200]=function() player_update(0,-1) end -- вверх
  248. command[208]=function() player_update(0,1) end  -- вниз
  249. command[203]=function() player_update(-1,0) end -- влево
  250. command[205]=function() player_update(1,0) end  -- вправо
  251. command[18]=function()                          -- ставить метку
  252.                 if not level[chamber.number].mark then level[chamber.number].mark={} end
  253.                 level[chamber.number].mark[#level[chamber.number].mark+1]={px,py,markColor[playerColor]}
  254.             end
  255. command[44]=function() if playerColor-1<1 then playerColor=7 else playerColor=playerColor-1 end end -- цвет слева
  256. command[46]=function() if playerColor+1>7 then playerColor=1 else playerColor=playerColor+1 end end -- цвет справа
  257. command[45]=function()                                              -- удалить метку
  258.                 local kostili=false
  259.                 if level[chamber.number].mark then
  260.                     for i=#level[chamber.number].mark, 1, -1  do
  261.                         if px==level[chamber.number].mark[i][1] and py==level[chamber.number].mark[i][2] then
  262.                             table.remove(level[chamber.number].mark,i)
  263.                         end
  264.                     end
  265.                 end
  266.             end
  267.  
  268.  
  269. while true do
  270.     _,_,_, key, nick = event.pull("key_down")
  271.     if key==16 then gpu.setBackground(0x000000) term.clear() return elseif command[key] then command[key]() end
  272.     update(nick)
  273.     gpu.setBackground(0x000000)
  274.     if chamber.number == 1 then break end
  275.     os.sleep(1/15) -- для удобного управления
  276. end
  277.  
  278. -- прощание
  279. term.clear()
  280. print("Congratulations "..nick_player.."!")
  281. print("")
  282. print("you win!")
  283. print("press any key to continue...")
  284. event.pull("key_down")
  285. term.clear()
  286.  
  287. -- P.S. извините за резервные переменные. Просто фантазии нет как их назвать.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement