Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    def init_game(self, sfen):
        engine.setfen(sfen)
        startpos = sfen
        sfenlst = sfen.split()
        if sfenlst[1] == "b":
            if gv.verbose:
                print "setting stm to black"
            stm = BLACK
        elif sfenlst[1] == "w":
            stm = WHITE
        else:
            stm = BLACK
        engine.setplayer(stm)

        gv.usib.set_newgame()
        gv.usiw.set_newgame()
        gv.gui.set_status_bar_msg("ready")
        self.gameover = False

        gv.gshogi.set_movelist([])
        gv.gshogi.set_redolist([])
        gv.gshogi.set_startpos(startpos)

        gv.board.update()

        # update move list in move list window
        self.move_list.update()

        stm = gv.gshogi.get_side_to_move()
        gv.gshogi.set_side_to_move(stm)
        gv.gui.set_side_to_move(stm)
        gv.gui.unhilite_squares()

        gv.tc.reset_clock()
Esempio n. 4
0
 def process_sfen(self, sfen):
     sfen = sfen.strip('"')
     engine.setfen(sfen)
     startpos = sfen
     sfenlst = sfen.split()
     if sfenlst[1] == 'b':
         stm = BLACK
     elif sfenlst[1] == 'w':
         stm = WHITE
     else:
         stm = BLACK
     engine.setplayer(stm)
     return startpos, stm
Esempio n. 5
0
 def process_sfen(self, sfen):
     sfen = sfen.strip('"')        
     engine.setfen(sfen)
     startpos = sfen
     sfenlst = sfen.split()                    
     if sfenlst[1] == 'b':           
         stm = BLACK                                
     elif sfenlst[1] == 'w':
         stm = WHITE
     else:
         stm = BLACK                    
     engine.setplayer(stm)
     return startpos, stm
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
Esempio n. 9
0
    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
Esempio n. 10
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
Esempio n. 11
0
    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
Esempio n. 12
0
    def get_move(self, ptr, movelist, stm):

        # get next word in file
        word, newptr = self.get_word(ptr)
        if word is None:
            return None, None

        move = word

        if self.verbose:
            print
            print "In get_move in psn.py"
            print "get_move has been passed this possible move:", move

        # Parse move and return its component parts
        promoted_piece, piece, source_square, dest_square, move_promotes, move_equals, move_type = self.parse_move(
            move, movelist)
        if piece is None:
            if self.verbose:
                print "Unable to parse move:", move
            return None, None

        # Get list of legal moves
        engine.setplayer(stm)
        legal_move_list = self.get_legal_move_list(piece)
        if self.verbose:
            print "legal_move_list=", legal_move_list

        # Create move by concat of component parts
        if self.validate_square(source_square) and self.validate_square(
                dest_square):
            move = source_square + dest_square + move_promotes
        else:
            move = promoted_piece + piece + source_square + dest_square + move_promotes

        # Search for move in the legal move list
        move2 = self.search_legal_moves(move, legal_move_list)
        if move2 is not None:
            # Move Found
            # The move returned by the search is in the source+dest format suitable for gshogi
            # e.g. S7b -> 7a7b
            if self.verbose:
                print "Search succeeded and returned move:", move2
            return move2, newptr  # found a valid move

        # Search failed
        if self.verbose:
            print "Search did not find move"

        # try a drop
        if move_type == 1 and len(move) == 3:
            rmove = move[0] + '*' + move[1:]
            if self.verbose:
                print "trying a drop. move changed from", move, "to", rmove
            move2 = self.search_legal_moves(rmove, legal_move_list)
            if move2 is not None:
                # Move Found
                if self.verbose:
                    print "Search succeeded and returned move:", move2
            return move2, newptr  # found a valid move

        # No valid move found
        return None, None
Esempio n. 13
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
Esempio n. 14
0
    def get_move(self, ptr, movelist, stm):        

        # get next word in file
        word, newptr = self.get_word(ptr)
        if word is None:
            return None, None
        
        move = word

        if self.verbose:
            print
            print "In get_move in psn.py"            
            print "get_move has been passed this possible move:",move            

        # Parse move and return its component parts
        promoted_piece, piece, source_square, dest_square, move_promotes, move_equals, move_type = self.parse_move(move, movelist)
        if piece is None:
            if self.verbose:                
                print "Unable to parse move:",move                
            return None, None

        # Get list of legal moves
        engine.setplayer(stm)
        legal_move_list = self.get_legal_move_list(piece) 
        if self.verbose:
            print "legal_move_list=",legal_move_list

        # Create move by concat of component parts
        if self.validate_square(source_square) and self.validate_square(dest_square):
            move = source_square + dest_square + move_promotes
        else:               
            move = promoted_piece + piece + source_square + dest_square + move_promotes

        # Search for move in the legal move list        
        move2 = self.search_legal_moves(move, legal_move_list)
        if move2 is not None:  
            # Move Found
            # The move returned by the search is in the source+dest format suitable for gshogi
            # e.g. S7b -> 7a7b 
            if self.verbose:
                print "Search succeeded and returned move:",move2
            return move2, newptr  # found a valid move  

        # Search failed        
        if self.verbose:            
            print "Search did not find move"

        # try a drop
        if move_type == 1 and len(move) == 3:
            rmove = move[0] + '*' + move[1:]
            if self.verbose:
                print "trying a drop. move changed from", move, "to", rmove
            move2 = self.search_legal_moves(rmove, legal_move_list)
            if move2 is not None:  
                # Move Found                
                if self.verbose:
                    print "Search succeeded and returned move:",move2
            return move2, newptr  # found a valid move  

        # No valid move found
        return None, None
Esempio n. 15
0
    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