Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function createMatrix(xs, ys)
- local matrix = {}
- for x=1,xs do
- matrix[x] = {}
- for y=1,ys do
- matrix[x][y] = 0
- end
- end
- matrix.size = {xs, ys}
- matrix.values = {}
- matrix.setValue = function(self, is, name, cap)
- local value = {}
- value.inds = is
- value.name = name
- value.matrix = self
- value.cap = cap
- value.getValue = function(self)
- local val = 0
- for i=1,#self.inds do
- local ind = self.inds[i]
- local pos = self.matrix:getPos(ind)
- local v = self.matrix[pos[1]][pos[2]]
- if self.cap ~= nil then
- if v > self.cap then
- self.matrix[pos[1]][pos[2]] = self.cap
- v = self.cap
- end
- end
- val = val + v
- end
- return val
- end
- value.add = function(self, amt)
- while amt ~= 0 do
- if amt > 0 then
- local possible = {}
- for i=1,#self.inds do
- local ind = self.inds[i]
- local pos = self.matrix:getPos(ind)
- local v = self.matrix[pos[1]][pos[2]]
- if self.cap ~= nil then
- if v < self.cap then possible[#possible + 1] = pos end
- else possible[#possible + 1] = pos end
- end
- if #possible > 0 then
- local pos = possible[math.random(#possible)]
- matrix[pos[1]][pos[2]] = matrix[pos[1]][pos[2]] + 1
- end
- amt = amt - 1
- elseif amt < 0 then
- local possible = {}
- for i=1,#self.inds do
- local ind = self.inds[i]
- local pos = self.matrix:getPos(ind)
- local v = self.matrix[pos[1]][pos[2]]
- if v > 0 then possible[#possible + 1] = pos end
- end
- if #possible > 0 then
- local pos = possible[math.random(#possible)]
- matrix[pos[1]][pos[2]] = matrix[pos[1]][pos[2]] - 1
- end
- amt = amt + 1
- end
- end
- end
- self.values[name] = value
- return value
- end
- matrix.getValue = function(self, name)
- return self.values[name]
- end
- matrix.getIndex = function(self, x, y)
- local index = 0
- index = (self.size[1]*(x-1)) + y
- return index
- end
- matrix.getPos = function(self, index)
- local x = 1
- local y = index%self.size[1]
- local i = index - y
- x = math.floor(i/self.size[1])
- return {x, y}
- end
- matrix.getCode = function(self)
- local code = 0
- for x=1,self.size[1] do
- for y=1,self.size[2] do
- code = code + self[x][y]
- end
- end
- return code
- end
- matrix.place = function(self)
- end
- matrix.addM = function(self, matrix)
- local size = {self.size[1], self.size[2]}
- if matrix.size[1] < self.size[1] then size[1] = matrix.size[1] end
- if matrix.size[2] < self.size[2] then size[2] = matrix.size[2] end
- local nmat = createMatrix(size[1], size[2])
- for x=1,size[1] do
- for y=1,size[2] do
- nmat[x][y] = self[x][y] + matrix[x][y]
- end
- end
- nmat.values = self.values
- return nmat
- end
- local mt = {
- __tostring = function(t)
- return "matrix"
- end,
- __add = function(lhs, rhs)
- if tostring(lhs) == "matrix" and tostring(rhs) == "matrix" then
- lhs:place()
- return lhs:addM(rhs)
- else
- local t1 = type(lhs)
- local t2 = type(rhs)
- if tostring(lhs) == "matrix" then t1 = "matrix" end
- if tostring(rhs) == "matrix" then t2 = "matrix" end
- error("error adding "..t1.." to "..t2)
- end
- end
- }
- setmetatable(matrix, mt)
- return matrix
- end
- --[[
- -| : health
- -- x: damage
- + |-: ???
- ]]
- local form = {{ " ", colors.white, colors.black },
- { "-", colors.white, colors.black },
- { "|", colors.white, colors.black },
- { "+", colors.white, colors.black },
- { "x", colors.white, colors.black }}
- local function drawMatrix(p, matrix, col)
- for i=1,matrix:getIndex(matrix.size[1], matrix.size[2]) do
- local pos = matrix:getPos(i)
- local i = matrix[pos[1]][pos[2]]
- local text = form[i+1]
- if col ~= nil then
- for i=1,#text do
- if col[i] ~= nil then text[i] = col[i] end
- end
- end
- if text == nil then text = {" ", colors.white, colors.red} end
- term.setCursorPos(pos[1]+p[1]-1, pos[2]+p[2]-1)
- term.setBackgroundColor(text[2])
- term.setTextColor(text[3])
- term.write(text[1])
- end
- end
- local power_names =
- {"glitched", "novice", "weak", "student", "apprentice",
- "working", "average", "modest", "strong",
- "professional", "expert", "master", "ultimate", "impossible"}
- local health_names =
- {"shielded", "protected", "resistant", "tanky", "immortal"}
- local damage_names =
- {"soldier", "knight", "archer", "wizard", "sorcerer", "god"}
- local function generateName(rune)
- local power = rune:getCode()
- local pname = power_names[math.max(power/3)+1].." "
- -- power-name [health-class] damage-class
- local hname = ""
- local hclass = math.floor(rune:getValue("health"):getValue()/4)
- if hclass > 0 then
- hname = health_names[hclass].." "
- end
- local dname = damage_names(math.max(rune:getValue("damage"):getValue()/4))
- local name = pname..hname..dname
- end
- local etyps = {
- ["death"] = {1, "damage"},
- ["death"] = {2, "heal"},
- ["place"] = {3, "damage"},
- ["place"] = {4, "heal"}
- }
- local function runEvent(rune, event)
- local typ = rune:getValue("eve_type"):getValue()
- local amt = rune:getValue("eve_amount"):getValue()
- local ename = etyps[event]
- if ename ~= nil then
- if typ == ename[1] then
- local eve = ename[2]
- if eve == "damage" then
- local deck = rune.deck
- if deck.enemy ~= nil then
- local edeck = deck.enemy
- if #edeck.shown > 0 then
- for i=1,#edeck.shown do
- local rune = edeck.shown[i]
- rune:getValue("health"):add(-amt)
- rune:check()
- end
- else
- edeck.health = edeck.health - amt
- edeck:check()
- end
- end
- elseif eve == "heal" then
- if #deck.shown > 0 then
- for i=1,#deck.shown do
- local rune = deck.shown[i]
- rune:getValue("health"):add(amt)
- end
- end
- end
- end
- end
- end
- local function createRune(code, deck)
- local matrix = createMatrix(4, 3)
- for x=1,string.len(code) do
- local i = code:sub(x, x)
- local pos = matrix:getPos(x)
- matrix[pos[1]][pos[2]] = i
- end
- matrix:setValue({1, 2, 3, 4}, "health", 4)
- matrix:setValue({5, 6, 7, 8}, "damage", 4)
- matrix:setValue({9}, "eve_type", 4)
- matrix:setValue({10, 11, 12}, "eve_amount", 4)
- matrix.name = generateName(matrix)
- matrix.defense = 0
- matrix.hurt = false
- matrix.used = false
- matrix.place = function(self)
- runEvent(self, "place")
- end
- matrix.death = function(self)
- runEvent(self, "death")
- end
- matrix.damage = function(self, amt)
- if self.defense > 0 then
- amt = math.max(amt/2)
- self:getValue("health"):add(-amt)
- defense = defense - 1
- else
- self:getValue("health"):add(-amt)
- end
- self.hurt = true
- end
- matrix.check = function(self)
- if self:getValue("health"):getValue() <= 0 then
- local deck = self.deck
- if #deck.shown > 0 then
- local nshown = {}
- for i=1,#deck.shown do
- local rune = deck.shown[i]
- if rune ~= self then
- nshown[#nshown + 1] = rune
- else
- self:death()
- end
- end
- deck.shown = nshown
- end
- end
- end
- matrix.deck = deck
- return matrix
- end
- local on = true
- local winner = "nobody"
- local function createDeck(name)
- local deck = {}
- deck.runes = {}
- deck.piles = {}
- deck.shown = {}
- deck.enemy = nil
- deck.health = 100
- deck.turn = 0
- deck.name = name
- deck.getValue = function(self, value)
- local v = 0
- for i=1,#shown do
- local rune = shown[i]
- v = v + rune:getValue(value):getValue()
- end
- return v
- end
- deck.addRune = function(self, rune)
- self.runes[#self.runes + 1] = rune
- end
- deck.shuffle = function(self)
- local nrunes = {}
- for i=1,#self.runes do
- table.insert(nrunes, math.random(#nrunes + 1), self.runes[i])
- end
- self.runes = nrunes
- end
- deck.split = function(self, n)
- local piles = {}
- local curn = 1
- for i=1,#self.runes do
- if piles[curn] == nil then piles[curn] = {} end
- local pile = piles[curn]
- pile[#pile + 1] = self.runes[i]
- curn = curn + 1
- if curn >= n then curn = 1 end
- end
- self.piles = piles
- for i=1,#piles do
- local pile = piles[i]
- local rune = pile[#pile]
- self.shown[#self.shown + 1] = rune
- pile[#pile] = nil
- end
- end
- deck.sort = function(self, n)
- self:shuffle()
- self:split(n)
- end
- deck.placeRune = function(self, pileID, shownID)
- if turn > 0 then
- local pile = pileID
- if type(pile) == "number" then pile = self.pile[pileID] end
- local shown = shownID
- if type(shown) == "number" then shown = self.shown[shownID] end
- if pile ~= nil and shown ~= nil then
- local rune = pile[#pile]
- self.shown[shownID] = shown + rune
- pile[#pile] = nil
- turn = turn - 1
- return true
- elseif pile ~= nil and shown == nil then
- local rune = pile[#pile]
- self.shown[shownID] = rune
- pile[#pile] = nil
- turn = turn - 1
- return true
- end
- end
- return false
- end
- deck.attack = function(self, shownID, enemyID)
- if turn > 0 then
- if self.enemy ~= nil then
- local erune = enemyID
- if type(erune) == "number" then erune = self.enemy.shown[enemyID] end
- local rune = shownID
- if type(rune) == "number" then rune = self.shown[shownID] end
- if erune ~= nil and rune ~= nil then
- erune:damage(rune:getValue("damage"))
- rune.used = true
- turn = turn - 1
- return true
- end
- end
- end
- return false
- end
- deck.defend = function(self, shownID)
- if turn > 0 then
- local rune = shownID
- if type(rune) == "number" then rune = self.shown[shownID] end
- if rune ~= nil then
- rune.defense = rune.defense + 1
- end
- end
- end
- deck.check = function(self)
- if self.healh <= 0 then
- on = false
- winner = self.name
- end
- end
- end
- local deck = createDeck("you")
- local edeck = createDeck("enemy")
- local function getRuneID(name)
- local nm = name:sub(1, -3)
- local id = tonumber(name:sub(-1, -1))
- if nm == "enemy_card" then
- return edeck, edeck.shown[id], "card", id
- elseif nm == "player_card" then
- return deck, deck.shown[id], "card", id
- elseif nm == "player_pile" then
- local pile = deck.piles[id]
- local rune = pile[#pile]
- return deck, rune, "pile", id
- end
- return deck, deck.shown[id], "card"
- end
- local tooltip = "Welcome to Runes!"
- local gui = {
- {"enemy_card_1", {3, 3}, {3, 3}, "An enemy rune, left click to attack"},
- {"enemy_card_2", {7, 3}, {3, 3}, "An enemy rune, left click to attack"},
- {"enemy_card_3", {11, 3}, {3, 3}, "An enemy rune, left click to attack"},
- {"player_card_1", {3, 8}, {3, 3}, "Your rune, left click to use"},
- {"player_card_2", {7, 8}, {3, 3}, "Your rune, left click to use"},
- {"player_card_3", {11, 8}, {3, 3}, "Your rune, left click to use"},
- {"player_pile_1", {3, 12}, {3, 4}, "Your deck, left click to use"},
- {"player_pile_2", {7, 12}, {3, 4}, "Your deck, left click to use"},
- {"player_pile_3", {11, 12}, {3, 4}, "Your deck, left click to use"},
- }
- local background =
- {"2~~~~~~~~~~~~~1 _____ ",
- "$.%%%.%%%.%%%.$ / \\__ ",
- "$%***%***%***%$ |Runes/ \\ ",
- "$%***%***%***%$ \\_____|by|__ ",
- "$%***%***%***%$ / \\__/ \\ ",
- "$#%^%#%^%#%^%#$ | billysback| ",
- "$#%^%#%^%#%^%#$ \\__________/ ",
- "$%***%***%***%$ ",
- "$%***%***%***%$ v ____ v ",
- "$%***%***%***%$ >% / || \\ %< ",
- "$.%%%.%%% %%%.$ /\\ __ /\\ ",
- "$.***.***.***.$ | X X | ",
- "$.***.***.***.$ |- |xx| -| ",
- "$.***.***.***.$ | X__X | ",
- "$.***.***.***.$ \\/ \\/ ",
- "$.............$ >% \\_||_/ %< ",
- "1~~~~~~~~~~~~~2 ^ ^ "}
- local convert = {}
- convert["2"] = {colors.lightGray, colors.gray, "/"}
- convert["1"] = {colors.lightGray, colors.gray, "\\"}
- convert["$"] = {colors.gray, colors.lightGray, "|"}
- convert["~"] = {colors.gray, colors.lightGray, "-"}
- convert["%"] = {colors.gray, colors.orange}
- convert["."] = {colors.lightGray, colors.gray, " "}
- convert["*"] = {colors.black, colors.gray}
- convert["^"] = {colors.gray, colors.red}
- convert["v"] = {colors.gray, colors.red}
- convert[">"] = {colors.gray, colors.red}
- convert["<"] = {colors.gray, colors.red}
- convert["#"] = {colors.gray, colors.yellow}
- convert["/"] = {colors.white, colors.lightGray}
- convert["\\"] = {colors.white, colors.lightGray}
- convert["|"] = {colors.white, colors.lightGray}
- convert["_"] = {colors.white, colors.lightGray}
- convert["-"] = {colors.white, colors.lightGray}
- convert["X"] = {colors.white, colors.orange}
- convert[" "] = {colors.white, colors.lightGray}
- local function drawImage()
- term.setBackgroundColor(colors.black)
- term.clear()
- local lines = background
- if #lines > 0 then
- for y=1,#lines do
- local line = lines[y]
- for x=1,string.len(line) do
- local char = line:sub(x,x)
- term.setCursorPos(x,y+1)
- local col = convert[char]
- if col == nil then col = {colors.black, colors.white} end
- term.setBackgroundColor(col[1])
- term.setTextColor(col[2])
- if col[3] ~= nil then char = col[3] end
- term.write(char)
- end
- end
- end
- end
- local function draw()
- drawImage()
- for i=1,#gui do
- local item = gui[i]
- local pos = item[2]
- local d, rune, typ = getRuneID(item[1])
- if rune ~= nil then
- local col = {nil, nil, nil}
- if rune.defense > 0 then col[2] = colors.blue end
- if d == edeck then col[3] = colors.purple end
- if rune.hurt then
- col[3] = colors.red
- rune.hurt = false
- end
- if typ == "pile" then
- col[2] = colors.black
- col[3] = colors.white
- for x=1,3 do
- term.setCursorPos(pos[1]+x-1, pos[2]+3)
- term.setBackgroundColor(colors.gray)
- term.write(" ")
- end
- end
- drawMatrix(pos, rune, col)
- end
- end
- if deck.turn > 0 then
- for y=2,deck.turn+1 do
- term.setCursorPos(1, y)
- term.setBackgroundColor(colors.green)
- term.write(" ")
- end
- end
- end
- local function getButton(x, y)
- for i=1,#gui do
- local item = gui[i]
- local pos = item[2]
- local size = item[3]
- if x >= pos[1] and y >= pos[2] and x < pos[1]+size[1] and y < pos[2]+size[2] then
- return item
- end
- end
- end
- local function getMaxVal(deck, val, pile)
- local id = 1
- local maxVal = 0
- for i=1,3 do
- local rune = nil
- if pile then
- local pile = deck.pile[i]
- rune = pile[#pile]
- else
- rune = deck.shown[i]
- end
- if rune ~= nil then
- if rune.used == false then
- local v = rune:getValue(val):getValue()
- if v > maxVal then
- v = maxVal
- id = i
- end
- end
- end
- end
- return id
- end
- local function doAI()
- while edeck.turn > 0 do
- if #edeck.shown <= 0 then
- local id = getMaxVal(edeck, "health", true)
- edeck:placeRune(id, 1)
- elseif #deck.shown <= 0 then
- local id = getMaxVal(edeck, "damage", true)
- local pile = edeck.piles[id]
- edeck:attack(pile[#pile], math.random(1, 3))
- else
- local health1 = edeck:getValue("health")
- local damage1 = edeck:getValue("damage")
- local health2 = deck:getValue("health")
- local damage2 = deck:getValue("damage")
- local turnDmg1 = math.floor((damage1/3)*2)
- local turnDmg2 = math.floor((damage2/3)*2)
- if health1 < turnDmg2 then
- local id = getMaxVal(edeck, "health", true)
- edeck:placeRune(id, math.random(1, 3))
- elseif health2 < turnDmg1 then
- local id = getMaxVal(edeck, "damage", false)
- local rune = edeck.shown[id]
- edeck:attack(rune, math.random(1, 3))
- elseif damage1 < damage2 then
- local id = getMaxVal(edeck, "damage", true)
- edeck:placeRune(id, math.random(1, 3))
- elseif health1 < health2 then
- local id = getMaxVal(edeck, "health", true)
- edeck:placeRune(id, math.random(1, 3))
- else
- local id = getMaxVal(edeck, "damage", false)
- edeck:attack(id, math.random(1, 3))
- end
- end
- draw()
- end
- end
- local function doTurn()
- local selected = nil
- while deck.turn > 0 do
- local event, p1, p2, p3 = os.pullEvent()
- if event == "mouse_click" then
- local item = getButton(p2, p3)
- if p1 == 1 then
- if selected == nil then selected = item
- else
- if selected == item then
- local d, rune, typ = getRuneID(item[1])
- d:defend(rune)
- selected = nil
- else
- local d1, rune1, typ1, id1 = getRuneID(item[1])
- local d2, rune2, typ2, id2 = getRuneID(selected[1])
- if d1 == deck and d2 == edeck then
- d1:attack(rune1, rune2)
- selected = nil
- elseif d1 == d2 and d1 == deck and typ1 == "pile" and typ2 == "card" then
- d1:placeRune(id1, rune2)
- selected = nil
- end
- end
- end
- elseif p1 == 2 then
- tooltip = item[4]
- end
- end
- draw()
- end
- end
- local player_turn = true
- local turns = 1
- while on do
- if player_turn then
- deck.turn = turns
- doTurn()
- else
- edeck.turn = turns
- doAI()
- end
- player_turn = (player_turn == false)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement