Skip to content

Commit 3019e02

Browse files
committed
Update python_easy_chess_gui.py
* Fix RuntimeError "main thread is not in main loop" that may appear from time to time when user selects computer opponent often. Use subprocess.popen to start the engine and get its id name. * Remove parameter bind_return_key on list box.
1 parent 041e42a commit 3019e02

1 file changed

Lines changed: 34 additions & 26 deletions

File tree

python_easy_chess_gui.py

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959

6060
APP_NAME = 'Python Easy Chess GUI'
61-
APP_VERSION = 'v0.81'
61+
APP_VERSION = 'v0.82'
6262
BOX_TITLE = '{} {}'.format(APP_NAME, APP_VERSION)
6363

6464

@@ -1020,7 +1020,7 @@ def play_game(self, engine_id_name, board):
10201020

10211021
try:
10221022
self.engine_file = v['engine_file_k'][0]
1023-
engine_id_name = self.get_engine_id_name()
1023+
self.get_engine_id_name()
10241024
self.update_engine_list()
10251025
except:
10261026
pass
@@ -1154,7 +1154,7 @@ def play_game(self, engine_id_name, board):
11541154
layout = [
11551155
[sg.T('Current Opponent: {}'.format(self.opp_eng_id_name), size=(40,1))],
11561156
[sg.Listbox(values=self.engine_list, size=(48,6),
1157-
bind_return_key = True, key='engine_file_k')],
1157+
key='engine_file_k')],
11581158
[sg.T('Threads', size=(12, 1)),
11591159
sg.Spin([t for t in range(1, 9)], initial_value=self.threads,
11601160
size=(8, 1), key='threads_k')],
@@ -1190,7 +1190,7 @@ def play_game(self, engine_id_name, board):
11901190

11911191
try:
11921192
self.engine_file = v['engine_file_k'][0]
1193-
engine_id_name = self.get_engine_id_name()
1193+
self.get_engine_id_name()
11941194
self.update_engine_list()
11951195
except:
11961196
pass
@@ -1690,24 +1690,33 @@ def save_game(self):
16901690
f.write('{}\n\n'.format(self.game))
16911691

16921692
def get_engine_id_name(self):
1693-
""" Set the engine path and return id name """
1693+
""" Set the engine path """
16941694
cur_dir = Path.cwd()
16951695
eng_path = Path(cur_dir, 'Engines', self.engine_file)
1696-
self.engine_path_and_name = eng_path
1697-
logging.info('engine path: {}'.format(eng_path))
1696+
self.engine_path_and_name = eng_path
16981697

1699-
# Exit app if we fail to load the engine
1700-
if not eng_path.is_file():
1701-
logging.info('Quit app, failed to load engine.')
1702-
sys.exit(0)
1703-
1704-
# Start the engine and get its id name for update to GUI
1705-
engine = chess.engine.SimpleEngine.popen_uci(str(self.engine_path_and_name))
1706-
self.opp_eng_id_name = engine.id['name']
1707-
engine.quit()
1698+
p = subprocess.Popen(str(eng_path), bufsize=1,
1699+
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1700+
stderr=subprocess.STDOUT, universal_newlines=True,
1701+
creationflags=subprocess.CREATE_NO_WINDOW)
17081702

1709-
return self.opp_eng_id_name
1710-
1703+
p.stdin.write('uci\n')
1704+
for eline in iter(p.stdout.readline, ''):
1705+
line = eline.strip()
1706+
if 'id name' in line:
1707+
engine_id_name = ' '.join(line.split()[2:]).strip()
1708+
if 'uciok' in line:
1709+
break
1710+
1711+
p.stdin.write('quit')
1712+
try:
1713+
p.communicate(timeout=5)
1714+
except subprocess.TimeoutExpired:
1715+
p.kill()
1716+
p.communicate()
1717+
1718+
self.opp_eng_id_name = engine_id_name
1719+
17111720
def get_engines(self):
17121721
""" Returns a list of engines located in Engines dir """
17131722
engine_list = []
@@ -1870,7 +1879,8 @@ def main_loop(self):
18701879

18711880
# Define the opponent engine to use, this is the first engine in the list
18721881
self.engine_file = self.engine_list[0]
1873-
engine_id_name = self.get_engine_id_name()
1882+
self.get_engine_id_name()
1883+
engine_id_name = self.opp_eng_id_name
18741884

18751885
self.adviser_engine = self.engine_list[0]
18761886
self.adviser_engine_path = Path('Engines', self.adviser_engine)
@@ -1913,7 +1923,7 @@ def main_loop(self):
19131923
layout = [
19141924
[sg.T('Current Opponent: {}'.format(self.opp_eng_id_name), size=(40,1))],
19151925
[sg.Listbox(values=self.engine_list, size=(48,6),
1916-
bind_return_key = True, key='engine_file_k')],
1926+
key='engine_file_k')],
19171927
[sg.T('Threads', size=(12, 1)),
19181928
sg.Spin([t for t in range(1, 9)], initial_value=self.threads,
19191929
size=(8, 1), key='threads_k')],
@@ -1949,12 +1959,10 @@ def main_loop(self):
19491959
self.threads = min(MAX_THREADS, max(MIN_THREADS, threads_value))
19501960

19511961
# In case the user did not select an engine and presses OK
1952-
try:
1953-
self.engine_file = v['engine_file_k'][0]
1954-
engine_id_name = self.get_engine_id_name()
1955-
self.update_engine_list()
1956-
except:
1957-
pass
1962+
self.engine_file = v['engine_file_k'][0]
1963+
self.get_engine_id_name()
1964+
engine_id_name = self.opp_eng_id_name
1965+
self.update_engine_list()
19581966
break
19591967

19601968
self.window.Enable()

0 commit comments

Comments
 (0)