Code Golf: Tetris spielen

83

Die Grundlagen:

Betrachten Sie die folgenden Tetrominoes und das leere Spielfeld:

                                            0123456789
    IOZTLSJ []
                                           []
    # ## ## ### # ## # []
    # ## ## # # ## # []
    # ## ## []
    # []
                                           [==========]

Die Abmessungen des Spielfeldes sind festgelegt. Die Zahlen oben geben nur die Spaltennummer an (siehe auch Eingabe).

Eingang:

1 . Sie erhalten ein bestimmtes Spielfeld (basierend auf dem oben Gesagten), das bereits teilweise mit Tetrominos gefüllt werden kann (dies kann in einer separaten Datei erfolgen oder über stdin bereitgestellt werden).

Beispieleingabe:

[]
[]
[]
[]
[# # #]
[## ######]
[==========]

2 . Sie erhalten eine Zeichenfolge, die beschreibt (durch Leerzeichen getrennt), welches Tetromino an welcher Spalte eingefügt (und abgelegt) werden soll. Tetrominoes müssen nicht gedreht werden. Die Eingabe kann von stdin gelesen werden.

Beispieleingabe:

T2 Z6 I0 T7

Sie können davon ausgehen, dass die Eingabe "wohlgeformt" ist (oder undefiniertes Verhalten erzeugen, wenn dies nicht der Fall ist).

Ausgabe

Rendern Sie das resultierende Feld ('volle' Zeilen müssen verschwinden) und drucken Sie die Punktzahl (jede abgelegte Zeile entspricht 10 Punkten).

Beispielausgabe basierend auf der obigen Beispieleingabe:

[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10

Gewinner:

Kürzeste Lösung (nach Anzahl der Codezeichen). Anwendungsbeispiele sind nett. Viel Spaß beim Golfen!

Bearbeiten : Es wurde eine Menge +500Reputation hinzugefügt, um mehr Aufmerksamkeit auf die netten Bemühungen der Antwortenden zu lenken (und möglicherweise auf einige neue Lösungen für diese Frage) ...

ChristopheD
quelle
5
@omouse: check meta.stackoverflow.com - Code Golf ist im Allgemeinen erlaubt (in Community-Wiki-Form)
ChristopheD
18
@omouse: Dafür ist die Abstimmung zum Schließen gedacht. Das Ziehen von Moderatoren durch Markieren der Frage wird Sie wahrscheinlich nicht so beliebt machen, da die Community immer wieder (widerwillig) das Vorhandensein von Code-Golf zugelassen hat (siehe Code-Golf-Tag und Metadiskussionen; es ist nichts Neues). .
Mark Peters
8
@omouse: Off-Topic! = Spam. Selbst wenn Sie nicht für das Schließen stimmen können, war diese Spam-Flagge nicht erforderlich.
BoltClock
3
Ich warte auf einen APL Jock! Ich wette, er kann es in 3,5 Symbolen tun
n8wrl
3
Die Abmessungen sollen fest sein, aber die Probeneingabe und das leere Feld haben unterschiedliche Höhen. Wie hoch soll es sein?
Nabb

Antworten:

27

GolfScript - 181 Zeichen

Zeilenumbrüche sind nicht erforderlich. Die Ausgabe erfolgt in der Standardausgabe, obwohl in stderr einige Fehler vorhanden sind.
\10sollte durch das entsprechende ASCII-Zeichen ersetzt werden, damit das Programm 181 Zeichen enthält.

{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{\!:F;>P{\(@{3&\(@.2$&F|:F;|}%\+}%\+F![f]P+:P
;}do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ 10R*+n*

Beispiel-E / A:

$ cat inp
[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7
$ cat inp|golfscript tetris.gs 2>/dev/null
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Tetromino-Komprimierung: Die
Teile werden als drei Basis-8-Ziffern gespeichert. Dies ist eine einfache binäre Darstellung, z T=[7,2,0], S=[6,3,0], J=[2,2,3]. [1]wird für das IStück in Komprimierung verwendet, dies wird jedoch explizit auf [1,1,1,1]später gesetzt (dh das 4*im Code). Alle diese Arrays werden zu einem einzigen Array verkettet, das in eine Ganzzahl und dann in eine Zeichenfolge konvertiert wird (Basis 126, um nicht druckbare Zeichen, Länge und nicht auf utf8 zu minimieren). Diese Zeichenfolge ist sehr kurz : "R@1(XBc_".

Die Dekomprimierung ist dann unkompliziert. Wir führen zuerst eine Basis-126-Konvertierung durch, gefolgt von einer Basis-8-Konvertierung ( "~\10"{base}/dh durchlaufen "~\10"und durchlaufen für jedes Element eine Basis-Konvertierung). Das resultierende Array wird in Dreiergruppen aufgeteilt, das Array für Iist fest ( 3/~4*). Wir konvertieren dann jedes Element in Basis 2 und ersetzen (nach dem Entfernen von Nullen) jede Binärziffer durch das Zeichen dieses Index in der Zeichenfolge " #"( 2base{" #"=}%...-1%- beachten Sie, dass wir das Array umkehren müssen, sonst 2würde es "# "statt " #").

Board / Piece-Format, Droping Pieces
Das Board besteht einfach aus einer Reihe von Zeichenfolgen, eine für jede Zeile. Zunächst wird daran keine Arbeit geleistet, daher können wir es mit n/(der Eingabe generieren . Stücke sind auch Anordnungen von Zeichenfolgen, die mit Leerzeichen links für ihre X-Position aufgefüllt sind, jedoch ohne nachgestellte Leerzeichen. Teile werden durch Voranstellen an das Array und kontinuierliches Testen, ob eine Kollision vorliegt, gelöscht.

Kollisionstests werden durchgeführt, indem alle Zeichen im Stück durchlaufen und mit dem Zeichen derselben Position auf dem Brett verglichen werden. Wir wollen #+ =und #+ #als Kollisionen betrachten, also testen wir, ob ((piecechar & 3) & boardchar) ungleich Null ist. Während dieser Iteration aktualisieren wir auch (eine Kopie von) der Karte mit ((piecechar & 3) | boardchar), wodurch der Wert für die Paare #+ , + #, + korrekt festgelegt wird [. Wir verwenden dieses aktualisierte Board, wenn es nach dem Verschieben des Teils um eine weitere Reihe zu einer Kollision kommt.

Das Entfernen gefüllter Zeilen ist ganz einfach. Wir entfernen alle Zeilen, für die "= "&false zurückgegeben wird. Eine gefüllte Zeile hat weder noch =noch , daher ist die Konjunktion eine leere Zeichenfolge, was false entspricht. Dann zählen wir die Anzahl der entfernten Zeilen, addieren die Anzahl zur Punktzahl und stellen so viele "[ ... ]"s voran . Wir erzeugen kompakt diese durch die erste Reihe des Gitters nimmt und Ersetzen #mit .

Bonus
Da wir berechnen, wie das Brett in jeder Position des Stücks aussehen würde, wenn es fällt, können wir diese auf dem Stapel behalten, anstatt sie zu löschen! Für insgesamt drei weitere Zeichen können wir alle diese Positionen ausgeben (oder zwei Zeichen, wenn die Board-Zustände einen einfachen Abstand haben).

{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{>[f]P+:P(!:F;{\(@{3&\(@.2$&F|:F;|}%\+}%\+F!}
do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ ]{n*n.}/10R*
Nabb
quelle
Genau hier wird extremes Code-Golf gespielt (ich hätte nicht gedacht, dass dies mit weniger als 200 Zeichen möglich ist). Gut gemacht!
ChristopheD
8
Tolle. Ich wünschte, ich hätte GolfScript verstanden. Warten Sie ... nein, ich nicht.
P Daddy
26

Perl, 586 523 483 472 427 407 404 386 387 356 353 Zeichen

(Benötigt Perl 5.10 für den definierten oder //Operator).

Nimmt alle Eingaben von stdin entgegen. Braucht noch ernsthaftes Golfen.
Es ist zu beachten, dass ^ Q ASCII 17 (DC1 / XON) darstellt, ^ C ASCII 3 darstellt und ^ @ ASCII 0 (NUL) darstellt.

while(<>){push@A,[split//]if/]/;while(/\w/g){for$i(0..6){for($f=0,$j=4;$j--;){$c=0;map{if($_){$i--,$f=$j=3,redo if$A[$k=$i+$j][$C=$c+$'+1]ne$";$A[$k][$C]="#"if$f}$c++}split//,unpack"b*",chr vec"3^@'^@c^@^Q^C6^@\"^C^Q^Q",index(OTZLSJI,$&)*4+$j,4;$s+=10,@A[0..$k]=@A[$k,0..$k-1],map{s/#/ /}@{$A[0]},$i++if 9<grep/#/,@{$A[$k]}}last if$f}}}print+(map@$_,@A),$s//0,$/

Kommentierte Version:

while(<>){
    # store the playfield as an AoA of chars
    push@A,[split//]if/]/;
    # while we're getting pieces
    while(/\w/g){
            # for each line of playfield
            for$i(0..6){
                    # for each line of current piece
                    for($f=0,$j=4;$j--;){
                            # for each column of current piece
                            $c=0;
                            map{
                                    if($_){
                                            # if there's a collision, restart loop over piece lines
                                            # with a mark set and playfield line decremented
                                            $i--,$f=$j=3,redo if$A[$k=$i+$j][$C=$c+$'+1]ne$";
                                            # if we already found a collision, draw piece
                                            $A[$k][$C]="#"if$f
                                    }
                                    $c++
                            # pieces are stored as a bit vector, 16 bits (4x4) per piece,
                            # expand into array of 1's and 0's
                            }split//,unpack"b*",chr vec"3^@'^@c^@^Q^C6^@\"^C^Q^Q",index(OTZLSJI,$&)*4+$j,4;
                            # if this playfield line is full, remove it. Done by array slicing
                            # and substituting all "#"'s in line 0 with " "'s
                            $s+=10,@A[0..$k]=@A[$k,0..$k-1],map{s/#/ /}@{$A[0]},$i++if 9<grep/#/,@{$A[$k]}
                    }
                    # if we found a collision, stop iterating over the playfield and get next piece from input
                    last if$f
            }
    }
}
# print everything
print+(map@$_,@A),$s//0,$/

Edit 1: einige ernsthafte Golfen, Ausgabefehler behoben.
Bearbeiten 2: einige Inlining, zwei Loops zu einem zusammengeführt, um eine Nettoersparnis von (Trommelwirbel ...) 3 Zeichen zu erzielen, sonstiges Golfen.
Edit 3: einige häufige Eliminierungen von Unterausdrücken, ein wenig konstantes Zusammenführen und Optimieren eines regulären Ausdrucks.
Edit 4: Die Darstellung von Tetrominoes wurde in einen gepackten Bitvektor geändert.
Bearbeiten 5: direktere Übersetzung vom Tetromino-Buchstaben zum Array-Index, Verwendung nicht druckbarer Zeichen, sonstiges Golfen.
Edit 6: Fehlerbehebung bei der Fehlerbehebung in r3 (Edit 2), entdeckt von Nakilon. Verwenden Sie mehr nicht druckbare Zeichen.
Edit 7: Verwenden Sie diese vecOption, um auf Tetromino-Daten zuzugreifen. Nutzen Sie die Tatsache, dass das Spielfeld feste Abmessungen hat. ifAnweisung =>ifModifikator, das Zusammenführen von Schleifen von Edit 2 beginnt sich auszuzahlen. Verwenden Sie //für den Fall mit 0 Punkten.
Edit 8: Ein weiterer Fehler wurde behoben, der in r6 (Edit 5) eingeführt wurde und von Nakilon entdeckt wurde.
Bearbeiten 9: Erstellen Sie beim Löschen von Linien keine neuen Referenzen, sondern verschieben Sie Referenzen einfach über das Array-Slicing. Füge zwei mapzu einem zusammen. Intelligentere Regex. "Klüger" for. Verschiedene Golfplätze.
Edit 10: Inline Tetromino Array, kommentierte Version hinzugefügt.

ninjalj
quelle
Sehr gut funktionieren (und bereits eine gute Anzahl von Charakteren für dieses nicht triviale Problem). Eine kleine Besonderheit ist, dass mein Perl (Perl, v5.10.0, erstellt für Darwin-Thread-Multi-2level) das Ergebnis zweimal zu drucken scheint (Eingabe eingespeist).
ChristopheD
@ChristopheD: Die doppelte Ausgabe wurde korrigiert. Ich habe in meiner Hauptschleife gedruckt, aber nur für Zeilen ohne Spielfeld. Sie hatten wahrscheinlich eine neue Zeile zu viel :)
Ninjalj
4 weitere Zeichen, um Python zu schlagen !!
Vivin Paliath
1
Ich habe Perl noch nicht aufgegeben! xD (obwohl ich jetzt auch einige andere Lösungen sehen möchte ..)
stupsen
@ Nakilon: Guter Fang! Sie haben dort einen schönen Testfall.
Ninjalj
24

Ruby - 427 408 398 369 359

t=[*$<]
o=0
u=->f{f.transpose}
a=u[t.reverse.join.scan /#{'( |#)'*10}/]
t.pop.split.map{|w|m=(g='I4O22Z0121T01201L31S1201J13'[/#{w[0]}\d+/].scan(/0?\d/).zip a.drop w[1].to_i).map{|r,b|(b.rindex ?#or-1)-r.size+1}.max
g.map{|r,b|b.fill ?#,m+r.size,r.to_i}
v=u[a]
v.reject!{|i|i-[?#]==[]&&(o+=10;v)<<[' ']*10}
a=u[v]}
puts u[a].reverse.map{|i|?[+i*''+?]},t[-1],o
Nakilon
quelle
Sehr schöne Lösung! Ich muss mir ansehen, wie genau Sie die Teromino-Formen codiert haben (sieht auf diese Weise sehr kompakt aus).
ChristopheD
3
Ich würde wirklich gerne eine erweiterte Erklärung dieses Codes sehen. Es sieht so krank aus ... ich kann es nicht verstehen.
Nils Riedemann
1
@Nils Riedemann, schreibe ich jetzt eine Erklärung, aber denk daran, es jetzt zu veröffentlichen, oder nach dem Gewinner bekannt geben) Wie auch immer , wenn ich schreiben werde und alle Fragen beantworten, weil es ein Community Wiki mit Hauptidee ist , nützlich zu sein)
Nakilon
Bei Debians Ruby 1.9.2dev (30.07.2010) schlägt dies für Ihren Testfall unter paste.org.ru/?6ep1on fehl. Außerdem wird das Spielfeld immer auf zehn Zeilen erweitert.
Ninjalj
@ninjalj, ruby ​​1.9.2p0 (18.08.2010) [i386-mingw32] paste.org.ru/?1qnjhj Sieht gut aus. Die Breite von 10 ist wohl ein Tetris-Standard.
Nakilon
17

Bash-Shell-Skript ( 301 304 Zeichen)


UPDATE: Es wurde ein Fehler behoben, der Teile betraf, die bis in die oberste Reihe reichen. Außerdem wird die Ausgabe jetzt an den Standardausgang gesendet, und als Bonus ist es möglich, das Skript erneut auszuführen, um ein Spiel fortzusetzen (in diesem Fall müssen Sie die Gesamtpunktzahl selbst addieren).

Dies schließt nicht druckbare Zeichen ein, daher habe ich einen Hex-Dump bereitgestellt. Speichern Sie es als tetris.txt:

0000000: 7461 696c 202d 3120 245f 7c7a 6361 743e  tail -1 $_|zcat>
0000010: 753b 2e20 750a 1f8b 0800 35b0 b34c 0203  u;. u.....5..L..
0000020: 5590 516b 8330 10c7 dff3 296e 4c88 ae64  U.Qk.0....)nL..d
0000030: a863 0c4a f57d 63b0 07f7 b452 88d1 b4da  .c.J.}c....R....
0000040: 1a5d 5369 91a6 df7d 899a d05d 5e72 bfbb  .]Si...}...]^r..
0000050: fbff 2fe1 45d5 0196 7cff 6cce f272 7c10  ../.E...|.l..r|.
0000060: 387d 477c c4b1 e695 855f 77d0 b29f 99bd  8}G|....._w.....
0000070: 98c6 c8d2 ef99 8eaa b1a5 9f33 6d8c 40ec  ...........3m.@.
0000080: 6433 8bc7 eeca b57f a06d 27a1 4765 07e6  d3.......m'.Ge..
0000090: 3240 dd02 3df1 2344 f04a 0d1d c748 0bde  2@..=.#D.J...H..
00000a0: 75b8 ed0f 9eef 7bd7 7e19 dd16 5110 34aa  u.....{.~...Q.4.
00000b0: c87b 2060 48a8 993a d7c0 d210 ed24 ff85  .{ `H..:.....$..
00000c0: c405 8834 548a 499e 1fd0 1a68 2f81 1425  ...4T.I....h/..%
00000d0: e047 bc62 ea52 e884 42f2 0f0b 8b37 764c  .G.b.R..B....7vL
00000e0: 17f9 544a 5bbd 54cb 9171 6e53 3679 91b3  ..TJ[.T..qnS6y..
00000f0: 2eba c07a 0981 f4a6 d922 89c2 279f 1ab5  ...z....."..'...
0000100: 0656 c028 7177 4183 2040 033f 015e 838b  .V.(qwA. @.?.^..
0000110: 0d56 15cf 4b20 6ff3 d384 eaf3 bad1 b9b6  .V..K o.........
0000120: 72be 6cfa 4b2f fb03 45fc cd51 d601 0000  r.l.K/..E..Q....

Dann an der Bash-Eingabeaufforderung, vorzugsweise mit elvisanstatt viminstalliert als vi:

$ xxd -r tetris.txt tetris.sh
$ chmod +x tetris.sh
$ cat << EOF > b
> [          ]
> [          ]
> [          ]
> [          ]
> [ #    #  #]
> [ ## ######]
> [==========]
> EOF
$ ./tetris.sh T2 Z6 I0 T7 2>/dev/null
-- removed stuff that is not in standard out --
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Wie es funktioniert

Der Code extrahiert sich selbst ähnlich wie ausführbare Programme, die mit dem gzexeSkript komprimiert wurden . Tetromino-Stücke werden als Sequenzen von vi-Editor-Befehlen dargestellt. Die Zeichenzählung wird verwendet, um Kollisionen zu erkennen, und die Linienzählung wird verwendet, um die Punktzahl zu berechnen.

Der entpackte Code:

echo 'rej.j.j.:wq!m'>I
echo '2rejh.:wq!m'>O
echo '2rej.:wq!m'>Z
echo '3rejh1.:wq!m'>T
echo 'rej.j2.:wq!m'>L
echo 'l2rej2h.:wq!m'>S
echo 'lrej.jh2.:wq!m'>J
for t
do for y in `seq 1 5`
do echo -n ${y}jk$((${t:1}+1))l|cat - ${t:0:1}|vi b>0
grep ========== m>0||break
[ `tr -cd '#'<b|wc -c` = `tr -cd '#'<m|wc -c` ]||break
tr e '#'<m>n
done
cat n>b
grep -v '##########' b>m
$((S+=10*(`wc -l < b`-`wc -l < m`)))
yes '[          ]'|head -7|cat - m|tail -7>b
done
cat b
echo $S

Der Originalcode vor dem Golfen:

#!/bin/bash

mkpieces() {
    pieces=('[email protected].' '2r@jh.' '2r@j.' '3r@jh1.' '[email protected].' 'l2r@j2h.' '[email protected].')
    letters=(I O Z T L S J)

    for j in `seq 0 9`; do
        for i in `seq 0 6`; do
            echo "jk$(($j+1))l${pieces[$i]}:wq! temp" > ${letters[$i]}$j
        done
    done
}

counthashes() {
    tr -cd '#' < $1 | wc -c
}

droppiece() {
    for y in `seq 1 5`; do
        echo -n $y | cat - $1 | vi board > /dev/null
        egrep '={10}' temp > /dev/null || break
        [ `counthashes board` -eq `counthashes temp` ] || break
        tr @ "#" < temp > newboard
    done
    cp newboard board
}

removelines() {
    egrep -v '#{10}' board > temp
    SCORE=$(($SCORE + 10 * (`wc -l < board` - `wc -l < temp`)))
    yes '[          ]' | head -7 | cat - temp | tail -7 > board
}

SCORE=0
mkpieces
for piece; do
    droppiece $piece
    removelines
done
cat board
echo $SCORE
PleaseStand
quelle
1
Eine Bash-Datei, die dekomprimiert und ausgeführt wird. Ich bin mir nicht sicher, ob ein solcher Gräuel legal ist. Aber es ist am beeindruckendsten, +1. Ein großes Lob an Sie, Sir.
Michael Anderson
Die Fertigstellung dauert lächerlich lange und generiert dann die falsche Ausgabe für den Testfall "(gleiche Karte wie Beispieleingabe). Darüber hinaus werden Tausende von Müllleitungen in Rohrleitungen ausfallen, und das Ergebnis der Platine sollte wahrscheinlich stattdessen dorthin gehen.
Nabb
Es wäre viel schneller, wenn Elvis anstelle von Vim als vi installiert würde.
PleaseStand
2
@Nabb: Ich habe gerade all diese Probleme zu einem Preis von nur drei Zeichen behoben.
PleaseStand
Beeindruckend. Das ist ein ziemlich beeindruckender Missbrauch von Bash.
P Daddy
13

Python: 504 519 Zeichen

(Python 3-Lösung) Derzeit muss die Eingabe in dem oben gezeigten Format eingestellt werden (Eingabecode wird nicht gezählt). Ich werde später erweitern, um aus einer Datei oder einem Standard zu lesen. Funktioniert jetzt mit einer Eingabeaufforderung, fügen Sie einfach die Eingabe ein (insgesamt 8 Zeilen).

R=range
f,p=[input()[1:11]for i in R(7)],p
for(a,b)in input().split():
 t=[' '*int(b)+r+' '*9for r in{'I':'#,#,#,#','O':'##,##','Z':'##, ##','T':'###, # ','L':'#,#,##','S':' ##,##','J':' #, #,##'}[a].split(',')]
 for r in R(6-len(t),0,-1):
  for i in R(len(t)):
   if any(a==b=='#'for(a,b)in zip(t[i],f[r+i])):break
  else:
   for i in R(0,len(t)):
    f[r+i]=''.join(a if b!='#'else b for(a,b)in zip(t[i],f[r+i]))
    if f[r+i]=='#'*10:del f[r+i];f[0:0]=[' '*10];p+=10
   break
print('\n'.join('['+r+']'for r in f[:7]),p,sep='\n')

Ich bin mir nicht sicher, ob ich dort viel mehr sparen kann. Bei der Umwandlung in Bitfelder gehen ziemlich viele Zeichen verloren, aber das spart viel mehr Zeichen als das Arbeiten mit den Zeichenfolgen. Ich bin mir auch nicht sicher, ob ich dort mehr Leerzeichen entfernen kann, aber ich werde es später versuchen.
Wird es nicht viel mehr reduzieren können; Nachdem ich die bitfeldbasierte Lösung erhalten hatte, wechselte ich zurück zu Strings, da ich einen Weg fand, sie stärker zu komprimieren (8 Zeichen über dem Bitfeld gespeichert!). Aber da ich vergessen habe, das einzuschließen, Lund einen Fehler mit den Punkten darin hatte, steigt meine Anzahl an Charakteren nur seufzend ... Vielleicht finde ich später etwas, um es ein bisschen mehr zu komprimieren, aber ich denke, ich bin kurz vor dem Ende. Für den ursprünglichen und kommentierten Code siehe unten:

Originalfassung:

field = [ input()[1:11] for i in range(7) ] + [ 0, input() ]
# harcoded tetrominoes
tetrominoes = {'I':('#','#','#','#'),'O':('##','##'),'Z':('##',' ##'),'T':('###',' # '),'L':('#','#','##'),'S':(' ##','##'),'J':(' #',' #','##')}
for ( f, c ) in field[8].split():
    # shift tetromino to the correct column
    tetromino = [ ' ' * int(c) + r + ' ' * 9 for r in tetrominoes[f] ]

    # find the correct row to insert
    for r in range( 6 - len( tetromino ), 0, -1 ):
        for i in range( len( tetromino ) ):
            if any( a == b == '#' for (a,b) in zip( tetromino[i], field[r+i] ) ):
                # skip the row if some pieces overlap
                break
        else:
            # didn't break, insert the tetromino
            for i in range( 0, len( tetromino ) ):
                # merge the tetromino with the field
                field[r+i] = ''.join( a if b != '#' else b for (a,b) in zip( tetromino[i], field[r+i] ) )

                # check for completely filled rows
                if field[r+i] == '#' * 10:
                    # remove current row
                    del field[r+i]
                    # add new row
                    field[0:0] = [' '*10]
                    field[7] += 10
            # we found the row, so abort here
            break
# print it in the requested format
print( '\n'.join( '[' + r + ']' for r in field[:7] ) )
# and add the points = 10 * the number of redundant lines at the end
print( str( field[7] ) )
stoßen
quelle
Ich denke nicht, dass das richtig ist. Es gibt keine Regel, die besagt, dass nur die unterste Zeile verschwinden kann, aber nach Ihren Kommentaren zu urteilen, überprüfen Sie nur diese Zeile.
Michael Madsen
Bitte machen Sie Ihre Eingabe wie in einer Aufgabe. Ich meine, Eingabe aus Datei oder STDIN.
Nakilon
6
Liebst du nicht, wie selbst minimierter Python-Code noch ziemlich lesbar ist?
EMP
@ Evgeny, nur im Vergleich zu Perl oder Malbolge)
Nakilon
Nun, ich meinte "lesbar" im Vergleich zu anderen Code-Golf-Antworten!
EMP
13

Ruby 1.9, 357 355 353 339 330 310 309 Zeichen

d=0
e=[*$<]
e.pop.split.map{|f|f="L\003\003\007J\005\005\007O\007\007Z\007\013S\013\007I\003\003\003\003T\017\005"[/#{f[j=0]}(\W*)/,1].bytes.map{|z|?\0+?\0*f[1].hex+z.to_s(2).tr("01"," #")[1,9]}
k,f,i=i,[p]+f,e.zip(f).map{|l,m|l.bytes.zip(m.to_s.bytes).map{|n,o|j|=n&3&q=o||0;(n|q).chr}*""}until j>0
e=[]
e+=k.reject{|r|r.sum==544&&e<<r.tr(?#,?\s)&&d+=10}}
puts e,d

Beachten Sie, dass die \000Escapezeichen (einschließlich der Null-Bytes in der dritten Zeile) durch ihre tatsächlichen nicht druckbaren Entsprechungen ersetzt werden sollten.

Beispieleingabe:

[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7

Verwendung:

ruby1.9 tetris.rb < input

oder

ruby1.9 tetris.rb input
Ventero
quelle
Eine andere Möglichkeit, Tetrominos fallen zu lassen und das gesamte Glas in Ordnung zu halten, auch mit Rändern ... schön. Jetzt bist du der Ruby / Perl-Anführer. PS: Ich wusste nichts davon ?\s.
Nakilon
12

C, 727 [...] 596 581 556 517 496 471 461 457 Zeichen

Dies ist mein erster Code Golf, ich denke, die Anzahl der Charaktere kann viel niedriger werden. Es wäre schön, wenn erfahrene Golfer mir einige Hinweise geben könnten.

Die aktuelle Version kann auch Spielfelder mit unterschiedlichen Abmessungen verarbeiten. Die Eingabe kann Zeilenumbrüche sowohl im DOS / Windows- als auch im Unix-Format aufweisen.

Der Code war vor der Optimierung ziemlich einfach, die Tetrominoes werden in 4 Ganzzahlen gespeichert, die als (7 * 3) x4-Bit-Array interpretiert werden, das Spielfeld wird unverändert gespeichert, Kacheln werden gelöscht und vollständige Zeilen werden zu Beginn und nach jedem entfernt Fliesen fallen.

Ich war mir nicht sicher, wie ich Zeichen zählen sollte, also habe ich die Dateigröße des Codes verwendet, wobei alle unnötigen Zeilenumbrüche entfernt wurden.

EDIT 596 => 581: Dank KitsuneYMG, alles außer dem %lsVorschlag perfekt gearbeitet, zusätzlich habe ich festgestellt , putchanstatt putcharverwendet werden ( getchirgendwie nicht funktioniert) und entfernt alle Klammern #define G.

EDIT 581 => 556: War mit den verbleibenden forund den verschachtelten FSchleifen nicht zufrieden , daher wurden einige Schleifen zusammengeführt, geändert und entfernt, ziemlich verwirrend, aber es lohnt sich auf jeden Fall.

EDIT 556 => 517: Endlich einen Weg gefunden, aein int-Array zu erstellen. Einige N;verschmolzen mit c, nicht breakmehr.

EDIT 496 => 471: Spielfeldbreite und -höhe jetzt festgelegt.

EDIT 471 => 461: Kleinere Änderungen, putcharwieder verwendet, da dies putchkeine Standardfunktion ist.

BEARBEITEN: Bugfix, vollständige Zeilen wurden vor dem Ablegen der Kacheln anstatt nach dem Entfernen entfernt , sodass am Ende vollständige Zeilen verbleiben konnten. Fix ändert die Anzahl der Zeichen nicht.

#define N (c=getchar())
#define G T[j%4]&1<<t*3+j/4
#define X j%4*w+x+j/4
#define F(x,m) for(x=0;x<m;x++)
#define W while
T[]={916561,992849,217,1},C[99],c,i,j,s,t,x,A,a[99],w=13;
main(){F(j,7)C["IJLSTZO"[j]]=j;
F(j,91)a[j]=N;
W(N>w){t=C[c];x=N-86;
W(c){F(j,12)if(G&&X>1?a[X]-32:0)c=0;
F(j,12)if(G&&X>w&&!c)a[X-w]=35;x+=w;}N;
F(i,6){A=0;t=i*w;F(x,w)A|=(a[t+x]==32);
if(!A){s++;F(j,t)a[t+w-j]=a[t-j];
x=1;W(a[x]-93)a[x++]=32;}}}
F(i,91)putchar(a[i]);printf("%i0",s);}
Schnaader
quelle
1
Kannst du nicht definieren forals #define F(x,m) for(x=0;x++<m;)? Es funktioniert auf C # ...: P
BrunoLM
@BrunoLM: Danke, aber das wird nicht funktionieren, zB F(x,3){printf("%i",x}druckt 12statt 012mit dieser Änderung. Könnte sich ändern for(x=-1;x++<m;), aber das spart nichts :)
Schnaader
1
Wenn Sie den Code richtig geschrieben haben und als C kompilieren, müssen Sie stdio.h nicht einschließen (es sei denn, ich habe etwas verpasst?). Speichern Sie ein paar Zeichen :)
1
Sie können Ihre Definition von N durch ersetzen (c=getchar())und alle c = N Zeilen entfernen, wobei 6 Zeichen gespart werden. Wenn ich mich nicht irre, sollten Sie bis zum
10.
1
Typ ist standardmäßig int auch für Variablen, zumindest für C89.
Ninjalj
8

Python 2.6+ - 334 322 316 Zeichen

397 368 366 Zeichen unkomprimiert

#coding:l1
exec'xÚEPMO!½ï¯ i,P*Ýlš%ì­‰=‰Ö–*†­þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆ­ùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')

Der einzelne Zeilenumbruch ist erforderlich, und ich habe ihn als ein Zeichen gezählt.

Mumbo-Jumbo auf der Browser-Codepage verhindert möglicherweise das erfolgreiche Kopieren und Einfügen dieses Codes, sodass Sie die Datei optional aus diesem Code generieren können:

s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21
10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6
96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9
2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D
1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11
EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B
C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42
4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20
BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC
80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5
44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE
5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD
10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A
69 70 27 29
"""

with open('golftris.py', 'wb') as f:
    f.write(''.join(chr(int(i, 16)) for i in s.split()))

Testen

intetris

[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7

Zeilenumbrüche müssen im Unix-Stil erfolgen (nur Zeilenvorschub). Ein nachfolgender Zeilenumbruch in der letzten Zeile ist optional.

Zu testen:

> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10

Dieser Code entpackt den Originalcode und führt ihn mit aus exec. Dieser dekomprimierte Code wiegt 366 Zeichen und sieht folgendermaßen aus:

import sys
r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n'
for l in r.pop().split():
 n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2))
 for l in range(12):
  if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:]
 while a in r:s+=10;r.remove(a);r=p+r
print''.join(r),s

Zeilenumbrüche sind erforderlich und bestehen jeweils aus einem Zeichen.

Versuchen Sie nicht, diesen Code zu lesen. Die Variablennamen werden auf der Suche nach der höchsten Komprimierung buchstäblich zufällig ausgewählt (bei verschiedenen Variablennamen habe ich nach der Komprimierung bis zu 342 Zeichen gesehen). Eine verständlichere Version folgt:

import sys

board = sys.stdin.readlines()
score = 0
blank = board[:1] # notice that I rely on the first line being blank
full  = '[##########]\n'

for piece in board.pop().split():
    column = int(piece[1]) + 1 # "+ 1" to skip the '[' at the start of the line

    # explanation of these three lines after the code
    bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12
    drop = min(zip(*board[:6]+[full])[column + x].index('#') -
               len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2))

    for i in range(12):
        if bits >> i & 2: # if the current cell should be a '#'
            x = column + i / 4
            y = drop + i % 4
            board[y] = board[y][:x] + '#' + board[y][x + 1:]

    while full in board:      # if there is a full line,
        score += 10           # score it,
        board.remove(full)    # remove it,
        board = blank + board # and replace it with a blank line at top
        
print ''.join(board), score

Der Kern liegt in den drei kryptischen Zeilen, von denen ich sagte, dass ich sie erklären würde.

Die Form der Tetrominoes ist dort in der Hexadezimalzahl kodiert. Es wird angenommen, dass jedes Tetronimo ein 3x4-Gitter von Zellen einnimmt, wobei jede Zelle entweder leer (ein Leerzeichen) oder voll (ein Zahlenzeichen) ist. Jedes Stück wird dann mit 3 hexadezimalen Ziffern codiert, wobei jede Ziffer eine 4-Zellen-Spalte beschreibt. Die niedrigstwertigen Ziffern beschreiben die am weitesten links stehenden Spalten, und das niedrigstwertige Bit in jeder Ziffer beschreibt die oberste Zelle in jeder Spalte. Wenn ein Bit 0 ist, ist diese Zelle leer, andernfalls ist es ein '#'. Zum Beispiel wird das I- Tetronimo so codiert 00F, dass die vier Bits der niedrigstwertigen Ziffer aktiviert sind , um die vier Zahlenzeichen in der Spalte ganz links zu codieren, und das T ist131mit dem oberen Bit links und rechts und den beiden oberen Bits in der Mitte.

Die gesamte Hexadezimalzahl wird dann um ein Bit nach links verschoben (multipliziert mit zwei). Dadurch können wir das unterste Bit ignorieren. Ich werde gleich erklären, warum.

Wenn wir also das aktuelle Stück aus der Eingabe erhalten, finden wir den Index in dieser Hexadezimalzahl, in der die 12 Bits beginnen, die seine Form beschreiben, und verschieben ihn dann nach unten, sodass die Bits 1–12 (Überspringen von Bit 0) der bitsVariablen das aktuelle Stück beschreiben.

Die Zuordnung zu dropbestimmt, wie viele Zeilen vom oberen Rand des Gitters das Stück fallen wird, bevor es auf anderen Stückfragmenten landet. In der ersten Zeile wird angegeben, wie viele leere Zellen sich oben in jeder Spalte des Spielfelds befinden, während in der zweiten Zeile die niedrigste belegte Zelle in jeder Spalte des Stücks angegeben wird. Die zipFunktion gibt eine Liste von Tupeln zurück, wobei jedes Tupel aus der n- ten Zelle jedes Elements in der Eingabeliste besteht. Wenn Sie also die Sample-Eingangskarte verwenden, zip(board[:6] + [full])wird Folgendes zurückgegeben:

[
 ('[', '[', '[', '[', '[', '[', '['),
 (' ', ' ', ' ', ' ', ' ', ' ', '#'),
 (' ', ' ', ' ', ' ', '#', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', ' ', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', '#', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', '#', '#', '#'),
 (']', ']', ']', ']', ']', ']', ']')
]

Wir wählen das Tupel aus dieser Liste aus, das der entsprechenden Spalte entspricht, und finden den Index des ersten '#'in der Spalte. Aus diesem Grund haben wir vor dem Aufruf eine "vollständige" Zeile angehängt zip, damit indexeine sinnvolle Rückgabe (anstatt eine Ausnahme auszulösen) erfolgt, wenn die Spalte ansonsten leer ist.

Um dann das niedrigste '#'in jeder Spalte des Stücks zu finden, verschieben und maskieren wir die vier Bits, die diese Spalte beschreiben, und verwenden dann die binFunktion, um daraus eine Folge von Einsen und Nullen zu machen. Die binFunktion gibt nur signifikante Bits zurück, daher müssen wir nur die Länge dieser Zeichenfolge berechnen, um die niedrigste belegte Zelle (höchstwertiges gesetztes Bit) zu finden. Die binFunktion steht auch vor '0b', also müssen wir das subtrahieren. Wir ignorieren auch das niedrigstwertige Bit. Aus diesem Grund wird die Hexadezimalzahl um ein Bit nach links verschoben. Dies dient dazu, leere Spalten zu berücksichtigen, deren Zeichenfolgendarstellungen dieselbe Länge wie eine Spalte haben würden, in der nur die oberste Zelle voll ist (z. B. das T- Stück).

Zum Beispiel werden die Spalten der ich erwähnt tetromino, wie früher, sind F, 0und 0. bin(0xF)ist '0b1111'. Nachdem '0b'wir das ignoriert haben , haben wir eine Länge von 4, was richtig ist. Ist bin(0x0)aber 0b0. Nachdem '0b'wir das ignoriert haben , haben wir immer noch eine Länge von '1, was falsch ist. Um dies zu berücksichtigen, haben wir am Ende ein zusätzliches Bit hinzugefügt, damit wir dieses unbedeutende Bit ignorieren können. Daher ist das +3im Code dazu da, die zusätzliche Länge zu berücksichtigen, die '0b'am Anfang und das unbedeutende Bit am Ende benötigt wird.

All dies geschieht innerhalb eines Generatorausdrucks für drei Spalten ( (0,1,2)), und wir ermitteln minanhand des Ergebnisses die maximale Anzahl von Zeilen, die das Stück ablegen kann, bevor es in einer der drei Spalten berührt wird.

Der Rest sollte durch Lesen des Codes ziemlich leicht zu verstehen sein, aber die forSchleife, die diesen Zuweisungen folgt, fügt das Stück der Tafel hinzu. Danach whileentfernt die Schleife volle Zeilen, ersetzt sie durch leere Zeilen oben und zählt die Punktzahl. Am Ende werden die Tafel und die Partitur auf die Ausgabe gedruckt.

P Papa
quelle
6

Python, 298 Zeichen

Schlägt alle bisher nicht- esoterischen Sprachlösungen (Perl, Ruby, C, Bash ...)


... und verwendet nicht einmal Schikanen mit Code-Zipping.

import os
r=os.read
b='[%11c\n'%']'*99+r(0,91)
for k,v in r(0,99).split():
    t=map(ord,' -:G!.:; -:; !-.!"-. !". !./')['IJLOSTZ'.find(k)*4:][:4];v=int(v)-31
    while'!'>max(b[v+j+13]for j in t):v+=13
    for j in t:b=b[:v+j]+'#'+b[v+j+1:]
    b=b.replace('[##########]\n','')
print b[-91:],1060-10*len(b)/13

Am Testbeispiel

[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7

es gibt aus

[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

PS. Es wurde ein Fehler behoben, auf den Nakilon mit einem Preis von +5 hingewiesen hatte

Nas Banov
quelle
Das ist ein ziemlich beeindruckender Code. Es würde 14 weitere Zeichen erfordern , um das Problem zu beheben ( ideone.com/zeuYB ), es sei denn, es gibt einen besseren Weg, aber trotzdem schlägt es alles außer GolfScript und Bash. Es ist sicherlich eine clevere Lösung.
P Daddy
Ja, absolut eine sehr gute Lösung!
ChristopheD
@ Nakilon: Danke, offensichtlich habe ich das verpasst. Fixed @ Kosten 293-> 298
Nas Banov
@P Daddy, danke - ich habe einen Weg gefunden, das Update unter Bash & Toolchain zu bringen, um mich ehrlich zu halten, indem ich "all non-esoteric"
sage
@Nabb: Um den Code kürzer zu halten, wurde er mit einigen Einschränkungen geschrieben. so etwas wie max. 33 Tetrominos und max. 99 Line Drops. Kann leicht zum Preis von +3 verlängert werden. Oder für einen niedrigen Preis :), können die Einschränkungen insgesamt aufgehoben werden. Übrigens, dies ist ein großartiges Beispiel dafür, wie ein Test-Set die Spezifikation geklärt hätte (was ich ChristopherD in Kommentaren
abgehört habe
5

Golfscript 260 Zeichen

Ich bin mir sicher, dass dies verbessert werden könnte. Ich bin ein bisschen neu in Golfscript.

[39 26.2/0:$14{.(}:?~1?15?1?14 2??27?13.!14?2?27?14 1]4/:t;n/)\n*:|;' '/-1%.,:c;~{)18+:&;'XIOZTLSJX'\%~;,1-t\={{.&+.90>{;.}*|\=32=!{&13-:&;}*}%}6*{&+}/|{\.@<'#'+\)|>+}4*{'['\10*']'++}:
;n/0\~n+:|;0\{.'#'
={;)}{n+|+:|;}if\.}do;' '
n+\.@*|+\$+:$;.,1-<:|;}c*|n?$*

Zeilenende sind relevant (es sollte keine am Ende geben). Wie auch immer, hier sind einige der Testfälle, die ich verwendet habe:

> cat init.txt 
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7> cat init.txt | ruby golfscript.rb tetris.gsc
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10

> cat init.txt
[]
[]
[]
[]
[# # #]
[## #####]
[==========]
I0 O7 Z1 S4> cat init.txt | ruby golfscript.rb tetris.gsc
[]
[]
[]
[#]
[### ####]
[### #####]
[==========]
10

> cat init.txt
[]
[]
[]
[## ###]
[# #]
[## ######]
[==========]
T7 I0 I3> cat init.txt | ruby golfscript.rb tetris.gsc
[]
[]
[]
[]
[# #]
[## # # #]
[==========]
20

Beachten Sie, dass die Eingabedatei kein Zeilenende enthält. Ein Zeilenende würde das Skript unverändert beschädigen.

coderaj
quelle
2
/ Ich halte GolfScript nicht für eine echte Wettbewerbssprache ... Es ist nur eine Bibliothek, die direkt auf Golfaufgaben zugeschnitten ist ... Die Größe dieser Bibliothek kann zur Größe des Golfscript-Codes hinzugefügt werden ...
Nakilon
4
@Nakilon - Kannst du nicht etwas Ähnliches über etwas sagen, das nicht in roher Maschinensprache geschrieben ist? :) Der Python-Interpreter ist nur eine Bibliothek. Fügen Sie Ihrem Eintrag seine Größe hinzu. </
sarcasm
2
@ Nakilon: das ist nur der Dolmetscher. Es könnte in jeder anderen Sprache geschrieben werden; Würden Sie immer noch sagen, dass Golfscript keine echte Sprache ist?
Michael Foukarakis
1
@Nabb: Danke, ich dachte, es gibt einige Tricks, die ich verpasst habe ... Fühle dich nicht schlecht, ich habe mir auch nicht die Mühe gemacht, meinen Code zu verstehen :).
Coderaj
1
@ Michael Foukarakis, ich kann in 1 Minute meinen eigenen Dolmetscher schreiben, um diese Aufgabe in einem Zeichen zu lösen, na und?
Nakilon
4

O'Caml 809 782

open String let w=length let c s=let x=ref 0in iter(fun k->if k='#'then incr x)s;!x open List let(@),g,s,p,q=nth,ref[],ref 0,(0,1),(0,2)let l=length let u=Printf.printf let rec o x i j=let a=map(fun s->copy s)!g in if snd(fold_left(fun(r,k)(p,l)->let z=c(a@r)in blit(make l '#')0(a@r)(i+p)l;if c(a@r)=z+l then r+1,k else r,false)(j-l x+1,true)x)then g:=a else o x i(j-1)and f x=let s=read_line()in if s.[1]='='then g:=rev x else f(sub s 1 10::x)let z=f [];read_line();;for i=0to w z/3 do o(assoc z.[i*3]['I',[p;p;p;p];'O',[q;q];'Z',[q;1,2];'T',[0,3;1,1];'L',[p;p;q];'S',[1,2;q];'J',[1,1;1,1;q]])(Char.code z.[i*3+1]-48)(l!g-1);let h=l!g in g:=filter(fun s->c s<>w s)!g;for i=1to h-(l!g)do incr s;g:=make 10' '::!g done;done;iter(fun r->u"[%s]\n"r)!g;u"[==========]\n";u"%d\n"(!s*10)
Jessicah
quelle
4

Common Lisp 667 657 645 Zeichen

Mein erster Versuch, Code Golf zu spielen, daher gibt es wahrscheinlich viele Tricks, die ich noch nicht kenne. Ich habe dort einige Zeilenumbrüche hinterlassen, um die verbleibende "Lesbarkeit" zu gewährleisten (ich habe Zeilenumbrüche als 2 Byte gezählt, sodass durch das Entfernen von 6 unnötigen Zeilenumbrüchen 12 weitere Zeichen erhalten werden).

Geben Sie bei der Eingabe zuerst die Formen und dann das Feld ein.

(let(b(s 0)m(e'(0 1 2 3 4 5 6 7 8 9)))
(labels((o(p i)(mapcar(lambda(j)(+ i j))p))(w(p r)(o p(* 13 r)))(f(i)(find i b))
(a(&aux(i(position(read-char)"IOZTLSJ")))(when i(push(o(nth i'((0 13 26 39)(0 1 13 14)(0 1 14 15)(0 1 2 14)(0 13 26 27)(1 2 13 14)(1 14 26 27)))(read))m)(a))))
(a)(dotimes(i 90)(if(find(read-char)"#=")(push i b)))(dolist(p(reverse m))
(setf b`(,@b,@(w p(1-(position-if(lambda(i)(some #'f(w p i)))e)))))
(dotimes(i 6)(when(every #'f(w e i))(setf s(1+ s)b(mapcar(lambda(k)(+(if(>(* 13 i)k)13(if(<=(* 13(1+ i))k)0 78))k))b)))))
(dotimes(i 6)(format t"[~{~:[ ~;#~]~}]
"(mapcar #'f(w e i))))(format t"[==========]
~a0"s)))

Testen

T2 Z6 I0 T7
[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10
NIL
lpetru
quelle
Nicht zu kurz, aber +1 für Hässlichkeit! Ich stelle mir vor, dass Alphabetsuppe so aussehen würde, wenn sie mit Klammern versehen wäre.
P Daddy
@P Daddy: Danke. Ja, so würde es wahrscheinlich aussehen :).
lpetru
2

Ruby 505 479 474 442 439 426 Zeichen

Ein erster Versuch. Habe es mit IronRuby gemacht. Ich bin sicher, dass es verbessert werden kann, aber ich sollte heute wirklich etwas Arbeit erledigen!

p,q,r,s=(0..9),(0..2),(0..6),0
t=[*$<]
f=p.map{|a|g=0;r.map{|b|g+=2**b if t[6-b][a+1]==?#};g}
t.pop.split.map{|x|w,y=[15,51,306,562,23,561,113]["IOZTLSJ"=~/#{x[0]}/],x[1].to_i
l=q.map{|d|r.inject{|b,c|f[d+y]&(w>>(d*4)&15-c+1)>0?c:b}}.max
q.map{|b|f[b+y]|=w>>(b*4)&15-l}
r.map{i=f.inject{|a,b|a&b};f.map!{|a|b=i^(i-1);a=((a&~b)>>1)+(a&(b>>1))};s+=i>0?10:0}}
p.map{|a|r.map{|b|t[6-b][a+1]=f[a]&2**b>0??#:' '}}
puts t,s

Testen

cat test.txt | ruby tetris.rb
[          ]
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Jetzt mit normalem Rubin bearbeiten . Habe die Wände ausgegeben ..

Mongus Pong
quelle
Noch ein Rubist, nett! Aber machen Sie ein Glas um Ziegel.
Nakilon
1

Ein anderer in Ruby, 573 546 Zeichen

: **

Z={I:?#*4,J:'#,###',L:'###,#',O:'##,##',S:'#,##, #',Z:' #,##,#',T:' #,##, #'}
t=[*$<]
R=->s{s.reverse}
T=->m{m.transpose}
a = T[R[t].join.scan /.#{'(\D)'*10}.$/]
t.pop.split.each{|z|
t,o=Z[z[0].to_sym].split(',').map{|x|x.split //},z[1].to_i
r=0..t.size-1
y=r.map{|u|1+a[o+u].rindex(?#).to_i-t[u].count(' ')}.max
(0..3).each{|i|r.each{|j|t[j][i]==?#&&a[o+j][y+i]=t[j][i]}}}
s=0
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}
a=R[T[a].reject{|x|x*''=~/[#]{10}/&&s+=10}.map{|x|?[+x*''+?]}[0..6]]
puts (0..8-a.size).map{?[+' '*10+?]},a,s

Testen:

cat test.txt | ruby 3858384_tetris.rb
[          ]
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10
glebm
quelle
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}
Behoben