テトリス

ダウンロード
夏休みテトリス1.zip
zip ( 圧縮 ) ファイル 3.6 KB

テトリス② ブロック操作

import sys

from math import sqrt

from random import randint

import pygame

from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_DOWN, K_SPACE

 

BLOCK_DATA = (

    (

        (0, 0, 1, 1, 1, 1, 0, 0, 0),

        (0, 1, 0, 0, 1, 0, 0, 1, 1),

        (0, 0, 0, 1, 1, 1, 1, 0, 0),

        (1, 1, 0, 0, 1, 0, 0, 1, 0),

    ), (

        (2, 0, 0, 2, 2, 2, 0, 0, 0),

        (0, 2, 2, 0, 2, 0, 0, 2, 0),

        (0, 0, 0, 2, 2, 2, 0, 0, 2),

        (0, 2, 0, 0, 2, 0, 2, 2, 0)

    ), (

        (0, 3, 0, 3, 3, 3, 0, 0, 0),

        (0, 3, 0, 0, 3, 3, 0, 3, 0),

        (0, 0, 0, 3, 3, 3, 0, 3, 0),

        (0, 3, 0, 3, 3, 0, 0, 3, 0)

    ), (

        (4, 4, 0, 0, 4, 4, 0, 0, 0),

        (0, 0, 4, 0, 4, 4, 0, 4, 0),

        (0, 0, 0, 4, 4, 0, 0, 4, 4),

        (0, 4, 0, 4, 4, 0, 4, 0, 0)

    ), (

        (0, 5, 5, 5, 5, 0, 0, 0, 0),

        (0, 5, 0, 0, 5, 5, 0, 0, 5),

        (0, 0, 0, 0, 5, 5, 5, 5, 0),

        (5, 0, 0, 5, 5, 0, 0, 5, 0)

    ), (

        (6, 6, 6, 6),

        (6, 6, 6, 6),

        (6, 6, 6, 6),

        (6, 6, 6, 6)

    ), (

        (0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0),

        (0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0),

        (0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0),

        (0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0)

    )

)

 

class Block:

    """ ブロックオブジェクト """

    def __init__(self, count):

        self.turn = randint(0, 3)

        self.type = BLOCK_DATA[randint(0, 6)]

        self.data = self.type[self.turn]

        self.size = int(sqrt(len(self.data)))

        self.xpos = 5

        self.ypos = 8

 

        

 

 

    def draw(self):

        """ ブロックを描画する """

        for index in range(len(self.data)):

            xpos = index % self.size

            ypos = index // self.size

            val = self.data[index]

            if 0 <= ypos + self.ypos < HEIGHT and \

               0 <= xpos + self.xpos < WIDTH and val != 0:

                x_pos = 25 + (xpos + self.xpos) * 25

                y_pos = 25 + (ypos + self.ypos) * 25

                pygame.draw.rect(SURFACE, COLORS[val],

                                 (x_pos, y_pos, 24, 24))

 

def draw_block(count):

    global BLOCK

    BLOCK = Block(count)

 

def is_overlapped(xpos, ypos, turn):

    """ ブロックが壁や他のブロックと衝突するか否か """

    data = BLOCK.type[turn]

    for y_offset in range(BLOCK.size):

        for x_offset in range(BLOCK.size):

            if 0 <= xpos+x_offset < WIDTH and 0 <= ypos+y_offset < HEIGHT:

                if data[y_offset*BLOCK.size + x_offset] != 0 and \

                    FIELD[ypos+y_offset][xpos+x_offset] != 0:

                    return True

    return False

 

 

# グローバル変数

pygame.init()

pygame.key.set_repeat(30, 30)

SURFACE = pygame.display.set_mode([600, 600])

FPSCLOCK = pygame.time.Clock()

WIDTH = 12

HEIGHT = 22

FIELD = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)]

COLORS = ((0, 0, 0), (255, 165, 0), (0, 0, 255), (0, 255, 255), \

          (0, 255, 0), (255, 0, 255), (255, 255, 0), (255, 0, 0), (128, 128, 128))

 

 

