All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars    
perplexus dot info

Home > Shapes
One Piece Tetris (Posted on 2007-12-19) Difficulty: 4 of 5
A typical game of Tetris has 10 columns and 7 pieces. Consider a variation with fewer columns and only one piece, which repeats indefinitely.

For some pieces and column widths it is trivial to see that an infinite game is possible. For example the I tetromino with any column width or any other of the tetrominoes with an even column width.

For other pieces, an infinite game is possible, but not trivially so.
Consider the T tetromino in three columns, an infinite game is possible by following a pattern:
The first piece is horizontal with the stem of the T pointing down.
The second piece is vertical, with the stem of the T pointing to the right and the T is pushed to the left edge.
The third piece is vertical, with the stem of the T pointing to the left and the T is pushed to the right edge.

For each piece and number of columns listed below, find a strategy for each which allows for an infinite game:
1.                               2.
### in three columns             ### in four columns
#                                 #
                                  #
								  
3.                               4.
### in four columns              ##### in five columns
#                                  #
#

-----------------------------------------------------

Notes:
1 - Using the reflection of an asymmetrical piece is not allowed.
2 - Use classic gravity: when a row is filled, it is removed and all rows above move down, but no fragments of one partially filled row fall into another partially filled row.

See The Solution Submitted by Brian Smith    
Rating: 4.0000 (3 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
Hints/Tips re: a way to play around with this -- pentominos | Comment 2 of 5 |
(In reply to a way to play around with this by Charlie)

A versionfor pentominoes follows.  I haven't made a version for hexominoes, but look at the data statements and the arrays for the pieces, to see how to modify.

DEFINT A-Z
RANDOMIZE TIMER
SCREEN 12
' $DYNAMIC
perpetPiece = 2
gWidth = 4
DIM sh&(850, 1 TO 2, 1 TO 5), area&(10000)
DIM grid(20, gWidth)
DATA 9,14
DATA 1,1, 0,1, -1,1, -1,0, -1,-1,    1,1, 0,1, -1,1, 1,0, 1,-1 :     '***
DATA -1,-1, 0,-1, 1,-1, 1,0, 1,1,    -1,-1, 0,-1, 1,-1, -1,0, -1,1:  '*
                                                                     '*
DATA 2,14
DATA 1,0, 0,0, -1,-1, -1,0, -1,1,   1,1, 0,1, -1,1, 0,0, 0,-1:   '***
DATA -1,0, 0,0, 1,-1, 1,0, 1,1,     -1,-1, 0,-1, 1,-1, 0,0, 0,1: ' *
                                                                 ' *
 

CLS
FOR piece = 1 TO 2
  READ color1(piece), color2(piece)
  FOR rot = 1 TO 4
    FOR square = 1 TO 5
      READ x(piece, rot, square), y(piece, rot, square)
    NEXT
    x1 = piece * 80: y1 = rot * 100 - 30
    FOR square = 1 TO 5
      x = x(piece, rot, square): y = y(piece, rot, square)
      x = x * 20 + x1: y = y * 20 + y1
      LINE (x, y)-(x + 19, y + 19), color2(piece), B
      LINE (x + 1, y + 1)-(x + 18, y + 18), color2(piece), B
      PAINT (x + 10, y + 10), color1(piece), color2(piece)
    NEXT
    GET (x1 - 40, y1 - 40)-(x1 + 39, y1 + 39), sh&(0, piece, rot)
  NEXT
NEXT
t# = TIMER: DO: LOOP UNTIL TIMER >= t# + 2 OR TIMER < t#
' DO: a$ = INKEY$: LOOP UNTIL a$ > "": IF a$ = CHR$(27) THEN END
CLS
top = 40: left = 219
LINE (left, top)-(left + 20 * gWidth + 1, top + 401), 15, B
ERASE grid: REDIM grid(20, gWidth)
delay! = .5
piece = INT(RND(1) * 7 + 1): rot = 1
nxtPiece = piece
DO
  piece = nxtPiece
  nxtPiece = INT(RND(1) * 7 + 1): rot = 1
  IF perpetPiece > 0 THEN nxtPiece = perpetPiece: piece = perpetPiece
  PUT (5, 20), sh&(0, nxtPiece, 1), PSET
  row = 1: col = 2
  DO
    flag = 0
    FOR sq = 1 TO 5
      IF y(piece, rot, sq) + row < 0 THEN
flag = 1
  ELSEIF grid(y(piece, rot, sq) + row, x(piece, rot, sq) + col) > 0 THEN
EndIt = 1
END IF
    NEXT
    IF EndIt = 1 THEN GOTO GameOver
    IF flag > 0 THEN row = row + 1
  LOOP UNTIL flag = 0
  initRow = row
  old.x = 0: old.y = 0
  DO
    y = top + row * 20 - 59: x = left + col * 20 - 59
    IF old.x > 0 THEN PUT (old.x, old.y), sh&(0, piece, old.rot), XOR
    PUT (x, y), sh&(0, piece, rot), XOR
    old.x = x: old.y = y: old.rot = rot
    t# = TIMER
    DO
     a$ = INKEY$: IF a$ > "" THEN GOSUB Keyboard
    LOOP UNTIL TIMER > t# + delay! OR accel = 1
    hit = 0
    FOR i = 1 TO 5
      trow = y(piece, rot, i) + row + 1
      IF trow > 20 THEN hit = 1: EXIT FOR
      IF grid(trow, x(piece, rot, i) + col) > 0 THEN hit = 1
    NEXT
    IF hit = 1 THEN GOSUB HandleHit: EXIT DO:  ELSE row = row + 1
  LOOP
LOOP
END
GameOver:
LOCATE 30, 36: PRINT "Game Over.";
DO: a$ = INKEY$: LOOP UNTIL a$ > "": IF a$ = CHR$(27) THEN END
RUN
HandleHit:
  rMax = 0
  FOR i = 1 TO 5
    r = row + y(piece, rot, i): c = col + x(piece, rot, i)
    grid(r, c) = 1
    IF r > rMax THEN rMax = r
  NEXT
  r = rMax
  DO
    all = 1
    FOR i = 1 TO gWidth
      IF grid(r, i) = 0 THEN all = 0: EXIT FOR
    NEXT
    IF all = 1 THEN GOSUB DelRow ELSE r = r - 1
    IF r < 2 OR r < rMax - 4 THEN EXIT DO
  LOOP
  accel = 0
RETURN
DelRow:
  FOR i = 1 TO gWidth
    FOR row = r TO 2 STEP -1
      grid(row, i) = grid(row - 1, i)
    NEXT
    grid(1, i) = 0
  NEXT
  GET (left + 1, top + 1)-(left + 20 * gWidth, top + (r - 1) * 20), area&
  PUT (left + 1, top + 21), area&, PSET
  LINE (left + 1, top + 1)-(left + 20 * gWidth, top + 20), 0, BF
RETURN
Keyboard:
  DO
    SELECT CASE a$
      CASE CHR$(27)
        END
      CASE "5"
        rot = rot + 1: IF rot > 4 THEN rot = 1
        hit = 0
        FOR i = 1 TO 5
          trow = y(piece, rot, i) + row + 1
          tcol = x(piece, rot, i) + col
          IF trow > 20 THEN hit = 1: EXIT FOR
          IF tcol > gWidth OR tcol < 1 THEN hit = 1: EXIT FOR
          IF grid(trow, tcol) > 0 THEN hit = 1
        NEXT
        IF hit = 1 THEN rot = rot - 1: IF rot < 1 THEN rot = 4
      CASE "6"
        good = 1
        FOR i = 1 TO 5
          xp = x(piece, rot, i) + col: yp = y(piece, rot, i) + row
          IF xp >= gWidth THEN good = 0: EXIT FOR
          IF yp > 0 THEN IF grid(yp, xp + 1) > 0 THEN good = 0: EXIT FOR
        NEXT
        IF good = 1 THEN col = col + 1
      CASE "4"
        good = 1
        FOR i = 1 TO 5
          xp = x(piece, rot, i) + col: yp = y(piece, rot, i) + row
          IF xp <= 1 THEN good = 0: EXIT FOR
          IF yp > 0 THEN IF grid(yp, xp - 1) > 0 THEN good = 0: EXIT FOR
        NEXT
        IF good = 1 THEN col = col - 1
      CASE "2"
        accel = 1
      CASE "+"
        delay! = delay! / 2
      CASE "-"
        delay! = delay! * 2
    END SELECT
    y = top + row * 20 - 60: x = left + col * 20 - 59
    IF old.x > 0 THEN PUT (old.x, old.y), sh&(0, piece, old.rot), XOR
    PUT (x, y), sh&(0, piece, rot), XOR
    old.x = x: old.y = y: old.rot = rot
    a$ = INKEY$: IF a$ = CHR$(27) THEN END
  LOOP WHILE a$ > ""
RETURN


 


  Posted by Charlie on 2007-12-19 14:38:59
Please log in:
Login:
Password:
Remember me:
Sign up! | Forgot password


Search:
Search body:
Forums (0)
Newest Problems
Random Problem
FAQ | About This Site
Site Statistics
New Comments (2)
Unsolved Problems
Top Rated Problems
This month's top
Most Commented On

Chatterbox:
Copyright © 2002 - 2017 by Animus Pactum Consulting. All rights reserved. Privacy Information