2017-05-12 3 views
0

최근 tkinter (파이썬 버전 3.6.1)을 사용하여 작은 게임을 만들고 cx_Freeze을 사용하여 동결 시켰습니다. 이 게임에는 실행 취소 버튼, 재시작 버튼, "합법적 인 움직임 찾기"버튼 및 "가장 적합한 이동 버튼 찾기"버튼이 있습니다. "가장 좋은 이동 찾기"버튼은 shelve 데이터베이스를 사용하여 처음 3 번을 돌릴 때 가장 좋은 이동을 찾으며 4 번째 돌까지 이동 트리를 가로 지르는 재귀 함수를 찾습니다. 내 코드는 버튼을 사용하지 않아야 사용할 수 없도록합니다.cx_Freeze Tkinter 응용 프로그램 빌드 매우 버그

설치 스크립트에 필요한 DLL을 포함시켜야하며 오류없이 실행 파일을 실행할 수있었습니다. 그러나 세 번째 버튼은 네 번째 턴 (재귀 함수가 사용되기 시작)까지 비활성화되며 응용 프로그램은 다른 많은 방법으로 매우 버그가 있습니다. 그러나 고정되지 않은 버전을 실행하면 완벽하게 작동합니다.

정직하게도이 문제는 완전히 분실했기 때문에 내가 여러분에게 제공해야 할 코드 스 니펫을 알지 못합니다. 내가 가진 유일한 단서는 빌드에있는 pyc 파일의 크기가 고정되지 않은 앱과 다른 것입니다. 나는 이것이 다소 모호하다는 것을 안다. 그러나 나는 구체적인 것이 무엇이 유용 할 지 모른다. 가능한 한 모든 도움을 주시면 대단히 감사하겠습니다.

"최고의 이동 찾기"방법 :

def _find_best_move(self): 
    """Finds best move possible for current game.""" 
    if len(self.game.moves) <= 3: 
     with shelve.open("paths") as db: 
      best_paths = db[str(self.game.moves)] 
      best_path = choice(best_paths) 
    else: 
     self.path_finder(self.game) 
     best_path = self.path_finder.best_path 
    best_move = best_path[len(self.game.moves)] 
    best_move = (__class__._add_offset(best_move[0]), best_move[1]) 
    return best_move 

업데이트 버튼 주 :

def update_gui(self): 
    """Updates GUI to reflect current game conditions.""" 
    legal_moves = self.game.find_legal_moves() 
    if self.game.moves: 
     self.undo_btn["state"] = "!disabled" 
     self.restart_btn["state"] = "!disabled" 
     self.best_move_btn["state"] = "!disabled" 
    else: 
     self.undo_btn["state"] = "disabled" 
     self.restart_btn["state"] = "disabled" 
    if legal_moves: 
     self.show_moves_btn["state"] = "!disabled" 
    else: 
     self.show_moves_btn["state"] = "disabled" 
    if legal_moves and self.game.moves: 
     self.best_move_btn["state"] = "!disabled" 
    else: 
     self.best_move_btn["state"] = "disabled" 

__init__ 파일 :

initpath = os.path.dirname(__file__) 
os.chdir(os.path.join(initpath, "data")) 

PathFinder 클래스 (이송이 즉시 나무를 이동) :

class PathFinder: 
    """Provides methods to find move paths that meet various criteria. 

    Designed to be called after the player makes a move. 
    """ 

    _game = None 
    best_path = None 
    best_score = None 

    def __call__(self, game): 
     """Call self as function.""" 
     if not game: 
      self._game = DummyGame() 
     elif not isinstance(game, DummyGame): 
      self._game = DummyGame(game) 
     else: 
      self._game = game 
     moves = self._game.moves 
     self.possible_paths = dict.fromkeys(range(1,9)) 
     root = Node(moves[-1]) 
     self._find_paths(root) 
     self._find_paths.cache_clear() 
     found_scores = [score for score in self.possible_paths.keys() if 
         self.possible_paths[score]] 
     self.best_score = min(found_scores) 
     self.best_path = self.possible_paths[self.best_score] 

    @lru_cache(None) 
    def _find_paths(self, node): 
     """Finds possible paths and records them in 'possible_paths'.""" 
     legal_moves = self._game.find_legal_moves() 
     if not legal_moves: 
      score = self._game.peg_count 
      if not self.possible_paths[score]: 
       self.possible_paths[score] = self._game.moves.copy() 
     else: 
      children = [] 
      for peg in legal_moves: 
       for move in legal_moves[peg]: 
        children.append(Node((peg, move))) 
      for child in children: 
       self._game.move(*child.data) 
       self._find_paths(child) 
     try: 
      self._game.undo() 
     except IndexError: 
      pass 

페그 클래스 :

class Peg(RawPen): 
    """A specialized 'RawPen' that represents a peg.""" 

    def __init__(self, start_point, graphics): 
     """Initialize self. See help(type(self)) for accurate signature.""" 
     self.graphics = graphics 
     self.possible_moves = [] 
     super().__init__(self.graphics.canvas, "circle", _CFG["undobuffersize"], 
        True) 
     self.pen(pendown=False, speed=0, outline=2, fillcolor="red", 
      pencolor="black", stretchfactor=(1.25,1.25)) 
     self.start_point = start_point 
     self.goto(start_point) 
     self.ondrag(self._remove) 
     self.onrelease(self._place) 

    def _remove(self, x, y): 
     """Removes peg from hole if it has moves.""" 
     if self.possible_moves: 
      self.goto(x,y) 

    def _place(self, x, y): 
     """Places peg in peg hole if legal.""" 
     if self.possible_moves: 
      target_holes = [tuple(map(add, self.start_point, move)) for move in 
         self.possible_moves] 
      distances = [self.distance(hole) for hole in target_holes] 
      hole_distances = dict(zip(distances, target_holes)) 
      nearest_hole = hole_distances[min(hole_distances)] 
      if self.distance(nearest_hole) <= 0.45: 
       self.goto(nearest_hole) 
       peg = self.graphics._subtract_offset(self.start_point) 
       move = tuple(map(sub, self.pos(), self.start_point)) 
       move = tuple(map(int, move)) 
       self.graphics.game.move(peg, move) 
       self.start_point = self.pos() 
      else: 
       self.goto(self.start_point) 
+0

작동하지 않는 코드를 제공 할 수 있다면 도움이 될 것입니다. –

+0

많은 코드가 있으므로 가장 관련있는 부분 만 제공 할 것입니다. 그렇다면 cx_Freeze는 신의 선물입니다. 나는 그것으로 다른 응용 프로그램을 얼려 버렸고 그것은 매력처럼 작동합니다. 너는 아주 잘 했어. –

+0

다른 버그는 합법적으로 이동할 수있는 경우에만 드래그 할 수 있도록 설계된 "못"('거북이 .RawPen'의 하위 클래스)이 때때로 이동하지 못할 수도 있다는 점입니다. 또한'__init__' 파일은 작업 디렉토리를'data'로 변경합니다. 여기에는 이동 쉘프와'turtle.cfg' 파일이 있습니다. –

답변

1

는 정지 된 응용 프로그램은 __value__ 고정되지 않은 응용 프로그램에 대해 다른 값을 가질 예정이다. 그에 따라 처리해야합니다! 이것은 많은 사람들을 물리는 일반적인 문제입니다. 모듈이 파일 시스템에서 발견된다고 가정하는 모든 것은 정지 될 때 제대로 작동하지 않을 것입니다. 다른 하나는 동적 모듈 가져 오기입니다.

documentation은이 주제 및 기타 유용한 내용을 다룹니다.

+0

내'__init__' 파일에 FAQ의 "데이터 파일 사용"섹션에있는 예제와 비슷한 내용이 포함되어 있습니다. 내가해야만했던 또 다른 일은'includes '리스트에'dbm.dumb' 모듈을 포함시키는 것입니다.'shelve'는 그것이 작동하기 위해 필요하기 때문에'dbm' 패키지에 자동으로 포함되지 않았습니다. 이제 모든 것이 완벽하게 작동합니다. 감사합니다. –