void Board::newGame() { //kdDebug() << "NewGame" << endl; int i, x, y, k; mark_x = -1; mark_y = -1; highlighted_tile = -1; // will clear previous highlight _undo.clear(); _redo.clear(); connection.clear(); // distribute all tiles on board int cur_tile = 1; for(y = 0; y < y_tiles(); y += 4) { for(x = 0; x < x_tiles(); ++x) { for(k = 0; k < 4 && y + k < y_tiles(); k++) setField(x, y + k, cur_tile); cur_tile++; if(cur_tile > TileSet::nTiles) cur_tile = 1; } } if(getShuffle() == 0) { update(); starttime = time((time_t *)0); emit changed(); return; } // shuffle the field int tx = x_tiles(); int ty = y_tiles(); for(i = 0; i < x_tiles() * y_tiles() * getShuffle(); i++) { int x1 = random.getLong(tx); int y1 = random.getLong(ty); int x2 = random.getLong(tx); int y2 = random.getLong(ty); int t = getField(x1, y1); setField(x1, y1, getField(x2, y2)); setField(x2, y2, t); } // do not make solvable if _solvable_flag is false if(!_solvable_flag) { update(); starttime = time((time_t *)0); emit changed(); return; } int fsize = x_tiles() * y_tiles() * sizeof(int); int *oldfield = new int[x_tiles() * y_tiles()]; memcpy(oldfield, field, fsize); // save field int *tiles = new int[x_tiles() * y_tiles()]; int *pos = new int[x_tiles() * y_tiles()]; while(!solvable(true)) { //kdDebug() << "Not solvable" << endl; //dumpBoard(); // generate a list of free tiles and positions int num_tiles = 0; for(i = 0; i < x_tiles() * y_tiles(); i++) if(field[i] != EMPTY) { pos[num_tiles] = i; tiles[num_tiles] = field[i]; num_tiles++; } // restore field memcpy(field, oldfield, fsize); // redistribute unsolved tiles while(num_tiles > 0) { // get a random tile int r1 = random.getLong(num_tiles); int r2 = random.getLong(num_tiles); int tile = tiles[r1]; int apos = pos[r2]; // truncate list tiles[r1] = tiles[num_tiles-1]; pos[r2] = pos[num_tiles-1]; num_tiles--; // put this tile on the new position field[apos] = tile; } // remember field memcpy(oldfield, field, fsize); } // restore field memcpy(field, oldfield, fsize); delete tiles; delete pos; delete oldfield; update(); starttime = time((time_t *)0); emit changed(); }
void Board::newGame() { int i, j, x, y, k; mark_x = -1; mark_y = -1; while(_undo.count()) _undo.removeFirst(); while(_redo.count()) _redo.removeFirst(); clearHistory(); for(i = 0; i < x_tiles(); i++) for(j = 0; j < y_tiles(); j++) setField(i, j, EMPTY); // distribute all tiles on board int cur_tile = 0; for(i = 0; i < x_tiles() * y_tiles() * 12; i++) { // map the tileindex to a tile // not all tiles from the pixmap are really used, only // 36 out of 45 are used. This maps and index to // the "real" index. int tile; if(cur_tile == 28) tile = 30; else if(cur_tile >= 29 && cur_tile <= 35) tile = cur_tile + 7; else tile = cur_tile; cur_tile++; if(cur_tile == 36) cur_tile = 0; x = i % x_tiles(); y = i / x_tiles() * 4; tile++; for(k = 0; k < 4 && k + y < y_tiles(); k++) setField(x, y+k, tile); } if(getShuffle() == 0) { if(!trying) { update(); starttime = time((time_t *)0); emit changed(); } return; } // shuffle the field int tx = x_tiles(); int ty = y_tiles(); for(i = 0; i < x_tiles() * y_tiles() * getShuffle(); i++) { int x1 = random(tx); int y1 = random(ty); int x2 = random(tx); int y2 = random(ty); int t = getField(x1, y1); setField(x1, y1, getField(x2, y2)); setField(x2, y2, t); } // do not make solvable if _solvable_flag is FALSE if(!_solvable_flag) { if(!trying) { update(); starttime = time((time_t *)0); emit changed(); } return; } int fsize = x_tiles() * y_tiles() * sizeof(int); int *oldfield = new int[x_tiles() * y_tiles()]; memcpy(oldfield, field, fsize); // save field int *tiles = new int[x_tiles() * y_tiles()]; int *pos = new int[x_tiles() * y_tiles()]; while(!solvable(TRUE)) { // generate a list of free tiles and positions int num_tiles = 0; for(i = 0; i < x_tiles() * y_tiles(); i++) if(field[i] != EMPTY) { pos[num_tiles] = i; tiles[num_tiles] = field[i]; num_tiles++; } // restore field memcpy(field, oldfield, fsize); // redistribute unsolved tiles while(num_tiles > 0) { // get a random tile int r1 = random(num_tiles); int r2 = random(num_tiles); int tile = tiles[r1]; int apos = pos[r2]; // truncate list tiles[r1] = tiles[num_tiles-1]; pos[r2] = pos[num_tiles-1]; num_tiles--; // put this tile on the new position field[apos] = tile; } // remember field memcpy(oldfield, field, fsize); } // restore field memcpy(field, oldfield, fsize); delete tiles; delete pos; delete oldfield; if(!trying) { update(); starttime = time((time_t *)0); emit changed(); } }