qwertyMAN_rus

Cube v1,0

Jan 11th, 2016
257
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. local version = "Cube v1.0"
  8. local level = {}
  9. local doors = {}
  10. local indicator={}
  11. local nick_player
  12. local markColor = {0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff, 0xffffff}
  13. local playerColor = 3
  14. local sx,sy = gpu.getResolution()
  15. sx, sy = math.modf(sx/4), math.modf(sy/2)       -- точка отступа/координата игрока на экране (статичные)/центр событий
  16. local px,py = 3,3                   -- относительные координаты игрока в комнате
  17. local min_map, max_map = 1, 1000    -- ограничители номеров комнат, чтобы сильно не запутаться при прохождении
  18. level[1] = {number=1, color = 0xffffff,  mark=false} -- цель игры - попасть в эту комнату
  19. -------------------------------------------------------------------------------------
  20. ----------------------- Генерация случайных формул для дверей -----------------------
  21. local rand_1, rand_2 ,rand_3, rand_4
  22. while true do
  23.     rand_1, rand_2 ,rand_3, rand_4 = math.random(1,2), math.random(10,30), math.random(1,2), math.random(10,30)
  24.     if rand_1~=rand_3 and rand_2~=rand_4 then break end
  25. end
  26. formula={}
  27. formula[1]=function(n) return n*rand_1 + rand_2 end
  28. formula[2]=function(n) return n*rand_3 + rand_4 end
  29. formula[-1]=function(n) return (n - rand_2)/rand_1 end
  30. formula[-2]=function(n) return (n - rand_4)/rand_3 end
  31. -------------------------------------------------------------------------------------
  32. ---------------------- Возвращает или генерирует новую комнату ----------------------
  33. function gen_level(i)
  34.     i = tonumber(i)
  35.     if not level[i] then
  36.         level[i]={number=i, color = math.random(0x000000, 0xffffff), mark=false}
  37.     end
  38.     return level[i]
  39. end
  40. -------------------------------------------------------------------------------------
  41. -------------------------- Проверка, существует ли комната --------------------------
  42. function proverka(x,y) -- где x номер формулы, y номер текущей комнаты
  43.     local number = formula[x](y)
  44.     return number >= min_map and number <= max_map and number == math.modf(number)
  45. end
  46. -------------------------------------------------------------------------------------
  47. ---------------------------- Генерация статистики комнат ----------------------------
  48. function sorting(sorting_table, not_sorting_table)
  49.     local trash_table={}
  50.     while true do
  51.         if #not_sorting_table==0 then
  52.             break
  53.         else
  54.             local new_level = not_sorting_table[1]
  55.             local power = true
  56.             for i=1, #sorting_table do
  57.                 if sorting_table[i][1]== new_level[1] then
  58.                     power = false
  59.                     if new_level[2] < sorting_table[i][2] then
  60.                         sorting_table[i][2]=new_level[2]
  61.                         if proverka(1,new_level[1]) then
  62.                             trash_table[#trash_table+1] = {formula[1](new_level[1]), new_level[2]+1}
  63.                         end
  64.                         if proverka(2,new_level[1]) then
  65.                             trash_table[#trash_table+1] = {formula[2](new_level[1]), new_level[2]+1}
  66.                         end
  67.                         if proverka(-1,new_level[1]) then
  68.                             trash_table[#trash_table+1] = {formula[-1](new_level[1]), new_level[2]+1}
  69.                         end
  70.                         if proverka(-2,new_level[1]) then
  71.                             trash_table[#trash_table+1] = {formula[-2](new_level[1]), new_level[2]+1}
  72.                         end
  73.                     end
  74.                     table.remove(not_sorting_table,1)
  75.                 end
  76.             end
  77.             if power then
  78.                 sorting_table[#sorting_table+1] = new_level
  79.                 table.remove(not_sorting_table,1)
  80.                 if proverka(1,new_level[1]) then
  81.                     not_sorting_table[#not_sorting_table+1] = {formula[1](new_level[1]), new_level[2]+1}
  82.                 end
  83.                 if proverka(2,new_level[1]) then
  84.                     not_sorting_table[#not_sorting_table+1] = {formula[2](new_level[1]), new_level[2]+1}
  85.                 end
  86.                 if proverka(-1,new_level[1]) then
  87.                     not_sorting_table[#not_sorting_table+1] = {formula[-1](new_level[1]), new_level[2]+1}
  88.                 end
  89.                 if proverka(-2,new_level[1]) then
  90.                     not_sorting_table[#not_sorting_table+1] = {formula[-2](new_level[1]), new_level[2]+1}
  91.                 end
  92.             end
  93.         end
  94.     end
  95.     return sorting_table, trash_table
  96. end
  97.  
  98. -- первая сортировка
  99. local not_sorting_tb, trash_tb={}
  100. not_sorting_tb[1]={1,0}
  101. local sorting_tb, trash_tb = sorting({}, not_sorting_tb)
  102.  
  103. -- последующие сортировки
  104. while true do
  105.     not_sorting_tb = trash_tb
  106.     sorting_tb, trash_tb = sorting(sorting_tb, not_sorting_tb)
  107.     if #trash_tb == 0 then break end
  108. end
  109.  
  110. -- очищаем память
  111. not_sorting_tb, trash_tb = nil, nil
  112.  
  113. -- перестраиваем таблицу
  114. local stat_table={}
  115. for i=1, #sorting_tb do
  116.     stat_table[sorting_tb[i][1]]=sorting_tb[i][2]
  117. end
  118. -------------------------------------------------------------------------------------
  119. ------------------ Находим номер самой удалённой комнаты от выхода ------------------
  120. local j=1
  121. for i=1, #sorting_tb do
  122.     if sorting_tb[i][2]>sorting_tb[j][2] then
  123.         j=i
  124.     end
  125. end
  126. -------------------------------------------------------------------------------------
  127. ----------------------- Устанавливаем номер стартовой комнаты -----------------------
  128. local chamber = gen_level(sorting_tb[j][1])
  129.  
  130. -- запишем количество комнат в игре
  131. local max_table, max_level = #sorting_tb, sorting_tb[j][2]
  132.  
  133. -- удалим из памяти ненужную таблицу
  134. sorting_tb = nil
  135. -------------------------------------------------------------------------------------
  136. --------------------------- Переставляет двери в комнате ----------------------------
  137. function reload_doors()
  138.     local rezerv={}
  139.     for i=1,4 do -- занесём двери в базу данных, чтобы знать использованные формулы
  140.         if doors[i] then
  141.             rezerv[#rezerv+1]=doors[i]
  142.         end
  143.     end
  144.     for i=1,4 do -- перебираем все 4 двери
  145.         if not doors[i] then
  146.             while true do
  147.                 local rand = math.random(-2,2)
  148.                 local rezerv_2 = 0
  149.                 if rand ~= 0 then
  150.                     if #rezerv > 0 then -- проверка, есть ли комната с такой же формулой
  151.                         for j=1, #rezerv do
  152.                             if rezerv[j] == rand then break else rezerv_2 = rezerv_2 + 1 end
  153.                         end
  154.                     end
  155.                     if rezerv_2 == #rezerv then -- если нет повторяющихся формул, то присваивается данная формула
  156.                         doors[i] = rand
  157.                         rezerv[#rezerv+1]=rand
  158.                         break
  159.                     end
  160.                 end
  161.             end
  162.         end
  163.     end
  164. end
  165. -- //данная функция достаточно сложна чтобы запутаться
  166. -------------------------------------------------------------------------------------
  167. ---------------------------------- Рисования меток ----------------------------------
  168. function mark_print(nx, ny, number)
  169.     if level[number].mark then
  170.         for i=1, #level[number].mark do
  171.             gpu.setBackground(level[number].mark[i][3])
  172.             gpu.set((level[number].mark[i][1]+nx)*2, level[number].mark[i][2]+ny, "  ")
  173.         end
  174.     end
  175. end
  176. -------------------------------------------------------------------------------------
  177. ------------------------- Рисования комнаты по координатам --------------------------
  178. function level_print(nx, ny, color, number)
  179.     number = tostring(number)
  180.     gpu.setBackground(color)
  181.     gpu.set(nx*2, ny, "      ")
  182.     gpu.set((nx+4)*2, ny, "      ")
  183.     gpu.set(nx*2, ny+6, "      ")
  184.     gpu.set((nx+4)*2, ny+6, "      ")
  185.    
  186.     gpu.set(nx*2, ny+1, "  ")
  187.     gpu.set(nx*2, ny+2, "  ")
  188.     gpu.set(nx*2, ny+4, "  ")
  189.     gpu.set(nx*2, ny+5, "  ")
  190.     gpu.set((nx+6)*2, ny+1, "  ")
  191.     gpu.set((nx+6)*2, ny+2, "  ")
  192.     gpu.set((nx+6)*2, ny+4, "  ")
  193.     gpu.set((nx+6)*2, ny+5, "  ")
  194.    
  195.     gpu.setBackground(0x000000)
  196.     gpu.set(nx*2+6-math.modf((string.len(number)-1)/2), ny+3, number)
  197. end
  198. -------------------------------------------------------------------------------------
  199. ----------------------------- Переходы между комнатами ------------------------------
  200. pxx, pyy = {}, {}
  201. pxx[-1]=function(nx)
  202.     local rezerv_3 = doors[1]
  203.     if proverka(rezerv_3, chamber.number) then
  204.         doors={}
  205.         doors[2] = -rezerv_3
  206.         reload_doors()
  207.         chamber = gen_level(formula[rezerv_3](chamber.number))
  208.         ppx = 6
  209.     else
  210.         ppx = px
  211.     end
  212. end
  213. pxx[7]=function(nx)
  214.     local rezerv_3 = doors[2]
  215.     if proverka(rezerv_3, chamber.number) then
  216.         doors={}
  217.         doors[1] = -rezerv_3
  218.         reload_doors()
  219.         chamber = gen_level(formula[rezerv_3](chamber.number))
  220.         ppx = 0
  221.     else
  222.         ppx = px
  223.     end
  224. end
  225. pyy[-1]=function(ny)
  226.     local rezerv_3 = doors[3]
  227.     if proverka(rezerv_3, chamber.number) then
  228.         doors={}
  229.         doors[4] = -rezerv_3
  230.         reload_doors()
  231.         chamber = gen_level(formula[rezerv_3](chamber.number))
  232.         ppy = 6
  233.     else
  234.         ppy = py
  235.     end
  236. end
  237. pyy[7]=function(ny)
  238.     local rezerv_3 = doors[4]
  239.     if proverka(rezerv_3, chamber.number) then
  240.         doors={}
  241.         doors[3] = -rezerv_3
  242.         reload_doors()
  243.         chamber = gen_level(formula[rezerv_3](chamber.number))
  244.         ppy = 0
  245.     else
  246.         ppy = py
  247.     end
  248. end
  249. -- //работает как надо, но лучше подредактировать
  250. -------------------------------------------------------------------------------------
  251. -------------------------------- Передвижение игрока --------------------------------
  252. function player_update(nx,ny)
  253.     ppx, ppy = px+nx, py+ny
  254.     if not ((ppx==0 or ppy==0 or ppx==6 or ppy==6) and ppx~=3 and ppy~=3) then
  255.         if pxx[ppx] then pxx[ppx](ppx)
  256.         elseif pyy[ppy] then pyy[ppy](ppy)
  257.         end
  258.         px,py = ppx,ppy
  259.     end
  260. end
  261. -- //работает как надо, но лучше подредактировать
  262. -------------------------------------------------------------------------------------
  263. --------------------------------- Блок отображения ----------------------------------
  264. function update(nick)
  265.     nick_player = nick
  266.     term.clear()
  267.  
  268.     -- текущая комната
  269.     gen_level(chamber.number)
  270.     mark_print(sx-px,sy-py, chamber.number)
  271.     level_print(sx-px,sy-py,chamber.color, chamber.number)
  272.    
  273.     -- комната слева
  274.     if proverka(doors[1], chamber.number) and px==0 then
  275.         local number = formula[doors[1]](chamber.number)
  276.         gen_level(number)
  277.         mark_print(sx-7-px,sy-py, number)
  278.         level_print(sx-7-px,sy-py,gen_level(formula[doors[1]](chamber.number)).color, gen_level(formula[doors[1]](chamber.number)).number)
  279.     end
  280.    
  281.     -- комната справа
  282.     if proverka(doors[2], chamber.number) and px==6 then
  283.         local number = formula[doors[2]](chamber.number)
  284.         gen_level(number)
  285.         mark_print(sx+7-px,sy-py, number)
  286.         level_print(sx+7-px,sy-py,gen_level(formula[doors[2]](chamber.number)).color, gen_level(formula[doors[2]](chamber.number)).number)
  287.     end
  288.    
  289.     -- комната сверху
  290.     if proverka(doors[3], chamber.number) and py==0 then
  291.         local number = formula[doors[3]](chamber.number)
  292.         gen_level(number)
  293.         mark_print(sx-px,sy-7-py, number)
  294.         level_print(sx-px,sy-7-py,gen_level(formula[doors[3]](chamber.number)).color, gen_level(formula[doors[3]](chamber.number)).number)
  295.     end
  296.    
  297.     -- комната снизу
  298.     if proverka(doors[4], chamber.number) and py==6 then
  299.         local number = formula[doors[4]](chamber.number)
  300.         gen_level(number)
  301.         mark_print(sx-px,sy+7-py, number)
  302.         level_print(sx-px,sy+7-py,gen_level(formula[doors[4]](chamber.number)).color, number)
  303.     end
  304.    
  305.     -- отображение игрока
  306.     gpu.setBackground(0xff0000)
  307.     gpu.set(sx*2, sy, "  ")
  308.    
  309.     -- текстовые индикаторы
  310.     for i=1, #indicator do
  311.     indicator[i]()
  312.     end
  313.    
  314.     -- индикатор выбранного цвета
  315.     gpu.setBackground(markColor[playerColor])
  316.     gpu.set(2, sy*2, "     ")
  317. end
  318. -------------------------------------------------------------------------------------
  319. ---------------------------------- Блок управления ----------------------------------
  320. local command={}
  321. command[200]=function() player_update(0,-1) end -- вверх
  322. command[208]=function() player_update(0,1) end  -- вниз
  323. command[203]=function() player_update(-1,0) end -- влево
  324. command[205]=function() player_update(1,0) end  -- вправо
  325. command[17]=function()                          -- ставить метку
  326.                 if not level[chamber.number].mark then level[chamber.number].mark={} end
  327.                 level[chamber.number].mark[#level[chamber.number].mark+1]={px,py,markColor[playerColor]}
  328.             end
  329. command[30]=function() if playerColor-1<1 then playerColor=#markColor else playerColor=playerColor-1 end end    -- цвет слева
  330. command[32]=function() if playerColor+1>#markColor then playerColor=1 else playerColor=playerColor+1 end end    -- цвет справа
  331. command[31]=function()                                                                              -- удалить метку
  332.                 if level[chamber.number].mark then
  333.                     for i=#level[chamber.number].mark, 1, -1  do
  334.                         if px==level[chamber.number].mark[i][1] and py==level[chamber.number].mark[i][2] then
  335.                             table.remove(level[chamber.number].mark,i)
  336.                         end
  337.                     end
  338.                 end
  339.             end
  340. command[23]=function() -- включает режим разработчика
  341.     if #indicator==0 then
  342.         indicator[1]=function()
  343.             gpu.setBackground(0x000000)
  344.             gpu.setForeground(0xffff00)
  345.             gpu.set(2, 2, "max level: "..max_level)
  346.             gpu.set(2, 3, "all levels: "..max_table)
  347.             gpu.set(2, 4, "this level: "..stat_table[chamber.number])
  348.             gpu.setForeground(0xff0000)
  349.             gpu.set(2, 5, "formula 1: ".."n".."*"..rand_1.." + "..rand_2)
  350.             gpu.set(2, 6, "formula 2: ".."n".."*"..rand_3.." + "..rand_4)
  351.             gpu.set(2, 7, "formula -1: ".."(n - "..rand_2..")/"..rand_1)
  352.             gpu.set(2, 8, "formula -2: ".."(n - "..rand_4..")/"..rand_3)
  353.             gpu.setForeground(0xff00ff)
  354.             gpu.set(2, 9, "progress: " .. math.modf(100-stat_table[chamber.number]*100/max_level).."%")
  355.             gpu.setForeground(0xff00ff)
  356.             gpu.set(2, 10, "color: "..playerColor)
  357.             gpu.setForeground(0xffffff)
  358.         end
  359.     else
  360.         table.remove(indicator,1)
  361.     end
  362. end
  363. command[35]=function()                          -- отобразить управление
  364.     term.clear()
  365.     gpu.setForeground(0xff0000)
  366.     print(version)
  367.     print("")
  368.     gpu.setForeground(0x00ff00)
  369.     print("Target: searching chamber 1")
  370.     print("Game 100% passable")
  371.     gpu.setForeground(0xffff00)
  372.     print("Control:")
  373.     print("Q - exit game")
  374.     print("H - help")
  375.     print("I - info")
  376.     print("W - set mark")
  377.     print("S - remove mark")
  378.     print("A - back color mark")
  379.     print("D - next color mark")
  380.     print("")
  381.     gpu.setForeground(0xffffff)
  382.     print("press enter to continue...")
  383.     while true do
  384.         _,_,_, key = event.pull("key_down")
  385.         if key == 28 then
  386.             break
  387.         end
  388.     end
  389. end
  390. -------------------------------------------------------------------------------------
  391. ---------------------- Показываем управление до начала игры -------------------------
  392. command[35]()
  393. -------------------------------------------------------------------------------------
  394. ------------------------- Отображение комнат до начала игры -------------------------
  395. reload_doors()
  396. update(nick)
  397. gpu.setBackground(0x000000)
  398. -------------------------------------------------------------------------------------
  399. ------------------------------------- Тело игры -------------------------------------
  400. while true do
  401.     _,_,_, key, nick = event.pull("key_down")
  402.     if key==16 then
  403.         term.clear()
  404.         gpu.setForeground(0xff0000)
  405.         print("Exit to game?")
  406.         gpu.setForeground(0xffffff)
  407.         print("")
  408.         print("y/n")
  409.         while true do
  410.             _,_,_, key = event.pull("key_down")
  411.             if key == 21 then
  412.                 term.clear()
  413.                 return
  414.             elseif key == 49 then
  415.                 break
  416.             end
  417.         end
  418.     elseif command[key] then
  419.         command[key]()
  420.     end
  421.     update(nick)
  422.     gpu.setBackground(0x000000)
  423.     if chamber.number == 1 then break end       -- цель игры, комната с этим номером
  424.     os.sleep(1/15)                              -- задержка, для более удобного управления
  425. end
  426. -------------------------------------------------------------------------------------
  427. ------------------------------------- Прощание -------------------------------------
  428. term.clear()
  429. gpu.setForeground(0x00ff00)
  430. print("Congratulations "..nick_player.."!")
  431. print("You win!")
  432. print("")
  433. gpu.setForeground(0xffffff)
  434. print("press enter to exit...")
  435. while true do
  436.     _,_,_, key = event.pull("key_down")
  437.     if key == 28 then
  438.         break
  439.     end
  440. end
  441. term.clear()
  442. -------------------------------------------------------------------------------------
RAW Paste Data