def redo_single_move(self, widget): move = None try: move = self.redolist.pop() # get side to move before appending to movelist self.stm = self.get_side_to_move() self.movelist.append(move) # do the move in gshogi engine engine.setplayer(self.stm) engine.hmove(move) # side to move changes to opponent self.stm = self.get_side_to_move() gv.gui.set_side_to_move(self.stm) except IndexError: pass try: gv.usib.stop_engine() gv.usiw.stop_engine() except: pass gv.board.update() # set move list window to last move self.move_list.set_move(len(self.movelist)) if move is not None: gv.gui.set_status_bar_msg(move) # highlight the move by changing square colours self.hilite_move(move)
def redo_move(self): move = None try: move = self.redolist.pop() # get side to move before appending to movelist self.stm = self.get_side_to_move() self.movelist.append(move) # do the move in gshogi engine engine.setplayer(self.stm) engine.hmove(move) except IndexError: pass
def square_clicked(self, data): # get x,y co-ords of square clicked on x, y = data # convert the x, y co-ords into the gui checkers representation gc_loc = self.board.get_gc_loc(x, y) # if the square clicked on is a valid source square # then set this square as the source square if self.board.valid_source_square(gc_loc, self.side_to_move): self.src = gc_loc # call display board to set the square clicked on as highlighted self.board.display_board() return # if the square clicked on is a valid destination square (i.e. unoccupied) # then set this square as the destination square. The engine will check # if the move is legal if self.board.valid_destination_square(gc_loc): self.dst = gc_loc # call the engine to update with the Human move source square (src) # to destination square (dst) board_position = engine.hmove(self.src, self.dst) self.board.set_board_position(board_position) self.board.display_board() self.gui.init_all_dnd() if self.legalmove == 0: # legalmove = 0 means human made illegal move # must try again - still his go pass elif self.legalmove == 2000: # double jump not yet completed - still human's go self.src = self.dst self.dst = 0 self.board.display_board() else: #self.gui.set_status_bar_msg(self.get_side_to_move_msg()) self.set_panel_msg2() # Move was OK - now let the other side move # If human is playing both sides (i.e. computer is off) then return # now without calling the engine if self.side_to_move == RED and self.red_player != COMPUTER: return if self.side_to_move == WHITE and self.white_player != COMPUTER: return # It's the computers turn to move # kick off a separate thread for computers move so that gui is still useable self.ct= thread.start_new_thread( self.computer_move, () ) return
def get_move(self, piece, src, dst, src_x, src_y, dst_x, dst_y): if gv.verbose: print "in get move" print "src=", src print "dst=", dst print "src_x=", src_x print "src_y=", src_y print "dst_x=", dst_x print "dst_y=", dst_y move = self.src + dst # check for promotion if self.promotion_zone(src, dst, self.stm): promote = gv.board.promote(piece, src_x, src_y, dst_x, dst_y, self.stm) if (promote == 2): # must promote move = move + "+" elif (promote == 1): # promotion is optional # # But always prompt before promoting a silver since it # can be valuable to have an unpromoted silver on the # opposite side of the board. if self.ask_before_promoting or piece == " s" or piece == " S": response = gv.gui.promote_popup() if (response == Gtk.ResponseType.CANCEL): return None if (response == Gtk.ResponseType.YES): move = move + "+" else: move = move + "+" if gv.verbose: print "move=", move engine.setplayer(self.stm) validmove = engine.hmove(move) if (not validmove): # illegal move gv.gui.set_status_bar_msg("Illegal Move") return None return move
def computer_move(self): try: self.thinking = True while True: self.thinking = True self.stm = self.get_side_to_move() # update time for last move Gdk.threads_enter() # gv.tc.update_clock() gv.gui.set_side_to_move(self.stm) # set clock ready for move to come # gv.tc.start_clock(self.stm) Gdk.threads_leave() if gv.verbose: print "#" print("# " + self.get_side_to_move_string(self.stm) + " to move") print "#" if self.player[self.stm] == "Human": Gdk.threads_enter() gv.gui.apply_drag_and_drop_settings( self.player[self.stm], self.stm) Gdk.threads_leave() self.thinking = False gv.tc.start_clock(self.stm) return t_start = time.time() if self.player[self.stm] != "gshogi": if self.stm == BLACK: self.usi = gv.usib # usi_opponent = self.usiw # opponent_stm = WHITE else: self.usi = gv.usiw # usi_opponent = self.usib # opponent_stm = BLACK ponder_enabled = gv.engine_manager.get_ponder() if not ponder_enabled: # get engines move self.cmove, self.pondermove[self.stm] = self.usi.cmove( self.movelist, self.stm) else: # pondering ponderhit = False if (self.pondermove[self.stm] is not None and len(self.movelist) > 0): if (self.movelist[-1] == self.pondermove[self.stm] ): ponderhit = True if ponderhit: # ponderhit, wait for return of bestmove and # pondermove self.cmove, self.pondermove[self.stm] = \ self.usi.send_ponderhit(self.stm) else: if self.pondermove[self.stm] is not None: # stop ponder, wait for return of bestmove and # pondermove from ponder bm, pm = self.usi.stop_ponder() # get engines move self.cmove, self.pondermove[self.stm] = \ self.usi.cmove(self.movelist, self.stm) # start pondering if self.pondermove[self.stm] is not None: # send position and ponder command, # return immediately self.usi.start_ponder(self.pondermove[self.stm], self.movelist, self.cmove) if self.stopped or self.cmove is None: self.thinking = False return if gv.verbose: print "computer move is", self.cmove # check if player resigned if self.cmove == "resign": if gv.verbose: print "computer resigned" self.gameover = True self.thinking = False colour = self.get_side_to_move_string(self.stm) msg = "game over - " + colour + " resigned" Gdk.threads_enter() self.stop() gv.gui.set_status_bar_msg(msg) Gdk.threads_leave() self.thinking = False return # engine.setplayer(WHITE) engine.setplayer(self.stm) validmove = engine.hmove(self.cmove) if (not validmove): Gdk.threads_enter() self.stop() gv.gui.set_status_bar_msg( self.cmove + " - computer made illegal Move!") Gdk.threads_leave() self.gameover = True self.thinking = False return if gv.verbose: engine.command("bd") else: if gv.verbose: print "using gshogi builtin engine" # # We are using the builtin gshogi engine (not a USI engine) # if self.player[self.stm ^ 1] == "Human": Gdk.threads_enter() gv.gui.set_status_bar_msg("Thinking ...") Gdk.threads_leave() # set the computer to black or white engine.setplayer(self.stm ^ 1) # start the clock # print "starting clock from gshogi.py" Gdk.threads_enter() gv.tc.start_clock(self.stm) Gdk.threads_leave() # set time limit/level for move in gshogi engine gv.tc.set_gshogi_time_limit(self.stm) # call the gshogi engine to do the move self.cmove = engine.cmove() # update time for last move Gdk.threads_enter() # print "updating clock from gshogi.py" gv.tc.update_clock() gv.gui.set_side_to_move(self.stm) Gdk.threads_leave() if self.quitting: return if self.stopped: self.thinking = False Gdk.threads_enter() gv.gui.set_status_bar_msg("stopped") Gdk.threads_leave() engine.command("undo") return if self.cmove != "": self.movelist.append(self.cmove) self.redolist = [] else: # empty move is returned by gshogi engine when it is in # checkmate if gv.verbose: print "empty move returned by engine" # if the engine moved very fast then wait a bit # before displaying the move. The time to wait # is in MIN_MOVETIME in constants.py t_end = time.time() move_t = t_end - t_start if move_t < MIN_MOVETIME: diff = MIN_MOVETIME - move_t time.sleep(diff) # if program is exitting then quit this thread asap if self.quitting: return # gv.board.save_board(len(self.movelist)) # show computer move Gdk.threads_enter() gv.board.update() self.move_list.update() # highlight the move by changing square colours self.hilite_move(self.cmove) Gdk.threads_leave() # if self.player[self.stm] != "gshogi" # and gv.engine_manager.get_ponder(): # self.usi.send_ponder() # # self.ctp= thread.start_new_thread( # self.usi.send_ponder, () ) if gv.verbose: engine.command("bd") if gv.verbose: print "move=", self.cmove msg = self.cmove self.gameover, gmsg = self.check_for_gameover() if (self.gameover): if (msg == ""): msg = gmsg else: msg = self.get_side_to_move_string( self.stm) + ": " + msg msg = msg + ". " + gmsg self.thinking = False self.stm = self.get_side_to_move() Gdk.threads_enter() self.stop() gv.gui.set_side_to_move(self.stm) gv.gui.set_status_bar_msg(msg) Gdk.threads_leave() return msg = self.get_side_to_move_string(self.stm) + ": " + msg Gdk.threads_enter() gv.gui.set_status_bar_msg(msg) Gdk.threads_leave() self.thinking = False except: traceback.print_exc() return
def load_game_psn_from_str(self, gamestr): cnt = 0 comment_active = False movelist = [] redolist = [] startpos = 'startpos' engine.command('new') stm = BLACK movecnt = 0 self.gamestr = gamestr self.game_len = len(self.gamestr) self.comments.clear_comments() # First header should be near the start of the file # Note the first chars in the file may be a BOM entry and # we need to skip these ptr = 0 # Find '[' of first header while 1: if ptr >= self.game_len or ptr > 2000: self.gui.info_box("Error (1) loading file. No headers found") self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 if gamestr[ptr] == '[': break ptr += 1 # First Header found (ptr pointing at '[') hdr, newptr = self.get_header(ptr) if hdr is None: self.gui.info_box("Error (2) loading file. No headers found") self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 # Read remaining headers while hdr is not None: ptr = newptr try: prop, value = hdr.split(None, 1) except ValueError: # Error - cannot split header into a property/value pair self.gui.info_box("Error loading file. Invalid header:" + hdr) self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 if prop == 'SFEN': # set board position, side to move startpos, stm = self.process_sfen(value) elif prop == "Handicap": handicap = value.strip('"') handicap = handicap.lower() sfen = '' if handicap == 'lance': sfen = 'lnsgkgsn1/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'bishop': sfen = 'lnsgkgsnl/1r7/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'rook': sfen = 'lnsgkgsnl/7b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'rook+lance': sfen = 'lnsgkgsn1/7b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'rook+bishop': sfen = 'lnsgkgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'four piece': sfen = '1nsgkgsn1/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'six piece': sfen = '2sgkgs2/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'eight piece': sfen = '3gkg3/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'ten piece': sfen = '4k4/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' if sfen != '': startpos, stm = self.process_sfen(sfen) hdr, newptr = self.get_header(ptr) # Moves while 1: if self.verbose: print print "Processing move number (ply):" + str(movecnt + 1) newptr = self.skip_whitespace(ptr) if newptr is None: break ptr = newptr # if we get a header here then it must be a multi-game file # We cannot process multi-game so treat it as eof and exit if gamestr[ptr] == '[': break # Check for stuff to ignore # ignore it and continue processing ignore_string, newptr = self.get_ignore_string(ptr) if ignore_string is not None: # Can get '1....' to indicate white to move first #if ignore_string == '1....' and movecnt == 0: # # Use sfen for initial position but set stm to white # startpos, stm = self.process_sfen("lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1") ptr = newptr continue # comment if self.gamestr[ptr] == '{': comment = '' ptr += 1 while 1: if ptr >= self.game_len: self.gui.info_box("Error unterminated comment") self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 # end of file before end of comment if self.gamestr[ptr] == '}': ptr += 1 break comment += self.gamestr[ptr] ptr += 1 # add comment self.comments.set_comment(movecnt, comment) continue # move number # we do not use it moveno, newptr = self.get_moveno(ptr) if moveno is not None: ptr = newptr continue # move move, newptr = self.get_move(ptr, movelist, stm) if move is not None: ptr = newptr engine.setplayer(stm) stm = stm ^ 1 if self.verbose: print "move=", move validmove = engine.hmove(move) if (not validmove): # Should never get this message since get_move has already # validated the move aginst the legal move list # Can get it for sennichite (repetition) self.gui.info_box( "Error loading file, illegal move (possible sennichite (repetition)):" + move + " move number:" + str(movecnt + 1)) self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 movecnt += 1 movelist.append(move) if self.verbose: engine.command('bd') continue # Invalid - Display Error # If we get here we have an invalid word # Errors here will stop the processing and prevent the file loading # If the invalid word should be skipped instead then add it to the # ignore processing above word, newptr = self.get_word(ptr) if word is not None: self.gui.info_box( "Error loading file, unable to process move number " + str(movecnt + 1) + ". (illegal move or invalid format):" + word) # Load failed part way through so reset the game self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 ptr += 1 self.usib.set_newgame() self.usiw.set_newgame() self.gui.set_status_bar_msg("game loaded") self.gameover = False self.game.set_movelist(movelist) self.game.set_redolist(redolist) self.game.set_startpos(startpos) self.board.update() # update move list in move list window self.move_list.update() stm = self.game.get_side_to_move() self.game.set_side_to_move(stm) self.gui.set_side_to_move(stm) self.gui.unhilite_squares() self.tc.reset_clock() return 0
def computer_move(self): try: self.thinking = True while True: self.thinking = True self.stm = self.get_side_to_move() # update time for last move Gdk.threads_enter() # gv.tc.update_clock() gv.gui.set_side_to_move(self.stm) # set clock ready for move to come # gv.tc.start_clock(self.stm) Gdk.threads_leave() if gv.verbose: print "#" print("# " + self.get_side_to_move_string(self.stm) + " to move") print "#" if self.player[self.stm] == "Human": Gdk.threads_enter() gv.gui.apply_drag_and_drop_settings( self.player[self.stm], self.stm) Gdk.threads_leave() self.thinking = False gv.tc.start_clock(self.stm) return t_start = time.time() if self.player[self.stm] != "gshogi": if self.stm == BLACK: self.usi = gv.usib # usi_opponent = self.usiw # opponent_stm = WHITE else: self.usi = gv.usiw # usi_opponent = self.usib # opponent_stm = BLACK ponder_enabled = gv.engine_manager.get_ponder() if not ponder_enabled: # get engines move self.cmove, self.pondermove[self.stm] = self.usi.cmove( self.movelist, self.stm) else: # pondering ponderhit = False if (self.pondermove[self.stm] is not None and len(self.movelist) > 0): if (self.movelist[-1] == self.pondermove[self.stm]): ponderhit = True if ponderhit: # ponderhit, wait for return of bestmove and # pondermove self.cmove, self.pondermove[self.stm] = \ self.usi.send_ponderhit(self.stm) else: if self.pondermove[self.stm] is not None: # stop ponder, wait for return of bestmove and # pondermove from ponder bm, pm = self.usi.stop_ponder() # get engines move self.cmove, self.pondermove[self.stm] = \ self.usi.cmove(self.movelist, self.stm) # start pondering if self.pondermove[self.stm] is not None: # send position and ponder command, # return immediately self.usi.start_ponder( self.pondermove[self.stm], self.movelist, self.cmove) if self.stopped or self.cmove is None: self.thinking = False return if gv.verbose: print "computer move is", self.cmove # check if player resigned if self.cmove == "resign": if gv.verbose: print "computer resigned" self.gameover = True self.thinking = False colour = self.get_side_to_move_string(self.stm) msg = "game over - " + colour + " resigned" Gdk.threads_enter() self.stop() gv.gui.set_status_bar_msg(msg) Gdk.threads_leave() self.thinking = False return # engine.setplayer(WHITE) engine.setplayer(self.stm) validmove = engine.hmove(self.cmove) if (not validmove): Gdk.threads_enter() self.stop() gv.gui.set_status_bar_msg( self.cmove + " - computer made illegal Move!") Gdk.threads_leave() self.gameover = True self.thinking = False return if gv.verbose: engine.command("bd") else: if gv.verbose: print "using gshogi builtin engine" # # We are using the builtin gshogi engine (not a USI engine) # if self.player[self.stm ^ 1] == "Human": Gdk.threads_enter() gv.gui.set_status_bar_msg("Thinking ...") Gdk.threads_leave() # set the computer to black or white engine.setplayer(self.stm ^ 1) # start the clock # print "starting clock from gshogi.py" Gdk.threads_enter() gv.tc.start_clock(self.stm) Gdk.threads_leave() # set time limit/level for move in gshogi engine gv.tc.set_gshogi_time_limit(self.stm) # call the gshogi engine to do the move self.cmove = engine.cmove() # update time for last move Gdk.threads_enter() # print "updating clock from gshogi.py" gv.tc.update_clock() gv.gui.set_side_to_move(self.stm) Gdk.threads_leave() if self.quitting: return if self.stopped: self.thinking = False Gdk.threads_enter() gv.gui.set_status_bar_msg("stopped") Gdk.threads_leave() engine.command("undo") return if self.cmove != "": self.movelist.append(self.cmove) self.redolist = [] else: # empty move is returned by gshogi engine when it is in # checkmate if gv.verbose: print "empty move returned by engine" # if the engine moved very fast then wait a bit # before displaying the move. The time to wait # is in MIN_MOVETIME in constants.py t_end = time.time() move_t = t_end - t_start if move_t < MIN_MOVETIME: diff = MIN_MOVETIME - move_t time.sleep(diff) # if program is exitting then quit this thread asap if self.quitting: return # gv.board.save_board(len(self.movelist)) # show computer move Gdk.threads_enter() gv.board.update() self.move_list.update() # highlight the move by changing square colours self.hilite_move(self.cmove) Gdk.threads_leave() # if self.player[self.stm] != "gshogi" # and gv.engine_manager.get_ponder(): # self.usi.send_ponder() # # self.ctp= thread.start_new_thread( # self.usi.send_ponder, () ) if gv.verbose: engine.command("bd") if gv.verbose: print "move=", self.cmove msg = self.cmove self.gameover, gmsg = self.check_for_gameover() if (self.gameover): if (msg == ""): msg = gmsg else: msg = self.get_side_to_move_string( self.stm) + ": " + msg msg = msg + ". " + gmsg self.thinking = False self.stm = self.get_side_to_move() Gdk.threads_enter() self.stop() gv.gui.set_side_to_move(self.stm) gv.gui.set_status_bar_msg(msg) Gdk.threads_leave() return msg = self.get_side_to_move_string(self.stm) + ": " + msg Gdk.threads_enter() gv.gui.set_status_bar_msg(msg) Gdk.threads_leave() self.thinking = False except: traceback.print_exc() return
def receiveCallback(self, widget, context, x, y, selection, targetType, time, data): self.dnd_data_received = True if selection.get_text() != "samuel": print "invalid selection data. ignored" return False x, y = data # convert the x, y co-ords into the gui checkers representation gc_loc = self.board.get_gc_loc(x, y) self.dst = gc_loc board_position = engine.hmove(self.src, self.dst) self.board.set_board_position(board_position) self.board.set_board_status() # fixme if self.game.legalmove == 0: # illegal move so set piece back at source square zx, zy = self.board.get_x_y(self.src) pce = self.board.get_piece_at_square(zx, zy) self.board.set_piece_at_square(self.src, pce) self.board.display_board() return False # Set piece at dest square as dragged piece pce = self.board.get_piece_at_square(x, y) self.board.set_piece_at_square(gc_loc, pce) # if move was a jump then set the square jumped over to empty diff = self.dst - self.src if diff < 0: diff = -diff hdiff = diff / 2 # 8 or 10 is a jump # 4 or 5 is normal move if diff > 5: if self.dst > self.src: gc_loc = self.src + hdiff else: gc_loc = self.src - hdiff self.board.set_piece_at_square(gc_loc, 0) zx, zy = self.board.get_x_y(gc_loc) self.eb[zx][zy].queue_draw() Gtk.drag_finish(context, True, True, time) # fixme if self.game.legalmove == 2000: # double jump not yet completed - don't call computer move self.init_all_dnd() return False stm = self.game.get_side_to_move() red_player, white_player = self.game.get_players() self.init_all_dnd() # If human is playing both sides (i.e. computer is off) then return # now without calling the engine if stm == RED and red_player != COMPUTER: return False if stm == WHITE and white_player != COMPUTER: return False # kick off computer move self.game.comp_move() return False
def load_game_psn_from_str(self, gamestr): cnt = 0 comment_active = False movelist = [] redolist = [] startpos = 'startpos' engine.command('new') stm = BLACK movecnt = 0 self.gamestr = gamestr self.game_len = len(self.gamestr) self.comments.clear_comments() # First header should be near the start of the file # Note the first chars in the file may be a BOM entry and # we need to skip these ptr = 0 # Find '[' of first header while 1: if ptr >= self.game_len or ptr > 2000: self.gui.info_box("Error (1) loading file. No headers found") self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 if gamestr[ptr] == '[': break ptr += 1 # First Header found (ptr pointing at '[') hdr, newptr = self.get_header(ptr) if hdr is None: self.gui.info_box("Error (2) loading file. No headers found") self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 # Read remaining headers while hdr is not None: ptr = newptr try: prop, value = hdr.split(None, 1) except ValueError: # Error - cannot split header into a property/value pair self.gui.info_box("Error loading file. Invalid header:" + hdr) self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 if prop == 'SFEN': # set board position, side to move startpos, stm = self.process_sfen(value) elif prop == "Handicap": handicap = value.strip('"') handicap = handicap.lower() sfen = '' if handicap == 'lance': sfen = 'lnsgkgsn1/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'bishop': sfen = 'lnsgkgsnl/1r7/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'rook': sfen = 'lnsgkgsnl/7b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'rook+lance': sfen = 'lnsgkgsn1/7b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'rook+bishop': sfen = 'lnsgkgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'four piece': sfen = '1nsgkgsn1/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'six piece': sfen = '2sgkgs2/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'eight piece': sfen = '3gkg3/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' elif handicap == 'ten piece': sfen = '4k4/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1' if sfen != '': startpos, stm = self.process_sfen(sfen) hdr, newptr = self.get_header(ptr) # Moves while 1: if self.verbose: print print "Processing move number (ply):" + str(movecnt + 1) newptr = self.skip_whitespace(ptr) if newptr is None: break ptr = newptr # if we get a header here then it must be a multi-game file # We cannot process multi-game so treat it as eof and exit if gamestr[ptr] == '[': break # Check for stuff to ignore # ignore it and continue processing ignore_string, newptr = self.get_ignore_string(ptr) if ignore_string is not None: # Can get '1....' to indicate white to move first #if ignore_string == '1....' and movecnt == 0: # # Use sfen for initial position but set stm to white # startpos, stm = self.process_sfen("lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w - 1") ptr = newptr continue # comment if self.gamestr[ptr] == '{': comment = '' ptr += 1 while 1: if ptr >= self.game_len: self.gui.info_box("Error unterminated comment") self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 # end of file before end of comment if self.gamestr[ptr] == '}': ptr += 1 break comment += self.gamestr[ptr] ptr += 1 # add comment self.comments.set_comment(movecnt, comment) continue # move number # we do not use it moveno, newptr = self.get_moveno(ptr) if moveno is not None: ptr = newptr continue # move move, newptr = self.get_move(ptr, movelist, stm) if move is not None: ptr = newptr engine.setplayer(stm) stm = stm ^ 1 if self.verbose: print "move=",move validmove = engine.hmove(move) if (not validmove): # Should never get this message since get_move has already # validated the move aginst the legal move list # Can get it for sennichite (repetition) self.gui.info_box("Error loading file, illegal move (possible sennichite (repetition)):" + move + " move number:" + str(movecnt + 1)) self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 movecnt += 1 movelist.append(move) if self.verbose: engine.command('bd') continue # Invalid - Display Error # If we get here we have an invalid word # Errors here will stop the processing and prevent the file loading # If the invalid word should be skipped instead then add it to the # ignore processing above word, newptr = self.get_word(ptr) if word is not None: self.gui.info_box("Error loading file, unable to process move number " + str(movecnt + 1) + ". (illegal move or invalid format):" + word) # Load failed part way through so reset the game self.game.new_game('NewGame') self.gui.set_status_bar_msg("Error loading game") return 1 ptr +=1 self.usib.set_newgame() self.usiw.set_newgame() self.gui.set_status_bar_msg("game loaded") self.gameover = False self.game.set_movelist(movelist) self.game.set_redolist(redolist) self.game.set_startpos(startpos) self.board.update() # update move list in move list window self.move_list.update() stm = self.game.get_side_to_move() self.game.set_side_to_move(stm) self.gui.set_side_to_move(stm) self.gui.unhilite_squares() self.tc.reset_clock() return 0