pico-8 cartridge // http://www.pico-8.com version 34 __lua__ -- generic shmup -- by kistaro windrider game = 1 win = 2 lose = 3 debug = {} function _init() -- create the pwr gradient -- 15 is the gradient color poke(0x5f5f,0x3f) poke(0x5f68,10) poke(0x5f69,10) poke(0x5f6a,9) poke(0x5f6b,4) memset(0x5f78,0xa8,3) init_bullet_mt() init_ship_mt() wipe_level() primary_ship.special_gun = new_gun_of(blast_gun_t) load_level(example_level) state = game end function wipe_level() primary_ship = new_p1() pships = {primary_ship} eships = {} pbullets = {} ebullets = {} intangibles = {} events = {} end function _update60() if (state == game) updategame() end function updategame() local leveldone = level_frame() local deaths = {} for i, e in ipairs(events) do if (e()) add(deaths, i) end bury_the_dead(events, deaths) for _, tbl in ipairs({pships, eships, pbullets, ebullets, intangibles}) do local deaths = {} for i, x in ipairs(tbl) do if (x:move()) add(deaths, i) end bury_the_dead(tbl, deaths) end --then, calculate collisions local pdeaths = {} local edeaths = {} for ip, ps in ipairs(pships) do for ie, es in ipairs(eships) do if collides(hurtbox(ps), hurtbox(es)) then if (es:hitship(ps)) add(edeaths, ie) if ps:hitship(es) then add(pdeaths, ip) break end end end end bury_the_dead(pships, pdeaths) bury_the_dead(eships, edeaths) pdeaths = {} edeaths = {} for ip, ps in ipairs(pships) do for ie, eb in ipairs(ebullets) do if collides(hurtobx(ps), hurtbox(eb)) then if (eb:hitship(ps)) add(edeaths, ie) if ps:hitbullet(eb) then add(pdeaths, ip) break end end end end bury_the_dead(pships, pdeaths) bury_the_dead(ebullets, edeaths) pdeaths = {} edeaths = {} for ip, pb in ipairs(pbullets) do for ie, es in ipairs(eships) do if collides(hurtbox(pb), hurtbox(es)) then if (es:hitbullet(pb)) add(edeaths, ie) if pb:hitship(es) then add(pdeaths, ip) break end end end end bury_the_dead(eships, edeaths) bury_the_dead(pbullets, pdeaths) if leveldone and ((#eships + #ebullets + #events) == 0) then state = win end if #pships == 0 then state = lose end end function _draw() drawgame() draw_debug() if (state == win) dropshadow("win",50,61,11) if (state == lose) dropshadow("fail",48,61,8) end function draw_debug() if (#debug==0) return cursor(0,0,7) foreach(debug,print) debug={} end function drawgame() cls() clip(0,0,112,128) for tbl in all{pbullets, pships, eships, intangibles, ebullets} do for x in all(tbl) do x:draw() end end clip(0,0,128,128) drawhud() end function drawhud() -- 112-and-right is hud zone rectfill(112, 0, 127, 127,0x56) rect(112,0,127,127,7) line(127,1,127,127,5) line(113,127) draw_gun_info("❎",116,3,primary_ship.main_gun) draw_gun_info("🅾️",116,31,primary_ship.special_gun) dropshadow("pwr",114,59,1) inset(114,66,125,92) vertmeter(115,67,124,91,primary_ship.power, primary_ship.max_power, 15) dropshadow("h s",114,97,1) inset(114,104,125,125) line(119,105,119,124,7) line(120,105,120,125,5) vertmeter(115,105,118,124,primary_ship.hp, primary_ship.maxhp, 8) vertmeter(121,105,124,124,primary_ship.shield, primary_ship.maxshield,12) end function draw_gun_info(lbl,x,y,gun) dropshadow(lbl,x,y,1) inset(114,y+7,125,y+18) inset(114,y+20,125,y+24) if(gun) then spr(gun.icon,116,y+9,1,1) --115 to 124 - ammo bar. round up if gun.ammo == nil then fillp(0xa5a5) rectfill(115,y+21,124,y+23,0xea) fillp(0) elseif gun.ammo > 0 then rectfill( 115,y+21, 115+flr(9*gun.ammo/gun.maxammo), y+23,10) else line(118, y+22, 121, y+22, 2) end end end function vertmeter(x0,y0,x1,y1,val,maxval,col) if (val <= 0) return local h = y1-y0 local pxm1 = flr(h*val/maxval) rectfill(x0,y1-pxm1,x1,y1,col) end function inset(x0,y0,x1,y1) rectfill(x0,y0,x1,y1,0) rect(x0,y0,x1,y1,7) line(x1,y0,x0,y0,5) line(x0,y1,5) end function dropshadow(str, x, y, col) print(str, x+1, y+1, 5) print(str, x, y, col) end function grab_p1_butts() local b = btn() return { [0]=b&0x1, [1]=(b&0x2)>>1, [2]=(b&0x4)>>2, [3]=(b&0x8)>>3, [4]=(b&0x10)>>4, [5]=(b&0x20)>>5 } end function bury_the_dead(tbl, dead) if (#dead == 0) return local tail = dead[1] local head = tail + 1 local deaddex = 2 while head <= #tbl do while deaddex <= #dead and head == dead[deaddex] do deaddex += 1 head += 1 end if (head > #tbl) break tbl[tail] = tbl[head] head += 1 tail += 1 end for i=1,(head-tail) do deli(tbl) end end -->8 --ships, including player function init_ship_mt() setmetatable(player, ship_t) setmetatable(frownie, ship_t) setmetatable(blocky, frownie_t) end player = { --shape sprite = 1, --index of ship sprite size = 2, --all ships are square; how many 8x8 sprites? hurt = { -- hurtbox - where this ship can be hit x_off = 6, -- upper left corner y_off = 6, -- relative to ship ulc width = 4, height = 4 }, -- health and power hp = 3, -- current health, non-regenerating maxhp = 3, -- player only; other ships never heal shield = 2, -- regenerates, using power maxshield = 2, shieldcost = 300, -- power cost to refill shield generator = 1.5, -- 1 feels too slow -- gun main_gun = nil, -- assign at spawn time special_gun = nil, fire_off_x = 8, -- offset where bullets come from fire_off_y = 0, -- position x=52, -- x and y are for upper left corner y=96, xmomentum = 0, ymomentum = 0, maxspd = 2.5, -- momentum cap thrust = 0.25, -- momentum added from button drag = 0.125, -- momentum lost per frame slip = false, -- does not slide down screen grab_butts = grab_p1_butts, -- button fetch algorithm } player_t = { __index = player } function new_p1() p = { main_gun = new_gun_of(zap_gun_t, false) } setmetatable(p, player_t) return p end frownie = { --shape sprite = 3, --index of ship sprite size = 1, --all ships are square; how many 8x8 sprites? hurt = { -- hurtbox - where this ship can be hit x_off = 1, -- upper left corner y_off = 1, -- relative to ship ulc width = 6, height = 6 }, -- health and power hp = 1, -- enemy ships need no max hp -- position x=60, -- x and y are for upper left corner y=8, xmomentum = 0, ymomentum = 0, maxspd = 2, -- momentum cap thrust = 0.12, -- momentum added from button drag = 0.07, -- momentum lost per frame slip = true, grab_butts = function(discard_self) -- buttons are effectively analog -- and negative buttons work just fine! local butts = {} local tstate = (1 + flr(4*t() + 0.5)) % 6 butts[0] = ((tstate==1 or tstate==2) and 1) or 0 butts[1] = ((tstate==4 or tstate==5) and 1) or 0 for b=2, 5 do butts[b]=0 end return butts end, -- button fetch algorithm } frownie_t = { __index = frownie } blocky = { sprite = 10, hp = 2, ow = function(self) if self.hp <= 1 then self.sprite = 11 else self.sprite = 10 end end } blocky_t = { __index = blocky } -->8 --ship behavior scrollrate = 0.25 --in px/frame ship_m = { -- ships have no shield by default shield = 0, maxshield = 0, shieldcost = 32767.9, shieldcooldown = 180, -- default generator behavior: -- 10 seconds for a full charge max_power = 600, power = 600, generator = 1, -- power gen per frame invincible_until = -32768, slip = true -- most enemies slide } ship_t = { __index = ship_m, } function ship_m.die(_) end function ship_m.move(ship) ship:refresh_shield() ship.power = min(ship.max_power, ship.power + ship.generator) butt = ship.grab_butts() if (butt[5] > 0) ship:maybe_shoot(ship.main_gun) if (butt[4] > 0) ship:maybe_shoot(ship.special_gun) ship.xmomentum += (ship.thrust * butt[1]) - (ship.thrust * butt[0]) ship.ymomentum += (ship.thrust * butt[3]) - (ship.thrust * butt[2]) ship.xmomentum = mid(-ship.maxspd, ship.maxspd, ship.xmomentum) ship.ymomentum = mid(-ship.maxspd, ship.maxspd, ship.ymomentum) ship.x = mid(0, 112 - 8 * ship.size, ship.x + ship.xmomentum) if not ship.slip then ship.y = mid(0, 128 - 8 * ship.size, ship.y + ship.ymomentum) end --friction local xfric = 0 local yfric = 0 if (ship.xmomentum > 0) xfric = min(ship.xmomentum, ship.drag) if (ship.xmomentum < 0) xfric = max(ship.xmomentum, -ship.drag) if (ship.ymomentum > 0) yfric = min(ship.ymomentum, ship.drag) if (ship.ymomentum < 0) yfric = max(ship.ymomentum, -ship.drag) ship.xmomentum -= xfric ship.ymomentum -= yfric -- "scrolling" behavior if ship.slip then ship.y += scrollrate if ship.y >= 128 then ship:die() return true end end return false end -- moveship(ship) function ship_m.draw(ship) spr(ship.sprite, ship.x, ship.y, ship.size, ship.size) end function hurtbox(ship) return { x=ship.x + ship.hurt.x_off, y=ship.y + ship.hurt.y_off, width=ship.hurt.width, height=ship.hurt.height } end function ship_m:maybe_shoot(gun) if (not gun) return if (self.power < gun.power) return if (not gun:shoot(self.x + self.fire_off_x, self.y + self.fire_off_y)) return self.power -= gun.power end function ship_m:hitship(other) return self:hitsomething(1) end function ship_m:hitbullet(b) return self:hitsomething(b.damage) end function ship_m:hitsomething(dmg) if (dmg <= 0) return false if (lframe < self.invincible_until) return false self.shield_refresh_ready = lframe + self.shieldcooldown if self.shield >= dmg then self.shield -= dmg self:ow() return false end dmg -= self.shield self.shield = 0 self.hp -= dmg if self.hp <= 0 then self:die() return true end self:ow() return false end function ship_m:ow() -- todo: implement damage blink end function ship_m:refresh_shield() if (self.shield >= self.maxshield) return if (lframe < self.shield_refresh_ready) return if (self.power < self.shieldcost) return self.shield += 1 self.power -= self.shieldcost self.shield_refresh_ready = lframe + self.shieldcooldown end -->8 -- collisions -- box: x, y, width, height function collides(box1, box2) local dx = box2.x - box1.x local cx = dx >= 0 and dx <= (box1.width or 0) dx = box1.x - box2.x cx = cx or (dx >= 0 and dx <= (box2.width or 0)) if (not cx) return false local dy = box2.y - box1.y local cy = dy >= 0 and dy <= (box1.height or 0) dy = box1.y - box2.y cy = cy or (dy >= 0 and dy <= (box2.height or 0)) return cy end -->8 -- level and event system -- a level is a map from -- effective frame number to -- callback for that frame. -- effective frame number stops -- when freeze count is nonzero -- a level is won when it hits -- the end-of-level sentinel -- and there are no more -- tracked enemies. -- lost when there are no -- player ships left. -- effective frame distance = 0 -- actual frame count since -- start of level lframe = 0 -- do not advance distance when -- nonzero freeze = 0 eol = {} function load_level(lvltbl) distance = 0 lframe = 0 freeze = 0 current_level = {} for frame, cb in pairs(lvltbl) do current_level[frame] = cb end end function level_frame() lframe += 1 if (current_level == nil) return true if freeze == 0 then distance += 1 local cb = current_level[distance] if cb ~= nil then if cb == eol then current_level = nil return true else cb() end end end return false end -->8 -- example level function spawn_rnd_x(mt) s = { x = rnd(104), y = -(mt.__index.size * 8 - 1) } setmetatable(s, mt) add(eships, s) end function spawn_blocking_rnd_x(mt) freeze += 1 s = { x = rnd(104), y = -7, die = function(self) freeze -= 1 mt.__index.die(self) end } setmetatable(s, mt) add(eships, s) end function spawn_frownie() spawn_rnd_x(frownie_t) end function spawn_blocking_frownie() spawn_blocking_rnd_x(frownie_t) end function spawn_blocky() spawn_rnd_x(blocky_t) end function spawn_blocking_blocky() spawn_blocking_rnd_x(blocky_t) end example_level = { [1]=spawn_frownie, [60]=spawn_blocky, [61]=spawn_blocky, [250]=spawn_blocking_blocky, [310]=function() spawn_blocking_blocky() spawn_blocking_blocky() spawn_blocking_blocky() end, [311]=spawn_frownie, [401]=spawn_frownie, [420]=spawn_blocking_frownie, [450]=spawn_frownie, [451]=eol } -->8 -- bullets and guns function init_bullet_mt() setmetatable(zap, bullet_t) setmetatable(zap_gun, gun_t) setmetatable(blast, bullet_t) setmetatable(blast_gun, gun_t) end zap = { --shape psprite = 8, --index of player ammo sprite esprite = 9, -- index of enemy ammo sprite width = 1, --in 8x8 blocks height = 1, hurt = { -- hurtbox - where this ship can be hit x_off = 0, -- upper left corner y_off = 0, -- relative to sprite width = 2, height = 8 }, center_x_off = 1, -- how to position by ship bottom_y_off = 0, top_y_off = 0, damage = 1, dx = 0, -- px/frame dy = 8, hitship = function(_, _) return true end } zap_t = { __index = zap } zap_gun = { enemy = false, power = 30, -- power consumed per shot cooldown = 10, -- frames between shots ammo = nil, -- unlimited ammo - main gun t = zap_t -- metatable of bullet to fire } zap_gun_t = { __index = zap_gun } blast = { --shape psprite = 12, --index of player ammo sprite esprite = 3, -- index of enemy ammo sprite width = 1, --in 8x8 blocks height = 1, hurt = { -- hurtbox - where this ship can be hit x_off = 1, -- upper left corner y_off = 1, -- relative to sprite width = 6, height = 6 }, center_x_off = 4, -- how to position by ship bottom_y_off = 0, top_y_off = 0, damage = 4, dx = 0, -- px/frame dy = 2, -- disable damage for 2 frames -- when hitting something hitship = function(self, _) self.damage = 0 local wait = 2 e = function() wait -= 1 if wait <= 0 then self.damage = 4 return true end return false end add(events, e) end } blast_t = { __index = blast } blast_gun = { icon = 13, enemy = false, power = 0, -- ammo, not power cooldown = 30, -- frames between shots ammo = 5, maxammo = 5, t = blast_t -- metatable of bullet to fire } blast_gun_t = { __index = blast_gun } function new_gun_of(mt, is_enemy) g = { enemy = e } setmetatable(g, mt) return g end -->8 -- bullet and gun behaviors bullet_base = { } bullet_t = { __index = bullet_base } gun_base = { shoot_ready = -32768, icon = 20 } gun_t = { __index = gun_base } function bullet_base:hitship(_) self:die() return true end function bullet_base:die() end function bullet_base:move() self.x += self.dx if self.enemy then self.y += self.dy if self.y > 128 then self:die() return true end else self.y -= self.dy if self.y < -8*self.height then self:die() return true end end return false end function bullet_base:draw() spr(self.sprite, self.x, self.y, self.width, self.height) end function bullet_base:spawn_at(x, y) self.x = x - self.center_x_off if self.enemy then self.y = y + self.top_y_off add(ebullets, self) else self.y = y - (8 * self.height) + self.bottom_y_off add(pbullets, self) end end function gun_base:shoot(x, y) if (lframe < self.shoot_ready) return false if self.ammo then if (self.ammo <= 0) return false self.ammo -= 1 end self.shoot_ready = lframe + self.cooldown b = { } setmetatable(b, self.t) if self.enemy then b.enemy = true b.sprite = b.esprite else b.enemy = false b.sprite = b.psprite end b:spawn_at(x, y) return true end __gfx__ 000000000000000aa00000000088880090000009e00000000000000e00dddd003b00000082000000066666600555555000333300002222000000000000000000 000000000000000aa00000000822228099000009ee0000000000000e0d1111d037000000a2000000655555565555555503bbbb30028888200000000000000000 00700700000000aaaa00000082a22a280990009000ee0000000000eed171171db7000000a800000065755756557557553bbaabb3288aa8820000000000000000 00077000000000aaaa0000008222222800990900000ee00000000ee0d111111db7000000a800000065555556555555553ba77ab328a77a820000000000000000 0007700000000aaaaaa00000822aa228000990000000ee000000ee00d117711db7000000a800000065555556555775553ba77ab328a77a820000000000000000 0070070000000aaaaaa0000082a22a2800999900000000eee00ee000d171171db7000000a800000065777756557557553bbaabb3288aa8820000000000000000 000000000000aaaaaaaa0000082222800990099000000000eeee00000d1111d037000000a2000000655555565557755503bbbb30028888200000000000000000 000000000000aa8888aa0000008888009900009900000000eeee000000dddd003b00000082000000066666600555555000333300002222000000000000000000 00000000000aaa8888aaa00000000000b000000b0000000ee00ee000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000aaa8888aaa0000000000000bbbb00000000ee000eeee0000000000000000000000000000000000000000000000000000000000000000000000000 0000000000aaaa8888aaaa00000000000b0000b000000ee0000eeee0000000000000000000000000000000000000000000000000000000000000000000000000 0000000000aaaaaaaaaaaa00000000000b0bb0b00000ee000000eee0000000000000000000000000000000000000000000000000000000000000000000000000 000000000aaaaaaaaaaaaaa0000000000b0bb0b0000ee00000000eee000000000000000000000000000000000000000000000000000000000000000000000000 000000000aaaaaaaaaaaaaa0000000000b0000b000ee000000000eee000000000000000000000000000000000000000000000000000000000000000000000000 00000000aaaaaaaaaaaaaaaa0000000000bbbb00ee000000000000ee000000000000000000000000000000000000000000000000000000000000000000000000 00000000aaaaaaaaaaaaaaaa00000000b000000be0000000000000ee000000000000000000000000000000000000000000000000000000000000000000000000 __label__ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777777777777777 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115151166665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666111611156665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115161156665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111556665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666665555566665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650b000000b0765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765000bbbb000765 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0000b00765 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0bb0b00765 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0bb0b00765 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076500b0000b00765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765000bbbb000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650b000000b0765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777777777765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aeaeaeaeae765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765eaeaeaeaea765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aeaeaeaeae765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777777777765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115551166665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115161156665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666115651156665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666611111556665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666665555566665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650002222000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650028888200765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650288aa8820765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765028a77a820765 0000000000000000000000000000000000006666660000000000000000000000000000000000000005555550006666660000000000000000765028a77a820765 00000000000000000000000000000000000655555560000000000000000000000000000000000000555555550655555560000000000000007650288aa8820765 00000000000000000000000000000000000657557560000000000000000000000000000000000000557557550657557560000000000000007650028888200765 00000000000000000000000000000000000655555560000000000000000000000000000000000000555555550655555560000000000000007650002222000765 00000000000000000000000000000000000655555560000000000000000000000000000000000000555775550655555560000000000000007650000000000765 00000000000000000000000000000000000657777560000000000000000000000000000000000000557557550657777560000000000000007657777777777765 00000000000000000000000000000000000655555560000000000000000000000000000000000000555775550655555560000000000000007666666666666665 00000000000000000000000000000000000066666600000000000000000000000000000000000000055555500066666600000000000000007655555555555565 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aaaaaaaaaa765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aaaaaaaaaa765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765aaaaaaaaaa765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777777777765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007611161616111665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007615151515151565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007611151515116565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007615551115151665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007615661115151565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007665666555656565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007655555555555565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007650000000000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007659999999999765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007654444444444765 000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000007654444444444765 000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000000000000000000000007654444444444765 00000000000000000000000000000000000000000000000aaaa00000000000000000000000000000000000000000000000000000000000007654444444444765 00000000000000000000000000000000000000000000000aaaa00000000000000000000000000000000000000000000000000000000000007657777777777765 0000000000000000000000000000000000000000000000aaaaaa0000000000000000000000000000000000000000000000000000000000007666666666666665 0000000000000000000000000000000000000000000000aaaaaa0000000000000000000000000000000000000000000000000000000000007666666666666665 000000000000000000000000000000000000000000000aaaaaaaa000000000000000000000000000000000000000000000000000000000007666666666666665 000000000000000000000000000000000000000000000aa8888aa000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000aaa8888aaa00000000000000000000000000000000000000000000000000000000007616166666611665 00000000000000000000000000000000000000000000aaa8888aaa00000000000000000000000000000000000000000000000000000000007615156666165565 0000000000000000000000000000000000000000000aaaa8888aaaa0000000000000000000000000000000000000000000000000000000007611156666111665 0000000000000000000000000000000000000000000aaaaaaaaaaaa0000000000000000000000000000000000000000000000000000000007615156666651565 000000000000000000000000000000000000000000aaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000007615156666116565 000000000000000000000000000000000000000000aaaaaaaaaaaaaa000000000000000000000000000000000000000000000000000000007665656666655665 00000000000000000000000000000000000000000aaaaaaaaaaaaaaaa00000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000aaaaaaaaaaaaaaaa00000000000000000000000000000000000000000000000000000007655555555555565 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007658888750000765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765888875cccc765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007657777757777765 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007666666666666665 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007555555555555555