| |||||||
Du magst keine Werbung? Wir auch nicht!
Einfach registrieren und die Werbung ist weg. Diese Nachricht sehen nur nicht registrierte Nutzer.
![]() |
| | LinkBack | Themen-Optionen | Ansicht |
| | #1 (permalink) | |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
| [stuff] Array2d
Was zum Sammeln oder schnell ein Tetris abreissen. Mit dieser Klasse kann man bequem ein rechteckiges zweidimensionales Array verwalten. Ich habe versucht alle Array Methoden auf das Array2d zu übertragen. Es lassen sich also Zeilen oder Spalten löschen, verschieben, hinzufügen, dazwischenfügen. Das Array lässt sich spiegeln und/oder drehen. Vielleicht hat noch jemand weitere Ideen ? Beispiel: Code: import org.gamepackage.util.*; var map: Array2d = new Array2d( [1,2,3,0], [4,5,6,0], [7,8,9,0] ); trace( "UrsprungsMap" ); trace( map ); trace( "Ab Spalte 1, 2 Einträge löschen und zurückgeben. 2 Spalten hinzufügen( [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] )." ); trace( map.spliceCol( 1 , 2 , [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ) ); trace( "Neue Map" ); trace( map ); trace( "Drehen um den Urzeigersinn" ); map.rotateClockwise(); trace( "Neue Map" ); trace( map ); trace( "Drehen gegen den Urzeigersinn" ); map.rotateAntiClockwise(); trace( "Neue Map" ); trace( map ); Zitat:
Code: /* class Array2d
*
* MODIFY RECTANGLE 2D MAPS
*/
class org.gamepackage.util.Array2d extends Array
{
/*
* CONSTRUCTOR
*/
function Array2d()
{
splice.apply( this , [ 0 , 0 ].concat( arguments ) );
}
/*
* PUSHES A NEW ROW TO INSTANCE
* RETURN NEW ROW LENGTH
*/
function pushRow( row: Array ): Number
{
if( row.length != this[0].length ) return null;
return push( row );
}
/*
* PUSHES A NEW COL TO INSTANCE
* RETURN NEW COL LENGTH
*/
function pushCol( col: Array ): Number
{
if( col.length != this.length ) return null;
var len: Number = length;
while( --len > -1 )
{
this[ len ].push( col[ len ] );
}
return this[0].length;
}
/*
* UNSHIFT A NEW ROW TO INSTANCE
* RETURN NEW ROW LENGTH
*/
function unshiftRow( row: Array ): Number
{
if( row.length != this[0].length ) return null;
return unshift( row );
}
/*
* UNSHIFT A NEW COL TO INSTANCE
* RETURN NEW COL LENGTH
*/
function unshiftCol( col: Array ): Number
{
if( col.length != this.length ) return null;
var len: Number = length;
while( --len > -1 )
{
this[ len ].unshift( col[ len ] );
}
return this[0].length;
}
/*
* REMOVE LAST ROW FROM INSTANCE
* RETURN REMOVED ROW
*/
function popRow( Void ): Array
{
return Array( pop() );
}
/*
* REMOVE LAST COL FROM INSTANCE
* RETURN REMOVED COL
*/
function popCol( Void ): Array
{
var col: Array = new Array;
var len: Number = length;
while( --len > -1 )
{
col.unshift( this[ len ].pop() );
}
return col;
}
/*
* REMOVE FIRST ROW FROM INSTANCE
* RETURN REMOVED ROW
*/
function shiftRow( Void ): Array
{
return Array( shift() );
}
/*
* REMOVE FIRST COL FROM INSTANCE
* RETURN REMOVED COL
*/
function shiftCol( Void ): Array
{
var col: Array = new Array;
var len: Number = length;
while( --len > -1 )
{
col.unshift( this[ len ].shift() );
}
return col;
}
/*
* REMOVE ROWS FROM START TO END INDEX IN INSTANCE
* RETURNS NEW ARRAY2D WITH REMOVED ROWS
*/
function sliceRow( start: Number, end: Number ): Array2d
{
start = start - 1 || 0;
end = end || length;
var result: Array2d = new Array2d();
while( --end > start )
{
result.unshift( this[ end ] );
}
return result;
}
/*
* REMOVE COLS FROM START TO END INDEX IN INSTANCE
* RETURNS NEW ARRAY2D WITH REMOVED COLS
*/
function sliceCol( start: Number, end: Number ): Array2d
{
start = start || 0;
end = end || length;
var result: Array2d = new Array2d();
var len: Number = length;
while( --len > -1 )
{
result.unshift( this[len].slice( start, end ) );
}
return result;
}
/*
* REMOVE 'deleteCount' ROWS FROM STARTINDEX AND INSERT PASSED ROWS ARRAYS
* RETURNS REMOVED ROWS
*/
function spliceRow( start: Number, deleteCount: Number ) //@ TODO: FIX RETURN TYPE( Array2d )
{
return splice.apply( this , [ start , deleteCount ].concat( arguments.slice( 2 ) ) );
}
/*
* REMOVE 'deleteCount' COLS FROM STARTINDEX AND INSERT PASSED COLS ARRAYS
* RETURNS REMOVED COLS AS COPY(!) <<< NOT LIKE FLASH ARRAY
*/
function spliceCol( start: Number, deleteCount: Number ): Array2d
{
var len: Number = length;
var result: Array2d = new Array2d();
var newCols: Array = arguments.slice( 2 );
while( --len > -1 )
{
result.unshift( this[len].splice( start , deleteCount ) );
var cn: Number = newCols.length;
while( --cn > -1 )
{
this[len].splice( start , 0 , newCols[ cn ][ len ] );
}
}
return result;
}
/*
* ROTATE ALL ARRAY2D ENTRIES AROUND CENTER
*/
function rotateClockwise( Void ): Void
{
var copy: Array2d = clone();
var len: Number = this[0].length;
splice( 0 );
while( --len > -1 )
{
var o = copy.shiftCol();
o.reverse();
push( o );
}
}
/*
* ROTATE ALL ARRAY2D ENTRIES AROUND CENTER
*/
function rotateAntiClockwise( Void ): Void
{
var copy: Array2d = clone();
var len: Number = this[0].length;
splice( 0 );
while( --len > -1 )
{
this[ len ] = copy.shiftCol();
}
}
/*
* FLIP ALL ARRAY2D ENTRIES HORIZONTAL
*/
function flipHorizontal( Void ): Void
{
var len: Number = length;
while( --len > -1 )
{
this[ len ].reverse();
}
}
/*
* FLIP ALL ARRAY2D ENTRIES VERTICAL
*/
function flipVertical( Void ): Void
{
reverse();
}
/*
* RETURN NUMBER OF COLS
*/
function getNumCols( Void ): Number
{
return this[0].length;
}
/*
* RETURN NUMBER OF ROWS
*/
function getNumRows( Void ): Number
{
return length;
}
/*
* RETURNS TRUE IF ARRAY2D IS RECTANGLE
* AND FALSE IF NOT > INVAID
*/
function isRect( Void ): Boolean
{
var l0: Number = 0;
var l1: Number = Number.POSITIVE_INFINITY;
var len: Number = length;
var min: Function = Math.min;
var max: Function = Math.max;
while( --len > -1 )
{
l0 = max( this[ len ].length , l0 );
l1 = min( this[ len ].length , l1 );
}
return l0 == l1;
}
/*
* RETURNS A CLONE OF THE INSTANCE
*/
function clone( Void ): Array2d
{
var copy: Array2d = new Array2d;
var len: Number = length;
while( --len > -1 )
{
copy[ len ] = this[ len ].slice();
}
return copy;
}
/*
* RETURN FORMATTED STRING (EACH ROW A LINE)
*/
function toString( Void ): String
{
return join( newline );
}
} Geändert von André Michelle (29-10-2004 um 12:49 Uhr) | |
| | |
| | #2 (permalink) |
| flachzange Registriert seit: Jun 2003 Ort: berlin
Beiträge: 3.932
|
nette idee! nur bastel ich experimenteller weise an einem tetris mit einem linearen array, aber ganz durchsteigen tu ich da noch nicht ![]() -) 1 rotateAntiClockwise() in rotateCounterClockwise() oder rotateCCW() umbenennen -) 2 sumRow([row_id]) sumCol([col_id]) berechnet summe aus arrays mit nummern. -) 3 countTypeOf([typ]) zählt die datentypen die in einer reihe/zeile existieren. -) 4 getNextlIdCo([wert|typ], [toptobottom|bottomtotop] [, [offset] ]) getNextIdRow([wert|typ], [lefttoright|righttoleft] [, [offset] ]) sucht in reihe oder spalte von oben nach unten bzw von links nach rechts nach bestimmten wert. offset und suchrichtung optional?!? hab jetzt sicher etwas tetris gerichtet gedacht, so hätte man schon ne menge methoden die man braucht.
__________________ |
| | |
| | #3 (permalink) |
| helpQLODhelp Registriert seit: Feb 2002 Ort: Köln
Beiträge: 8.505
|
Nur weil ich gerade hier sehe, Void als Parameter für eine Funktion hat in Flash leider nicht den Effekt, dass der Compiler Parameter verbietet. Stattdessen wird eine sinnlose Variable angelegt. ActionScript:
mfg r.
__________________ Ralf Bokelberg™ - Flex & Flash Consulting Geändert von bokel (30-10-2004 um 00:11 Uhr) |
| | |
| | #4 (permalink) |
| flachzange Registriert seit: Jun 2003 Ort: berlin
Beiträge: 3.932
|
hab jetzt einige der vorgeschlagenen funktionen hinzugefügt. ausserdem habe ich noch eine ArrayUtil klasse gebaut die einige funktionen bietet um (mehrdimensionale-)arrays zu generieren. ArrayUtil Klasse: ActionScript:
die ArrayUtil.fill|fill2d sind vermutlich nutzlos, denn wenn ein array nicht bei 0 anfängt werden die vorlaufenden indizes auf undefined gesetzt. ArrayUtil.range|range2d kann man wohl seltener gebrauchen. die map methoden bieten schonmal eine nette grundlage für maps mit einheitlich vordefinierten werten. Array2d mit den hinzugefügten methoden: ActionScript:
countTypes* und sum* sind neu und könnten zb das finden von kompletten reihen für tetris transparenter gestalten. edit: ganz wichtig. ich habe den konstruktor der Array2d klasse geändert. jetzt wird ein einziges array erwartet und keine einzelnen reihen die als argumente übergeben werden. so ist es auch möglich ein ganzes array zu übergeben. edit2: ohgott! nächstes mal mach ich nen anhang
__________________ Geändert von elias (01-11-2004 um 22:14 Uhr) |
| | |
| | #6 (permalink) | |
| flachzange Registriert seit: Jun 2003 Ort: berlin
Beiträge: 3.932
| Zitat:
gesteckt werden. wenn man das zb bei tetris machen würde könnte man so komplette reihen einfach finden. ich lasse mich da aber gerne über sinn und unsinn belehren. ich habe jetzt einige änderungen vorgenommen: ArrayUtil heißt jetzt ArrayGenerator und ist durch erhöhung der abhängigkeiten ca um die hälfte geschrumpft und viel übersichtlicher. das geht wohl zur last der performance, aber maps generiert man ja nicht jedes frame. der Array2d klasse habe ich die searchValueInCol/searchValueInRow methoden geschenkt. denke das ist ganz nützlich. alles im anhang..
__________________ | |
| | |
| | #7 (permalink) | |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
| Zitat:
Zum Tetris hätte ich noch eine Idee. Von wegen lineares Array (1D). Schon überlegt mit Bytes zu arbeiten ? Eine Zeile hat die Bits: 1 2 4 8 16 32 64 128 256 512 Wenn eine Reihe gefüllt ist, dann ist der Wert 1023. Schön einfach :o) Kollisionsabfrage wäre auch simple mit dem & Operator. Ich frage mich nur, ob es möglich ist, ein Block per Bitoperatoren zu drehen. Möglich wird es sein, aber vielleicht gibt es eine besonders kurze und raffinierte Methode. | |
| | |
| | #8 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
|
Das hat mich nicht losgelassen :o) Code: //-- T - Block ( 3x3 Matrix )
a = 1 + 2 + 4 + 0 + 16 + 0 + 0 + 128 + 0;
//-- Rotate Matrix
r = ( ( a & 0x001 ) << 2 ) + ( ( a & 0x002 ) << 4 ) + ( ( a & 0x004 ) << 6 )
+( ( a & 0x008 ) >> 2 ) + ( ( a & 0x010 ) ) + ( ( a & 0x020 ) << 2 )
+( ( a & 0x040 ) >> 6 ) + ( ( a & 0x080 ) >> 4 ) + ( ( a & 0x100 ) >> 2 )
printMatrix = function( byte: Number, mLen: Number )
{
for( var y = 0 ; y < mLen ; y++ )
{
var row: String = new String( "" );
for( var x = 0 ; x < mLen ; x++ )
{
row += ( byte & ( 1 << x ) << ( y * mLen ) ) ? "*" : " ";
}
trace( row );
}
}
trace( "original:" );
printMatrix( a , 3 );
trace( "rotate:" );
printMatrix( r , 3 ); |
| | |
| | #9 (permalink) |
| flachzange Registriert seit: Jun 2003 Ort: berlin
Beiträge: 3.932
|
cool! wäre schon ne gute herausforderung. allerdings für mich etwas mehr weil bit schubsereien für mich nicht so alltäglich sind. ![]() edit: *grummel* zu magiemathisch. schaffs nichtmal ne 4x4 matrix auszugeben.
__________________ Geändert von elias (02-11-2004 um 14:50 Uhr) |
| | |
| | #10 (permalink) |
| Flashaholic Registriert seit: Feb 2003 Ort: Berlin
Beiträge: 1.459
|
OFFTOPIC @andre du hast echt ein an der waffel .schönes teil um zu verzweifeln bei bitverschiebungen. aber respekt mfg alex
__________________ TVNEXT Solutions |
| | |
| | #11 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
|
Danke für die Blumen :o) hier eine dynamische Lösung für eine n x n Matrix: Code: //-- Full Block
a = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024 + 2048 + 4096 + 8192 + 16384 + 32768;
rotateMatrix = function( byte: Number, mLen: Number )
{
var r: Number = 0;
var l: Number = mLen * mLen;
var mLenP = mLen + 1;
var mLenM = mLen - 1;
var pow: Function = Math.pow;
while( --l > -1 )
{
var shift: Number = mLen * 2 - int( l / mLen ) * mLenP + ( l % mLen * mLenM - mLenP );
if( shift > 0 )
{
r += ( byte & pow( 2 , l ) ) << shift;
}
else
{
r += ( byte & pow( 2 , l ) ) >> -shift;
}
}
return r;
}
printMatrix = function( byte: Number, mLen: Number )
{
for( var y = 0 ; y < mLen ; y++ )
{
var row: String = new String( "" );
for( var x = 0 ; x < mLen ; x++ )
{
row += ( byte & ( 1 << x ) << ( y * mLen ) ) ? "*" : " ";
}
trace( row );
}
}
r = rotateMatrix( a , 4 );
printMatrix( a , 4 );
printMatrix( r , 4 ); |
| | |
| | #12 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
|
Noch etwas schöner:) Code: rotateMatrix = function( byte: Number, mLen: Number )
{
var l: Number = mLen * mLen;
var mLenP = mLen + 1;
var mLenM = mLen - 1;
var r: Number = 0;
while( --l > -1 )
{
var shift: Number = mLen * 2 - int( l / mLen ) * mLenP + ( l % mLen * mLenM - mLenP );
if( shift > 0 )
{
r += ( ( 1 << l ) & byte ) << shift;
}
else
{
r += ( ( 1 << l ) & byte ) >> -shift;
}
}
return r;
} |
| | |
| | #13 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
|
Und letztendlich die Klasse mit Rechts- und Linksdrehung und beliebiger Ausdehnung. Geht aber leider nur bis zu 6x6 grossen Feldern, da sonst die Integergrenze in Flash erreicht ist. Code: import org.gamepackage.util.*; a = 1 + 2 + 0 + 0 + 16 + 0 + 0 + 0 + 256 + 0 + 1024 + 2048 + 4096 + 8192 + 16384 + 32768; var matrix: BitMatrix = new BitMatrix( a , 4 ); trace( "ORG:" ); trace( matrix ); matrix.rotateCCW(); trace( "CCW:" ); trace( matrix ); matrix.rotateCW(); trace( "CW:" ); trace( matrix ); Code: class org.gamepackage.util.BitMatrix
{
private var dim: Number;
private var byte: Number;
private var dimP: Number;
private var dimM: Number;
private var dim2: Number;
private var len: Number;
function BitMatrix( byte: Number, dim: Number )
{
this.byte = byte;
this.dim = dim;
precompute();
}
private function precompute( Void ): Void
{
dimP = dim + 1;
dimM = dim - 1;
dim2 = dim * 2;
len = dim * dim;
}
function rotateCW( Void ): Void
{
var shift: Number;
var l: Number = len;
var b: Number = 0;
while( --l > -1 )
{
if( ( shift = dim2 - int( l / dim ) * dimP + ( l % dim * dimM - dimP ) ) > 0 )
{
b += ( ( 1 << l ) & byte ) << shift;
}
else
{
b += ( ( 1 << l ) & byte ) >> -shift;
}
}
byte = b;
}
function rotateCCW( Void ): Void
{
var shift: Number;
var l: Number = len;
var b: Number = 0;
while( --l > -1 )
{
if( ( shift = -( l % dim ) * dimP + dim * dimM - int( l / dim ) * dimM ) > 0 )
{
b += ( ( 1 << l ) & byte ) << shift;
}
else
{
b += ( ( 1 << l ) & byte ) >> -shift;
}
}
byte = b;
}
function setByte( byte: Number ): Void
{
this.byte = byte;
}
function getByte( Void ): Number
{
return byte;
}
function toString( Void ): String
{
var o: String = new String( "" );
for( var y = 0 ; y < dim ; y++ )
{
var row: String = new String( "" );
for( var x = 0 ; x < dim ; x++ )
{
row += ( byte & ( 1 << x ) << ( y * dim ) ) ? "*" : " ";
}
o += row;
if( y < dimM ) o += newline;
}
return o;
}
} Geändert von André Michelle (03-11-2004 um 10:05 Uhr) |
| | |
| | #14 (permalink) |
| flachzange Registriert seit: Jun 2003 Ort: berlin
Beiträge: 3.932
|
mit der integer begrenzung kann man ja leider keine komplette map umsetzen, zumindest nicht ohne eselsbrücken. aber das wird mir eh alles zu komplifiziert ![]() mal ne grundlegende tetris frage: benutzt du für die kleinen formen wie T,Z,S etc 3x3 maps und nur für das I eine 4x4 map oder benutzt du für alles 4x4? weil bei 4x4 maps ist die rotation (mit der Array2d klasse) der formen nicht mehr korrekt. baue nämlich ne methode mit der man maps mit presets versehen kann, dh ich hab ein array mit vier werten: var T = [4,5,6,9]; //T form die 4x4 map sehe ich mit dem obigen preset als lineares array an und setze so mit den presets die form in die matrix. so hab ich nur arrays mit 4 indizes, das spart etwas platz. und normalsterbliche können es auch noch benutzen
__________________ |
| | |
| | #15 (permalink) |
| [+] Registriert seit: Dec 2002 Ort: cologne
Beiträge: 2.271
|
Noch gibt es ja kein Tetris, aber ich würde verschiedene Größen nehmen (3x3,4x4). Das geht dann mit der Bitmatrix wunderbar. Aber du hast recht, dass es nicht wirklich notwendig ist, es so zu lösen. Trotzdem hat mir das geholfen, besser zu verstehen, wie man mit Bits rechnet.
|
| | |
![]() |
| Lesezeichen |
| Themen-Optionen | |
| Ansicht | |
| |