bool Pawn::canMove(int x, int y, int move_x, int move_y) { if(isPromoted()) { return move_x == 0 || move_y == 0 || abs(move_x)==abs(move_y); } int dir = getSide()==0?-1:1; if(move_x == 0) { if(board_->get(x,y+dir) != NULL) { return false; } if(move_y == dir) { return true; } if(!isMoved() && move_y==dir*2) { return board_->get(x,y+move_y)==NULL; } return false; } if(move_y != dir) { return false; } if(abs(move_x) != 1) { return false; } Man *target = board_->get(x+move_x,y+move_y); return target?target->getSide()!=getSide():false; }
PromotionTaskMenu::PromotionState PromotionTaskMenu::createPromotionActions(QDesignerFormWindowInterface *formWindow) { // clear out old if (!m_promotionActions.empty()) { qDeleteAll(m_promotionActions); m_promotionActions.clear(); } // No promotion of main container if (formWindow->mainContainer() == m_widget) return NotApplicable; // Check for a homogenous selection const PromotionSelectionList promotionSelection = promotionSelectionList(formWindow); if (promotionSelection.empty()) return NoHomogenousSelection; QDesignerFormEditorInterface *core = formWindow->core(); // if it is promoted: demote only. if (isPromoted(formWindow->core(), m_widget)) { const QString label = m_demoteLabel.arg( promotedExtends(core , m_widget)); QAction *demoteAction = new QAction(label, this); connect(demoteAction, SIGNAL(triggered()), this, SLOT(slotDemoteFromCustomWidget())); m_promotionActions.push_back(demoteAction); return CanDemote; } // figure out candidates const QString baseClassName = WidgetFactory::classNameOf(core, m_widget); const WidgetDataBaseItemList candidates = promotionCandidates(core->widgetDataBase(), baseClassName ); if (candidates.empty()) { // Is this thing promotable at all? return QDesignerPromotionDialog::baseClassNames(core->promotion()).contains(baseClassName) ? CanPromote : NotApplicable; } // Set up a signal mapper to associate class names if (!m_promotionMapper) { m_promotionMapper = new QSignalMapper(this); connect(m_promotionMapper, SIGNAL(mapped(QString)), this, SLOT(slotPromoteToCustomWidget(QString))); } QMenu *candidatesMenu = new QMenu(); // Create a sub menu const WidgetDataBaseItemList::const_iterator cend = candidates.constEnd(); // Set up actions and map class names for (WidgetDataBaseItemList::const_iterator it = candidates.constBegin(); it != cend; ++it) { const QString customClassName = (*it)->name(); QAction *action = new QAction((*it)->name(), this); connect(action, SIGNAL(triggered()), m_promotionMapper, SLOT(map())); m_promotionMapper->setMapping(action, customClassName); candidatesMenu->addAction(action); } // Sub menu action QAction *subMenuAction = new QAction(m_promoteLabel, this); subMenuAction->setMenu(candidatesMenu); m_promotionActions.push_back(subMenuAction); return CanPromote; }
void PromotionTaskMenu::slotDemoteFromCustomWidget() { QDesignerFormWindowInterface *fw = formWindow(); const PromotionSelectionList promotedWidgets = promotionSelectionList(fw); Q_ASSERT(!promotedWidgets.empty() && isPromoted(fw->core(), promotedWidgets.front())); // ### use the undo stack DemoteFromCustomWidgetCommand *cmd = new DemoteFromCustomWidgetCommand(fw); cmd->init(promotedWidgets); fw->commandHistory()->push(cmd); }
ConnectDialog::WidgetMode ConnectDialog::widgetMode(QWidget *w, QDesignerFormWindowInterface *formWindow) { QDesignerFormEditorInterface *core = formWindow->core(); if (qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core)) return NormalWidget; if (w == formWindow || formWindow->mainContainer() == w) return MainContainer; if (isPromoted(formWindow->core(), w)) return PromotedWidget; return NormalWidget; }
bool Pawn::isJump() { if(isPromoted()) { return false; } if(!isMoved()) { return false; } vector<Pos>::reverse_iterator it = move_history_.rbegin(); int y0 = (*it++).second; int y1 = (*it).second; return abs(y0-y1)==2; }
PromotionTaskMenu::PromotionSelectionList PromotionTaskMenu::promotionSelectionList(QDesignerFormWindowInterface *formWindow) const { // In multi selection mode, check for a homogenous selection (same class, same promotion state) // and return the list if this is the case. Also make sure m_widget // is the last widget in the list so that it is re-selected as the last // widget by the promotion commands. PromotionSelectionList rc; if (m_mode != ModeSingleWidget) { QDesignerFormEditorInterface *core = formWindow->core(); const QDesignerIntrospectionInterface *intro = core->introspection(); const QString className = intro->metaObject(m_widget)->className(); const bool promoted = isPromoted(formWindow->core(), m_widget); // Just in case someone plugged an old-style Object Inspector if (QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(core->objectInspector())) { Selection s; designerObjectInspector->getSelection(s); // Find objects of similar state const QWidgetList &source = m_mode == ModeManagedMultiSelection ? s.managed : s.unmanaged; const QWidgetList::const_iterator cend = source.constEnd(); for (QWidgetList::const_iterator it = source.constBegin(); it != cend; ++it) { QWidget *w = *it; if (w != m_widget) { // Selection state mismatch if (intro->metaObject(w)->className() != className || isPromoted(core, w) != promoted) return PromotionSelectionList(); rc.push_back(w); } } } } rc.push_back(m_widget); return rc; }
void Pawn::updatePossibleMoves() { possible_move_.clear(); int x = move_history_.back().first; int y = move_history_.back().second; if(isPromoted()) { checkLine(x,y, -1,-1); checkLine(x,y, -1, 0); checkLine(x,y, -1, 1); checkLine(x,y, 0,-1); checkLine(x,y, 0, 1); checkLine(x,y, 1,-1); checkLine(x,y, 1, 0); checkLine(x,y, 1, 1); } else { Man *target = NULL; int next_x, next_y; switch(player_) { case 0: next_x = x; next_y = y-1; break; case 1: next_x = x; next_y = y+1; break; } if(board_->isInBounds(next_x, next_y) && !board_->get(next_x, next_y)) { possible_move_.push_back(pair<int,int>(next_x,next_y)); if(!isMoved()) { switch(player_) { case 0: next_x = x; next_y = y-2; break; case 1: next_x = x; next_y = y+2; break; } if(board_->isInBounds(next_x, next_y) && !board_->get(next_x, next_y)) { possible_move_.push_back(pair<int,int>(next_x,next_y)); } } } switch(player_) { case 0: next_x = x+1; next_y = y-1; break; case 1: next_x = x-1; next_y = y+1; break; } if(board_->isInBounds(next_x, next_y)) { Man *target = board_->get(next_x, next_y); if(target) { if(target->getSide() != getSide()) { possible_move_.push_back(pair<int,int>(next_x,next_y)); } } else { switch(player_) { case 0: target = board_->get(next_x, next_y+1); break; case 1: target = board_->get(next_x, next_y-1); break; } /** Pawn *pawn = dynamic_cast<Pawn*>(board_->getLastMoved()); if(pawn && pawn->isJump() && pawn == target) { possible_move_.push_back(pair<int,int>(next_x,next_y)); } /**/ } } switch(player_) { case 0: next_x = x-1; next_y = y-1; break; case 1: next_x = x+1; next_y = y+1; break; } if(board_->isInBounds(next_x, next_y)) { Man *target = board_->get(next_x, next_y); if(target) { if(target->getSide() != getSide()) { possible_move_.push_back(pair<int,int>(next_x,next_y)); } } else { switch(player_) { case 0: target = board_->get(next_x, next_y+1); break; case 1: target = board_->get(next_x, next_y-1); break; } /** Pawn *pawn = dynamic_cast<Pawn*>(board_->getLastMoved()); if(pawn && pawn->isJump() && pawn == target) { possible_move_.push_back(pair<int,int>(next_x,next_y)); } /**/ } } } }
/** * ユーザが入力した指し手を読み込みます。 */ bool ConsoleManager::inputMove(const char* str, const Board& board, Move& move) const { // CSA形式で読み込んでみる if (CsaReader::readMove(str, record_.getBoard(), move)) { return true; } if (strlen(str) < 4) { return false; } // 移動元 auto to = Square::parse(&str[2]); if (!to.isValid()) { return false; } // 移動先 auto from = Square::parse(&str[0]); if (from.isValid()) { // 盤上の駒を動かす手 // 駒種 auto piece = board.getBoardPiece(from); if (piece.isEmpty()) { return false; } // 成 auto promote = str[4] == 'n'; if (promote && piece.isPromoted()) { return false; } move.set(piece, from, to, promote); // 合法手チェック if (board.isValidMoveStrict(move)) { return true; } // 成を自動付加 if (!promote && piece.isUnpromoted()) { move.setPromote(true); if (board.isValidMoveStrict(move)) { return true; } } } else { // 持ち駒を打つ手 // 駒種 auto piece = Piece::parse(&str[0]); if (piece.isEmpty()) { return false; } move.set(piece.black(), to); // 合法手チェック if (board.isValidMoveStrict(move)) { return true; } } return false; }