• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kmahjongg

BoardLayout.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 1997 Mathias Mueller   <in5y158@public.uni-hamburg.de>
00003     Copyright (C) 2006 Mauricio Piacentini   <mauricio@tabuleiro.com>
00004 
00005     Kmahjongg is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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     //version 1.0 layouts used hardcoded board dimensions
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         //maybe a version 1_0 layout?
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     // loop will be left by break or return
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                     // number of tiles have to be even
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             // tile going off board, delete it
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             // tile going off board, delete it
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     // remove tiles going off the top
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     // remove tiles going off the top
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 // is there a tile anywhere above here (top left to bot right quarter)
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 

kmahjongg

Skip menu "kmahjongg"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

API Reference

Skip menu "API Reference"
  • kblackbox
  • kgoldrunner
  • kmahjongg
  • ksquares
  • libkdegames
  •   highscore
  •   kgame
  •   kggzgames
  •   kggzmod
  •   kggznet
  • libkmahjongg
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal