501|0

183

帖子

12

TA的资源

一粒金砂(高级)

楼主
 

【DigiKey“智造万物,快乐不停”创意大赛】MAIX BIT KIT上的“九子贤棋” [复制链接]

 

“九子贤棋”又名LuckyStar,是中国西部的一种在五角星形棋盘上玩的益智游戏。

开始时在五角星形棋盘的每个直线交叉点各放一枚棋子,然后按玩家意愿,移除一个棋子。之后,玩家可以像跳棋那样,移动一颗棋子到空白的位置,同时可以移除移动过程中跳过的棋子。移动棋子必须沿着直线,一次必须跳过一枚棋子,且只能跳过一枚棋子。当按前述规则无法移动任何棋子时,游戏结束。如果游戏结束时,棋盘上只剩下一枚棋子,则玩家获胜。 

做出来了:

  • class OneAppStats():# = ['init','running','sleep','restore','exit','kill','killed','back']
  • INIT = 0
  • RUNNING = 1
  • SLEEP = 2
  • RESTORE = 3
  • EXIT = 4
  • KILL = 5
  • KILLED = 6
  • BACK = 7
  • # One Application
  • class OneApp(object):
  • def __init__(self, name=None):
  • self.name = name
  • self.data = {}
  • self.stat = OneAppStats.INIT
  • self.childApps =[]
  • def setup(self, **kw):
  • for key in kw:
  • self.data[key]=kw[key]
  • self.stat = OneAppStats.RUNNING
  • def loop(self):
  • print('__getitem__', key)
  • return self.data[key] if key in self.data else None
  • def beforePaint(self):
  • pass
  • def rePaint(self):
  • pass
  • def afterPaint(self):
  • pass
  • def _paint(self):
  • self.beforePaint()
  • self.rePaint()
  • self.afterPaint()
  • def onEvent(self,evtName,*args,**kw):
  • print('x11',evtName,len(self.childApps), self.name , 'onEvent:',evtName,'*args',args,'**kw',kw)
  • for childrenApp in self.childApps:
  • if childrenApp.stat in (OneAppStats.RUNNING,OneAppStats.SLEEP,OneAppStats.RESTORE,OneAppStats.BACK):
  • #childrenApp.onEvent(evtName,*args,**kw)
  • childrenApp.onEvent(*args,**kw)
  • def _removeApp(self,app):
  • app.stat = OneAppStats.KILLED
  • self.childApps.remove(app)
  • del app
  • def _countChildApp(self):
  • cntAliveChildren = 0
  • for childrenApp in self.childApps[::]:
  • if childrenApp.stat == OneAppStats.INIT :
  • cntAliveChildren = cntAliveChildren +1
  • elif childrenApp.stat == OneAppStats.RUNNING :
  • flag = childrenApp.loop()
  • if flag in (OneAppStats.EXIT,OneAppStats.KILL):
  • #print(self , childrenApp)
  • self._removeApp(childrenApp)
  • else:
  • cntAliveChildren = cntAliveChildren +1
  • elif childrenApp.stat in (OneAppStats.EXIT,OneAppStats.KILL):
  • self._removeApp(childrenApp)
  • print('_removeApp',childrenApp,len(self.childApps) )
  • return cntAliveChildren
  • def _loop(self):
  • """
  • cntAliveChildren = 0
  • for childrenApp in self.childApps[::]:
  • if childrenApp.stat == OneAppStats.INIT :
  • cntAliveChildren = cntAliveChildren +1
  • elif childrenApp.stat == OneAppStats.RUNNING :
  • flag = childrenApp.loop()
  • if flag in (OneAppStats.EXIT,OneAppStats.KILL):
  • self._removeApp(childrenApp)
  • else:
  • cntAliveChildren = cntAliveChildren +1
  • elif childrenApp.stat in (OneAppStats.EXIT,OneAppStats.KILL):
  • self._removeApp(childrenApp)
  • print('_removeApp',childrenApp,len(self.childApps) )
  • """
  • cntAliveChildren = self._countChildApp()
  • return OneAppStats.BACK if cntAliveChildren>0 else OneAppStats.RUNNING
  • def loop(self):
  • self._loop()
  • def _startChildApp(self,defClass,appName=None):
  • childrenApp = defClass(appName)
  • self.childApps.append(childrenApp)
  • return childrenApp
  • #attention : need do childrenApp.setup() by you self,and maybe change parent App to 7(back)
  • def doHideback(self):
  • self.stat = OneAppStats.RUNNING
  • return self.stat
  • def doSleep(self):
  • self.stat = OneAppStats.SLEEP
  • return self.stat
  • def doRestore(self):
  • self.stat = OneAppStats.RESTORE
  • #do some thing
  • # if sucess
  • self.stat = OneAppStats.RUNNING
  • #if not sucess
  • #self.stat = 2
  • return self.stat
  • def doKill(self):
  • self.stat = OneAppStats.KILL
  • return self.stat
  • def doStop(self):
  • #do some thing
  • # if sucess
  • self.stat = OneAppStats.EXIT
  • #if not sucess
  • #self.stat = 5
  • return self.stat
  • import time
  • DEBUG_DELAY = 0.5
  • ################################################################################
  • # lucky9starClass #
  • ################################################################################
  • MSG_LEFT = 160
  • MSG_TOP = 10
  • '''
  • 0 show_msg("huanying ",NONE);
  • 1 show_msg("remove",p );
  • 2 show_msg("pickup", game_piece_id);
  • 3 show_msg('You Win',NONE);
  • 4 show_msg('Game Over',NONE);
  • 5 show_msg("move ", game_piece_id );
  • 6 show_msg("release ", pieces[point_id] );
  • '''
  • class lucky9starClass():
  • def __init__(self):
  • self.btnFunCnt = 1+1 #重新开始、退出
  • self.btnCnt = 10 + self.btnFunCnt
  • self.msg_id = 0
  • self.msg_num = None
  • # 每条边上有哪些点
  • self.edges=( (0,3,6,8),(0,2,5,7),(1,2,3,4),(1,5,9,8),(4,6,9,7) )
  • # 点在哪条边上
  • self.point_in_edges=[list() for _ in range(10)]
  • for i,edge in enumerate(self.edges):
  • for j in edge:
  • self.point_in_edges[j].append(i)
  • #print(i,j,point_in_edges)
  • self.point_in_edges=tuple([ tuple(x) for x in self.point_in_edges])
  • # 每个点的坐标,平面直角坐标表示(x,y)
  • self.points = ((120,18),(15,93),(93,93),(146,93),(225,93),(78,142),(161,142),(56,221),(183,221),(120,172))
  • # 每个点上是几号棋子(棋子1-10号)
  • self.pieces=list(range(1,10+1))
  • # 每个号的棋子在什么位置(0表示空棋子)
  • #self.positions=[[]]+list(range(10)) # dict([[0,None]]+[[x,x-1] for x in range(1,10+1)])
  • self.pieces,self.positions = self.init_pieces()
  • self.game_point_id,self.game_piece_id=0,0
  • self.game_state=0 # 0 游戏开始未持子;1持有一子
  • #self.msg_id = 0
  • #self.msg_num = None
  • self.selIDX = 0
  • #self.update_screen()
  • print("init-1")
  • #lcd.display(imgBuf)#oled.show()
  • # 初始化棋子
  • def setScreen(self,obj_screen):
  • self.screen = obj_screen
  • self.imgBuf = image.Image()
  • # 初始化棋子
  • def init_pieces(self):
  • #global edges,point_in_edges
  • # 每个点上是几号棋子(棋子1-10号)
  • v_pieces=list(range(1,10+1))
  • # 每个号的棋子在什么位置(0表示空棋子)
  • v_positions=[[]]+list(range(10)) # dict([[0,None]]+[[x,x-1] for x in range(1,10+1)])
  • return (v_pieces,v_positions)
  • # 测试某个点上的棋子是否可以移动目标点
  • def test_move(self,v_pieces,v_positions,start_point,target_point):
  • #global edges,point_in_edges
  • # 找到公共边
  • #print('test_move:edges',edges,start_point,target_point)
  • for e in self.edges:
  • if start_point in e and target_point in e :
  • i=e.index(start_point)
  • j=e.index(target_point)
  • # 起点有子、目标空,中间只隔1子
  • #if 0<=i<4 and pieces[start_point] and 0<=j<4 and not pieces[target_point]and abs(i-j)==2 and pieces[e[(i+j)//2]]:
  • # 目标空,中间只隔1子
  • #print('test_move:',0<=i<4 , 0<=j<4 , not pieces[target_point] , abs(i-j)==2 , pieces[e[(i+j)//2]] )
  • if 0<=i<4 and 0<=j<4 and not v_pieces[target_point] and abs(i-j)==2 and v_pieces[e[(i+j)//2]]:
  • return e[(i+j)//2] # 返回需提子的点
  • return False
  • # 移走一颗棋子(可能因为要移动或是被跳过)
  • def piece_pickup(self,v_pieces,v_positions,the_point):
  • #global edges,point_in_edges
  • tmp_piece=v_pieces[the_point]
  • v_positions[tmp_piece]=-1 # 不在棋盘上
  • v_pieces[the_point]=0 # 此点无子
  • return tmp_piece # 返回棋子号
  • # 放下一颗棋子
  • def piece_putdown(self,v_pieces,v_positions,the_piece,the_point):
  • #global edges,point_in_edges
  • v_positions[the_piece]=the_point
  • v_pieces[the_point]=the_piece
  • # 移动一步
  • def move_point_to_point(self,v_pieces,v_positions,start_point,target_point):
  • #global edges,point_in_edges
  • i = self.test_move(v_pieces,v_positions,start_point,target_point)
  • if i:
  • p = self.piece_pickup(v_pieces,v_positions,start_point)
  • self.piece_putdown(v_pieces,v_positions,p,target_point)
  • return self.piece_pickup(v_pieces,v_positions,i)
  • return None
  • # 测试是否是开局状态(所有棋子都在)
  • def test_is_game_start(self,v_pieces,v_positions):
  • # 每一个位置上都有棋子
  • return min(v_pieces)>0
  • # 显示棋子位置
  • '''
  • 1
  • 2--3-4--5
  • 6 7
  • / a \
  • 8 9
  • '''
  • def uart_debug_out_pieces(self,v_pieces):
  • print("~~~ Pieces BEGIN ~~~")
  • print(" %d"%v_pieces[0])
  • print("%d--%d--%d--%d"%(v_pieces[1],v_pieces[2],v_pieces[3],v_pieces[4]))
  • print(" %d %d"%(v_pieces[5],v_pieces[6]))
  • print(" / %d \\"%v_pieces[9])
  • print("%d %d"%(v_pieces[7],v_pieces[8]))
  • print("~~~ Pieces END ~~~")
  • # 计算某个棋子可以移动的目标
  • def get_piece_targets(self,v_pieces,v_positions,piece):
  • targets=[] # 可行目标点
  • position_point=v_positions[piece] # 求棋子位置
  • # 对该位置对应的每一条边测试
  • for edge_id in self.point_in_edges[position_point]:
  • edge=self.edges[edge_id]
  • idx = edge.index(position_point) # 求棋子所在索引
  • # 对棋子2个方向隔一个的索引
  • for tmp_idx in ( idx-2,idx+2):
  • # 如果该索引在合法范围内 且 目标点可以移动
  • if 0<=tmp_idx<4 and self.test_move(v_pieces,v_positions,position_point,edge[tmp_idx] ):
  • targets.append(edge[tmp_idx]) # 增加目标点
  • return targets
  • # 计算是否棋盘上剩余的所有棋子都不可移动
  • def test_all_piece_can_not_move(self,v_pieces,v_positions):
  • # 是否存在某个棋子可以移动的目标点数大于0
  • return 0==sum([ len(self.get_piece_targets(v_pieces,v_positions,p)) for p in self.pieces if p>0 ] )
  • # 计算棋盘上剩余的棋子数
  • def count_exists_piece_num(self,v_pieces,v_positions):
  • return len([ 1 for p in v_pieces if p>0 ])
  • # 求解
  • def solution(self,v_pieces,v_positions,steps=[]):
  • import random
  • if 10==self.count_exists_piece_num(v_pieces,v_positions):#刚开始
  • #print("刚开始")
  • #for i_piece in (random.choice([0,1,4,7,8]),random.choice([2,3,5,6,9])):#(1,2):
  • for i_piece in (random.choice([1,2,5,8,9]),random.choice([3,4,6,7,10])):#(1,2):
  • new_pieces,new_positions,new_steps=v_pieces[::],v_positions[::],steps[::]
  • tmp_point = v_positions[i_piece]
  • self.piece_pickup(new_pieces,new_positions,tmp_point )
  • new_steps.append( (i_piece,tmp_point,tmp_point) )
  • result = self.solution(new_pieces,new_positions,new_steps)
  • return result
  • elif self.test_all_piece_can_not_move(v_pieces,v_positions):#无子可动
  • #print("无子可动")
  • if 1==self.count_exists_piece_num(v_pieces,v_positions):#成功解开
  • print("成功解开",steps)
  • return steps
  • else:
  • #print("失败",v_pieces,v_positions,steps)
  • return False
  • else:
  • #print("求解中")
  • success_flag = False
  • tmp_list = list(range(1,10+1))
  • random.shuffle(tmp_list)
  • for i_piece in tmp_list:
  • tmp_point = v_positions[i_piece]
  • if tmp_point>=0 :#还在棋盘上
  • tgts = self.get_piece_targets(v_pieces,v_positions,i_piece)
  • for target_point in tgts:
  • new_pieces,new_positions,new_steps=v_pieces[::],v_positions[::],steps[::]
  • self.move_point_to_point(new_pieces,new_positions,tmp_point,target_point)
  • new_steps.append( (i_piece,tmp_point,target_point) )
  • result = self.solution(new_pieces,new_positions,new_steps)
  • if result:
  • success_flag = result
  • return success_flag # 如果没有注释本行,那么一旦找到一个解,就会返回
  • return success_flag
  • #pieces,positions=self.init_pieces()
  • #print("初始状态",pieces,positions)
  • #self.solution(pieces,positions,[])
  • #print("求解结束")
  • ## 重新开始
  • #def init_game():
  • # global pieces,positions,buttons
  • # pieces,positions=self.init_pieces()
  • # #print(pieces,positions,buttons)
  • # for i,p in enumerate(star_points):
  • # tmpButtonID=buttons[pieces[i]]
  • # #print(i,pieces[i],tmpButtonID,p)
  • # canvas.coords(tmpButtonID,*p)
  • # canvas.itemconfig(tmpButtonID, state='normal')
  • #
  • ## 某位置属于棋盘上某点
  • #def get_event_point_idx(x,y):
  • # global star_points
  • # for i,p in enumerate(star_points):
  • # if abs(x-p[0])<=40 and abs(y-p[1])<=40:
  • # return i
  • # return None
  • def select_a_point(self,point_id):
  • #global game_point_id,game_piece_id,pieces,positions,msg_id,msg_num
  • self.game_point_id=point_id
  • self.game_piece_id=0
  • if point_id!=None and self.test_is_game_start(self.pieces,self.positions):
  • p = self.piece_pickup(self.pieces,self.positions,point_id)
  • ##canvas.itemconfig(buttons[p], state='hidden')
  • #print( self.test_is_game_start(self.pieces,self.positions) , p,self.pieces,buttons[p])
  • self.game_point_id=None
  • #show_msg("remove %d"% p )
  • self.msg_id = 1
  • self.msg_num = p
  • return 0
  • elif point_id!=None :
  • self.game_piece_id=self.pieces[point_id]
  • ##show_msg("pickup %d"% self.game_piece_id)
  • self.msg_id = 2
  • self.msg_num = self.game_piece_id
  • return self.game_piece_id
  • else :
  • return 0
  • #def mousedown(event):
  • # widget=event.widget
  • # x,y = event.x,event.y
  • # widget.startx,widget.starty=x,y # 开始拖动时, 记录控件位置
  • # i=get_event_point_idx(x,y)
  • # self.select_a_point(i)
  • def release_a_point(self,point_id):
  • #global game_point_id,game_piece_id,self.pieces,positions,msg_id,msg_num
  • if point_id==None:
  • #print('--mouseup:back',point_id)
  • point_id=self.game_point_id
  • if point_id!=None and self.game_piece_id>0:
  • ##canvas.coords(buttons[game_piece_id],*star_points[point_id])
  • self.game_piece_id = 0
  • elif self.game_point_id!=None and self.game_piece_id>0:
  • self.uart_debug_out_pieces(self.pieces)
  • if self.test_move(self.pieces,self.positions,self.game_point_id,point_id):
  • #print('--mouseup:move from',self.pieces)
  • p = self.move_point_to_point(self.pieces,self.positions,self.game_point_id,point_id)
  • ##if p:
  • ## canvas.itemconfig(buttons[p], state='hidden')
  • #canvas.move(buttons[game_piece_id], star_points[point_id][0]-x, star_points[point_id][1]-y )
  • ##canvas.coords(buttons[game_piece_id],*star_points[point_id])
  • #print('--mouseup:move',point_id,self.pieces,game_piece_id,)
  • #print('--mouseup:test_all_piece_can_not_move',self.test_all_piece_can_not_move(),count_exists_piece_num() )
  • f = self.test_all_piece_can_not_move(self.pieces,self.positions)
  • if f :
  • print(">>> all_piece_can_not_move,%d"%f)
  • self.uart_debug_out_pieces(self.pieces)
  • if 1==self.count_exists_piece_num(self.pieces,self.positions):
  • ##show_msg('You Win')
  • self.msg_id = 3
  • self.msg_num = None
  • print(">>> You Win")
  • else:
  • ##show_msg('Game Over')
  • self.msg_id = 4
  • self.msg_num = None
  • print(">>> Game Over");
  • else:
  • ##show_msg("move %d"% self.game_piece_id )
  • self.msg_id = 5
  • self.msg_num = self.game_piece_id
  • self.game_piece_id=0
  • else:
  • point_id=self.game_point_id
  • if point_id!=None and self.pieces[point_id]>0:
  • ##canvas.coords(buttons[pieces[point_id]],*star_points[point_id])
  • self.game_piece_id = 0
  • ##show_msg("release %d"% pieces[point_id] )
  • self.msg_id = 6
  • self.msg_num = self.pieces[point_id]
  • def map_value(self,value,vin_min,vin_max,vout_min,vout_max,FullScale=False,ForceInteger=True):
  • func = int if ForceInteger else lambda x:x
  • if value <=vin_min:
  • return func(vout_min)
  • elif value>=vin_max:
  • return func(vout_max)
  • else:
  • scale_max = vout_max +1 if FullScale else vout_max
  • return func( vout_min + (value-vin_min)*(scale_max - vout_min)/(vin_max - vin_min) )
  • def confirm_select(self):
  • #global game_state,selIDX,msg_id,msg_num,pieces,positions
  • print( 'confirm_select(self)' , self.selIDX )
  • if self.selIDX==0:
  • ##init_game()
  • self.pieces,self.positions = self.init_pieces()
  • self.game_state=0
  • self.msg_id = 0
  • self.msg_num = None
  • elif self.selIDX >=1 and self.selIDX <=10 :#else:
  • print('confirm_select:',self.selIDX)
  • if self.game_state==0:
  • i = self.select_a_point(self.selIDX-1)
  • print(i)
  • if i!=0:
  • self.game_state=1
  • print("confirm_select:try to pickup a piece",self.game_state,self.game_point_id,self.game_piece_id)
  • elif self.game_state==1:
  • self.release_a_point(self.selIDX-1)
  • self.game_state=0
  • print("confirm_select:try to putdown a piece",self.game_state,self.game_point_id,self.game_piece_id)
  • elif self.selIDX == 10 +1 : #// 按钮:退出
  • #self.doStop()
  • return False
  • return True
  • """
  • ##### DRAW LIB begin #####
  • from char_cn import *
  • def drawXBM(self,x,y,w,h,buffer):
  • #fb = framebuf.FrameBuffer(bytearray(buffer), w, h, framebuf.MVLSB)
  • #oled.blit(fb, x, y)
  • self.drawBuf(buffer,x,y,w,h)
  • ### draw Bitmap Buffer
  • def drawBuf(self,buffer,x,y,w,h):
  • fb = framebuf.FrameBuffer(buffer, w, h, framebuf.MVLSB)
  • oled.blit(fb, x, y)
  • ### draw piece without focus
  • def draw_piece_without_focus(self,x,y):
  • #p = bytearray(b'\x38\x7c\x7c\x7c\x38')
  • #self.drawBuf(p,x,y,5,8)
  • #USE:piece
  • #p = bytearray(b'\x0e\x1f\x1f\x1f\x0e')
  • #self.drawBuf(p,x,y+2,5,5)
  • imgBuf.draw_circle( (x,y, 5) , color=lcd.BLUE, thickness=1, fill=True )
  • ### draw piece focus
  • def draw_piece_focus(self,x,y):
  • #imgBuf.draw_line(x+3, y+2 , x+3+ 3, y+2 , color=lcd.YELLOW) #oled.hline(x+3, y+2 , 3, 1)
  • #imgBuf.draw_line(x+3, y+2 , x , y+2+3, color=lcd.YELLOW) #oled.line( x+3, y+2 , x , y+2+3, 1)
  • #imgBuf.draw_line(x , y+2+3, x ,y+2+3+3, color=lcd.YELLOW) #oled.vline(x , y+2+3, 3, 1)
  • #imgBuf.draw_line(x+5, y+2 , x+8, y+2+3, color=lcd.YELLOW) #oled.line( x+5, y+2 , x+8, y+2+3, 1)
  • #imgBuf.draw_line(x+8, y+2+3, x+8,y+2+3+3, color=lcd.YELLOW) #oled.vline(x+8, y+2+3, 3, 1)
  • #imgBuf.draw_line(x , y+7 , x+3, y+2+8, color=lcd.YELLOW) #oled.line( x , y+7 , x+3, y+2+8, 1)
  • #imgBuf.draw_line(x+3, y+2+8, x+3+ 3, y+2+8, color=lcd.YELLOW) #oled.hline(x+3, y+2+8, 3, 1)
  • #imgBuf.draw_line(x+5, y+2+8, x+8, y+2+5, color=lcd.YELLOW) #oled.line( x+5, y+2+8, x+8, y+2+5, 1)
  • imgBuf.draw_circle( (x,y, 7) , color=lcd.YELLOW, thickness=1, fill=False )
  • ### draw piece with focus
  • def draw_piece_with_focus(self,x,y):
  • self.draw_piece_without_focus(x,y)
  • self.draw_piece_focus(x-2,y-2)
  • ### draw chinese char
  • def draw_chinese_char(self,x,y,c):
  • p = bytearray(c)
  • self.drawBuf(p,x,y,8,8)
  • ### draw half width char
  • def draw_half_width_char(self,x,y,c):
  • p = bytearray(c)
  • self.drawBuf(p,x,y,4,8)
  • ##### DRAW LIB end #####
  • def update_number(self, x, y,num):
  • i = 0
  • if num >= 10 :
  • print(" >pos:",x+i," , n:",int(num / 10))
  • ##u8g2.drawXBM(x + i, 11, 4, 7, CHAR_NUM_BITMAP_ARRAY[ int(num / 10) ])
  • self.draw_half_width_char( x + i, y, CHAR_NUM_BITMAP_ARRAY[ int(num / 10) ] )
  • i += 4
  • #
  • if num>=0 :
  • print(" >pos:",x+i," , n:",int(num % 10) )
  • #//u8g2.drawXBM(x + i, 11, 4, 7, CHAR_NUM_BITMAP_ARRAY[ int(num % 10) ])
  • self.draw_half_width_char( x + i, y, CHAR_NUM_BITMAP_ARRAY[ int(num % 10) ] )
  • #print(" ,n:",msg_num)
  • else :
  • print("ALERT: num < 0")
  • """
  • def update_message(self):
  • #print(dir(lcd))
  • #['__class__', '__name__', 'clear', 'type', 'BLACK', 'BLUE', 'CYAN', 'DARKCYAN', 'DARKGREEN', 'DARKGREY', 'GREEN', 'GREENYELLOW', 'LIGHTGREY', 'MAGENTA', 'MAROON', 'NAVY', 'OLIVE', 'ORANGE', 'PINK', 'PURPLE', 'RED', 'WHITE', 'XY_LRDU', 'XY_LRUD', 'XY_RLDU', 'XY_RLUD', 'YELLOW', 'YX_LRDU', 'YX_LRUD', 'YX_RLDU', 'YX_RLUD', 'bgr_to_rgb', 'deinit', 'direction', 'display', 'draw_string', 'fill_rectangle', 'freq', 'get_backlight', 'height', 'init', 'mirror', 'register', 'rotation', 'set_backlight', 'width']
  • self.imgBuf.draw_rectangle(MSG_LEFT+0,MSG_TOP+0,40,7, color=lcd.YELLOW, thickness=1 , fill=True )#oled.fill_rect(MSG_LEFT+0,MSG_TOP+0,40,7,0)
  • #switch (msg_id) {
  • if self.msg_id == 0: #case 0://show_msg("huanying ",NONE);
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP,, "huanying", scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "WELCOM!", scale=1,color=lcd.BLACK)
  • #break;
  • elif self.msg_id == 1: #case 1://show_msg("remove",p );
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "remove %d"%self.msg_num, scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "remove %d"%self.msg_num, scale=1,color=lcd.BLACK)
  • #break;
  • elif self.msg_id == 2: #case 2://show_msg("pickup", self.game_piece_id);
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "pickup %d"%self.msg_num, scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "pickup %d"%self.msg_num , scale=1,color=lcd.BLACK)
  • #break;
  • elif self.msg_id == 3: #case 3://show_msg('You Win',NONE);
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "You Win", scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "You Win" , scale=1,color=lcd.BLACK)
  • #break;
  • elif self.msg_id == 4: #case 4://show_msg('Game Over',NONE);
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "Game Over", scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "Game Over" , scale=1,color=lcd.BLACK)
  • #break;
  • elif self.msg_id == 5: #case 5://show_msg("move ", self.game_piece_id );
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "move %d"%self.msg_num, scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "move %d"%self.msg_num , scale=1,color=lcd.BLACK)
  • #break;
  • elif self.msg_id == 6: #case 6://show_msg("release ", self.pieces[point_id] );
  • #imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "release %d"%self.msg_num, scale=1,color=lcd.WHITE)
  • self.imgBuf.draw_string(MSG_LEFT+ 0, MSG_TOP, "release %d"%self.msg_num , scale=1,color=lcd.BLACK)
  • #break;
  • def update_screen(self):
  • #lcd.clear()#oled.fill(0)#u8g2.clearBuffer();
  • self.imgBuf.clear()
  • self.imgBuf.draw_rectangle(0, 0, 320, 240 , color=lcd.WHITE, thickness=1 , fill=True )
  • #
  • #// 绘制边
  • #print("edge>>> ")
  • #u8g2.setDrawColor(1);
  • for i in range(5):
  • #oled.line( self.points[self.edges[i][0]][0], self.points[self.edges[i][0]][1], self.points[self.edges[i][3]][0], self.points[self.edges[i][3]][1], 1)
  • self.imgBuf.draw_line( self.points[self.edges[i][0]][0], self.points[self.edges[i][0]][1], self.points[self.edges[i][3]][0], self.points[self.edges[i][3]][1], color=lcd.BLACK)
  • #print("edge ",i,":(",self.points[self.edges[i][0]][0],",", self.points[self.edges[i][0]][1],")-(", self.points[self.edges[i][3]][0],",", self.points[self.edges[i][3]][1],")" )
  • #print()
  • #
  • #// 绘制棋子
  • #print(positions)
  • for i in range(1,10+1):
  • #print( ("piece>>> "),i,":", self.positions[i] )
  • if self.positions[i] >= 0 :
  • ##### 绘制棋子 #####
  • #u8g2.drawDisc(points[positions[i]][0], points[positions[i]][1], 3, U8G2_DRAW_ALL);
  • self.imgBuf.draw_circle(self.points[self.positions[i]][0], self.points[self.positions[i]][1], 11 , color=lcd.RED , thickness=1 , fill= True )
  • # # self.draw_piece_without_focus(self.points[self.positions[i]][0]-2, self.points[self.positions[i]][1]-4)
  • #//Serial.print(points[positions[i]][0],DEC);
  • #//Serial.print(F(" "));
  • #//Serial.print(points[positions[i]][1],DEC);
  • #}
  • #// Serial.println();
  • #// 显示信息
  • #//Serial.println(F("msg 0"));
  • self.update_message();
  • #//Serial.println(F("msg 1"));
  • #// 显示按钮:重新开始
  • #u8g2.setDrawColor(1);
  • #/* */
  • #uint8_t data[7];
  • #u8g2.drawFrame( 70, 37, 43, 13 );
  • self.imgBuf.draw_rectangle(MSG_LEFT - 6, MSG_TOP + 27, 43, 13 , color=lcd.YELLOW, thickness=1 , fill=True )#oled.rect( 70, 37, 43, 13, 1)
  • #self.draw_chinese_char( 72, 40-1, CHAR_CN_BITMAP_CHONG2 )
  • #self.draw_chinese_char( 82, 40-1, CHAR_CN_BITMAP_XIN1 )
  • #self.draw_chinese_char( 92, 40-1, CHAR_CN_BITMAP_KAI1 )
  • #self.draw_chinese_char(102, 40-1, CHAR_CN_BITMAP_SHI3 )
  • self.imgBuf.draw_string( MSG_LEFT -4, MSG_TOP +30 -1, "replay", scale=1,color=lcd.PURPLE)
  • #// 显示按钮:重新开始
  • self.imgBuf.draw_rectangle(MSG_LEFT -6+60, MSG_TOP + 27, 43, 13 , color=lcd.YELLOW, thickness=1 , fill=True )#oled.rect( 70, 37, 43, 13, 1)
  • self.imgBuf.draw_string( MSG_LEFT -4+60, MSG_TOP +30 -1, "EXIT", scale=1,color=lcd.PURPLE)
  • #//画焦点
  • #//Serial.print(F("Focus:"));
  • #//Serial.println(selIDX, DEC);
  • if 0 == self.selIDX : #// 按钮:重新开始
  • #u8g2.setDrawColor(1);
  • self.imgBuf.draw_rectangle( MSG_LEFT - 8 , MSG_TOP + 25 , 47, 17 ,1 , color=lcd.GREEN, thickness=2 , fill=False )#oled.rect( 68, 35, 47, 17 ,1 )
  • elif self.selIDX >=1 and self.selIDX <=10 :
  • j = self.selIDX - 1
  • if 0 != self.pieces[j] :#//此处有子
  • pass
  • else:
  • #加个黑圈
  • #u8g2.setDrawColor(0);
  • #u8g2.drawCircle(points[j][0], points[j][1], 4, U8G2_DRAW_ALL);
  • #self.draw_piece_focus( points[j][0]-2, points[j][1]-2)
  • pass
  • #}
  • #u8g2.setDrawColor(1);
  • #u8g2.drawCircle(points[j][0], points[j][1], 5, U8G2_DRAW_ALL);
  • # # self.draw_piece_focus( self.points[j][0]-4, self.points[j][1]-6)
  • self.imgBuf.draw_circle(self.points[j][0], self.points[j][1], 15 , color=lcd.GREEN , thickness=2 , fill= False )
  • elif self.selIDX == 10 +1 : #// 按钮:退出
  • #self.doStop()
  • self.imgBuf.draw_rectangle( MSG_LEFT - 8+60 , MSG_TOP + 25 , 47, 17 ,1 , color=lcd.GREEN, thickness=2 , fill=False )#oled.rect( 68, 35, 47, 17 ,1 )
  • else:
  • print('update_screen',self.selIDX,'__ERROR__')
  • #}
  • #lcd.display(imgBuf)#oled.show()
  • self.screen.display(self.imgBuf)
  • #}
  • def main_loop(self):
  • #lcd.clear()#oled.fill(0)#u8g2.clearBuffer();
  • # self.imgBuf.clear()
  • # self.imgBuf.draw_rectangle(0, 0, 320, 240 , color=lcd.WHITE, thickness=1 , fill=True )
  • #
  • self.update_screen()
  • #lcd.display(imgBuf)#oled.show()
  • # self.screen.display(self.imgBuf)
  • def prv_click(self):
  • #global selIDX
  • i = self.selIDX
  • i-=1
  • if i<0:
  • i=self.btnCnt-1
  • self.selIDX = i #update_and_draw_selection(i)
  • print('prv_click' , self.selIDX )
  • def nxt_click(self):
  • #global selIDX
  • i = self.selIDX
  • i+=1
  • if i>=self.btnCnt:
  • i=0
  • self.selIDX = i #update_and_draw_selection(i)
  • print('nxt_click' , self.selIDX )
  • def btn_so_click(self):
  • #global pieces,positions
  • print("当前状态",self.pieces,self.positions)
  • flag = self.solution(self.pieces[::],self.positions[::],[])
  • if type([])==type(flag):
  • if len(flag)>0:
  • show_msg("有解:%d->%d"%(flag[0][1],flag[0][2]))
  • else:
  • show_msg("已解")
  • else:
  • show_msg("无解")
  • print("求解结束",flag)
  • ################################################################################
  • # One Player Application #
  • ################################################################################
  • class appOnePlayer(OneApp,lucky9starClass):
  • def setup(self, **kw):
  • self.selIdx = 0
  • super().setup(**kw)
  • self.game = lucky9starClass()
  • self.game.setScreen(self.data['screen'] )
  • def rePaint(self):
  • self.game.update_screen()
  • def loop(self):
  • OneApp.loop(self)
  • try:
  • self.game.main_loop()
  • #print('self.game.main_loop()')
  • except:
  • pass
  • """
  • cnt = self.data['cnt']
  • if cnt<20:
  • print('app[',self.name,'] cnt:',cnt,self.name)
  • self.data['cnt']=cnt+1
  • time.sleep(DEBUG_DELAY)
  • return self.stat
  • elif 20==cnt:
  • print('app1 stop:',cnt)
  • return self.doStop()
  • """
  • def onEvent(self,evtName,*args,**kw):
  • print('appOnePlayer-onEvent',self.name , 'onEvent:',evtName,'*args',args,'**kw',kw)
  • if 'btn1_pressed'==evtName:
  • self.game.nxt_click()
  • elif 'btn2_pressed'==evtName:
  • b_not_exit = self.game.confirm_select()
  • print( 'b_not_exit',b_not_exit )
  • if not b_not_exit :
  • print( self.name, 'self.doStop()' )
  • self.doStop()
  • ################################################################################
  • # simple Application #
  • ################################################################################
  • class appSimple(OneApp):
  • def loop(self):
  • OneApp.loop(self)
  • cnt = self.data['cnt']
  • if cnt<10:
  • print('app[',self.name,'] cnt:',cnt,self.name)
  • self.data['cnt']=cnt+1
  • time.sleep(DEBUG_DELAY)
  • return self.stat
  • elif 20==cnt:
  • print('app1 stop:',cnt)
  • return self.doStop()
  • def onEvent(self,evtName,*args,**kw):
  • print( 'appSimple-onEvent',self.name , 'onEvent:',evtName,'*args',args,'**kw',kw)
  • ################################################################################
  • # System Application #
  • ################################################################################
  • class SysApp(OneApp):
  • def setup(self, **kw):
  • self.selIdx = 0
  • super().setup(**kw)
  • def loop(self):
  • if self.stat == OneAppStats.RUNNING:
  • #print( self.selIdx ,utime.ticks() )
  • #print(self.name,'loop(self)')
  • self._paint()
  • OneApp.loop(self)
  • return self.stat
  • def rePaint(self):
  • cntChild=self._countChildApp()
  • #print(self.name,'rePaint',cntChild ,self.selIdx)
  • if cntChild ==0:
  • screen = self.data['screen']
  • img = image.Image()
  • img.clear()
  • img.draw_rectangle(0, 0, 320, 240 , color=lcd.WHITE, thickness=1 , fill=True )
  • l,t=100,60
  • img.draw_string(l , t + 0*60, "ONE PLAYER", scale=2,color=lcd.BLACK)
  • img.draw_string(l , t + 1*60, "TWO PLAYER", scale=2,color=lcd.BLACK)
  • img.draw_string(l , t + 2*60, "AI PLAYER", scale=2,color=lcd.BLACK)
  • img.draw_rectangle(l-15, t + self.selIdx * 60 -5 , 150 , 5+ 24 +5 , color=lcd.BLACK, thickness=1 , fill=False )
  • screen.display(img)
  • else:
  • for childrenApp in self.childApps:
  • if childrenApp.stat == OneAppStats.RUNNING :
  • #print(childrenApp.name,'rePaint','before')
  • childrenApp._paint()
  • def onEvent(self,evtName,*args,**kw):
  • print(self.name , 'onEvent:',evtName,'*args',args,'**kw',kw)
  • if len(self.childApps)>0:
  • print("super().onEvent(self,evtName,*args,**kw)")
  • super().onEvent(self,evtName,*args,**kw)
  • else:
  • if evtName=='btn2_pressed':
  • if self.selIdx == 0:# ONE PLAYER
  • app = self._startChildApp(appOnePlayer,'ONE PLAYER')
  • app.setup(**{'cnt':0,'screen':self.data['screen']})
  • print('start ONE PLAYER')
  • #while app.loop()==OneAppStats.RUNNING:
  • # print(self.name,self.stat,len(self.childApps),app.name, app.stat)
  • # time.sleep(DEBUG_DELAY)
  • #print('exit app1',app.stat)
  • elif self.selIdx == 1:# TWO PLAYER
  • app = self._startChildApp(appSimple,'TWO PLAYER')
  • app.setup(**{'cnt':0,'screen':self.data['screen']})
  • print('start TWO PLAYER')
  • #while app.loop()==OneAppStats.RUNNING:
  • # print(self.name,self.stat,len(self.childApps),app.name, app.stat)
  • # time.sleep(DEBUG_DELAY)
  • #print('exit app1',app.stat)
  • elif self.selIdx == 2:# AI PLAYER
  • app = self._startChildApp(appSimple,'AI PLAYER')
  • app.setup(**{'cnt':0,'screen':self.data['screen']})
  • print('start AI PLAYER')
  • #while app.loop()==OneAppStats.RUNNING:
  • # print(self.name,self.stat,len(self.childApps),app.name, app.stat)
  • # time.sleep(DEBUG_DELAY)
  • # print('exit app1',app.stat)
  • else:
  • print('error idx',self.selIdx)
  • if evtName=='btn1_pressed':
  • if self.selIdx==2:
  • self.selIdx=0
  • else:
  • self.selIdx = self.selIdx +1
  • print('self.selIdx',self.selIdx)
  • utime.sleep_ms(300)
  • def call_object_method(obj,method_name,*args,**kv):
  • if method_name in dir(obj):
  • getattr(obj,method_name)(method_name,*args,**kv)
  • import lcd,image
  • import utime
  • from Maix import GPIO
  • from fpioa_manager import fm
  • lcd.init(type=1, freq=15000000, color=lcd.BLACK, invert = 0, lcd_type = 0)
  • lcd.clear()
  • root = SysApp('root')
  • root.setup(**{'screen':lcd})
  • fm.register(22, fm.fpioa.GPIOHS0)
  • key22 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_NONE)
  • fm.register(23, fm.fpioa.GPIOHS1)
  • key23 = GPIO(GPIO.GPIOHS1, GPIO.IN, GPIO.PULL_NONE)
  • last_ticks=0
  • def test_irq22(pin_num):
  • global last_ticks
  • #key22.disirq() # 禁用中断
  • #key23.disirq() # 禁用中断
  • disable_buttons_irq()
  • utime.sleep_ms(500)
  • tmp_last_ticks = utime.ticks()
  • print("key1?", pin_num,'val22',key22.value(),'val23',key23.value(), 'at',tmp_last_ticks,last_ticks,"\n")
  • if last_ticks+500<tmp_last_ticks :
  • #call_object_method(root,'onEvent','btn1_pressed',pin_num)
  • root.onEvent('btn1_pressed',pin_num)
  • last_ticks = tmp_last_ticks
  • #key22.irq(test_irq22, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
  • #key23.irq(test_irq23, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
  • enable_buttons_irq()
  • def test_irq23(pin_num):
  • global last_ticks
  • #key22.disirq() # 禁用中断
  • #key23.disirq() # 禁用中断
  • disable_buttons_irq()
  • utime.sleep_ms(500)
  • tmp_last_ticks = utime.ticks()
  • print("key2?", pin_num,'val22',key22.value(),'val23',key23.value(), 'at',tmp_last_ticks,last_ticks,"\n")
  • if last_ticks+500<tmp_last_ticks :
  • #call_object_method(root,'onEvent','btn2_pressed',pin_num)
  • root.onEvent('btn2_pressed',pin_num)
  • last_ticks = tmp_last_ticks
  • #key22.irq(test_irq22, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
  • #key23.irq(test_irq23, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
  • enable_buttons_irq()
  • def enable_buttons_irq():
  • key22.irq(test_irq22, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
  • key23.irq(test_irq23, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
  • def disable_buttons_irq():
  • key22.disirq() # 禁用中断
  • key23.disirq() # 禁用中断
  • enable_buttons_irq()
  • while root.stat==OneAppStats.RUNNING:
  • print('root loop',root.loop() )
  • time.sleep(DEBUG_DELAY)
  • print('1111')
  • #key.disirq() # 禁用中断
  • #fm.unregister(16)

还是从这里进入。用绿色键选第一项:

然后按红色键进入游戏。绿色的圈表示当前选中的项目:

按绿色键,移动选到第行第2个。按红色键消去:

然后绿色键,移动选到第行第4个。按红色键选中后,再绿色键,移动到第行第2个。按红色键,就可以让右边的棋子跳到左边,同时消去第3个棋子:

以此类推,如果能够把棋子消除到只剩1个,就成功了。

顺便说一下,“replay”的作用是重置棋盘,“EXIT”是退出到上一级菜单。

 

 

 

 

 

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
立即报名 | 2025 瑞萨电子工业以太网技术日即将开启!
3月-4月 深圳、广州、北京、苏州、西安、上海 走进全国6城
2025瑞萨电子工业以太网技术巡回沙龙聚焦工业4.0核心需求,为工程师与企业决策者提供实时通信技术最佳解决方案。
预报从速,好礼等您拿~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表