def process_console_command(self, raw): cmd = raw.lower() try: # Here starts the simulation of a dgt-board! # Let the user send events like the board would do if cmd.startswith('fen:'): fen = raw.split(':')[1].strip() # dgt board only sends the basic fen => be sure it's same no matter what fen the user entered fen = fen.split(' ')[0] bit_board = chess.Board() # valid the fen bit_board.set_board_fen(fen) EvtObserver.fire(Event.KEYBOARD_FEN(fen=fen)) # end simulation code elif cmd.startswith('go'): if 'last_dgt_move_msg' in self.shared: fen = self.shared['last_dgt_move_msg']['fen'].split(' ')[0] EvtObserver.fire(Event.KEYBOARD_FEN(fen=fen)) # TEST webserver with 2 clocks (web & i2c) - doesnt work anymore with normal dgt board! elif cmd.startswith('but:'): button = raw.split(':')[1].strip() MsgDisplay.show(Message.DGT_BUTTON(button=button, dev='i2c')) else: # Event.KEYBOARD_MOVE tranfers "move" to "fen" and then continues with "Message.DGT_FEN" move = chess.Move.from_uci(cmd) EvtObserver.fire(Event.KEYBOARD_MOVE(move=move)) except (ValueError, IndexError): logging.warning('Invalid user input [%s]', raw)
def post(self): action = self.get_argument('action') if action == 'broadcast': fen = self.get_argument('fen') pgn_str = self.get_argument('pgn') result = { 'event': 'Broadcast', 'msg': 'Position from Spectators!', 'pgn': pgn_str, 'fen': fen } EventHandler.write_to_clients(result) elif action == 'move': move = chess.Move.from_uci( self.get_argument('source') + self.get_argument('target')) Observable.fire( Event.REMOTE_MOVE(move=move, fen=self.get_argument('fen'))) elif action == 'clockbutton': Observable.fire( Event.KEYBOARD_BUTTON(button=self.get_argument('button'), dev='web')) elif action == 'room': inside = self.get_argument('room') == 'inside' Observable.fire(Event.REMOTE_ROOM(inside=inside)) elif action == 'command': self.process_console_command(self.get_argument('command'))
def _process_button4(self, dev): logging.debug('(%s) clock handle button 4 press', dev) if self._inside_updt_menu(): tag = self.dgtmenu.updt_down(dev) Observable.fire(Event.UPDATE_PICO(tag=tag)) else: text = self.dgtmenu.main_down() # button4 can exit the menu, so check if text: DispatchDgt.fire(text) else: Observable.fire(Event.EXIT_MENU())
def callback3(self, command): """Callback function.""" try: self.res = command.result() except chess.uci.EngineTerminatedException: logging.error('Engine terminated') # @todo find out, why this can happen! self.show_best = False logging.info('res: %s', self.res) Observable.fire(Event.STOP_SEARCH()) if self.show_best and self.res: Observable.fire(Event.BEST_MOVE(move=self.res.bestmove, ponder=self.res.ponder, inbook=False)) else: logging.info('event best_move not fired')
def _process_lever(self, right_side_down, dev): logging.debug('(%s) clock handle lever press - right_side_down: %s', dev, right_side_down) if not self._inside_main_menu(): self.play_move = chess.Move.null() self.play_fen = None self.play_turn = None Observable.fire(Event.SWITCH_SIDES())
def ponder(self): """Ponder engine.""" self.show_best = False Observable.fire(Event.START_SEARCH()) self.future = self.engine.go(ponder=True, infinite=True, async_callback=self.callback) return self.future
def on_go(self): """Engine sends GO.""" self.allow_score = True self.allow_pv = True self.allow_depth = True EvtObserver.fire(Event.START_SEARCH()) super().on_go()
def go(self, time_dict: dict): """Go engine.""" self.show_best = True time_dict['async_callback'] = self.callback Observable.fire(Event.START_SEARCH()) self.future = self.engine.go(**time_dict) return self.future
def brain(self, time_dict: dict): """Permanent brain.""" self.show_best = True time_dict['ponder'] = True time_dict['async_callback'] = self.callback3 Observable.fire(Event.START_SEARCH()) self.future = self.engine.go(**time_dict) return self.future
def _flag_time(self, time_start): """Fire a CLOCK_FLAG event.""" self.run_color = None if self.mode == TimeMode.FIXED: logging.debug('timeout - but in "MoveTime" mode, dont fire event') elif self.active_color is not None: display_color = 'WHITE' if self.active_color == chess.WHITE else 'BLACK' txt = 'current clock time (before subtracting) is %f and color is %s, out of time event started from %f' logging.debug(txt, self.internal_time[self.active_color], display_color, time_start) EvtObserver.fire(Event.CLOCK_FLAG(color=self.active_color))
def _process_button2(self, dev): logging.debug('(%s) clock handle button 2 press', dev) if self._inside_main_menu() or self.dgtmenu.inside_picochess_time(dev): text = self.dgtmenu.main_middle(dev) # button2 can exit the menu (if in "position"), so check if text: DispatchDgt.fire(text) else: Observable.fire(Event.EXIT_MENU()) else: if self.dgtmenu.get_mode() in (Mode.ANALYSIS, Mode.KIBITZ, Mode.PONDER): DispatchDgt.fire(self.dgttranslate.text('B00_nofunction')) else: if self.play_move: self.play_move = chess.Move.null() self.play_fen = None self.play_turn = None Observable.fire(Event.ALTERNATIVE_MOVE()) else: Observable.fire(Event.PAUSE_RESUME())
def _process_button4(self, dev: str): logging.debug('(%s) clock handle button 4 press', dev) if self._inside_updt_menu(dev): text = self.dgtmenu.updt_down( dev) # button4 can exit the menu, so check else: text = self.dgtmenu.main_down( dev) # button4 can exit the menu, so check if text: DgtObserver.fire(text) else: EvtObserver.fire(Event.EXIT_MENU(dev=dev))
def _process_lever(self, right_side_down, dev): logging.debug('(%s) clock handle lever press - right_side_down: %s', dev, right_side_down) self.c_time_counter = 0 ##molli if self.c_last_player == 'C' or self.c_last_player == '': ##molli self.c_last_player = 'U' else: self.c_last_player = 'C' if not self._inside_main_menu(): self.play_move = chess.Move.null() self.play_fen = None self.play_turn = None Observable.fire(Event.SWITCH_SIDES())
def run(self): global keyboard_last_fen logging.info('msg_queue terminaldisplay ready') while True: # Check if we have something to display try: message = self.msg_queue.get() if not isinstance(message, Message.DGT_SERIAL_NR): logging.debug('received message from msg_queue: %s', message) #print(message) if isinstance(message, Message.COMPUTER_MOVE): game_copy = message.game.copy() game_copy.push(message.move) keyboard_last_fen = game_copy.fen().split(' ')[0] Observable.fire(Event.KEYBOARD_FEN(fen=keyboard_last_fen)) mov = message.move.uci() elif isinstance(message, Message.CLOCK_TIME): time_u = message.time_white time_c = message.time_black l_hms = hms_time(time_u) r_hms = hms_time(time_c) text_l = '{}:{:02d}.{:02d}'.format(l_hms[0], l_hms[1], l_hms[2]) text_r = '{}:{:02d}.{:02d}'.format(r_hms[0], r_hms[1], r_hms[2]) print('Clock time: {} - {}'.format(text_l,text_r)) elif isinstance(message, Message.ENGINE_STARTUP): print(message.level_index) elif isinstance(message, Message.ENGINE_READY): print(message.engine_name) elif isinstance(message, Message.SYSTEM_INFO): engine_name = message.info['engine_name'] self.user_name = message.info['user_name'] self.user_elo = message.info['user_elo'] print(engine_name) elif isinstance(message, Message.STARTUP_INFO): self.level_text = message.info['level_text'] self.level_name = message.info['level_name'] timetexta = message.info['time_text'] timetext = timetexta.m print(timetext) elif isinstance(message, Message.LEVEL): print(message.level_text.m) elif isinstance(message, Message.DISPLAY_TEXT): print(message.text) except queue.Empty: pass
def process_console_command(self, raw): cmd = raw.lower() try: # Here starts the simulation of a dgt-board! # Let the user send events like the board would do if cmd.startswith('fen:'): fen = raw.split(':')[1].strip() # dgt board only sends the basic fen => be sure it's same no matter what fen the user entered fen = fen.split(' ')[0] bit_board = chess.Board() # valid the fen bit_board.set_board_fen(fen) Observable.fire(Event.KEYBOARD_FEN(fen=fen)) # end simulation code elif cmd.startswith('go'): if 'last_dgt_move_msg' in self.shared: fen = self.shared['last_dgt_move_msg']['fen'].split(' ')[0] Observable.fire(Event.KEYBOARD_FEN(fen=fen)) else: # Event.KEYBOARD_MOVE tranfers "move" to "fen" and then continues with "Message.DGT_FEN" move = chess.Move.from_uci(cmd) Observable.fire(Event.KEYBOARD_MOVE(move=move)) except (ValueError, IndexError): logging.warning('Invalid user input [%s]', raw)
def _power_off(self, dev='web'): DgtObserver.fire(self.dgttranslate.text('Y15_goodbye')) self.dgtmenu.set_engine_restart(True) EvtObserver.fire(Event.SYSTEM_SHUTDOWN(dev=dev))
def _process_fen(self, fen: str, raw: bool): level_map = ('rnbqkbnr/pppppppp/8/q7/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/1q6/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/2q5/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/3q4/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/4q3/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/5q2/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/6q1/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/7q/8/8/PPPPPPPP/RNBQKBNR') book_map = ('rnbqkbnr/pppppppp/8/8/8/q7/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/1q6/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/2q5/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/3q4/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/4q3/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/5q2/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/6q1/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/8/7q/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/q7/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/1q6/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/2q5/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/3q4/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/4q3/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/5q2/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/6q1/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/8/8/7q/8/PPPPPPPP/RNBQKBNR') engine_map = ('rnbqkbnr/pppppppp/q7/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/1q6/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/2q5/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/3q4/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/4q3/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/5q2/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/6q1/8/8/8/PPPPPPPP/RNBQKBNR', 'rnbqkbnr/pppppppp/7q/8/8/8/PPPPPPPP/RNBQKBNR') shutdown_map = ('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQQBNR', 'RNBQQBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbkqbnr', '8/8/8/8/8/8/8/3QQ3', '3QQ3/8/8/8/8/8/8/8') reboot_map = ('rnbqqbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', 'RNBKQBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbqqbnr', '8/8/8/8/8/8/8/3qq3', '3qq3/8/8/8/8/8/8/8') mode_map = { 'rnbqkbnr/pppppppp/8/Q7/8/8/PPPPPPPP/RNBQKBNR': Mode.NORMAL, 'rnbqkbnr/pppppppp/8/1Q6/8/8/PPPPPPPP/RNBQKBNR': Mode.BRAIN, 'rnbqkbnr/pppppppp/8/2Q5/8/8/PPPPPPPP/RNBQKBNR': Mode.ANALYSIS, 'rnbqkbnr/pppppppp/8/3Q4/8/8/PPPPPPPP/RNBQKBNR': Mode.KIBITZ, 'rnbqkbnr/pppppppp/8/4Q3/8/8/PPPPPPPP/RNBQKBNR': Mode.OBSERVE, 'rnbqkbnr/pppppppp/8/5Q2/8/8/PPPPPPPP/RNBQKBNR': Mode.PONDER, 'rnbqkbnr/pppppppp/8/7Q/8/8/PPPPPPPP/RNBQKBNR': Mode.REMOTE } drawresign_map = { '8/8/8/3k4/4K3/8/8/8': GameResult.WIN_WHITE, '8/8/8/3K4/4k3/8/8/8': GameResult.WIN_WHITE, '8/8/8/4k3/3K4/8/8/8': GameResult.WIN_BLACK, '8/8/8/4K3/3k4/8/8/8': GameResult.WIN_BLACK, '8/8/8/3kK3/8/8/8/8': GameResult.DRAW, '8/8/8/3Kk3/8/8/8/8': GameResult.DRAW, '8/8/8/8/3kK3/8/8/8': GameResult.DRAW, '8/8/8/8/3Kk3/8/8/8': GameResult.DRAW } bit_board = chess.Board( fen + ' w - - 0 1' ) # try a standard board and check for any starting pos if bit_board.chess960_pos(ignore_castling=True): logging.debug('flipping the board - W infront') self.dgtmenu.set_position_reverse_flipboard(False) bit_board = chess.Board( fen[::-1] + ' w - - 0 1') # try a revered board and check for any starting pos if bit_board.chess960_pos(ignore_castling=True): logging.debug('flipping the board - B infront') self.dgtmenu.set_position_reverse_flipboard(True) if self.dgtmenu.get_flip_board() and raw: # Flip the board if needed fen = fen[::-1] logging.debug('DGT-Fen [%s]', fen) if fen == self.dgtmenu.get_dgt_fen(): logging.debug('ignore same fen') return self.dgtmenu.set_dgt_fen(fen) _, _, _, rnk_5, rnk_4, _, _, _ = fen.split('/') self.drawresign_fen = '8/8/8/' + rnk_5 + '/' + rnk_4 + '/8/8/8' # Fire the appropriate event if fen in level_map: eng = self.dgtmenu.get_engine() level_dict = eng['level_dict'] if level_dict: inc = len(level_dict) / 7 level = min(floor(inc * level_map.index(fen)), len(level_dict) - 1) # type: int self.dgtmenu.set_engine_level(level) msg = sorted(level_dict)[level] text = self.dgttranslate.text('M10_level', msg) text.wait = self._exit_menu() logging.debug('map: New level %s', msg) if not self.dgtmenu.remote_engine: write_picochess_ini('engine-level', msg) EvtObserver.fire( Event.NEW_LEVEL(options=level_dict[msg], level_text=text, level_name=msg)) else: logging.debug('engine doesnt support levels') elif fen in book_map: book_index = book_map.index(fen) try: book = self.dgtmenu.all_books[book_index] self.dgtmenu.set_book(book_index) logging.debug('map: Opening book [%s]', book['file']) text = book['text'] text.beep = self.dgttranslate.bl(BeepLevel.MAP) text.maxtime = 1 text.wait = self._exit_menu() EvtObserver.fire( Event.NEW_BOOK(book=book, book_text=text, show_ok=False)) except IndexError: pass elif fen in engine_map: if self.dgtmenu.installed_engines: try: self.dgtmenu.set_engine_index(engine_map.index(fen)) eng = self.dgtmenu.get_engine() level_dict = eng['level_dict'] logging.debug('map: Engine name [%s]', eng['name']) eng_text = eng['text'] eng_text.beep = self.dgttranslate.bl(BeepLevel.MAP) eng_text.maxtime = 1 eng_text.wait = self._exit_menu() if level_dict: len_level = len(level_dict) if self.dgtmenu.get_engine_level( ) is None or len_level <= self.dgtmenu.get_engine_level( ): self.dgtmenu.set_engine_level(len_level - 1) msg = sorted(level_dict)[ self.dgtmenu.get_engine_level()] options = level_dict[ msg] # cause of "new-engine", send options lateron - now only {} EvtObserver.fire( Event.NEW_LEVEL(options={}, level_text=self.dgttranslate.text( 'M10_level', msg), level_name=msg)) else: msg = None options = {} if not self.dgtmenu.remote_engine: write_picochess_ini('engine-level', msg) EvtObserver.fire( Event.NEW_ENGINE(eng=eng, eng_text=eng_text, options=options, show_ok=False)) self.dgtmenu.set_engine_restart(True) except IndexError: pass else: DgtObserver.fire(self.dgttranslate.text('Y10_erroreng')) elif fen in mode_map: logging.debug('map: Interaction mode [%s]', mode_map[fen]) if mode_map[fen] == Mode.REMOTE and not self.dgtmenu.inside_room: DgtObserver.fire(self.dgttranslate.text('Y10_errorroom')) elif mode_map[ fen] == Mode.BRAIN and not self.dgtmenu.get_engine_has_ponder( ): DgtObserver.fire(self.dgttranslate.text('Y10_erroreng')) else: self.dgtmenu.set_mode(mode_map[fen]) text = self.dgttranslate.text(mode_map[fen].value) text.beep = self.dgttranslate.bl(BeepLevel.MAP) text.maxtime = 1 # wait 1sec not forever text.wait = self._exit_menu() EvtObserver.fire( Event.INTERACTION_MODE(mode=mode_map[fen], mode_text=text, show_ok=False)) elif fen in self.dgtmenu.tc_fixed_map: logging.debug('map: Time control fixed') self.dgtmenu.set_time_mode(TimeMode.FIXED) self.dgtmenu.set_time_fixed( list(self.dgtmenu.tc_fixed_map.keys()).index(fen)) text = self.dgttranslate.text( 'M10_tc_fixed', self.dgtmenu.tc_fixed_list[self.dgtmenu.get_time_fixed()]) text.wait = self._exit_menu() timectrl = self.dgtmenu.tc_fixed_map[fen] # type: TimeControl EvtObserver.fire( Event.TIME_CONTROL(tc_init=timectrl.get_parameters(), time_text=text, show_ok=False)) elif fen in self.dgtmenu.tc_blitz_map: logging.debug('map: Time control blitz') self.dgtmenu.set_time_mode(TimeMode.BLITZ) self.dgtmenu.set_time_blitz( list(self.dgtmenu.tc_blitz_map.keys()).index(fen)) text = self.dgttranslate.text( 'M10_tc_blitz', self.dgtmenu.tc_blitz_list[self.dgtmenu.get_time_blitz()]) text.wait = self._exit_menu() timectrl = self.dgtmenu.tc_blitz_map[fen] # type: TimeControl EvtObserver.fire( Event.TIME_CONTROL(tc_init=timectrl.get_parameters(), time_text=text, show_ok=False)) elif fen in self.dgtmenu.tc_fisch_map: logging.debug('map: Time control fischer') self.dgtmenu.set_time_mode(TimeMode.FISCHER) self.dgtmenu.set_time_fisch( list(self.dgtmenu.tc_fisch_map.keys()).index(fen)) text = self.dgttranslate.text( 'M10_tc_fisch', self.dgtmenu.tc_fisch_list[self.dgtmenu.get_time_fisch()]) text.wait = self._exit_menu() timectrl = self.dgtmenu.tc_fisch_map[fen] # type: TimeControl EvtObserver.fire( Event.TIME_CONTROL(tc_init=timectrl.get_parameters(), time_text=text, show_ok=False)) elif fen in shutdown_map: logging.debug('map: shutdown') self._power_off() elif fen in reboot_map: logging.debug('map: reboot') self._reboot() elif self.drawresign_fen in drawresign_map: logging.debug('map: drawresign') EvtObserver.fire( Event.DRAW_RESIGN(result=drawresign_map[self.drawresign_fen])) else: bit_board = chess.Board(fen + ' w - - 0 1') pos960 = bit_board.chess960_pos(ignore_castling=True) if pos960 is not None: if pos960 == 518 or self.dgtmenu.get_engine_has_960(): logging.debug('map: New game') EvtObserver.fire(Event.NEW_GAME(pos960=pos960)) else: # self._reset_moves_and_score() DgtObserver.fire(self.dgttranslate.text('Y10_error960')) else: EvtObserver.fire(Event.NEW_FEN(fen=fen))
def _reboot(self, dev='web'): DispatchDgt.fire(self.dgttranslate.text('Y15_pleasewait')) self.dgtmenu.set_engine_restart(True) self.c_last_player = '' ##molli self.c_time_counter = 0 ##molli Observable.fire(Event.REBOOT(dev=dev))
def _power_off(self, dev='web'): DispatchDgt.fire(self.dgttranslate.text('Y15_goodbye')) self.dgtmenu.set_engine_restart(True) Observable.fire(Event.SHUTDOWN(dev=dev))
def on_bestmove(self, bestmove, ponder): EvtObserver.fire(Event.STOP_SEARCH()) super().on_bestmove(bestmove, ponder)
def _reboot(self, dev='web'): DgtObserver.fire(self.dgttranslate.text('Y15_pleasewait')) self.dgtmenu.set_engine_restart(True) EvtObserver.fire(Event.SYSTEM_REBOOT(dev=dev))
def score(self, cp, mate, lowerbound, upperbound): """Engine sends SCORE.""" if self._allow_fire_score(): EvtObserver.fire(Event.NEW_SCORE(score=cp, mate=mate)) super().score(cp, mate, lowerbound, upperbound)
def run(self): logging.info('evt_queue ready') print('#' * 42 + ' PicoChess v' + version + ' ' + '#' * 42) print('To play a move enter the from-to squares like "e2e4". To play this move on board, enter "go".') print('When the computer displays its move, also type "go" to actually do it on the board (see above).') print('Other commands are:') print('newgame:<w|b>, print:<fen>, setup:<fen>, fen:<fen>, button:<0-5>, lever:<l|r>, plug:<in|off>') print('') print('This console mode is mainly for development. Better activate picochess together with a DGT-Board ;-)') print('#' * 100) print('') while True: raw = input('PicoChess v'+version+':>').strip() if not raw: continue cmd = raw.lower() try: if cmd.startswith('print:'): fen = raw.split(':')[1] print(chess.Board(fen)) else: if not self.board_plugged_in and not cmd.startswith('plug:'): print('The command isnt accepted cause the virtual board is not plugged in') continue if cmd.startswith('newgame:'): side = cmd.split(':')[1] if side == 'w': self.flip_board = False self.fire(Event.DGT_FEN(fen='rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')) elif side == 'b': self.flip_board = True self.fire(Event.DGT_FEN(fen='RNBKQBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbkqbnr')) else: raise ValueError(side) elif cmd.startswith('setup:'): fen = raw.split(':')[1] uci960 = False # make it easy for the moment bit_board = chess.Board(fen, uci960) if bit_board.is_valid(): self.fire(Event.SETUP_POSITION(fen=bit_board.fen(), uci960=uci960)) else: raise ValueError(fen) # Here starts the simulation of a dgt-board! # Let the user send events like the board would do elif cmd.startswith('fen:'): fen = raw.split(':')[1] # dgt board only sends the basic fen => be sure # it's same no matter what fen the user entered self.fire(Event.DGT_FEN(fen=fen.split(' ')[0])) elif cmd.startswith('button:'): button = int(cmd.split(':')[1]) if button not in range(6): raise ValueError(button) if button == 5: # make it to power button button = 0x11 self.fire(Event.KEYBOARD_BUTTON(button=button, dev = 'ser')) elif cmd.startswith('lever:'): lever = cmd.split(':')[1] if lever not in ('l', 'r'): raise ValueError(lever) button = 0x40 if lever == 'r' else -0x40 self.fire(Event.KEYBOARD_BUTTON(button=button, dev = 'ser')) elif cmd.startswith('plug:'): plug = cmd.split(':')[1] if plug not in ('in', 'off'): raise ValueError(plug) if plug == 'in': self.board_plugged_in = True self.rt.stop() text_l, text_m, text_s = 'VirtBoard ', 'V-Board ', 'VBoard' text = Dgt.DISPLAY_TEXT(l=text_l, m=text_m, s=text_s, wait=True, beep=False, maxtime=1) DisplayMsg.show(Message.EBOARD_VERSION(text=text, channel='console')) if plug == 'off': self.board_plugged_in = False self.rt.start() elif cmd.startswith('go'): if keyboard_last_fen is not None: self.fire(Event.KEYBOARD_FEN(fen=keyboard_last_fen)) else: print('last move already send to virtual board') elif cmd.startswith('shutdown'): self.fire(Event.SHUTDOWN()) # end simulation code else: # move => fen => virtual board sends fen move = chess.Move.from_uci(cmd) self.fire(Event.KEYBOARD_MOVE(move=move)) except ValueError as e: logging.warning('Invalid user input [%s]', raw)
def depth(self, dep): """Engine sends DEPTH.""" if self._allow_fire_depth(): EvtObserver.fire(Event.NEW_DEPTH(depth=dep)) super().depth(dep)
def pv(self, moves): """Call when engine sends PV.""" if self._allow_fire_pv() and moves: EvtObserver.fire(Event.NEW_PV(pv=moves)) super().pv(moves)
def _process_message(self, message): if False: # switch-case pass elif isinstance(message, Message.ENGINE_READY): self._process_engine_ready(message) elif isinstance(message, Message.ENGINE_STARTUP): self._process_engine_startup(message) elif isinstance(message, Message.ENGINE_FAIL): DgtObserver.fire(self.dgttranslate.text('Y10_erroreng')) self.dgtmenu.set_engine_restart(False) elif isinstance(message, Message.COMPUTER_MOVE): self._process_computer_move(message) elif isinstance(message, Message.NEW_GAME): self._process_new_game(message) elif isinstance(message, Message.COMPUTER_MOVE_DONE): self._process_computer_move_done() elif isinstance(message, Message.USER_MOVE_DONE): self._process_user_move_done(message) elif isinstance(message, Message.REVIEW_MOVE_DONE): self._process_review_move_done(message) elif isinstance(message, Message.ALTERNATIVE_MOVE): self.force_leds_off() self.play_mode = message.play_mode DgtObserver.fire(self.dgttranslate.text('B05_altmove')) elif isinstance(message, Message.NEW_LEVEL): if not self.dgtmenu.get_engine_restart(): DgtObserver.fire(message.level_text) elif isinstance(message, Message.TIME_CONTROL): self._process_time_control(message) elif isinstance(message, Message.NEW_BOOK): if not self.dgtmenu.get_confirm() or not message.show_ok: DgtObserver.fire(message.book_text) elif isinstance(message, Message.TAKE_BACK): self.force_leds_off() self._reset_moves_and_score() DgtObserver.fire(self.dgttranslate.text('C10_takeback')) DgtObserver.fire( Dgt.DISPLAY_TIME(force=True, wait=True, devs={'ser', 'i2c', 'web'})) elif isinstance(message, Message.GAME_ENDS): if not self.dgtmenu.get_engine_restart( ): # filter out the shutdown/reboot process text = self.dgttranslate.text(message.result.value) text.beep = self.dgttranslate.bl(BeepLevel.CONFIG) text.maxtime = 0.5 DgtObserver.fire(text) if self.dgtmenu.get_mode() == Mode.PONDER: self._reset_moves_and_score() text.beep = False text.maxtime = 1 self.score = text elif isinstance(message, Message.INTERACTION_MODE): if not self.dgtmenu.get_confirm() or not message.show_ok: DgtObserver.fire(message.mode_text) elif isinstance(message, Message.PLAY_MODE): self.play_mode = message.play_mode DgtObserver.fire(message.play_mode_text) elif isinstance(message, Message.NEW_SCORE): self._process_new_score(message) elif isinstance(message, Message.BOOK_MOVE): self.score = self.dgttranslate.text('N10_score', None) DgtObserver.fire(self.dgttranslate.text('N10_bookmove')) elif isinstance(message, Message.NEW_PV): self._process_new_pv(message) elif isinstance(message, Message.NEW_DEPTH): self.depth = message.depth elif isinstance(message, Message.IP_INFO): self.dgtmenu.int_ip = message.info['int_ip'] self.dgtmenu.ext_ip = message.info['ext_ip'] elif isinstance(message, Message.STARTUP_INFO): self._process_startup_info(message) elif isinstance(message, Message.SEARCH_STARTED): logging.debug('search started') elif isinstance(message, Message.SEARCH_STOPPED): logging.debug('search stopped') elif isinstance(message, Message.CLOCK_START): self._process_clock_start(message) elif isinstance(message, Message.CLOCK_STOP): DgtObserver.fire(Dgt.CLOCK_STOP(devs=message.devs, wait=True)) elif isinstance(message, Message.DGT_BUTTON): self._process_button(message) elif isinstance(message, Message.DGT_FEN): if self.dgtmenu.inside_updt_menu(): logging.debug('inside update menu => ignore fen %s', message.fen) else: self._process_fen(message.fen, message.raw) elif isinstance(message, Message.DGT_CLOCK_VERSION): DgtObserver.fire( Dgt.CLOCK_VERSION(main=message.main, sub=message.sub, devs={message.dev})) text = self.dgttranslate.text('Y21_picochess', devs={message.dev}) text.rd = ClockIcons.DOT DgtObserver.fire(text) if message.dev == 'ser': # send the "board connected message" to serial clock DgtObserver.fire(message.text) self._set_clock(devs={message.dev}) self._exit_display(devs={message.dev}) elif isinstance(message, Message.DGT_CLOCK_TIME): time_white = message.time_left time_black = message.time_right if self.dgtmenu.get_flip_board(): time_white, time_black = time_black, time_white EvtObserver.fire( Event.CLOCK_TIME(time_white=time_white, time_black=time_black, connect=message.connect, dev=message.dev)) elif isinstance(message, Message.CLOCK_TIME): self.low_time = message.low_time if self.low_time: logging.debug('time too low, disable confirm - w: %i, b: %i', message.time_white, message.time_black) elif isinstance(message, Message.DGT_SERIAL_NR): self._process_dgt_serial_nr() elif isinstance(message, Message.DGT_JACK_ERROR ): # only working in case of 2 clocks connected! DgtObserver.fire(self.dgttranslate.text('Y00_errorjack')) elif isinstance(message, Message.DGT_EBOARD_VERSION): if self.dgtmenu.inside_updt_menu(): logging.debug( 'inside update menu => board channel not displayed') else: DgtObserver.fire(message.text) self._exit_display(devs={'i2c', 'web' }) # ser is done, when clock found elif isinstance(message, Message.DGT_EBOARD_ERROR): if self.dgtmenu.inside_updt_menu( ) or self.dgtmenu.inside_main_menu(): logging.debug('inside menu => board error not displayed') else: DgtObserver.fire(message.text) elif isinstance(message, Message.DGT_CLOCK_ERROR): pass elif isinstance(message, Message.SWITCH_SIDES): self.play_move = chess.Move.null() self.play_fen = None self.play_turn = None self.hint_move = chess.Move.null() self.hint_fen = None self.hint_turn = None self.force_leds_off() logging.debug('user ignored move %s', message.move) elif isinstance(message, Message.EXIT_MENU): self._exit_display(devs={message.dev}) elif isinstance(message, Message.WRONG_FEN): DgtObserver.fire(self.dgttranslate.text('C10_setpieces')) elif isinstance(message, Message.BATTERY_BT): if message.percent == 0x7f: percent = ' NA' elif message.percent > 99: percent = ' 99' else: percent = str(message.percent) self.dgtmenu.battery = percent elif isinstance(message, Message.REMOTE_ROOM): self.dgtmenu.inside_room = message.inside else: # Default pass
def _reboot(self, dev='web'): DispatchDgt.fire(self.dgttranslate.text('Y15_pleasewait')) self.dgtmenu.set_engine_restart(True) Observable.fire(Event.REBOOT(dev=dev))