Advertisement
Guest User

Floodit

a guest
Mar 31st, 2013
560
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. --# Main
  3. -- Flood
  4.  
  5. function setup()
  6. if backup then backup("Flood 101") end
  7. parameter.integer("Size",10,30,15) --size of board
  8. parameter.action("Start",Start) --starts a new game
  9. parameter.integer("Moves_so_far",0,100,0)
  10. parameter.action("Undo",UndoMove)
  11. --set up palette of six colors
  12. colrs={color(255,0,0,255), color(0,255,0,255), color(0,0,255,255),
  13. color(255,255,0,255),color(255,0,255,255),color(0,255,255,255)}
  14. ss=readProjectData("Size") --read in user's last size selection
  15. if ss~=nil then Size=ss end --set size, if a saved value exists
  16. Start()
  17. end
  18.  
  19. function Start()
  20. --create random 2D table of colors
  21. board={}--create 1D table
  22. for i=1,Size do --loop through columns
  23. --this is how you create a 2D table
  24. board[i]={} --as we start each new column, create an array of rows
  25. for j=1,Size do --choose random color for each square
  26. board[i][j]=tostring(math.random(1,6))
  27. end
  28. end
  29. state="RUNNING" --to tell draw the game has started
  30. Moves_so_far=0
  31. output.clear()
  32. lastMove=board[1][1]
  33. back=Backup()
  34. saveProjectData("Size",Size) --save user size selection
  35. currSize=Size
  36. print("Press a color at the bottom to change the bottom left hand cell to that color, along with all adjoining cells. Try to flood the whole table with one color in as few moves as possible.")
  37. end
  38.  
  39. function draw()
  40. background(200)
  41. --calculate the size of square we can fit on screen
  42. local w=(HEIGHT-100)/currSize
  43. pushStyle()
  44. --draw table of colors
  45. local finished=true --see use below
  46. for x=1,currSize do
  47. for y=1,currSize do
  48. fill(colrs[tonumber(board[x][y])]) --set colour based on value in table 1-6
  49. rect(50+x*w-w,75+y*w-w,w,w) --draw square
  50. --if any of the squares are a different color, we haven't finished
  51. if board[x][y]~=board[1][1] then finished=false end
  52. end
  53. end
  54. --draw buttons for user to press, store button locations for touch detection
  55. button={}
  56. for i=1,6 do
  57. fill(colrs[i])
  58. --position button at bottom of screen
  59. local x,y,w,h=100*i,10,75,50
  60. rect(x,y,w,h)
  61. --save details of button position so we can trap touches
  62. button[i]={x=x,y=y,w=w,h=h}
  63. end
  64. popStyle()
  65. --if we've just finished, print a message
  66. if state~="FINISHED" then --we weren't finished last move
  67. if finished then --...but we are now
  68. state="FINISHED"
  69. print("Finished in",Moves_so_far,"moves")
  70. end
  71. end
  72. end
  73.  
  74. function touched(touch)
  75. --state has three values, BEGAN, MOVING and ENDED
  76. --we only want ENDED, ie when the finger lifts up
  77. if touch.state~=ENDED then return end
  78. --check touch postiion against each button
  79. --that's why we stored all that info about button position
  80. for i=1,6 do
  81. if touch.x>=button[i].x and touch.x<=button[i].x+button[i].w
  82. and touch.y>=button[i].y and touch.y<=button[i].y+button[i].h then
  83. --only react if the user has chosen a different color
  84. if tonumber(board[1][1])~=i then
  85. back:store(board)
  86. fillBoard(tostring(i))
  87. Moves_so_far = Moves_so_far + 1
  88. end
  89. break
  90. end
  91. end
  92. end
  93.  
  94. function UndoMove()
  95. board=back:restore() or board
  96. Moves_so_far = math.max(0,Moves_so_far - 1)
  97. end
  98.  
  99. --this is a recursive function that calls itself
  100. function fillBoard(c,r,x,y)
  101. --the first time it's called, from touched, it just passes the new color
  102. --so we'll make a note of the current color of bottom left
  103. --square, and our starting x,y, which is 1,1
  104. if r==nil then
  105. r=board[1][1]
  106. x=1 y=1
  107. end
  108. --check if the square we are in, needs to be changed
  109. --if it is the first one, 1,1, the answer is always yes
  110. if board[x][y]==r then
  111. board[x][y]=c
  112. --now check the neighbours around, excl diagonals
  113. if x>1 then fillBoard(c,r,x-1,y) end
  114. if x<Size then fillBoard(c,r,x+1,y) end
  115. if y>1 then fillBoard(c,r,x,y-1) end
  116. if y<Size then fillBoard(c,r,x,y+1) end
  117. end
  118. end
  119.  
  120. --# Backup
  121. Backup = class()
  122.  
  123. function Backup:init()
  124. self.backups={}
  125. end
  126.  
  127. --backs up a 1D or 2D table to a delimited string
  128. --one parameter is the table to be backed up, stores the string in an array backup
  129. --this provides unlimited backups
  130. function Backup:store(t)
  131. if t==nil then return end --do nothing if given nothing
  132. if self.backups==nil then self.backups={} end --if first time, create array
  133. local s={} --we use a 1D array for the backup because it's faster than strings, we convert later
  134. if type(t[1])~="table" then --1D table, we can use built in concat command
  135. self.backups[#self.backups+1]="1,"..table.concat(t,",")
  136. else --2D table, loop through
  137. for i=1,#t do
  138. for j=1,#t[i] do
  139. s[#s+1]=t[i][j]
  140. end
  141. end
  142. self.backups[#self.backups+1]=#t[1]..","..table.concat(s,",")
  143. end
  144. end
  145.  
  146. --restore last backup from a string to a table (1 or 2D)
  147. --parameter is the number of cols - if missing,table is assumed to be 1D
  148. --if cols is provided, it is used to calculate rows (since # total items backed up = cols x rows)
  149. --returns the table, deletes restored backup
  150. function Backup:restore()
  151. if #self.backups==0 then return end --no backups
  152. local t={} --the table we will return
  153. local b=self:split(self.backups[#self.backups]) --split backup string into a 1D table
  154. local cols=tonumber(b[1])
  155. if cols==1 then
  156. t=b --if a 1D table is needed, we're done
  157. table.remove(t,1)
  158. else
  159. local ii,jj=cols,(#b-1)/cols --otherwise we need a 2D table, calc number of rows (jj)
  160. local n=1
  161. for i=1,ii do --loop through cols
  162. t[i]={} --create array for this row
  163. for j=1,jj do --loop through row
  164. n = n + 1 --counter to help us find the place in b
  165. t[i][j]=b[n]
  166. end
  167. end
  168. end
  169. table.remove(self.backups,#self.backups) --remove latest backup
  170. return t
  171. end
  172.  
  173. function Backup:clear()
  174. self.backups=nil
  175. end
  176.  
  177. --splits a delimited string into a table, delimiter defaults to comma
  178. function Backup:split(str, delim)
  179. if delim==nil then delim="," end
  180. local result = {}
  181. local pat = "(.-)" .. delim .. "()"
  182. local lastPos = 1
  183. for part, pos in string.gfind(str, pat) do
  184. table.insert(result, part)
  185. lastPos = pos
  186. end
  187. -- Handle the last field
  188. table.insert(result, string.sub(str, lastPos))
  189. return result
  190. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement