00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "BoardLayout.h"
00021 #include <QFile>
00022 #include <qtextstream.h>
00023 #include <qtextcodec.h>
00024
00025 BoardLayout::BoardLayout()
00026 {
00027 filename="";
00028 m_width = 32;
00029 m_height = 16;
00030 m_depth = 5;
00031 board = QByteArray(m_width*m_height*m_depth, 0);
00032 clearBoardLayout();
00033 }
00034
00035 BoardLayout::~BoardLayout()
00036 {
00037 }
00038
00039 void BoardLayout::clearBoardLayout() {
00040 loadedBoard="";
00041 initialiseBoard();
00042 }
00043
00044 bool BoardLayout::saveBoardLayout(const QString &where) {
00045 QFile f(where);
00046 if (!f.open(QIODevice::ReadWrite)) {
00047 return false;
00048 }
00049
00050 QByteArray tmp = layoutMagic1_1.toUtf8();
00051 if (f.write(tmp, tmp.length()) == -1) {
00052 return(false);
00053 }
00054
00055 tmp = QString("\nw%1").arg(m_width).toUtf8();
00056 if (f.write(tmp, tmp.length()) == -1) {
00057 return(false);
00058 }
00059
00060 tmp = QString("\nh%1").arg(m_height).toUtf8();
00061 if (f.write(tmp, tmp.length()) == -1) {
00062 return(false);
00063 }
00064
00065 tmp = QString("\nd%1").arg(m_depth).toUtf8();
00066 if (f.write(tmp, tmp.length()) == -1) {
00067 return(false);
00068 }
00069
00070 for (int z=0; z<m_depth; z++) {
00071 for(int y=0; y<m_height; y++) {
00072 if(!f.putChar('\n'))
00073 return(false);
00074 for (int x=0; x<m_width; x++) {
00075 if (getBoardData(z,y,x)) {
00076 if(!f.putChar(getBoardData(z,y,x)))
00077 return false;
00078 } else {
00079 if(!f.putChar('.'))
00080 return false;
00081 }
00082 }
00083 }
00084 }
00085 return f.putChar('\n');
00086 }
00087
00088 bool BoardLayout::loadBoardLayout_10(const QString &from)
00089 {
00090 if (from == filename) {
00091 return true;
00092 }
00093
00094 QFile f(from);
00095 QString all = "";
00096
00097 if ( f.open(QIODevice::ReadOnly) ) {
00098 QTextStream t( &f );
00099 t.setCodec(QTextCodec::codecForName("UTF-8"));
00100 QString s;
00101 s = t.readLine();
00102 if (s != layoutMagic1_0) {
00103 f.close();
00104 return(false);
00105 }
00106
00107 m_width = 32;
00108 m_height = 16;
00109 m_depth = 5;
00110 int lines = 0;
00111 while ( !t.atEnd() ) {
00112 s = t.readLine();
00113 if (s[0] == '#')
00114 continue;
00115 all += s;
00116 lines++;
00117 }
00118 f.close();
00119 if (lines == m_height*m_depth) {
00120 loadedBoard = all.toLatin1();
00121 initialiseBoard();
00122 filename = from;
00123 return(true);
00124 } else {
00125 return(false);
00126 }
00127 return(true);
00128 } else {
00129 return(false);
00130 }
00131 }
00132
00133 bool BoardLayout::loadBoardLayout(const QString &from)
00134 {
00135 if (from == filename) {
00136 return true;
00137 }
00138
00139 QFile f(from);
00140 QString all = "";
00141 if ( f.open(QIODevice::ReadOnly) ) {
00142 QTextStream t( &f );
00143 t.setCodec(QTextCodec::codecForName("UTF-8"));
00144 QString s;
00145 s = t.readLine();
00146 if (s != layoutMagic1_1) {
00147 f.close();
00148
00149 return(loadBoardLayout_10(from));
00150 }
00151 int lines = 0;
00152 m_width = m_height = m_depth = 0;
00153 while ( !t.atEnd() ) {
00154 s = t.readLine();
00155 if (s[0] == '#')
00156 continue;
00157 if (s[0] == 'w') {
00158 m_width = s.mid(1).toInt();
00159 continue;
00160 }
00161 if (s[0] == 'h') {
00162 m_height = s.mid(1).toInt();
00163 continue;
00164 }
00165 if (s[0] == 'd') {
00166 m_depth = s.mid(1).toInt();
00167 continue;
00168 }
00169 all += s;
00170 lines++;
00171 }
00172 f.close();
00173 if ((lines == m_height*m_depth)&&(m_width>0)&&(m_height>0)&&(m_depth>0)) {
00174 loadedBoard = all.toLatin1();
00175 initialiseBoard();
00176 filename = from;
00177 return(true);
00178 } else {
00179 return(false);
00180 }
00181 return(true);
00182 } else {
00183 return(false);
00184 }
00185 }
00186
00187 void BoardLayout::initialiseBoard() {
00188 short z=0;
00189 short x=0;
00190 short y=0;
00191 maxTileNum = 0;
00192
00193 if (loadedBoard.isEmpty())
00194 return;
00195
00196 m_maxTiles = (m_width*m_height*m_depth)/4;
00197 board.resize(m_width*m_height*m_depth);
00198 board.fill(0);
00199
00200 int idx = 0;
00201
00202 while( true )
00203 {
00204 BYTE c = loadedBoard.at(idx++);
00205 switch( c )
00206 {
00207 case (UCHAR)'1': maxTileNum++;
00208 case (UCHAR)'3':
00209 case (UCHAR)'2':
00210 case (UCHAR)'4': setBoardData(z,y,x,c);
00211 break;
00212
00213 default: setBoardData(z,y,x,0);
00214 break;
00215 }
00216 if( ++x == m_width)
00217 {
00218 x=0;
00219 if( ++y == m_height)
00220 {
00221 y=0;
00222 if( ++z == m_depth)
00223 {
00224
00225 if( maxTileNum & 1 ) break;
00226 return;
00227 }
00228 }
00229 }
00230 }
00231 }
00232
00233 void BoardLayout::copyBoardLayout(UCHAR *to , unsigned short &n){
00234 memcpy(to, board.data(), m_width*m_height*m_depth);
00235 n = maxTileNum;
00236 }
00237
00238 void BoardLayout::shiftLeft() {
00239 for (int z=0; z<m_depth; z++) {
00240 for (int y=0; y<m_height; y++) {
00241 UCHAR keep=getBoardData(z,y,0);
00242 if (keep == '1') {
00243
00244 setBoardData(z,y,0,0);
00245 setBoardData(z,y,1,0);
00246 if (y<m_height-1) {
00247 setBoardData(z,y+1,0,0);
00248 setBoardData(z,y+1,1,0);
00249 }
00250 }
00251 for (int x=0; x<m_width-1; x++) {
00252 setBoardData(z,y,x,getBoardData(z,y,x+1));
00253 }
00254 setBoardData(z,y,m_width-1,0);
00255 }
00256 }
00257 }
00258
00259
00260 void BoardLayout::shiftRight() {
00261 for (int z=0; z<m_depth; z++) {
00262 for (int y=0; y<m_height; y++) {
00263 UCHAR keep=getBoardData(z,y,m_width-2);
00264 if (keep == '1') {
00265
00266 setBoardData(z,y,m_width-2,0);
00267 setBoardData(z,y,m_width-1,0);
00268 if (y < m_height-1) {
00269 setBoardData(z,y+1,m_width-2,0);
00270 setBoardData(z,y+1,m_width-1,0);
00271 }
00272 }
00273 for (int x=m_width-1; x>0; x--) {
00274 setBoardData(z,y,x,getBoardData(z,y,x-1));
00275 }
00276 setBoardData(z,y,0,0);
00277 }
00278 }
00279 }
00280 void BoardLayout::shiftUp() {
00281 for (int z=0; z<m_depth; z++) {
00282
00283 for (int x=0; x<m_width; x++) {
00284 if (getBoardData(z,0,x) == '1') {
00285 setBoardData(z,0,x,0);
00286 if (x<m_width-1) {
00287 setBoardData(z,0,x+1,0);
00288 setBoardData(z,1,x+1,0);
00289 }
00290 setBoardData(z,1,x,0);
00291 }
00292 }
00293 }
00294 for (int z=0; z<m_depth;z++) {
00295 for (int y=0; y<m_height-1; y++) {
00296 for (int x=0; x<m_width; x++) {
00297 setBoardData(z,y,x,getBoardData(z,y+1,x));
00298 if (y == m_height-2)
00299 setBoardData(z,y+1,x,0);
00300 }
00301 }
00302 }
00303 }
00304
00305
00306 void BoardLayout::shiftDown() {
00307 for (int z=0; z<m_depth; z++) {
00308
00309 for (int x=0; x<m_width; x++) {
00310 if (getBoardData(z,m_height-2,x) == '1') {
00311 setBoardData(z,m_height-2,x,0);
00312 if (x<m_width-1) {
00313 setBoardData(z,m_height-2,x+1,0);
00314 setBoardData(z,m_height-1,x+1,0);
00315 }
00316 setBoardData(z,m_height-1,x,0);
00317 }
00318 }
00319 }
00320 for (int z=0; z<m_depth;z++) {
00321 for (int y=m_height-1; y>0; y--) {
00322 for (int x=0; x<m_width; x++) {
00323 setBoardData(z,y,x,getBoardData(z,y-1,x));
00324 if (y == 1)
00325 setBoardData(z,y-1,x,0);
00326 }
00327 }
00328 }
00329 }
00330
00331
00332
00333 bool BoardLayout::tileAbove(short z, short y, short x) {
00334 if (z >= m_depth -1)
00335 return false;
00336 if( getBoardData(z+1,y,x) || getBoardData(z+1,y+1,x) || getBoardData(z+1,y,x+1) || getBoardData(z+1,y+1,x+1) ) {
00337 return true;
00338 }
00339 return false;
00340 }
00341
00342
00343 bool BoardLayout::blockedLeftOrRight(short z, short y, short x) {
00344 return( (getBoardData(z,y,x-1) || getBoardData(z,y+1,x-1)) &&
00345 (getBoardData(z,y,x+2) || getBoardData(z,y+1,x+2)) );
00346 }
00347
00348 void BoardLayout::deleteTile(POSITION &p) {
00349 if ( p.e <m_depth && getBoardData(p.e,p.y,p.x) == '1') {
00350 setBoardData(p.e,p.y,p.x,0);
00351 setBoardData(p.e,p.y,p.x+1,0);
00352 setBoardData(p.e,p.y+1,p.x,0);
00353 setBoardData(p.e,p.y+1,p.x+1,0);
00354 maxTileNum--;
00355 }
00356 }
00357
00358 bool BoardLayout::anyFilled(POSITION &p) {
00359 return(getBoardData(p.e, p.y, p.x) != 0 ||
00360 getBoardData(p.e, p.y, p.x+1) != 0 ||
00361 getBoardData(p.e, p.y+1, p.x) != 0 ||
00362 getBoardData(p.e, p.y+1, p.x+1) != 0);
00363 }
00364 bool BoardLayout::allFilled(POSITION &p) {
00365 return(getBoardData(p.e, p.y, p.x) != 0 &&
00366 getBoardData(p.e, p.y, p.x+1) != 0 &&
00367 getBoardData(p.e, p.y+1, p.x) != 0 &&
00368 getBoardData(p.e, p.y+1, p.x+1) != 0);
00369 }
00370 void BoardLayout::insertTile(POSITION &p) {
00371 setBoardData(p.e,p.y,p.x,'1');
00372 setBoardData(p.e,p.y,p.x+1,'2');
00373 setBoardData(p.e,p.y+1,p.x+1,'3');
00374 setBoardData(p.e,p.y+1,p.x,'4');
00375 }
00376
00377 UCHAR BoardLayout::getBoardData(short z, short y, short x) {
00378 return board.at((z*m_width*m_height)+(y*m_width)+x);
00379 }
00380
00381 void BoardLayout::setBoardData(short z, short y, short x, UCHAR value) {
00382 board[(z*m_width*m_height)+(y*m_width)+x] = value;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391