File indexing completed on 2024-03-24 04:04:48
0001 /*************************************************************************** 0002 * KBlocks, a falling blocks game by KDE * 0003 * SPDX-FileCopyrightText: 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com> * 0004 * * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 ***************************************************************************/ 0007 #include "KBlocksLayout.h" 0008 0009 KBlocksLayout::KBlocksLayout(FieldInterface *pF, PieceInterface *pA, PieceInterface *pN) 0010 { 0011 mpGameField = pF; 0012 mpActivePiece = pA; 0013 mpNextPiece = pN; 0014 0015 mPieceCellCount = mpActivePiece->getCellCount(); 0016 mpLastPiecePos = new QPoint*[mPieceCellCount]; 0017 for (int i = 0; i < mPieceCellCount; i++) { 0018 mpLastPiecePos[i] = new QPoint(0, 0); 0019 } 0020 0021 mWidth = mpGameField->getWidth(); 0022 mHeight = mpGameField->getHeight(); 0023 boardInfo = new int *[mHeight]; 0024 for (int i = 0; i < mHeight; i++) { 0025 boardInfo[i] = new int[mWidth]; 0026 for (int j = 0; j < mWidth; j++) { 0027 boardInfo[i][j] = -1; 0028 } 0029 } 0030 0031 prepareInfo = new int *[PREPARE_AREA_WIDTH]; 0032 for (int i = 0; i < PREPARE_AREA_WIDTH; i++) { 0033 prepareInfo[i] = new int[PREPARE_AREA_WIDTH]; 0034 for (int j = 0; j < PREPARE_AREA_WIDTH; j++) { 0035 prepareInfo[i][j] = -1; 0036 } 0037 } 0038 } 0039 0040 KBlocksLayout::~KBlocksLayout() 0041 { 0042 for (int i = 0; i < mHeight; i++) { 0043 delete [] boardInfo[i]; 0044 } 0045 delete [] boardInfo; 0046 0047 for (int i = 0; i < PREPARE_AREA_WIDTH; i++) { 0048 delete [] prepareInfo[i]; 0049 } 0050 delete [] prepareInfo; 0051 0052 for (int i = 0; i < mPieceCellCount; i++) { 0053 delete mpLastPiecePos[i]; 0054 } 0055 delete [] mpLastPiecePos; 0056 } 0057 0058 void KBlocksLayout::beginUpdate(QList<int> *list) 0059 { 0060 int px = 0; 0061 int py = 0; 0062 list->clear(); 0063 for (int i = 0; i < mPieceCellCount; i++) { 0064 px = mpLastPiecePos[i]->x(); 0065 py = mpLastPiecePos[i]->y(); 0066 list->append(px); 0067 list->append(py); 0068 if ((px >= 0) && (px < mWidth) 0069 && (py >= 0) && (py < mHeight)) { 0070 boardInfo[py][px] = -1; 0071 } 0072 } 0073 } 0074 0075 void KBlocksLayout::updateLayout(int type, const QList<int> &dataList) 0076 { 0077 switch (type) { 0078 case KBlocksLayout_Update_FreezePiece: 0079 updateFreezePiece(dataList); 0080 break; 0081 case KBlocksLayout_Update_RemoveLine: 0082 updateRemoveLine(dataList); 0083 break; 0084 case KBlocksLayout_Update_PunishLine: 0085 updatePunishLine(dataList); 0086 break; 0087 } 0088 } 0089 0090 void KBlocksLayout::endUpdate() 0091 { 0092 int px = 0; 0093 int py = 0; 0094 int activePieceColor = mpActivePiece->getType(); 0095 for (int i = 0; i < mPieceCellCount; i++) { 0096 px = mpActivePiece->getCellPosX(i); 0097 py = mpActivePiece->getCellPosY(i); 0098 mpLastPiecePos[i]->setX(px); 0099 mpLastPiecePos[i]->setY(py); 0100 if ((px >= 0) && (px < mWidth) 0101 && (py >= 0) && (py < mHeight)) { 0102 boardInfo[py][px] = activePieceColor; 0103 } 0104 } 0105 0106 updatePrepareArea(); 0107 } 0108 0109 void KBlocksLayout::updateSnapshot() 0110 { 0111 for (int y = 0; y < mHeight; y++) { 0112 for (int x = 0; x < mWidth; x++) { 0113 if (mpGameField->getCell(x, y)) { 0114 boardInfo[y][x] = 0; // TODO : what color is better here? 0115 } else { 0116 boardInfo[y][x] = -1; 0117 } 0118 } 0119 } 0120 0121 endUpdate(); 0122 } 0123 0124 int KBlocksLayout::getFieldColor(int posX, int posY) 0125 { 0126 if ((posX < 0) || (posX >= mWidth) || (posY < 0) || (posY >= mHeight)) { 0127 return -1; 0128 } 0129 0130 return boardInfo[posY][posX]; 0131 } 0132 0133 int KBlocksLayout::getPrepareColor(int posX, int posY) 0134 { 0135 if ((posX < 0) || (posX >= PREPARE_AREA_WIDTH) || (posY < 0) || (posY >= PREPARE_AREA_WIDTH)) { 0136 return -1; 0137 } 0138 0139 return prepareInfo[posY][posX]; 0140 } 0141 0142 void KBlocksLayout::updatePrepareArea() 0143 { 0144 for (int i = 0; i < PREPARE_AREA_WIDTH; i++) { 0145 for (int j = 0; j < PREPARE_AREA_WIDTH; j++) { 0146 prepareInfo[i][j] = -1; 0147 } 0148 } 0149 0150 int nextPieceColor = mpNextPiece->getType(); 0151 for (int i = 0; i < 4; i++) { 0152 int posX = mpNextPiece->getCellPosX(i); 0153 int posY = mpNextPiece->getCellPosY(i); 0154 prepareInfo[posY][posX] = nextPieceColor; 0155 } 0156 } 0157 0158 void KBlocksLayout::updateFreezePiece(const QList<int> &dataList) 0159 { 0160 QList<int> tmpList = dataList; 0161 int freezeColor = tmpList.takeFirst(); 0162 int loopCount = tmpList.size() / 2; 0163 for (int i = 0; i < loopCount; i++) { 0164 int posX = tmpList[i * 2]; 0165 int posY = tmpList[i * 2 + 1]; 0166 if ((posX >= 0) && (posX < mWidth) 0167 && (posY >= 0) && (posY < mHeight)) { 0168 boardInfo[posY][posX] = freezeColor; 0169 } 0170 } 0171 } 0172 0173 void KBlocksLayout::updateRemoveLine(const QList<int> &dataList) 0174 { 0175 int lineCount = dataList.size(); 0176 for (int k = 0; k < lineCount; k++) { 0177 for (int i = dataList[k]; i > 0; i--) { 0178 for (int j = 0; j < mWidth; j++) { 0179 boardInfo[i][j] = boardInfo[i - 1][j]; 0180 } 0181 } 0182 for (int j = 0; j < mWidth; j++) { 0183 boardInfo[0][j] = -1; 0184 } 0185 } 0186 } 0187 0188 void KBlocksLayout::updatePunishLine(const QList<int> &dataList) 0189 { 0190 int punishColor = mpNextPiece->getType(); // TODO : this color or new color? 0191 int lineCount = dataList.size(); 0192 for (int k = 0; k < lineCount; k++) { 0193 for (int i = 0; i < mHeight - dataList[k]; i++) { 0194 for (int j = 0; j < mWidth; j++) { 0195 boardInfo[i][j] = boardInfo[i + dataList[k]][j]; 0196 } 0197 } 0198 for (int i = mHeight - dataList[k]; i < mHeight; i++) { 0199 for (int j = 0; j < mWidth; j++) { 0200 if (mpGameField->getCell(j, i)) { 0201 boardInfo[i][j] = punishColor; 0202 } else { 0203 boardInfo[i][j] = -1; 0204 } 0205 } 0206 } 0207 } 0208 }