def _setup_left_frame(self, board_width): """ Setup the left part of the interface: BoardWidget and message label. """ left_frame = TT.Frame(self._root) left_frame.grid(row=0, column=0, sticky=T.W+T.E+T.N+T.S) left_frame.grid_columnconfigure(0, weight=1) # Board height may be changed left_frame.grid_rowconfigure(0, weight=1) # Caption is of fixed height left_frame.grid_rowconfigure(1, weight=0) # Padding frame for the board padding = TT.Frame(left_frame, width=board_width, height=board_width) padding.grid(row=0, column=0, sticky=T.W+T.E+T.N+T.S) # Board board = BoardWidget(left_frame, controller = self._controller, pil=self._has_pil, width=board_width, height=board_width, background='yellow', highlightthickness=0, cursor='hand1') self._boardplacer = _BoardPlacer(board, padding) # Message label v_message = T.StringVar() self._controller.register_message_var(v_message) label_message = TT.Label(left_frame, textvariable=v_message) label_message.grid(row=1, column=0)
def initUi(self): self.actionNewGame.triggered.connect(self.newGame) self.actionSeeStatistics.triggered.connect(self.openStatisticsWindow) self.board = BoardWidget(self) self.board.move(5, 30) self.board.gameEnded.connect(self.gameEnded) self.board.moveMade.connect(self.inGameUpdate) self.firstPlayerSurrenderBtn.clicked.connect(self.surrender) self.firstPlayerOfferDrawBtn.clicked.connect(self.offerDraw) self.secondPlayerSurrenderBtn.clicked.connect(self.surrender) self.secondPlayerOfferDrawBtn.clicked.connect(self.offerDraw) self.firstPlayerClock = ChessClock(self) self.firstPlayerClock.timeIsOver.connect(self.timeIsOver) self.rightColumnLayout.addWidget(self.firstPlayerClock, 3, 1) self.secondPlayerClock = ChessClock(self) self.secondPlayerClock.timeIsOver.connect(self.timeIsOver) self.rightColumnLayout.addWidget(self.secondPlayerClock, 0, 1)
def __init__(self): QtGui.QMainWindow.__init__(self) self.ui = gui.Ui_MainWindow() self.ui.setupUi(self) self.svg = BoardWidget() QtCore.QObject.connect(self.svg,QtCore.SIGNAL("clicked(int)"),self.board_click) self.ui.boardLayout.addWidget(self.svg) self.state = StateEnum.DISCONNECTED self.parser = parser.Parser() self.board = self.svg.getBoard() self.player_id = -1 self.my_turn = False self.steps=[] #connection to the server self.socket=QtNetwork.QTcpSocket() QtCore.QObject.connect(self.socket,QtCore.SIGNAL("readyRead()"), self.socket_event) QtCore.QObject.connect(self.socket,QtCore.SIGNAL("connected()"), self.socket_connected) QtCore.QObject.connect(self.socket,QtCore.SIGNAL("disconnected()"), self.socket_disconnected)
class GameUI(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.ui = gui.Ui_MainWindow() self.ui.setupUi(self) self.svg = BoardWidget() QtCore.QObject.connect(self.svg,QtCore.SIGNAL("clicked(int)"),self.board_click) self.ui.boardLayout.addWidget(self.svg) self.state = StateEnum.DISCONNECTED self.parser = parser.Parser() self.board = self.svg.getBoard() self.player_id = -1 self.my_turn = False self.steps=[] #connection to the server self.socket=QtNetwork.QTcpSocket() QtCore.QObject.connect(self.socket,QtCore.SIGNAL("readyRead()"), self.socket_event) QtCore.QObject.connect(self.socket,QtCore.SIGNAL("connected()"), self.socket_connected) QtCore.QObject.connect(self.socket,QtCore.SIGNAL("disconnected()"), self.socket_disconnected) def connect_server(self): '''slot connected to the event of button pressed''' hostname = self.ui.txtHostname.text() port = self.ui.spinPort.value() if self.socket.state() != QtNetwork.QAbstractSocket.UnconnectedState: self.socket.close() self.socket.connectToHost(hostname,port,QtNetwork.QAbstractSocket.ReadWrite) def socket_event(self): '''Slot connected to the signal of the socket''' while self.socket.canReadLine(): msg = self.socket.readLine() #FIXME ugly hack while str(msg).strip().endswith(','): msg += self.socket.readLine() self.new_data(msg) def new_data(self,msg): '''elaborates the messages from the server''' msg=str(msg) msg=msg.strip() #print "---->",msg msg=self.parser.input(msg) #print msg print msg,self.state if msg=="ok": if self.state == StateEnum.WAITING_AUTH: self.get_games() self.ui.cmdJoin.setEnabled(True) self.ui.cmdSpectate.setEnabled(True) self.ui.cmdStart.setEnabled(True) self.ui.cmdHost.setEnabled(True) elif self.state in (StateEnum.HOST_OK_WAIT,StateEnum.JOIN_OK_WAIT): self.ui.cmdJoin.setEnabled(False) self.ui.cmdSpectate.setEnabled(False) self.ui.cmdHost.setEnabled(False) if self.state == StateEnum.JOIN_OK_WAIT: self.ui.cmdStart.setEnabled(False) self.state = StateEnum.WAITING_PLAYERS elif self.state == StateEnum.START_WAIT: self.ui.cmdStart.setEnabled(False) self.state = StateEnum.GAME_STARTED elif self.state == StateEnum.SPECTATE_WAIT: self.state =StateEnum.SPECTATING self.ui.cmdJoin.setEnabled(False) self.ui.cmdSpectate.setEnabled(False) self.ui.cmdStart.setEnabled(False) self.ui.cmdHost.setEnabled(False) elif msg[0]=='error': if self.state == StateEnum.MOVE_WAIT: self.state = -1 self.my_turn = True self.steps=[] self.board=list(self.prev_board) self.svg.setBoard(self.board) elif self.state == StateEnum.SPECTATE_WAIT: #TODO can't spectate, show some error pass elif msg[0]=="games": self.ui.lstGames.clear() for i in msg[1]: self.ui.lstGames.addItem(str(i)) brush=QtGui.QBrush() brush.setStyle(1) brush.setColor(QtGui.QColor(255,0,0)) for i in msg[2]: item=QtGui.QListWidgetItem() item.setForeground(brush) item.setText(str(i)) self.ui.lstGames.addItem(item) pass elif msg[0] in ("player_joined","player_left"): self.ui.lstPlayers.clear() for i in msg[1]: self.ui.lstPlayers.addItem(str(i)) elif msg[0] == 'game_start': self.player_id = msg[1] palette=QtGui.QPalette() palette.setColor(9,self.svg.getColor(msg[1])) self.ui.lstPlayers.setPalette(palette) self.pretty_players(msg[2]) self.board = protocol.get_gui_board(msg[3]) self.svg.setBoard(self.board) elif msg[0] == 'your_turn': #TODO timeout msg[1] self.steps=list() self.ui.boardFrame.setTitle(QtGui.QApplication.translate("Form", "Make your move")) self.my_turn=True self.board = protocol.get_gui_board(msg[2]) self.svg.setBoard(self.board) self.prev_board=list(self.board) elif msg[0] == 'update': if self.state == StateEnum.MOVE_WAIT: self.state=-1 self.steps=[] self.ui.boardFrame.setTitle(QtGui.QApplication.translate("Form", "Board")) self.board = protocol.get_gui_board(msg[3]) self.svg.setBoard(self.board) #TODO Highlights the jumps #msg[2].pop() #for i in msg[2]: # self.svg.setMarble(i,7) elif msg[0]== 'game_state': #player left and game continues self.board = protocol.get_gui_board(msg[2]) self.svg.setBoard(self.board) self.pretty_players(msg[1]) elif msg[0] == 'won': if self.state ==StateEnum.SPECTATING: self.ui.boardFrame.setTitle(QtGui.QApplication.translate("Form", "Someone won")) elif msg[1][0] == self.player_id: self.ui.boardFrame.setTitle(QtGui.QApplication.translate("Form", "You won!")) else: self.ui.boardFrame.setTitle(QtGui.QApplication.translate("Form", "GAME OVER")) self.board = protocol.get_gui_board(msg[2]) self.svg.setBoard(self.board) def get_games(self): self.write(protocol.list_games()) def authenticate(self): '''sends authentication to the server''' self.write(protocol.login_message()) self.state = StateEnum.WAITING_AUTH def socket_connected(self): self.authenticate() self.ui.txtHostname.setEnabled(False) self.ui.spinPort.setEnabled(False) self.ui.cmdConnect.setEnabled(False) self.ui.cmdDisconnect.setEnabled(True) pass def socket_disconnected(self): self.ui.boardFrame.setTitle(QtGui.QApplication.translate("Form", "Board")) self.state = StateEnum.DISCONNECTED self.socket.close() self.ui.txtHostname.setEnabled(True) self.ui.spinPort.setEnabled(True) self.ui.cmdConnect.setEnabled(True) self.ui.cmdJoin.setEnabled(False) self.ui.cmdSpectate.setEnabled(False) self.ui.cmdStart.setEnabled(False) self.ui.cmdHost.setEnabled(False) self.ui.cmdDisconnect.setEnabled(False) palette=self.ui.lstGames.palette() #palette.setColor(9,None) self.ui.lstPlayers.setPalette(palette) def board_click(self,i): print i if self.my_turn == False or self.board[i] not in (self.player_id,0,7): return if len(self.steps)==0 and self.board[i]==0: return if len(self.steps)>1 and self.steps[-1]==i: #Move made message=protocol.move(self.steps) self.write(message) self.state = StateEnum.MOVE_WAIT self.my_turn = False return self.steps.append(i) self.svg.setMarble(i,7) def spectate(self): self.state = StateEnum.SPECTATE_WAIT message=protocol.spectate_game(self.ui.lstGames.currentItem().text()) self.write(message) def join(self): item = self.ui.lstGames.currentItem() if item == None: return message=protocol.join_game(item.text()) self.write(message) self.state = StateEnum.JOIN_OK_WAIT def host(self): gname = QtGui.QInputDialog.getText(self, QtGui.QApplication.translate("Form", "Host game"), QtGui.QApplication.translate("Form", "Insert the name for the new game"), QtGui.QLineEdit.Normal,"") if not gname[1]: return message= protocol.host_game_message(str(gname[0])) self.write(message) self.state = StateEnum.HOST_OK_WAIT self.get_games() def start(self): self.state = StateEnum.START_WAIT message = protocol.start_game() self.write(message) def write(self,message): print "---> %s" % message #TODO return to initial state if connection fails self.socket.write(message) def pretty_players(self,l): '''Fills the list of players, colorizing it l is a list of tuples in the form id,player_name ''' self.ui.lstPlayers.clear() for i in l:#msg[2]: item=QtGui.QListWidgetItem() bcolor=self.svg.getColor(i[0]) fcolor=self.svg.getColor(i[0],negated=True) bbrush=QtGui.QBrush() fbrush=QtGui.QBrush() bbrush.setColor(bcolor) fbrush.setColor(fcolor) bbrush.setStyle(1) fbrush.setStyle(1) item.setBackground(bbrush) item.setForeground(fbrush) item.setText(str(i[1])) self.ui.lstPlayers.addItem(item)
class MainWindow(QtWidgets.QMainWindow, MainWindowUi.Ui_mainWindow): def __init__(self, parent=None): super().__init__(parent) self.statistics = Statistics(resourcePath(DB_PATH)) self.setupUi(self) self.initUi() def initUi(self): self.actionNewGame.triggered.connect(self.newGame) self.actionSeeStatistics.triggered.connect(self.openStatisticsWindow) self.board = BoardWidget(self) self.board.move(5, 30) self.board.gameEnded.connect(self.gameEnded) self.board.moveMade.connect(self.inGameUpdate) self.firstPlayerSurrenderBtn.clicked.connect(self.surrender) self.firstPlayerOfferDrawBtn.clicked.connect(self.offerDraw) self.secondPlayerSurrenderBtn.clicked.connect(self.surrender) self.secondPlayerOfferDrawBtn.clicked.connect(self.offerDraw) self.firstPlayerClock = ChessClock(self) self.firstPlayerClock.timeIsOver.connect(self.timeIsOver) self.rightColumnLayout.addWidget(self.firstPlayerClock, 3, 1) self.secondPlayerClock = ChessClock(self) self.secondPlayerClock.timeIsOver.connect(self.timeIsOver) self.rightColumnLayout.addWidget(self.secondPlayerClock, 0, 1) def newGame(self): gameStarted = self.board.isGameStarted() if gameStarted is True: force = QtWidgets.QMessageBox\ .question(self, "", """Do you really want to start new game? This game is not ended.""", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if force != QtWidgets.QMessageBox.Yes: return self.newGameDialog = NewGameDialog(self.statistics, self) dataEnterSuccessful = self.newGameDialog.exec() if dataEnterSuccessful == 0: return self.firstPlayer = self.newGameDialog.getFirstPlayerData() self.secondPlayer = self.newGameDialog.getSecondPlayerData() timerData = self.newGameDialog.getTimerData() self.countTime = timerData[0] if self.countTime: self.firstPlayerClock.setTime(timerData[1]) self.secondPlayerClock.setTime(timerData[1]) self.firstPlayerNickname.setText(self.firstPlayer[1]) self.secondPlayerNickname.setText(self.secondPlayer[1]) self.movesList.clear() self.actionSeeStatistics.setEnabled(False) self.board.startGame() def updateClocks(self): if self.countTime is False: return if self.board.getCurrentTurn() == chess.WHITE: self.secondPlayerClock.stop() self.firstPlayerClock.start() else: self.firstPlayerClock.stop() self.secondPlayerClock.start() def inGameUpdate(self, move): self.firstPlayerSurrenderBtn.setEnabled(True) self.secondPlayerSurrenderBtn.setEnabled(True) self.updateClocks() if self.board.getCurrentTurn() == chess.WHITE: self.firstPlayerOfferDrawBtn.setEnabled(True) self.secondPlayerOfferDrawBtn.setEnabled(False) else: self.firstPlayerOfferDrawBtn.setEnabled(False) self.secondPlayerOfferDrawBtn.setEnabled(True) self.firstPlayerOfferDrawBtn.setText("Offer a draw") self.secondPlayerOfferDrawBtn.setText("Offer a draw") movesQuantity = self.board.getMovesQuantity() self.movesList.addItem(f"{movesQuantity}. {move.uci()}") self.movesList.scrollToBottom() def updateStatistics(self, result): firstPlayerStats = self.statistics.getPlayersData( self.firstPlayer[0], ("games_played", "games_won", "games_draw", "games_lost")) firstPlayerStats = list(firstPlayerStats) secondPlayerStats = self.statistics.getPlayersData( self.secondPlayer[0], ("games_played", "games_won", "games_draw", "games_lost")) secondPlayerStats = list(secondPlayerStats) firstPlayerStats[0] += 1 secondPlayerStats[0] += 1 if result == "1-0": firstPlayerStats[1] += 1 secondPlayerStats[3] += 1 elif result == "1/2-1/2": firstPlayerStats[2] += 1 secondPlayerStats[2] += 1 else: firstPlayerStats[3] += 1 secondPlayerStats[1] += 1 self.statistics.updatePlayersData( self.firstPlayer[0], zip(("games_played", "games_won", "games_draw", "games_lost"), firstPlayerStats)) self.statistics.updatePlayersData( self.secondPlayer[0], zip(("games_played", "games_won", "games_draw", "games_lost"), secondPlayerStats)) def gameEnded(self, result): self.firstPlayerClock.stop() self.secondPlayerClock.stop() self.firstPlayerOfferDrawBtn.setEnabled(False) self.firstPlayerOfferDrawBtn.setText("Offer a draw") self.firstPlayerSurrenderBtn.setEnabled(False) self.secondPlayerOfferDrawBtn.setEnabled(False) self.secondPlayerOfferDrawBtn.setText("Offer a draw") self.secondPlayerSurrenderBtn.setEnabled(False) self.actionSeeStatistics.setEnabled(True) self.movesList.addItem(result) self.movesList.scrollToBottom() self.updateStatistics(result) saveResult, filename = self.savePGN() if saveResult: self.movesList.addItem("Game PGN was saved in") self.movesList.addItem(filename) else: self.movesList.addItem("Game PGN wasn't saved") def offerDraw(self): if self.sender().text() == "Offer a draw": """Check if draw can be claimed without opponent approval""" if self.board.isDrawPossibleWithoutOpponentApproval(): self.board.draw() else: if self.sender() is self.firstPlayerOfferDrawBtn: self.firstPlayerOfferDrawBtn.setEnabled(False) self.secondPlayerOfferDrawBtn.setEnabled(True) self.secondPlayerOfferDrawBtn.setText("Approve a draw") else: self.secondPlayerOfferDrawBtn.setEnabled(False) self.firstPlayerOfferDrawBtn.setEnabled(True) self.firstPlayerOfferDrawBtn.setText("Approve a draw") else: self.board.draw() def surrender(self): if self.sender() is self.firstPlayerSurrenderBtn: self.board.forceLose(chess.WHITE) else: self.board.forceLose(chess.BLACK) def timeIsOver(self): if self.firstPlayerClock.getTime() == 0: if self.board.hasInsufficientMaterial(chess.BLACK): self.board.draw() else: self.board.forceLose(chess.WHITE) else: if self.board.hasInsufficientMaterial(chess.WHITE): self.board.draw() else: self.board.forceLose(chess.BLACK) def openStatisticsWindow(self): self.statisticsWindow = StatisticsWindow(self.statistics, self) self.statisticsWindow.show() def genPGN(self): game = self.board.getGame() game.headers["Date"] = datetime.datetime.now().strftime("%y.%m.%d") game.headers["White"] = self.firstPlayer[1] game.headers["Black"] = self.secondPlayer[1] return str(game) def savePGN(self, auto=True): if auto: curTime = datetime.datetime.now().strftime("%y-%m-%d-%H:%M:%S") if os.path.exists(RES_DIR) is False: try: os.mkdir(RES_DIR) except PermissionError: return 0, "" filePath = f"{RES_DIR}{curTime}-\ {self.firstPlayer[1]}-{self.secondPlayer[1]}.pgn" else: # TODO pass pgn = self.genPGN() try: file = open(filePath, 'w') file.write(pgn) file.close() return 1, filePath except PermissionError: return 0, ""