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()