The Tetris Project

Perhaps we should begin discussing the Tetris project.

One suggestion has been that we represent a "J" shape as _|. We can print that by executing …

print "_|`"

But, of course, in a real Tetris game, the "J" can be in any one of four positions. It is difficult to rotate the above representation into all of those positions.

We could represent the "J" shape like this instead, shown here in each of the four possible positions …

 #  ###  ##   #
 #    #  #    ###
##       # 

To print these, we can use this …

print "##"
print "#"
print "#"

this …

print "###"
print "  #"

this …

print " #"
print " #"
print "##"

and this …

print "#"
print "###"

Another issue, though, is that on an actual Tetris board, there will be other shapes in addition to the "J" shape, with the full set being "I", "J", "L", "O", "S", "T", and "Z". Most of these can also be rotated. A problem arises, when several of these shapes are adjacent to each other. If we use the same character to build each one, we cannot distinguish them on the board, when several of them are adjacent. All we would see would be a glob of "#" symbols. So, maybe we should build each shape by using the letter for which it is named. To print an "O", then, we would use …

print "OO"
print "OO"

An `“S”`` would be …

print " SS"
print "SS"

But there is still another problem. Shapes can interlock with each other, fitting snugly together …

   J
 SSJ
SSJJ

We cannot simply print a complete "S", and then a complete "J" to do that. We would need to intermix the print statements. Things could then get really messy.

So, another strategy could be to establish the board as a list of rows. Represent each shape as having a row, column location and a particular rotation. Based on that information, we can devise an algorithm to calculate what character needs to be printed at each row, column position on the board. Then print the board, one row at a time.

We should probably write a draw function that is designed to draw shapes, so we can call the function whenever needed, to insert a shape onto the board. drawing would actually consist of storing the characters that represent the shape into the board list. The function might take a shape name, a row, a column, and a rotation factor as arguments. It would need to make sure the specified location and position are in a valid place on the board, and that the shape being added does not impinge upon another shape that is already there.

Then once the board has been composed, we could use a print_board function to display it. We would, of course, need to create that function.

I’ll leave off here for now. Perhaps we can get some other suggestions.

Wouldn’t there also need to be some big control function that determines when to draw the board and at what rate? Of course, I guess we haven’t gotten to that in the course materials.

This whole Tetris project really excites me.

Yes, there should be a central control function that coordinates everything, such as when to draw the board, scoring, and the user input process.

During previous runs of the MMOOC, the game was based on a graphical user interface that used Tkinter, in order to draw the board. The whole project was built of user-defined classes that variously represented Board, Blocks, Shapes, each type of Shape as a subclass, and the game itself as a Tetris class.

Ah, clever. Are we pursuing a slightly different version of the past project then, or is it the same?

I don’t know what the ultimate plan is for this project, but it will be, essentially, and entirely different project if the previous version has been modified for console output. The game would run quite awkwardly, if every time the user presses an arrow key to move or rotate a shape, a series of lines get printed to the console to represent the new board configuration.

So, my guess is that sometime soon, we will discussing the same project that they’ve used in the past, which would be best. If that is the plan, then the suggestions they are making to us now are simply a means of getting us to begin thinking about the game, and what is really needed for it.

Here’s a link to the project, as it has been offered in the past: 6.189 Final Project – Tetris!

It’s an interesting programming experience, requires a lot of work, and is worth it, imo.

Excellent, looks exciting.

With graphics now used in the Tetris project, we need to save the graphics.py file that we are given in the same folder or directory as the tetris.py that we are creating.

The following implements an “I” shape built of square blocks. Conceptually, the code is in a rough draft condition, and will require major rethinking and revision later on. If we each post code as we go, we can have a lot to think about and discuss.

It helps to first draw the situation by hand, and to label the diagram with variables and numbers that represent locations and sizes of objects, and components of objects.

# tetris.py
# May 11, 2015
from graphics import *

def draw_i_shape(x, y, position):
    # function that draws an I shape on the board
    # x, y is board location, in pixels, of upper left corner of the shape
    # x is distance in pixels from left margin
    # y is distance in pixels from top margin
    # position is whether it is vertical or horizontal
    BLOCKSIZE = 50 # dimension, in pixels, of each square that makes up the shape
    if position == "horizontal":
        for i in range(4):
            Rectangle(Point(x + BLOCKSIZE * i, y), Point(x + BLOCKSIZE * i + BLOCKSIZE, y + BLOCKSIZE)).draw(win)
    elif position == "vertical":
        for i in range(4):
            Rectangle(Point(x, y + BLOCKSIZE * i), Point(x + BLOCKSIZE, y + BLOCKSIZE * i + BLOCKSIZE)).draw(win)
              
win = GraphWin('Rect', 800, 500)

Rectangle(Point(200, 200), Point(400, 400)).draw(win)
draw_i_shape(100, 50, "horizontal")
draw_i_shape(500, 140, "vertical")

win.mainloop()

So Glenn,

Where do we get this graphics.py file? Did I miss something?

@zinkeldonk there is a link in the mooc email…

Here is the link:

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-189-a-gentle-introduction-to-programming-using-python-january-iap-2011/assignments/graphics.py

I know I’m running a bit ahead, but I’m trying to figure out how to add colour to my tetris project. MOOC-E suggests to use this code:

rectangle.setFill(‘deep pink’)

But it doesn’t work for me. Am I missing an import of colour scheme or what?

Thank you so much!

Here’s an example that might help. It draws three shapes with various fill colors:

from graphics import *

def draw_i_shape(x, y, position):
    BLOCKSIZE = 50
    if position == "horizontal":
        for i in range(4):
            rect = Rectangle(Point(x + BLOCKSIZE * i, y), Point(x + BLOCKSIZE * i + BLOCKSIZE, y + BLOCKSIZE))
            rect.setFill("red")
            rect.draw(win)
    elif position == "vertical":
        for i in range(4):
            rect = Rectangle(Point(x, y + BLOCKSIZE * i), Point(x + BLOCKSIZE, y + BLOCKSIZE * i + BLOCKSIZE))
            rect.setFill("blue")
            rect.draw(win)
win = GraphWin('Rect', 800, 500)
squareBox = Rectangle(Point(200, 200), Point(400, 400))
squareBox.setFill("yellow")
squareBox.draw(win)
draw_i_shape(100, 50, "horizontal")
draw_i_shape(500, 140, "vertical")
win.mainloop()

I am inclined, at this early stage, to build the Tetris game WITHOUT so many fancy libraries, so we aren’t ahead of ourselves. So I’ll pick it up where you started in your first post and try to build this without extra modules.

There’s a unicode character box, \u2588, that works better than #, I think.

Printing characters in different colors is a key piece. But it is surprisingly very difficult, using Window 7 as I am, to use colors. per http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python, unless you import a library for that.

So already I am stuck with importing a module. Stackoverflow recommends Colorama to solve the problem (http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python/3332860#3332860) and here’s the module page: https://pypi.python.org/pypi/colorama

I was able to install it, and then, following the instructions, I created a new file with:

from colorama import init
init()
from colorama import Fore
print(Fore.RED + '\u2588')

But my output is still blue. Any idea why?

-Bram

Hi @bmoreinis, I posted about why this may not work earlier this week - http://discourse.p2pu.org/t/3rd-course-email-a-little-more-functions-please/609?u=bkglass

@bmoreinis,

Ultimately, the console-based version of Tetris will get bogged down, because each time the user presses an arrow key, or a shape drops down on its own accord, the entire board will need to be re-printed, row-by-row. It will get really slow.

Aside from random, the only imported code needed for the graphical version of the Tetris game is the graphics.py file that we are given. If you really would like the game to be self-contained, without its needing to import graphics, it is possible to scavenge the necessary code from graphics.py, and then to remove the import graphics statement. The scavenging task is a bit of work, but it is doable, though I’m not sure what the terms of use are for the graphics.py file. Just keep it a secret. :wink:

That makes sense, Glenn.

I guess maybe we should not be leaping into Tetris before we’ve mastered concepts like two dimensional arrays … I’ll let Tetris go for now. But initial thwacking at it got me into this Colorama thing that seems like a useful issue to be able to solve.

Here’s the issue I just created on Github: https://github.com/tartley/colorama/issues/60

I have also just put the issue up on the Python IRC channel.

AH - yes, I am a noob. IDLE force-colors text. I need to use PyCharm (an IDLE that respects text coloring)
Thanks to Python IRC! Resolved issue on Github.

Now I’m seeing how important it is to understand the differences between console and command line…

@bmoreinis you can run your script in Windows command prompt or Windows PowerShell and the colored text will work… I generally use Notepad++ and PowerShell for most things anyway.

Whether or not having different colored text will be useful for me remains to be seen… But it was fun seeing something besides ‘white’ for a change. :open_mouth:

So I managed to get the colours working, but now I’m trying to do this week’s (week 4) assignment. I know how to draw squares in graph and colour them. But if I want to make an “F” shaped form, how do I append the final square to the i-shape?

Here:

Doing it square-by-square doesn’t really make sense to me, but I’m not sure how to make this with iterations.

My silly code so far:

rect = Rectangle(Point(50, 50), Point(250, 100))
rect.setFill(“blue”)
rect.draw(win)

rect = Rectangle(Point(250, 50), Point(400, 100))
rect.setFill(“orange”)
rect.draw(win)

rect = Rectangle(Point(500, 50), Point(650, 100))
rect.setFill(“cyan”)
rect.draw(win)

Also this makes for one big rectangle instead of having several separate small squares… Should I make a small 50x50 square and multiply by the number of squares required?

Thanks a lot and sorry for being such a noob. :smile:

… You are absolutely right - and this concept is the motivation behind object oriented programming (OOP).

Note that an object of type Rectangle can be created with the following …

rect = Rectangle(Point(250, 50), Point(400, 100))

… then can be colored by …

rect.setFill("orange")

… and drawn by …

rect.draw(win)

… and so, we need to be able to do something like this in order to deal with the various Tetris shapes …

s = S_shape(4, 7) # create a new S shape at position 4, 7 on the Board
s.draw() #draw the S shape
s.move(3, 2) # move the S shape 3 positions to the right and 2 positions down
s.rotate() # rotate the S shape

To enable ourselves to do that, we first need to write code that, when we need to create the S shape as a unit, we can invoke to create the 4 rectangles that will comprise it, and fill them all with the correct color for that shape. We also need to write code that can draw, move, and rotate the entire shape as a unit.

But before we can do any of that, we will need to do the following work on Codecademy, which is about object oriented programming …

@Glenn I agree using Classes will probably be a good way to go as things progress. I have been struggling
the last couple of weeks trying to wrap my head around them… Classes can seem like a riddle wrapped
in a mystery inside an enigma.

I found this link to be a good beginning Introduction to Classes.

I have worked through most of ‘Learn Python The Hard Way’ up to Exercise 43… But I needed to find more
explanation on Classes. I found a post that uses Exercise 43 as an example to explain in depth about how
Classes work… This was one of the best things I have read concerning Classes. - https://gist.github.com/anonymous/91865cb266659c2c3f24

Hopefully, this is helpful for others learning about Classes.