void KisColorSelector::drawOutline(QPainter& painter, const QRect& rect) { painter.setRenderHint(QPainter::Antialiasing, true); painter.resetTransform(); painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); painter.scale(rect.width()/2, rect.height()/2); painter.setPen(QPen(QBrush(Qt::gray), 0.005)); if (getNumPieces() > 1) { for(int i=0; i<getNumRings(); ++i) { painter.resetTransform(); painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); painter.scale(rect.width()/2, rect.height()/2); painter.rotate(-m_colorRings[i].getShift().degrees()); for(int j=0; j<m_colorRings[i].pieced.size(); ++j) painter.drawPath(m_colorRings[i].pieced[j]); } if (m_selectedRing >= 0 && m_selectedPiece >= 0) { painter.resetTransform(); painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); painter.rotate(-m_colorRings[m_selectedRing].getShift().degrees()); painter.scale(rect.width()/2, rect.height()/2); painter.setPen(QPen(QBrush(Qt::red), 0.01)); painter.drawPath(m_colorRings[m_selectedRing].pieced[m_selectedPiece]); } } else { for(int i=0; i<getNumRings(); ++i) { qreal rad = m_colorRings[i].outerRadius; painter.drawEllipse(QRectF(-rad, -rad, rad*2.0, rad*2.0)); } } if (m_selectedRing >= 0) { qreal iRad = m_colorRings[m_selectedRing].innerRadius; qreal oRad = m_colorRings[m_selectedRing].outerRadius; painter.setPen(QPen(QBrush(Qt::red), 0.005)); painter.drawEllipse(QRectF(-iRad, -iRad, iRad*2.0, iRad*2.0)); painter.drawEllipse(QRectF(-oRad, -oRad, oRad*2.0, oRad*2.0)); if (getNumPieces() <= 1) { float c = std::cos(-m_selectedColor.getH() * PI2); float s = std::sin(-m_selectedColor.getH() * PI2); painter.drawLine(QPointF(c*iRad, s*iRad), QPointF(c*oRad, s*oRad)); } } }
void Game::play(bool verbose) { while(getNumResources() > 0 && getNumPieces() > 1) round(); }
void KisColorSelector::mousePressEvent(QMouseEvent* event) { m_clickPos = mapCoord(event->posF(), m_renderArea); m_mouseMoved = false; m_pressedButtons = event->buttons(); m_clickedRing = getSaturationIndex(m_clickPos); qint8 clickedLightPiece = getLightIndex(event->posF()); if (clickedLightPiece >= 0) { setLight(getLight(event->posF()), m_relativeLight); m_selectedLightPiece = clickedLightPiece; setSelectedColor(m_selectedColor, !(m_pressedButtons & Qt::RightButton), true); m_mouseMoved = true; } else if (m_clickedRing >= 0) { if (getNumPieces() > 1) { for(int i=0; i<getNumRings(); ++i) m_colorRings[i].setTemporaries(m_selectedColor); } else { Radian angle = std::atan2(m_clickPos.x(), m_clickPos.y()) - RAD_90; m_selectedColor.setH(angle.scaled(0.0f, 1.0f)); m_selectedColor.setS(getSaturation(m_clickedRing)); m_selectedColor.setX(getLight(m_light, m_selectedColor.getH(), m_relativeLight)); setSelectedColor(m_selectedColor, !(m_pressedButtons & Qt::RightButton), true); m_selectedRing = m_clickedRing; m_mouseMoved = true; update(); } } }
// play game until over void Game::play(bool verbose) { __verbose = verbose; round(); if(getNumPieces()>1 && getNumResources() > 0) { play(verbose); } }
void KisColorSelector::setInverseSaturation(bool inverse) { if (m_inverseSaturation != inverse) { m_selectedRing = (getNumRings()-1) - m_selectedRing; m_inverseSaturation = inverse; recalculateRings(quint8(getNumRings()), quint8(getNumPieces())); update(); } }
void Game::play(bool verbose) { __verbose = verbose; __status = PLAYING; round(); if (getNumResources() > 0) { if (getNumPieces() > 0) { play(verbose); } } }
void KisColorSelector::setNumRings(int num) { num = qBound(MIN_NUM_SATURATION_RINGS, num, MAX_NUM_SATURATION_RINGS); recalculateRings(quint8(num), quint8(getNumPieces())); if (m_selectedRing >= 0) m_selectedRing = getSaturationIndex(m_selectedColor.getS()); update(); }
void KisColorSelector::mouseMoveEvent(QMouseEvent* event) { QPointF dragPos = mapCoord(event->posF(), m_renderArea); qint8 clickedLightPiece = getLightIndex(event->posF()); if (clickedLightPiece >= 0) { setLight(getLight(event->posF()), m_relativeLight); m_selectedLightPiece = clickedLightPiece; setSelectedColor(m_selectedColor, m_selectedColorIsFgColor, true); } if (m_clickedRing < 0) return; if (getNumPieces() > 1) { float angle = std::atan2(dragPos.x(), dragPos.y()) - std::atan2(m_clickPos.x(), m_clickPos.y()); float dist = std::sqrt(dragPos.x()*dragPos.x() + dragPos.y()*dragPos.y()) * 0.80f; float threshold = 5.0f * (1.0f-(dist*dist)); if (qAbs(angle * TO_DEG) >= threshold || m_mouseMoved) { bool selectedRingMoved = true; if (m_pressedButtons & Qt::RightButton) { selectedRingMoved = m_clickedRing == m_selectedRing; m_colorRings[m_clickedRing].angle = m_colorRings[m_clickedRing].tmpAngle + angle; } else for(int i=0; i<getNumRings(); ++i) m_colorRings[i].angle = m_colorRings[i].tmpAngle + angle; if (selectedRingMoved) { KisColor color = m_colorRings[m_clickedRing].tmpColor; Radian angle = m_colorRings[m_clickedRing].getMovedAngel() + (color.getH()*PI2); color.setH(angle.scaled(0.0f, 1.0f)); color.setX(getLight(m_light, color.getH(), m_relativeLight)); m_selectedPiece = getHueIndex(angle, m_colorRings[m_clickedRing].getShift()); setSelectedColor(color, m_selectedColorIsFgColor, true); } m_mouseMoved = true; } } else { Radian angle = std::atan2(dragPos.x(), dragPos.y()) - RAD_90; m_selectedColor.setH(angle.scaled(0.0f, 1.0f)); m_selectedColor.setX(getLight(m_light, m_selectedColor.getH(), m_relativeLight)); setSelectedColor(m_selectedColor, m_selectedColorIsFgColor, true); } update(); }
void KisColorSelector::mouseReleaseEvent(QMouseEvent* /*event*/) { if (!m_mouseMoved && m_clickedRing >= 0) { Radian angle = std::atan2(m_clickPos.x(), m_clickPos.y()) - RAD_90; m_selectedRing = m_clickedRing; m_selectedPiece = getHueIndex(angle, m_colorRings[m_clickedRing].getShift()); if (getNumPieces() > 1) m_selectedColor.setH(getHue(m_selectedPiece, m_colorRings[m_clickedRing].getShift())); else m_selectedColor.setH(angle.scaled(0.0f, 1.0f)); m_selectedColor.setS(getSaturation(m_selectedRing)); m_selectedColor.setX(getLight(m_light, m_selectedColor.getH(), m_relativeLight)); setSelectedColor(m_selectedColor, !(m_pressedButtons & Qt::RightButton)); } else if (m_mouseMoved) setSelectedColor(m_selectedColor, m_selectedColorIsFgColor); m_clickedRing = -1; update(); }
void Game::round(){ if(__round == 0 && __verbose){ __status = PLAYING; cout << endl << *this; } for (int i = 0; i < __grid.size(); ++i) { if(__grid[i]!= nullptr){ if(__grid[i]->isViable()) { if (!__grid[i]->getTurned()) { Agent * agent = dynamic_cast<Agent*>(__grid[i]); if(agent) { __grid[i]->setTurned(true); Position currentPos = __grid[i]->getPosition(); Surroundings surround = getSurroundings(currentPos); ActionType action = __grid[i]->takeTurn(surround); if (action != STAY) { Position newPos = move(currentPos, action); int newPosIndx = (newPos.x * __width + newPos.y); (*__grid[i]) * (*__grid[newPosIndx]); if(!__grid[i]->isViable()){ delete __grid[i]; __grid[i]= nullptr; } else { __grid[i]->setPosition(newPos); if (__grid[newPosIndx] != nullptr) { delete __grid[newPosIndx]; __grid[newPosIndx] = __grid[i]; __grid[i] = nullptr; } else { __grid[newPosIndx] = __grid[i]; __grid[i] = nullptr; } } if(!__grid[newPosIndx]->isViable()){ delete __grid[newPosIndx]; __grid[newPosIndx]= nullptr; } } } } } } } for (int j = 0; j < __grid.size(); ++j) { if(__grid[j] != nullptr) { if (!__grid[j]->isViable()) { delete __grid[j]; __grid[j] = nullptr; } else { __grid[j]->setTurned(false); __grid[j]->age(); } } } if(getNumPieces()< 2 || getNumResources() < 1) __status = OVER; ++__round; // if(__verbose) cout << endl << *this; }
// play a single round void Game::round() { if(__round == 0 && __verbose) { __status = PLAYING; std::cout << std::endl << *this; } for (int count = 0; count < __grid.size(); ++count) { if(__grid[count]!= nullptr) { if(__grid[count]->isViable()) { if (! __grid[count]->getTurned()) { Agent * agent = dynamic_cast<Agent*>(__grid[count]); if(agent) { __grid[count]->setTurned(true); Position currPosition = __grid[count]->getPosition(); Surroundings s = getSurroundings(currPosition); ActionType aT = __grid[count]->takeTurn(s); if (aT != STAY) { Position newPosition = move(currPosition, aT); int newPosIndex = (newPosition.x * __width + newPosition.y); (*__grid[count]) * (*__grid[newPosIndex]); if(! __grid[count]->isViable()) { delete __grid[count]; __grid[count]= nullptr; } else { __grid[count]->setPosition(newPosition); if (__grid[newPosIndex] != nullptr) { delete __grid[newPosIndex]; __grid[newPosIndex] = __grid[count]; __grid[count] = nullptr; } else { __grid[newPosIndex] = __grid[count]; __grid[count] = nullptr; } } if(! __grid[newPosIndex]->isViable()) { delete __grid[newPosIndex]; __grid[newPosIndex]= nullptr; } } } } } } } for (int i = 0; i < __grid.size(); i++) { if(__grid[i] != nullptr) { if (!__grid[i]->isViable()) { delete __grid[i]; __grid[i] = nullptr; } else { __grid[i]->setTurned(false); __grid[i]->age(); } } } if(getNumPieces()< 2 || getNumResources() < 1) { __status = OVER; } ++__round; if(__verbose) { std::cout << std::endl << *this; } }
qreal KisColorSelector::getHue(int hueIdx, Radian shift) const { Radian hue = (qreal(hueIdx) / qreal(getNumPieces())) * PI2; hue += shift; return hue.scaled(0.0f, 1.0f); }
qint8 KisColorSelector::getHueIndex(Radian hue, Radian shift) const { hue -= shift; qreal partSize = 1.0 / qreal(getNumPieces()); return qint8(qRound(hue.scaled(0.0f, 1.0f) / partSize) % getNumPieces()); }