def main():

    """ メインルーチン """

    draw_block(1)

    for ypos in range(HEIGHT):

        for xpos in range(WIDTH):

            FIELD[ypos][xpos] = 8 if xpos == 0 or \

                xpos == WIDTH - 1 else 0

    for index in range(WIDTH):

        FIELD[HEIGHT-1][index] = 8

 

    while True:

        key = None

        for event in pygame.event.get():

            if event.type == QUIT:

                pygame.quit()

                sys.exit()

            elif event.type == KEYDOWN:

                key = event.key

 

            # キーイベント処理

            next_x, next_y, next_t = \

                BLOCK.xpos, BLOCK.ypos, BLOCK.turn

            if key == K_SPACE:

                next_t = (next_t + 1) % 4

            elif key == K_RIGHT:

                next_x += 1

            elif key == K_LEFT:

                next_x -= 1

            elif key == K_DOWN:

                next_y += 1

 

            if not is_overlapped(next_x, next_y, next_t):

                BLOCK.xpos = next_x

                BLOCK.ypos = next_y

                BLOCK.turn = next_t

                BLOCK.data = BLOCK.type[BLOCK.turn]

 

 

 

        # 全体&ブロックの描画

        SURFACE.fill((0, 0, 0))

        for ypos in range(HEIGHT):

            for xpos in range(WIDTH):

                val = FIELD[ypos][xpos]

                pygame.draw.rect(SURFACE, COLORS[val], (xpos*25 + 25, ypos*25 + 25, 24, 24))

        BLOCK.draw()

 

 

 

        pygame.display.update()

        FPSCLOCK.tick(15)

 

if __name__ == '__main__':

    main()

 

テトリス③ ブロック落下

import sys

from math import sqrt

from random import randint

import pygame

from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_DOWN, K_SPACE

 

BLOCK_DATA = (

    (

        (0, 0, 1, 1, 1, 1, 0, 0, 0),

        (0, 1, 0, 0, 1, 0, 0, 1, 1),

        (0, 0, 0, 1, 1, 1, 1, 0, 0),

        (1, 1, 0, 0, 1, 0, 0, 1, 0),

    ), (

        (2, 0, 0, 2, 2, 2, 0, 0, 0),

        (0, 2, 2, 0, 2, 0, 0, 2, 0),

        (0, 0, 0, 2, 2, 2, 0, 0, 2),

        (0, 2, 0, 0, 2, 0, 2, 2, 0)

    ), (

        (0, 3, 0, 3, 3, 3, 0, 0, 0),

        (0, 3, 0, 0, 3, 3, 0, 3, 0),

        (0, 0, 0, 3, 3, 3, 0, 3, 0),

        (0, 3, 0, 3, 3, 0, 0, 3, 0)

    ), (

        (4, 4, 0, 0, 4, 4, 0, 0, 0),

        (0, 0, 4, 0, 4, 4, 0, 4, 0),

        (0, 0, 0, 4, 4, 0, 0, 4, 4),

        (0, 4, 0, 4, 4, 0, 4, 0, 0)

    ), (

        (0, 5, 5, 5, 5, 0, 0, 0, 0),

        (0, 5, 0, 0, 5, 5, 0, 0, 5),

        (0, 0, 0, 0, 5, 5, 5, 5, 0),

        (5, 0, 0, 5, 5, 0, 0, 5, 0)

    ), (

        (6, 6, 6, 6),

        (6, 6, 6, 6),

        (6, 6, 6, 6),

        (6, 6, 6, 6)

    ), (

        (0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0),

        (0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0),

        (0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0),

        (0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0)

    )

)

 

class Block:

    """ ブロックオブジェクト """

    def __init__(self, count):

        self.turn = randint(0, 3)

        self.type = BLOCK_DATA[randint(0, 6)]

        self.data = self.type[self.turn]

        self.size = int(sqrt(len(self.data)))

        self.xpos = randint(2, 8 - self.size)

        self.ypos = 1 - self.size

        self.fire = count + INTERVAL

        

    def update(self, count):

        """ ブロックの状態更新 (消去した段の数を返す) """

        # 下に衝突?

        if is_overlapped(self.xpos, self.ypos + 1, self.turn):

            for y_offset in range(BLOCK.size):

                for x_offset in range(BLOCK.size):

                    if 0 <= self.xpos+x_offset < WIDTH and \

                        0 <= self.ypos+y_offset < HEIGHT:

                        val = BLOCK.data[y_offset*BLOCK.size + x_offset]

                        if val != 0:

                            FIELD[self.ypos+y_offset][self.xpos+x_offset] = val

 

            go_next_block(count)

 

        if self.fire < count:

            self.fire = count + INTERVAL

            self.ypos += 1

    

    def draw(self):

        """ ブロックを描画する """

        for index in range(len(self.data)):

            xpos = index % self.size

            ypos = index // self.size

            val = self.data[index]

            if 0 <= ypos + self.ypos < HEIGHT and \

               0 <= xpos + self.xpos < WIDTH and val != 0:

                x_pos = 25 + (xpos + self.xpos) * 25

                y_pos = 25 + (ypos + self.ypos) * 25

                pygame.draw.rect(SURFACE, COLORS[val],

                                 (x_pos, y_pos, 24, 24))

 

