PyQt5を使用してTic-Tac-Toe UIを作成しようとしています。三つのモードが用意されてい複数のプログラムによるクリックイベントに対して予期しない動作が発生する
- 人間対人間の
- 人間のAI 対
- AI AIのゲーム対
すべてのモードは、2つのAIが対戦(モード3のことを除いて非常に細かい作業ゲームの開始まで、各ターンの中間ステップをリフレッシュするのではなく、UIがロードして最終結果を表示するようになりました。どうすれば達成できますか?ありがとうございました!以下は
私のコードです:
class TicTacToeUI(QtWidgets.QWidget):
icons = ['icons/x-mark.png', 'icons/hollow-circle.png']
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("TicTacToe")
self.setStyleSheet('background-color: #D7CCC8;')
# Players
self._players_selector = QtWidgets.QGridLayout()
self._players = list()
for p in range(2):
label = QtWidgets.QLabel('Player {:}'.format(p))
selectbox = QtWidgets.QComboBox()
selectbox.setFixedHeight(24)
selectbox.addItems(list(PLAYERS.keys()))
self._players_selector.addWidget(label, 0, p)
self._players_selector.addWidget(selectbox, 1, p)
self._players.append(selectbox)
self._grid = QtWidgets.QGridLayout()
self._gameboard_buttons = dict()
for i in range(self.m):
for j in range(self.n):
btn = self.create_gameboard_button(row=i, col=j)
self._grid.addWidget(btn, i, j)
self._gameboard_buttons.update({(i, j): btn})
self._message_box = QtWidgets.QLabel('', parent=self)
self._restart_button = QtWidgets.QPushButton('Start', parent=self)
self._restart_button.setFixedHeight(32)
self._restart_button.clicked.connect(self.restart)
# Layout
self._layout = QtWidgets.QVBoxLayout()
self._layout.addLayout(self._players_selector)
self._layout.addLayout(self._grid)
self._layout.addWidget(self._message_box)
self._layout.addWidget(self._restart_button)
self.setLayout(self._layout)
# The game
self._game = TicTacToe()
self._started = False
def create_gameboard_button(self, row, col):
btn = TicTacToeUIButton('', parent=self, style_sheet='background-color: #D7CCC8;')
btn.setFixedSize(64, 64)
btn.clicked.connect(functools.partial(self.click, row, col))
return btn
def click(self, row, col):
if not self._started:
pass
elif self._game.is_ended:
pass
else:
btn = self._gameboard_buttons.get((row, col))
if btn is not None:
if btn.is_occupied:
msg = 'It is occupied. Please select another one.'
self._message_box.setText(msg)
else:
player = self._game.turn_player
# Icon appearance
for _, b in self._gameboard_buttons.items():
b.remove_border()
btn.setIcon(QtGui.QIcon(self.icons[player]))
btn.setIconSize(QtCore.QSize(48, 48))
btn.add_border('border: 1px solid #FF0000;')
btn.occupied_player = player
# Check result
self._game.move(row=row, col=col, player=player)
if self._game.winner is not None:
if self._game.winner == -1:
msg = 'Draw. What a game!'
else:
msg = 'Player {:} won. Congratulations!'
msg = msg.format(self._game.winner)
else:
msg = ''
self._message_box.setText(msg)
# Next turn
if self._game.is_ended:
pass
else:
self._game.players[self._game.turn_player].decide_ui(self)
def reset(self):
self._started = True
self._game.reset()
self._game.player0 = PLAYERS.get(self._players[0].currentText())
self._game.player1 = PLAYERS.get(self._players[1].currentText())
self._restart_button.setText('Restart')
self._message_box.setText('')
for _, btn in self._gameboard_buttons.items():
btn.reset()
if self._game.player0.is_ai:
self._game._player0.decide_ui(self)
def restart(self):
self.reset()
いくつかの注意: 'スタート'/'再起動' ボタンをクリックした後
はゲームが右を開始します、人間やAIのどちらかのプレイヤーは、その判断/アルゴリズムに基づいてゲームボードのボタンをクリックします。
Human().decide_ui(self)
SomeAI().decide_ui(self)
はいくつかのアルゴリズムに基づいてゲームボードのボタンをクリックします。TicTacToe()
は、ゲームボードマトリックスと当選基準を格納するオブジェクトです。
あなたがゲームをプレイに興味がある場合は、コードhereのセット全体をダウンロードすることができます。
AIがゲームを終了するスピードを遅くする必要があります。あなたは 'QTimer'クラスを試すことができます。 – Crispin
@Crispin私のAIの中には1回転ごとに1-2秒かかるものもありますが、最終結果は数秒後に直ちに表示されます。中間のものは見えません。 – kitman0804