Skip to content

Instantly share code, notes, and snippets.

@etandel
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etandel/abfb3f6aae3e7c774822 to your computer and use it in GitHub Desktop.
Save etandel/abfb3f6aae3e7c774822 to your computer and use it in GitHub Desktop.
Joust
local http = require('socket.http')
local get_mod
get_mod = function(ab_score)
return math.floor(0.5 * (ab_score - 10))
end
local Player
do
local _base_0 = {
attack = function(self)
return math.random(1, 20) + self.int + self.str + self.bab
end,
roll_dmg = function(self)
return math.random(1, 6) + self.str
end,
roll_init = function(self)
return math.random(1, 20) + self.init
end,
reset = function(self)
self.hp = self.maxhp
end,
__tostring = function(self)
return self.raw
end
}
_base_0.__index = _base_0
local _class_0 = setmetatable({
__init = function(self, raw)
self.raw = raw
self.name = raw:match('^(..-),')
local get_param
get_param = function(ab)
return tonumber(raw:match(ab .. '%s*[%+%-]?(%d+)'))
end
self.int = get_mod(get_param('Int'))
self.str = get_mod(get_param('Str'))
self.maxhp = get_param('hp')
self.ac = get_param('AC')
self.bab = get_param('Attack') - self.str
self.init = get_param('Init')
return self:reset()
end,
__base = _base_0,
__name = "Player"
}, {
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
Player = _class_0
end
local get_raw_npc
get_raw_npc = function()
local data = {
a = 'any',
class1 = 'fighter',
class2 = 'any',
class3 = 'any',
g = 'any',
level1 = '8',
level2 = 'any',
level3 = 'any',
n = '1',
r = 'any',
strat = '4'
}
local u = 'http://www.myth-weavers.com/generate_npc.php?do=npcgen'
local params = table.concat((function()
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(data) do
_accum_0[_len_0] = k .. '=' .. v
_len_0 = _len_0 + 1
end
return _accum_0
end)(), '&')
local r = http.request(u, params)
return r:match('<pre>(.+)</pre>')
end
local random_npc
random_npc = function()
return Player(get_raw_npc())
end
local initiative
initiative = function(p1, p2)
local init1 = p1:roll_init()
local init2 = p2:roll_init()
if init1 > init2 then
return p1, p2
elseif init2 > init1 then
return p2, p1
else
return initiative(p1, p2)
end
end
local joust
joust = function(p1, p2)
p1:reset()
p2:reset()
local attacker, defender = initiative(p1, p2)
while math.min(p1.hp, p2.hp) > 0 do
local atk_roll = attacker:attack()
if atk_roll >= defender.ac + defender.int then
defender.hp = defender.hp - attacker:roll_dmg()
end
attacker, defender = defender, attacker
end
if p1.hp > p2.hp then
return p1
else
return p2
end
end
local tournament
tournament = function(draw)
if #draw == 1 then
return draw[1]
else
local newdraw
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, #draw / 2 do
_accum_0[_len_0] = joust(draw[i], draw[#draw - i + 1])
_len_0 = _len_0 + 1
end
newdraw = _accum_0
end
return tournament(newdraw)
end
end
local main
main = function()
math.randomseed(os.time())
local nplayers = tonumber(arg[1])
if not nplayers then
io.stderr:write('Error: Number of players must be passed.')
os.exit(1)
end
print('Generating players...')
local draw
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, nplayers do
_accum_0[_len_0] = random_npc()
_len_0 = _len_0 + 1
end
draw = _accum_0
end
print('Running tournament...\n')
print('Winner:')
return print(tournament(draw))
end
return main()
http = require'socket.http'
------------ NPC ------------
get_mod = (ab_score) -> math.floor 0.5 * (ab_score - 10)
class Player
new: (raw) =>
@raw = raw
@name = raw\match '^(..-),'
get_param = (ab) -> tonumber raw\match ab .. '%s*[%+%-]?(%d+)'
@int = get_mod get_param 'Int'
@str = get_mod get_param 'Str'
@maxhp = get_param 'hp'
@ac = get_param 'AC'
@bab = get_param('Attack') - @str
@init = get_param 'Init'
@reset!
attack: => math.random(1, 20) + @int + @str + @bab
roll_dmg: => math.random(1, 6) + @str
roll_init: => math.random(1, 20) + @init
reset: =>
@hp = @maxhp
__tostring: => @raw
get_raw_npc = ->
data = {
a: 'any'
class1: 'fighter'
class2: 'any'
class3: 'any'
g: 'any'
level1: '8'
level2: 'any'
level3: 'any'
n: '1'
r: 'any'
strat: '4'
}
u = 'http://www.myth-weavers.com/generate_npc.php?do=npcgen'
params = table.concat [k .. '=' .. v for k,v in pairs data], '&'
r = http.request u, params
return r\match '<pre>(.+)</pre>'
random_npc = -> Player get_raw_npc!
-------- Tournament ---------
initiative = (p1, p2) ->
init1 = p1\roll_init!
init2 = p2\roll_init!
return if init1 > init2
p1, p2
elseif init2 > init1
p2, p1
else
initiative p1, p2
joust = (p1, p2) ->
p1\reset!
p2\reset!
attacker, defender = initiative p1, p2
while math.min(p1.hp, p2.hp) > 0
atk_roll = attacker\attack!
if atk_roll >= defender.ac + defender.int
defender.hp -= attacker\roll_dmg!
attacker, defender = defender, attacker
return if p1.hp > p2.hp then p1 else p2
tournament = (draw) ->
if #draw == 1
return draw[1]
else
newdraw = for i = 1, #draw / 2
joust draw[i], draw[#draw - i + 1]
return tournament newdraw
main = ->
math.randomseed os.time!
nplayers = tonumber arg[1]
if not nplayers then
io.stderr\write 'Error: Number of players must be passed.'
os.exit 1
print 'Generating players...'
draw = [random_npc! for i=1, nplayers]
print 'Running tournament...\n'
print 'Winner:'
print tournament draw
main!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment