#include "BoardLayout.h" #include <tqfile.h> #include <tqtextstream.h> #include <tqtextcodec.h> BoardLayout::BoardLayout() { filename=""; clearBoardLayout(); } BoardLayout::~BoardLayout() { } void BoardLayout::clearBoardLayout() { loadedBoard=""; initialiseBoard(); } bool BoardLayout::saveBoardLayout(const TQString where) { TQFile f(where); if (!f.open(IO_ReadWrite)) { return false; } TQCString tmp = layoutMagic1_0.utf8(); if (f.writeBlock(tmp, tmp.length()) == -1) { return(false); } for (int z=0; z<depth; z++) { for(int y=0; y<height; y++) { if(f.putch('\n')==-1) return(false); for (int x=0; x<width; x++) { if (board[z][y][x]) { if(f.putch(board[z][y][x])==-1) return false; } else { if(f.putch('.')==-1) return false; } } } } if(f.putch('\n')!=-1) return true; else return false; } bool BoardLayout::loadBoardLayout(const TQString from) { if (from == filename) { return true; } TQFile f(from); TQString all = ""; if ( f.open(IO_ReadOnly) ) { TQTextStream t( &f ); t.setCodec(TQTextCodec::codecForName("UTF-8")); TQString s; s = t.readLine(); if (s != layoutMagic1_0) { f.close(); return(false); } int lines = 0; while ( !t.eof() ) { s = t.readLine(); if (s[0] == '#') continue; all += s; lines++; } f.close(); if (lines == height*depth) { loadedBoard = all; initialiseBoard(); filename = from; return(true); } else { return(false); } return(true); } else { return(false); } } void BoardLayout::initialiseBoard() { short z=0; short x=0; // Rand lassen. short y=0; maxTileNum = 0; const char *pos = (const char *) loadedBoard.ascii(); memset( &board, 0, sizeof( board) ); if (loadedBoard.isEmpty()) return; // loop will be left by break or return while( true ) { BYTE c = *pos++; switch( c ) { case (UCHAR)'1': maxTileNum++; case (UCHAR)'3': case (UCHAR)'2': case (UCHAR)'4': board[z][y][x] = c; break; default: break; } if( ++x == width) { x=0; if( ++y == height) { y=0; if( ++z == depth) { // number of tiles have to be even if( maxTileNum & 1 ) break; return; } } } } } void BoardLayout::copyBoardLayout(UCHAR *to , unsigned short &n){ memcpy(to, board, sizeof(board)); n = maxTileNum; } const char* BoardLayout::getBoardLayout() { return loadedBoard.ascii(); } void BoardLayout::shiftLeft() { for (int z=0; z<depth; z++) { for (int y=0; y<height; y++) { UCHAR keep=board[z][y][0]; if (keep == '1') { // tile going off board, delete it board[z][y][0]=0; board[z][y][1]=0; board[z][y+1][0]=0; board[z][y+1][1]=0; } for (int x=0; x<width-1; x++) { board[z][y][x] = board[z][y][x+1]; } board[z][y][width-1] = 0; } } } void BoardLayout::shiftRight() { for (int z=0; z<depth; z++) { for (int y=0; y<height; y++) { UCHAR keep=board[z][y][width-2]; if (keep == '1') { // tile going off board, delete it board[z][y][width-2]=0; board[z][y][width-1]=0; board[z][y+1][width-2]=0; board[z][y+1][width-1]=0; } for (int x=width-1; x>0; x--) { board[z][y][x] = board[z][y][x-1]; } board[z][y][0] = 0; } } } void BoardLayout::shiftUp() { for (int z=0; z<depth; z++) { // remove tiles going off the top for (int x=0; x<width; x++) { if (board[z][0][x] == '1') { board[z][0][x] = 0; board[z][0][x+1] = 0; board[z][1][x] = 0; board[z][1][x+1] = 0; } } } for (int z=0; z<depth;z++) { for (int y=0; y<height-1; y++) { for (int x=0; x<width; x++) { board[z][y][x]=board[z][y+1][x]; if (y == height-2) board[z][y+1][x]=0; } } } } void BoardLayout::shiftDown() { for (int z=0; z<depth; z++) { // remove tiles going off the top for (int x=0; x<width; x++) { if (board[z][height-2][x] == '1') { board[z][height-2][x] = 0; board[z][height-2][x+1] = 0; board[z][height-1][x] = 0; board[z][height-1][x+1] = 0; } } } for (int z=0; z<depth;z++) { for (int y=height-1; y>0; y--) { for (int x=0; x<width; x++) { board[z][y][x]=board[z][y-1][x]; if (y == 1) board[z][y-1][x]=0; } } } } // is there a tile anywhere above here (top left to bot right quarter) bool BoardLayout::tileAbove(short z, short y, short x) { if (z >= depth -1) return false; if( board[z+1][y][x] || board[z+1][y+1][x] || board[z+1][y][x+1] || board[z+1][y+1][x+1] ) { return true; } return false; } bool BoardLayout::blockedLeftOrRight(short z, short y, short x) { return( (board[z][y][x-1] || board[z][y+1][x-1]) && (board[z][y][x+2] || board[z][y+1][x+2]) ); } void BoardLayout::deleteTile(POSITION &p) { if ( p.e <depth && board[p.e][p.y][p.x] == '1') { board[p.e][p.y][p.x]=0; board[p.e][p.y][p.x+1]=0; board[p.e][p.y+1][p.x]=0; board[p.e][p.y+1][p.x+1]=0; maxTileNum--; } } bool BoardLayout::anyFilled(POSITION &p) { return(board[p.e][ p.y][ p.x] != 0 || board[p.e][ p.y][ p.x+1] != 0 || board[p.e][ p.y+1][ p.x] != 0 || board[p.e][ p.y+1][ p.x+1] != 0); } bool BoardLayout::allFilled(POSITION &p) { return(board[p.e][ p.y][ p.x] != 0 && board[p.e][p.y][ p.x+1] != 0 && board[p.e][p.y+1][ p.x] != 0 && board[p.e][p.y+1][ p.x+1] != 0); } void BoardLayout::insertTile(POSITION &p) { board[p.e][p.y][p.x] = '1'; board[p.e][p.y][p.x+1] = '2'; board[p.e][p.y+1][p.x+1] = '3'; board[p.e][p.y+1][p.x] = '4'; }