Guest User

Untitled

a guest
Apr 20th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.82 KB | None | 0 0
  1. import ui
  2. import random
  3. from math import radians
  4. import time
  5. from functools import partial
  6. class Die(ui.View):
  7. def __init__(self,faces='ABCDEF',*args,**kwargs):
  8. self.faces=faces
  9. self._face_idx=0
  10. ui.View.__init__(self,*args,**kwargs)
  11. self.flex=''
  12.  
  13. @property
  14. def letter(self):
  15. return self.faces[self._face_idx]
  16.  
  17. @property
  18. def face_idx(self):
  19. return self._face_idx
  20.  
  21. @face_idx.setter
  22. def face_idx(self,value):
  23. if value < len(self.faces):
  24. self._face_idx=value
  25.  
  26. def draw(self):
  27. w=self.width
  28. corner_frac=0.05 #fractional corner radius for dice itself
  29. face_frac=0.5*0.65 # fractional corner radius of the face
  30. highlight_color='#e4e4db'
  31. shadow_color='#c6c6be'
  32. face_color='#fefaed'
  33.  
  34. s1=ui.Path.rounded_rect(0,0,w,w,w*corner_frac)
  35. s2=ui.Path.rounded_rect(0,w/2.,w,w/2.,w*corner_frac)
  36. s3=ui.Path.rounded_rect(0,0,w,w,w*face_frac)
  37. ui.set_color(highlight_color)
  38. s1.fill()
  39. ui.set_color(shadow_color)# little darker
  40. s2.fill()
  41. ui.set_color(face_color) # little lighter
  42. s3.fill()
  43. sz=ui.measure_string(self.faces[self.face_idx],font=('Futura',0.5*self.width))
  44. ui.draw_string(self.faces[self.face_idx],font=('Futura',0.5*w),
  45. rect=( (w-sz.width)/2, (w-sz.height)/2,sz.width,sz.height),
  46. color=(.17, .0, .97))
  47.  
  48. def roll(self):
  49. ''' choose a random face. also, transform angle, and size for animation purposes'''
  50. maxsc=1.4 #amount of relative size variation during roll
  51. minsc=0.6
  52. randscale=minsc+(maxsc-minsc)*random.random()
  53. randangle=radians(90*random.randrange(5))
  54. self.face_idx=random.randrange(len(self.faces))
  55. self.transform=ui.Transform.rotation(randangle).concat(
  56. ui.Transform.scale(randscale,randscale) )
  57. #self.set_needs_display()
  58.  
  59. def straighten(self):
  60. ''' set back to default orientation for reading'''
  61. self.transform=ui.Transform()
  62.  
  63.  
  64. class BoggleBoard(ui.View):
  65. ''' Just a container for dice. auto sizes the dice based on view size
  66. N: grid size (creates NxN grid)
  67. frame: size of board. always adjusts to be square
  68. other View attribs are valid (bg_color, etc)
  69. self.dice: list of Die's
  70. TODO: Take dice dictionary
  71. '''
  72. def __init__(self,N=4,*args,**kwargs):
  73. self.N=N
  74. self.border=0.05
  75. super(BoggleBoard,self).__init__(*args,**kwargs)
  76. dice=[]
  77. for i in range(N*N):
  78. dice.append(Die(['A','B','C','D','E','F'],
  79. frame=self._ind2frame(i)))
  80. self.add_subview(dice[-1])
  81. self.dice=dice
  82. self.flex='wh'
  83. self.shuffle()
  84.  
  85. def layout(self):
  86. '''resize board, called when view size changes'''
  87. # first, ensure we are square
  88. if self.width>self.height:
  89. self.width=self.height
  90. elif self.height>self.width:
  91. self.height=self.width
  92. # Then, set dice size/positions based on order of self.dice
  93. for ind,d in enumerate(self.dice):
  94. d.frame=self._ind2frame(ind)
  95. def draw(self):
  96. ''' TODO: draw semi 3d indentations underneath dice that are visible when rolling'''
  97. pass
  98.  
  99. def _ind2frame(self, index):
  100. ''' generate dice frame rect for a given index
  101. assume row major ordering'''
  102. N=self.N
  103. y,x=divmod(index,N) #gives x,y location in grid units of the given die
  104. b=self.border #fractional border width
  105. W=(self.width-(N+1)*b*self.width/N)/N #die width, accounting for border
  106. return ui.Rect(b*W + x*(1+b)*W, b*W + y*(1+b)*W, W, W)
  107.  
  108. def shuffle(self,sender=None):
  109. #first, shuffle die locations, then tell each die to roll itself
  110. random.shuffle(self.dice)
  111. for ind,d in enumerate(self.dice):
  112. d.frame=self._ind2frame(ind) # move to new spot on grid
  113. d.roll() #roll it
  114.  
  115. def letters(self, sender=None):
  116. '''return list of visible letters'''
  117. return [d.letter for d in self.dice]
  118.  
  119. def solve(self):
  120. ''' find best possible score, using internet anagram server,or bogglewords.com, etc'''
  121. pass
  122.  
  123. def animated_shuffle(self,sender=None, duration=0.5, straighten_after=True):
  124. '''animate a single shuffle.
  125. optionally: reorient dice after shuffling
  126. '''
  127. ui.animate(self.shuffle, duration)
  128. if straighten_after:
  129. ui.animate(self.straighten, duration/2, delay=duration/2)
  130.  
  131. def straighten(self):
  132. '''rotate all dice to correct reading orientation'''
  133. for d in self.dice:
  134. d.straighten()
  135.  
  136.  
  137. @ui.in_background #needed to use sleep, but could also just use animation delay arguments
  138. def long_roll(self,sender=None, duration=0.5, num_rolls=10, straighten_after=True):
  139. '''keep running the shuffle animation, before the last one completes.
  140. duration: time if single roll, though it will be interupted a little way through
  141. num_rolls: number of times to roll
  142. '''
  143. for i in range(num_rolls):
  144. time.sleep(duration/5) #adjustable, but shorter than animation gives a more continuous shuffle appearance. todo: experiment with random times here
  145. self.animated_shuffle(sender,duration, straighten_after= straighten_after and (i==num_rolls-1 ) )
  146.  
  147. if __name__=='__main__':
  148. '''this stuff all belongs in a BoggleGame type class ... but just here for experiments'''
  149. board_width=300
  150. b=BoggleBoard(frame=(10,10,board_width,board_width),bg_color='#664040')
  151. v=ui.View(frame=(0,0,board_width+20,board_width+64,))
  152. btn1=ui.Button(frame=(10,board_width+20,200,44),title='Roll',bg_color='white')
  153. btn1.border_color='blue'
  154. btn1.width+=20
  155. btn1.border_width=1
  156. btn1.corner_radius=5
  157.  
  158. btn2=ui.Button(frame=(btn1.x+20+btn1.width,board_width+20,200,44),title='LongRoll',bg_color='white')
  159. btn2.border_color='blue'
  160. btn2.width+=20
  161. btn2.border_width=1
  162. btn2.corner_radius=5
  163.  
  164. btn1.flex='tr'
  165. btn2.flex='tr'
  166. v.add_subview(b)
  167. v.add_subview(btn1)
  168. v.add_subview(btn2)
  169. '''some parameters to play with'''
  170. straighten_dice=False #set False for more authentic feel
  171. duration=.5 #set to 5 to see what is happening
  172.  
  173. btn1.action=partial(b.animated_shuffle, duration=duration, straighten_after=straighten_dice)
  174. btn2.action=partial(b.long_roll, duration=duration, straighten_after=straighten_dice)
  175. #v.present('') #auto size
  176. v.present('sheet')
  177. #v.layout()
Add Comment
Please, Sign In to add comment