def is_game_over():

    """ ゲームオーバーか否か """

    filled = 0

    for cell in FIELD[0]:

        if cell != 0:

            filled += 1

    return filled > 2   # 2 = 左右の壁

 

def go_next_block(count):

    """ 次のブロックに切り替える """

    global BLOCK, NEXT_BLOCK

    BLOCK = NEXT_BLOCK if NEXT_BLOCK != None else Block(count)

    NEXT_BLOCK = Block(count)

 

def is_overlapped(xpos, ypos, turn):

    """ ブロックが壁や他のブロックと衝突するか否か """

    data = BLOCK.type[turn]

    for y_offset in range(BLOCK.size):

        for x_offset in range(BLOCK.size):

            if 0 <= xpos+x_offset < WIDTH and \

                0 <= ypos+y_offset < HEIGHT:

                if data[y_offset*BLOCK.size + x_offset] != 0 and \

                    FIELD[ypos+y_offset][xpos+x_offset] != 0:

                    return True

    return False

 

 

# グローバル変数

pygame.init()

pygame.key.set_repeat(30, 30)

SURFACE = pygame.display.set_mode([600, 600])

FPSCLOCK = pygame.time.Clock()

WIDTH = 12

HEIGHT = 22

FIELD = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)]

COLORS = ((0, 0, 0), (255, 165, 0), (0, 0, 255), (0, 255, 255), \

          (0, 255, 0), (255, 0, 255), (255, 255, 0), (255, 0, 0), (128, 128, 128))

INTERVAL = 40

BLOCK = None

NEXT_BLOCK = None

 

 

def main():

    """ メインルーチン """

    global INTERVAL

    count = 0

    go_next_block(INTERVAL)

 

    for ypos in range(HEIGHT):

        for xpos in range(WIDTH):

            FIELD[ypos][xpos] = 8 if xpos == 0 or \

                xpos == WIDTH - 1 else 0

    for index in range(WIDTH):

        FIELD[HEIGHT-1][index] = 8

 

    while True:

        key = None

        for event in pygame.event.get():

            if event.type == QUIT:

                pygame.quit()

                sys.exit()

            elif event.type == KEYDOWN:

                key = event.key

 

        game_over = is_game_over()

        if not game_over:

            count += 5

            if count % 1000 == 0:

                INTERVAL = max(1, INTERVAL - 2)

            erased = BLOCK.update(count)

 

 

            # キーイベント処理

            next_x, next_y, next_t = \

                BLOCK.xpos, BLOCK.ypos, BLOCK.turn

            if key == K_SPACE:

                next_t = (next_t + 1) % 4

            elif key == K_RIGHT:

                next_x += 1

            elif key == K_LEFT:

                next_x -= 1

            elif key == K_DOWN:

                next_y += 1

 

            if not is_overlapped(next_x, next_y, next_t):

                BLOCK.xpos = next_x

                BLOCK.ypos = next_y

                BLOCK.turn = next_t

                BLOCK.data = BLOCK.type[BLOCK.turn]

 

 

 

        # 全体&ブロックの描画

        SURFACE.fill((0, 0, 0))

        for ypos in range(HEIGHT):

            for xpos in range(WIDTH):

                val = FIELD[ypos][xpos]

                pygame.draw.rect(SURFACE, COLORS[val], (xpos*25 + 25, ypos*25 + 25, 24, 24))

        BLOCK.draw()

 

 

 

        pygame.display.update()

        FPSCLOCK.tick(15)

 

if __name__ == '__main__':

    main()