Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Nspire Lua 2048
- -- (C) 2014 Adriweb
- -- TI-Planet.org - Inspired-Lua.org
- -- Game idea from http://gabrielecirulli.github.io/2048/
- -------------
- -- Globals --
- -------------
- W, H = 318, 212 -- will be overwritten by on.resize
- score = 0
- bestScore = 0 -- will be overwritten by on.restore
- newTileX = 0
- newTileY = 0
- colorTbl = {
- [2] = { 0xee, 0xe4, 0xda },
- [4] = { 0xed, 0xe0, 0xc8 },
- [8] = { 0xf2, 0xb1, 0x79 },
- [16] = { 0xf5, 0x95, 0x63 },
- [32] = { 0xf6, 0x7c, 0x5f },
- [64] = { 0xf6, 0x5e, 0x3b },
- [128] = { 0xed, 0xcf, 0x72},
- [256] = { 0xed, 0xcc, 0x61},
- [512] = { 0xed, 0xc8, 0x50 },
- [1024] = { 0xed, 0xc5, 0x3f },
- [2048] = { 0xed, 0xc2, 0x2e }
- }
- local mathrandom = math.random
- local function uCol(tbl)
- return tbl[1], tbl[2], tbl[3]
- end
- -------------
- -- Classes --
- -------------
- Game = class()
- function Game:init(size)
- if ((not size) or size<2 or size>10) then
- size=4
- print("Invalid size. Setting to 4")
- end
- self.size = size
- self.gridOffset = nil
- self:restart()
- end
- function Game:makeGrid()
- self.grid = {}
- self.filled = false
- for j=1,self.size do
- self.grid[j] = {}
- for i=1,self.size do
- self.grid[j][i] = 0
- end
- end
- end
- function Game:restart()
- score = 0
- self:makeGrid()
- local r1x = mathrandom(1,self.size)
- local r1y = mathrandom(1,self.size)
- local r2x = mathrandom(1,self.size)
- local r2y = mathrandom(1,self.size)
- while (r1x==r2x and r1y==r2y) do
- r2x = mathrandom(1,self.size)
- end
- self.grid[r1y][r1x] = mathrandom(1,4)>3 and 4 or 2
- self.grid[r2y][r2x] = mathrandom(1,4)>3 and 4 or 2
- end
- function Game:spawnNumber()
- local x = mathrandom(1,self.size)
- local y = mathrandom(1,self.size)
- while (self.grid[y][x]>0) do
- x, y = mathrandom(1,self.size), mathrandom(1,self.size)
- end
- newTileX, newTileY = x, y
- self.grid[y][x] = mathrandom(1,4)>3 and 4 or 2
- end
- function Game:countFilled()
- local count = 0
- for j=1,self.size do
- for i=1,self.size do
- if (self.grid[j][i])>0 then count = count + 1 end
- end
- end
- return count
- end
- -- merge 1 into 2
- function Game:mergeCellsIfPossible(x1, y1, x2, y2)
- local new = self.grid[y2][x2]
- if ((self.grid[y1][x1] == new) or (new == 0)) then
- self.grid[y2][x2] = new + self.grid[y1][x1]
- self.grid[y1][x1] = 0
- score = score + (new>0 and self.grid[y2][x2] or 0)
- if score>bestScore then
- bestScore = score
- end
- return true
- else
- return false
- end
- end
- function Game:move(direction)
- local tmpx1 = 0
- local tmpy1 = 0
- local tmpx2 = 0
- local tmpy2 = 0
- local moved = false
- if direction=="up" then
- for j=2,self.size do
- for i=1,self.size do
- if self.grid[j][i]>0 then
- tmpy1, tmpy2 = j, j-1
- while (tmpy2>=1 and tmpy1>=0
- and self:mergeCellsIfPossible(i, tmpy1, i, tmpy2)) do
- tmpy2 = tmpy2-1
- tmpy1 = tmpy1-1
- moved = true
- end
- end
- end
- end
- elseif direction=="right" then
- for j=1,self.size do
- for i=self.size,1,-1 do
- if self.grid[j][i]>0 then
- tmpx1, tmpx2 = i, i+1
- while (tmpx2<=self.size and tmpx1<=self.size
- and self:mergeCellsIfPossible(tmpx1, j, tmpx2, j)) do
- tmpx1 = tmpx1+1
- tmpx2 = tmpx2+1
- moved = true
- end
- end
- end
- end
- elseif direction=="down" then
- for j=self.size-1,1,-1 do
- for i=1,self.size do
- if self.grid[j][i]>0 then
- tmpy1, tmpy2 = j, j+1
- while (tmpy2<=self.size and tmpy1<=self.size
- and self:mergeCellsIfPossible(i, tmpy1, i, tmpy2)) do
- tmpy2 = tmpy2+1
- tmpy1 = tmpy1+1
- moved = true
- end
- end
- end
- end
- elseif direction=="left" then
- for j=1,self.size do
- for i=1,self.size do
- if self.grid[j][i]>0 then
- tmpx1, tmpx2 = i, i-1
- while (tmpx2>=0 and tmpx1>0
- and self:mergeCellsIfPossible(tmpx1, j, tmpx2, j)) do
- tmpx1 = tmpx1-1
- tmpx2 = tmpx2-1
- moved = true
- end
- end
- end
- end
- end
- self.filled = (self:countFilled() == self.size*self.size)
- if self.filled then -- TODO : add check for no move available
- print("Lost !")
- if score>=bestScore then
- document.markChanged()
- end
- else
- if moved then
- self:spawnNumber()
- end
- end
- end
- function Game:resize()
- self.gridOffset = .05*H
- self.gridStepX = W/(self.size+1)
- self.gridStepY = H/(self.size+1)
- end
- function Game:paint(gc)
- gc:setFont("sansserif", "b", W/25)
- gc:setPen()
- if not self.gridOffset then self:resize() end
- for j=1,self.size do
- for i=1,self.size do
- gc:drawLine(.1*W, j*self.gridStepY-0.08*H+self.gridOffset, .9*W, j*self.gridStepY-0.08*H+self.gridOffset)
- gc:drawLine(i*self.gridStepX-.1*W, .12*H+self.gridOffset, i*self.gridStepX-.1*W, .92*H+self.gridOffset)
- if (self.grid[j][i] > 0) then
- gc:setColorRGB(uCol(colorTbl[self.grid[j][i]]))
- gc:fillRect(i*self.gridStepX-.1*W+1, j*self.gridStepY-0.08*H+self.gridOffset+1, self.gridStepX, self.gridStepY)
- if (newTileX == i and newTileY == j) then
- gc:setColorRGB(255,0,0)
- gc:drawRect(i*self.gridStepX-.1*W+1, j*self.gridStepY-0.08*H+self.gridOffset+1, self.gridStepX-2, self.gridStepY-2)
- gc:drawRect(i*self.gridStepX-.1*W+2, j*self.gridStepY-0.08*H+self.gridOffset+2, self.gridStepX-4, self.gridStepY-4)
- end
- gc:setColorRGB(0, 0, 0)
- gc:drawString(self.grid[j][i],
- i*(W/(self.size+1)) - gc:getStringWidth(self.grid[j][i])*.3,
- j*(H/(self.size+1)) + self.gridOffset - gc:getStringHeight(self.grid[j][i])*.3,
- "top")
- end
- end
- end
- gc:setPen("medium", "smooth")
- gc:drawLine((self.size+1)*self.gridStepX-.1*W, .12*H+self.gridOffset+1, (self.size+1)*self.gridStepX-.1*W, .92*H+self.gridOffset)
- gc:drawLine(.1*W+1, (self.size+1)*self.gridStepY-0.08*H+self.gridOffset, .9*W, (self.size+1)*self.gridStepY-0.08*H+self.gridOffset)
- gc:drawString("NspireLua2048", .1*W, .03*H, "top")
- gc:setFont("sansserif", "b", W/30)
- local str = "Score : " .. score
- gc:drawString(str, .9*W-gc:getStringWidth(str), .005*H, "top")
- str = "Best : " .. bestScore
- gc:drawString(str, .9*W-gc:getStringWidth(str), .07*H, "top")
- end
- theGame = Game(4)
- ------------
- -- Events --
- ------------
- function on.paint(gc)
- theGame:paint(gc)
- end
- function on.arrowKey(key)
- if (key=="right" or key=="left" or key=="up" or key=="down") then
- theGame:move(key)
- platform.window:invalidate()
- end
- end
- function on.charIn(ch)
- local tbl = {["2"]="down", ["4"]="left", ["8"]="up", ["6"]="right"}
- on.arrowKey(tbl[ch])
- platform.window:invalidate()
- end
- function on.escapeKey()
- theGame:restart()
- platform.window:invalidate()
- end
- function on.resize(w, h)
- W, H = w, h
- theGame:resize()
- platform.window:invalidate()
- end
- function on.save()
- return {bestScore}
- end
- function on.restore(data)
- bestScore = data[1] or 0
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement