void _movewater(sim_Sim *s, int x, int y, double time) { int i; sim_Cell *cc, *bc;//center (x,y) sim_Cell *currs[4]; //current up, down, left right sim_Cell *buffs[4]; //next tick up, down, left right double heightdiff[4]; //>0 means flowing in double netflow; cc = &cellAt (x, y, s); bc = &cellAtBuff (x, y, s); currs[UP] = &cellAt (x, y - 1, s); buffs[UP] = &cellAtBuff (x, y - 1, s); currs[DN] = &cellAt (x, y + 1, s); buffs[DN] = &cellAtBuff (x, y + 1, s); currs[LF] = &cellAt (x - 1, y, s); buffs[LF] = &cellAtBuff (x - 1, y, s); currs[RT] = &cellAt (x + 1, y, s); buffs[RT] = &cellAtBuff (x + 1, y, s); if(x == 0) currs[LF] = NULL; if(x == s->w - 1) currs[RT] = NULL; if(y == 0) currs[UP] = NULL; if(y == s->h - 1) currs[DN] = NULL; for(i = 0; i < 4; i++) { bc->height -= bc->flow[i] * time; } }
bool Level::Private::cellsFromFile(FILE* in) { cells.resize(size.x * size.y, Private::Floor); Point read = { 0, 0 }; for (read.y = 0; read.y < size.y; ++read.y) { for (read.x = 0; read.x < size.x + 1; ++read.x) { char c = fgetc(in); switch (c) { case EOF: // Error: file is too short. return false; break; case '\n': // End of line, read next. if (read.x < size.x) return false; continue; break; case '+': cellAt(read) = Private::Wood; break; case '#': cellAt(read) = Private::Stone; break; case '@': // Spawner. Just a special floor cell. spawns.push_back(read); case ' ': cellAt(read) = Private::Floor; break; }; } } return true; }
void PageItem_Table::updateSpans(int index, int number, ChangeType changeType) { // Loop through areas of merged cells. QMutableListIterator<CellArea> areaIt(m_cellAreas); while (areaIt.hasNext()) { CellArea oldArea = areaIt.next(); // Get a copy of the area adjusted to the change. CellArea newArea; switch (changeType) { case RowsInserted: newArea = oldArea.adjustedForRowInsertion(index, number); break; case RowsRemoved: newArea = oldArea.adjustedForRowRemoval(index, number); break; case ColumnsInserted: newArea = oldArea.adjustedForColumnInsertion(index, number); break; case ColumnsRemoved: newArea = oldArea.adjustedForColumnRemoval(index, number); break; default: break; } // Check if the area was affected by the change. if (newArea != oldArea) { if (newArea.height() < 1 || newArea.width() < 1) { // Adjusted area was annihilated, so remove it. areaIt.remove(); } else if (newArea.height() == 1 && newArea.width() == 1) { // Adjusted area is 1x1, so remove it. areaIt.remove(); // And reset row/column span of spanning cell to 1. TableCell oldSpanningCell = cellAt(oldArea.row(), oldArea.column()); oldSpanningCell.setRowSpan(1); oldSpanningCell.setColumnSpan(1); } else { // Replace the area with the adjusted copy. areaIt.setValue(newArea); // And set row/column spanning of spanning cell. TableCell newSpanningCell = cellAt(newArea.row(), newArea.column()); newSpanningCell.setRowSpan(newArea.height()); newSpanningCell.setColumnSpan(newArea.width()); } } } }
Maze::Maze(int width,int height):m_width(width),m_height(height), m_cells(std::vector<Cell>(width*height)){ for(int i=0;i<width;i++){ cellAt(Point(i,0))=cellAt(Point(i,0)).cellBySetWall(DirectionTop,true); } for(int i=0;i<height;i++){ cellAt(Point(0,i))=cellAt(Point(0,i)).cellBySetWall(DirectionLeft,true); } }
void PageItem_Table::mergeCells(int row, int column, int numRows, int numCols) { ASSERT_VALID(); if (!validCell(row, column) || !validCell(row + numRows - 1, column + numCols - 1)) return; CellArea newArea(row, column, numCols, numRows); // Unite intersecting areas. QMutableListIterator<CellArea> areaIt(m_cellAreas); while (areaIt.hasNext()) { CellArea oldArea = areaIt.next(); if (newArea.intersects(oldArea)) { // The two areas intersect, so unite them. newArea = newArea.united(oldArea); // Reset row/column span of old spanning cell, then remove old area. TableCell oldSpanningCell = cellAt(oldArea.row(), oldArea.column()); oldSpanningCell.setRowSpan(1); oldSpanningCell.setColumnSpan(1); areaIt.remove(); } } // Set row/column span of new spanning cell, and add new area. TableCell newSpanningCell = cellAt(newArea.row(), newArea.column()); newSpanningCell.setRowSpan(newArea.height()); newSpanningCell.setColumnSpan(newArea.width()); m_cellAreas.append(newArea); // Update cells. TODO: Not for entire table. updateCells(); // If merged area covers active position, move to the spanning cell. if (newArea.contains(m_activeRow, m_activeColumn)) moveTo(newSpanningCell); // Remove all cells covered by the merged area from the selection. QMutableSetIterator<TableCell> cellIt(m_selection); while (cellIt.hasNext()) { TableCell cell = cellIt.next(); if (newArea.contains(cell.row(), cell.column()) && !(cell.row() == newArea.row() && cell.column() == newArea.column())) cellIt.remove(); } emit changed(); ASSERT_VALID(); }
/*! \fn void QTextTable::removeRows(int index, int rows) Removes a number of \a rows starting with the row at the specified \a index. \sa insertRows(), insertColumns(), resize(), removeColumns(), appendRows(), appendColumns() */ void QTextTable::removeRows(int pos, int num) { Q_D(QTextTable); // qDebug() << "-------- removeRows" << pos << num; if (num <= 0 || pos < 0) return; if (d->dirty) d->update(); if (pos >= d->nRows) return; if (pos+num > d->nRows) num = d->nRows - pos; QTextDocumentPrivate *p = d->pieceTable; QTextFormatCollection *collection = p->formatCollection(); p->beginEditBlock(); // delete whole table? if (pos == 0 && num == d->nRows) { const int pos = p->fragmentMap().position(d->fragment_start); p->remove(pos, p->fragmentMap().position(d->fragment_end) - pos + 1); p->endEditBlock(); return; } p->aboutToRemoveCell(cellAt(pos, 0).firstPosition(), cellAt(pos + num - 1, d->nCols - 1).lastPosition()); QList<int> touchedCells; for (int r = pos; r < pos + num; ++r) { for (int c = 0; c < d->nCols; ++c) { int cell = d->grid[r*d->nCols + c]; if (touchedCells.contains(cell)) continue; touchedCells << cell; QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell); QTextCharFormat fmt = collection->charFormat(it->format); int span = fmt.tableCellRowSpan(); if (span > 1) { fmt.setTableCellRowSpan(span - 1); p->setCharFormat(it.position(), 1, fmt); } else { // remove cell int index = d->cells.indexOf(cell) + 1; int f_end = index < d->cells.size() ? d->cells.at(index) : d->fragment_end; p->remove(it.position(), p->fragmentMap().position(f_end) - it.position()); } } } p->endEditBlock(); // qDebug() << "-------- end removeRows" << pos << num; }
void Maze::setWall(const Point &p,Direction d,bool exists){ switch(d){ case DirectionLeft: case DirectionTop: if(isInside(p)){ cellAt(p)=cellAt(p).cellBySetWall(d,exists); } break; case DirectionRight: case DirectionBottom: return setWall(p.neighbor(d),DirectionReverse(d),exists); } }
Puzzle *Sheet::toPuzzle() const { std::auto_ptr<Puzzle> puzzle(new Puzzle); Grid &grid = puzzle->grid; State &state = puzzle->state; grid.height = grid_size.height(); grid.width = grid_size.width(); grid.vars.resize(layout()->count(), -1); int hgrp = -1; std::vector<int> vgrps(grid_size.width(), -1); for(int n = grid_size.width() + 1, c = 1; n < layout()->count(); ++n) { if(cellAt(n).open()) { if(hgrp == -1) { hgrp = state.grps++; state.sum.push_back(cellAt(n - 1).hsum()); state.mem.resize(state.grps); } if(vgrps[c] == -1) { vgrps[c] = state.grps++; state.sum.push_back(cellAt(n - grid_size.width()).vsum()); state.mem.resize(state.grps); } grid.vars[n] = state.vars; state.cand.push_back(cellAt(n).cands()); state.hgrp.push_back(hgrp); state.vgrp.push_back(vgrps[c]); state.mem[hgrp].push_back(state.vars); state.mem[vgrps[c]].push_back(state.vars); ++state.vars; } else { hgrp = vgrps[c] = -1; } if(++c == grid_size.width()) c = 0; } return puzzle.release(); }
void _createflow(sim_Sim *s, int x, int y, double time) {//time elapsed in seconds int i; sim_Cell *cc, *bc;//center (x,y) sim_Cell *currs[4]; //current up, down, left right sim_Cell *buffs[4]; //next tick up, down, left right double heightdiff[4]; //>0 means flowing in double netflow; cc = &cellAt (x, y, s); bc = &cellAtBuff (x, y, s); currs[UP] = &cellAt (x, y - 1, s); buffs[UP] = &cellAtBuff (x, y - 1, s); currs[DN] = &cellAt (x, y + 1, s); buffs[DN] = &cellAtBuff (x, y + 1, s); currs[LF] = &cellAt (x - 1, y, s); buffs[LF] = &cellAtBuff (x - 1, y, s); currs[RT] = &cellAt (x + 1, y, s); buffs[RT] = &cellAtBuff (x + 1, y, s); if(x == 0) currs[LF] = NULL; if(x == s->w - 1) currs[RT] = NULL; if(y == 0) currs[UP] = NULL; if(y == s->h - 1) currs[DN] = NULL; for(i = 0; i < 4; i++) { if(currs[i]== NULL) { heightdiff[i] = 0; continue; } heightdiff[i] = currs[i]->height - cc->height; } //1 unit of flow = 1 height / second //zflow =~ flow netflow = 0; for(i = 0; i < 4; i++) { double temp = FLOWCONSTANT * sqrt(fabs(heightdiff[i])) * (heightdiff[i] < 0 ? 1 : -1); double flowdiff; flowdiff = temp - bc->flow[i]; bc->flow[i] += time * FLOWEQUALIZINGRATE * flowdiff; netflow += bc->flow[i]; } }
bool PickerCells::saveOpenCategories(std::list<std::list<std::string> >& masterList, const std::list<std::string> &parentHier, PickerCell *selectedCell) const { bool hasSelectedCell=false; for (int i=0; i<count(); i++) { const PickerCell* cell = cellAt(i); if (cell == selectedCell) { hasSelectedCell=true; } if (!cell->hideChildren()) { masterList.push_back(parentHier); std::list<std::string> * newItem = &masterList.back(); (*newItem).push_back(cell->id()); PickerCells *newCells = cell->children(); bool savedCell=false; if (newCells) { savedCell = newCells->saveOpenCategories(masterList, (*newItem), selectedCell); } if (savedCell) { (*newItem).push_back(selectedCell->id()); } } } return hasSelectedCell; }
bool Sheet::empty() { for(int n = 0; n < grid_size.width()*grid_size.height(); ++n) if(!cellAt(n).empty()) return false; return true; }
void Field::generate(int x, int y) { Cell *banned = cellAt(x, y); QVector<Cell*> bannedCells = banned->getNeighbors(); bannedCells.append(banned); int minesToPlace = m_numberOfMines; while (minesToPlace > 0) { Cell *cell = m_cells.at(qrand() % m_cells.count()); if (cell->haveMine()) { continue; } if (bannedCells.contains(cell)){ continue; } cell->setHaveMine(true); --minesToPlace; } m_generated = true; }
/************************************** * Definition: Whether or not we can occupy the cell at x,y * * Parameters: x and y as ints * * Returns: true if we can, false if not **************************************/ bool Map::canOccupy(int x, int y) { Cell *moveCell = NULL; moveCell = cellAt(x, y); if (moveCell == NULL) { return false; } return !moveCell->isBlocked(); }
void PageItem_Table::selectCell(int row, int column) { if (!validCell(row, column)) return; m_selection.insert(cellAt(row, column)); emit selectionChanged(); }
void Sheet::setPuzzle(const Puzzle &puzzle) { setUpdatesEnabled(false); int W = puzzle.grid.width, H = puzzle.grid.height; QSize new_size(W, H); if(grid_size != new_size) setGridSize(QSize(W, H)); for(int n = 0; n < W*H; ++n) { int v = puzzle.grid.vars[n]; if(v >= 0) { cellAt(n).setOpen(true); cellAt(n).setCands(puzzle.state.cand[v]); cellAt(n - W).setVsum(puzzle.state.sum[puzzle.state.vgrp[v]]); cellAt(n - 1).setHsum(puzzle.state.sum[puzzle.state.hgrp[v]]); } else { cellAt(n).setOpen(false); cellAt(n).setHsum(0); cellAt(n).setVsum(0); } } setUpdatesEnabled(true); }
void PageItem_Table::moveUp() { if (m_activeCell.row() < 1) return; // Move active position up and activate cell at new position. // m_activeRow = m_activeCell.row() - 1; activateCell(cellAt(m_activeCell.row() - 1, m_activeColumn)); }
void PageItem_Table::moveRight() { if (m_activeCell.column() + m_activeCell.columnSpan() >= columns()) return; // Move active position right and activate cell at new position. // m_activeColumn = m_activeCell.column() + m_activeCell.columnSpan(); activateCell(cellAt(m_activeRow, m_activeCell.column() + m_activeCell.columnSpan())); }
void PageItem_Table::moveLeft() { if (m_activeCell.column() < 1) return; // Move active position left and activate cell at new position. // m_activeColumn = m_activeCell.column() - 1; activateCell(cellAt(m_activeRow, m_activeCell.column() - 1)); }
void PageItem_Table::removeRows(int index, int numRows) { ASSERT_VALID(); if (!validRow(index) || numRows < 1 || numRows >= rows() || index + numRows > rows()) return; // Remove row heights, row positions and rows of cells. double removedHeight = 0.0; for (int i = 0; i < numRows; ++i) { // Remove row height and position. removedHeight += m_rowHeights.takeAt(index); m_rowPositions.removeAt(index); // Invalidate removed cells. foreach (TableCell removedCell, m_cellRows[index]) removedCell.setValid(false); // Remove row of cells. m_cellRows.removeAt(index); } // Adjust following rows. for (int nextRow = index; nextRow < rows() - numRows; ++nextRow) { // Adjust position of following row. m_rowPositions[nextRow] -= removedHeight; // "Move" cells in following row up. foreach (TableCell cell, m_cellRows[nextRow]) cell.moveUp(numRows); } // Update row spans. updateSpans(index, numRows, RowsRemoved); // Decrease number of rows. m_rows -= numRows; // Update cells. TODO: Not for entire table. updateCells(); // Remove any invalid cells from selection. QMutableSetIterator<TableCell> cellIt(m_selection); while (cellIt.hasNext()) if (!cellIt.next().isValid()) cellIt.remove(); // Move to cell below. moveTo(cellAt(qMin(index + 1, rows() - 1), m_activeColumn)); emit changed(); ASSERT_VALID(); }
void Field::prepare() { m_generated = false; m_MarkFlags = 0; m_numberOfOpenedCells = 0; setState(StateIdle); for (int i = 0; i < m_cells.size();i++) { m_cells[i]->reset(); QVector<Cell*> neighbors; for (int x = m_cells[i]->x() - 1; x <= m_cells[i]->x() + 1; ++x) { maybeAddCell(&neighbors, cellAt(x, m_cells[i]->y() - 1)); maybeAddCell(&neighbors, cellAt(x, m_cells[i]->y() + 1)); } maybeAddCell(&neighbors, cellAt(m_cells[i]->x() - 1, m_cells[i]->y())); maybeAddCell(&neighbors, cellAt(m_cells[i]->x() + 1, m_cells[i]->y())); m_cells[i]->setNeighbors(neighbors); } }
void PageItem_Table::removeColumns(int index, int numColumns) { ASSERT_VALID(); if (!validColumn(index) || numColumns < 1 || numColumns >= columns() || index + numColumns > columns()) return; // Remove column widths, column positions and columns of cells. double removedWidth = 0.0; for (int i = 0; i < numColumns; ++i) { // Remove columns widths and positions. removedWidth += m_columnWidths.takeAt(index); m_columnPositions.removeAt(index); // Remove and invalidate cells. QMutableListIterator<QList<TableCell> > rowIt(m_cellRows); while (rowIt.hasNext()) rowIt.next().takeAt(index).setValid(false); } // Adjust following columns. for (int nextColumn = index; nextColumn < columns() - numColumns; ++nextColumn) { // Adjust position of following column. m_columnPositions[nextColumn] -= removedWidth; // "Move" cells in following column left. foreach (QList<TableCell> cellRow, m_cellRows) cellRow[nextColumn].moveLeft(numColumns); } // Update column spans. updateSpans(index, numColumns, ColumnsRemoved); // Decrease number of columns. m_columns -= numColumns; // Update cells. TODO: Not for entire table. updateCells(); // Remove any invalid cells from selection. QMutableSetIterator<TableCell> cellIt(m_selection); while (cellIt.hasNext()) if (!cellIt.next().isValid()) cellIt.remove(); // Move to cell to the right. moveTo(cellAt(m_activeRow, qMin(m_activeColumn + 1, columns() - 1))); emit changed(); ASSERT_VALID(); }
TableCell PageItem_Table::cellAt(const QPointF& point) const { QPointF gridPoint = getTransform().inverted().map(point) - gridOffset(); if (!QRectF(0, 0, tableWidth(), tableHeight()).contains(gridPoint)) return TableCell(); // Outside table grid. return cellAt( qUpperBound(m_rowPositions, gridPoint.y()) - m_rowPositions.begin() - 1, qUpperBound(m_columnPositions, gridPoint.x()) - m_columnPositions.begin() - 1); }
double PageItem_Table::maxLeftBorderWidth() const { double maxWidth = 0.0; TableCell cell; for (int row = 0; row < rows(); row += cell.rowSpan()) { cell = cellAt(row, 0); maxWidth = qMax(maxWidth, TableUtils::collapseBorders(cell.leftBorder(), leftBorder()).width()); } return maxWidth; }
double PageItem_Table::maxBottomBorderWidth() const { double maxWidth = 0.0; TableCell cell; for (int col = 0; col < columns(); col += cell.columnSpan()) { cell = cellAt(rows() - 1, col); maxWidth = qMax(maxWidth, TableUtils::collapseBorders(bottomBorder(), cell.bottomBorder()).width()); } return maxWidth; }
/*! \fn QTextCursor QTextTable::rowStart(const QTextCursor &cursor) const Returns a cursor pointing to the start of the row that contains the given \a cursor. \sa rowEnd() */ QTextCursor QTextTable::rowStart(const QTextCursor &c) const { Q_D(const QTextTable); QTextTableCell cell = cellAt(c); if (!cell.isValid()) return QTextCursor(); int row = cell.row(); QTextDocumentPrivate *p = d->pieceTable; QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), d->grid[row*d->nCols]); return QTextCursor(p, it.position()); }
// Find a cell by id. Returns NULL if not found. PickerCell* PickerCells::cellWithId(const std::string& id) { for(int i=0; i<count(); i++) { PickerCell* cell = cellAt(i); if(cell->id() == id) { // Found it. return cell; } } // Didn't find a cell with the specified id. return NULL; }
void PageItem_Table::selectCells(int startRow, int startColumn, int endRow, int endColumn) { if (!validCell(startRow, startColumn) || !validCell(endRow, endColumn)) return; const TableCell startCell = cellAt(startRow, startColumn); const TableCell endCell = cellAt(endRow, endColumn); const int topRow = qMin(startCell.row(), endCell.row()); const int bottomRow = qMax(startCell.row() + startCell.rowSpan() - 1, endCell.row() + endCell.rowSpan() - 1); const int leftCol = qMin(startCell.column(), endCell.column()); const int rightCol = qMax(startCell.column() + startCell.columnSpan() - 1, endCell.column() + endCell.columnSpan() - 1); for (int row = topRow; row <= bottomRow; ++row) for (int col = leftCol; col <= rightCol; ++col) selectCell(row, col); emit selectionChanged(); }
void GridContainer::buildGrid(double gridPerThing) { int numThings = things.size(); extents.minExtent = vec(0,0,0,0); extents.maxExtent = vec(0,0,0,0); for (int i=0; i<numThings; i++) { extents.combine(things[i]->bounds()); } for (int x=0; x<3; x++) { extents.minExtent[x] -= EPSILON; extents.maxExtent[x] += EPSILON; } gridSize = (int)ceil(std::sqrt(gridPerThing * numThings)); std::cerr << gridSize << std::endl; if (grid) delete[] grid; unbounded.clear(); grid = new std::vector<Thing *>[(gridSize+1) * (gridSize+1) * (gridSize+1)]; cellSize = (extents.maxExtent - extents.minExtent) * (1.0/gridSize); for (int i=0; i<numThings; i++) { BoundingBox current = things[i]->bounds(); if (!current.isValid()) { unbounded.push_back(things[i]); } else { int mapMinX, mapMinY, mapMinZ; int mapMaxX, mapMaxY, mapMaxZ; vec shiftedMin = current.minExtent - extents.minExtent; vec shiftedMax = current.maxExtent - extents.minExtent; mapMinX = (int)(shiftedMin[0]/cellSize[0]); mapMinY = (int)(shiftedMin[1]/cellSize[1]); mapMinZ = (int)(shiftedMin[2]/cellSize[2]); //TODO: Make more sure this is correct mapMaxX = (int)(shiftedMax[0]/cellSize[0] + 1); mapMaxY = (int)(shiftedMax[1]/cellSize[1] + 1); mapMaxZ = (int)(shiftedMax[2]/cellSize[2] + 1); if (mapMaxX >= gridSize) mapMaxX = gridSize; if (mapMaxY >= gridSize) mapMaxY = gridSize; if (mapMaxZ >= gridSize) mapMaxZ = gridSize; for (int x=mapMinX; x<=mapMaxX; x++) for (int y=mapMinY; y<=mapMaxY; y++) for (int z=mapMinZ; z<mapMaxZ; z++) cellAt(x,y,z)->push_back(things[i]); } } }
void _equalizeflow(sim_Sim *s, int x, int y, double time) { int i; sim_Cell *cc, *bc;//center (x,y) sim_Cell *currs[4]; //current up, down, left right sim_Cell *buffs[4]; //next tick up, down, left right double heightdiff[4]; //>0 means flowing in double netflow; cc = &cellAt (x, y, s); bc = &cellAtBuff (x, y, s); currs[UP] = &cellAt (x, y - 1, s); buffs[UP] = &cellAtBuff (x, y - 1, s); currs[DN] = &cellAt (x, y + 1, s); buffs[DN] = &cellAtBuff (x, y + 1, s); currs[LF] = &cellAt (x - 1, y, s); buffs[LF] = &cellAtBuff (x - 1, y, s); currs[RT] = &cellAt (x + 1, y, s); buffs[RT] = &cellAtBuff (x + 1, y, s); if(x == 0) currs[LF] = NULL; if(x == s->w - 1) currs[RT] = NULL; if(y == 0) currs[UP] = NULL; if(y == s->h - 1) currs[DN] = NULL; for(i = 0; i < 4; i++) { if(currs[i]== NULL) continue; double dirflow;//net flow in the given direction dirflow = cc->flow[i] - currs[i]->flow[(i+2)%4]; dirflow /= 2; bc->flow[i] = dirflow; buffs[i]->flow[(i+2)%4] = -1 * dirflow; } }
/*! \fn QTextCursor QTextTable::rowEnd(const QTextCursor &cursor) const Returns a cursor pointing to the end of the row that contains the given \a cursor. \sa rowStart() */ QTextCursor QTextTable::rowEnd(const QTextCursor &c) const { Q_D(const QTextTable); QTextTableCell cell = cellAt(c); if (!cell.isValid()) return QTextCursor(); int row = cell.row() + 1; int fragment = row < d->nRows ? d->grid[row*d->nCols] : d->fragment_end; QTextDocumentPrivate *p = d->pieceTable; QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), fragment); return QTextCursor(p, it.position() - 1); }