两个选择一个你擅长的做就好
1、俄罗斯方块
要求:(1)两个人对战,同时记分,分高者胜;(2)至少设定三个档次,a、增加速度,b、增加难度,c、同时增加速度和难度,难度的增加可以通过增加方块形状实现(方块形状的增加使用随机生成和可行性判别算法实现,即在4×4的矩阵中随机生成四个方块,判断方块是否连续,使用八领域连接)。
2.1、学生成绩管理系统
要求:(1)使用链表或动态数组对成绩进行管理和评价,(2)完成基本数据的增删改查功能,(3)对成绩数据进行可视化(男生成绩分布图,女生成绩分布图,按生源地平均成绩的柱状图等),(4)必须具有统计分析的功能,包括对男生和女生成绩的分开评价和对比评价(方差分析看均值是否有显著差异),(5)成绩特点和趋势,以及对下一学期的成绩预测(回归分析),(6)对每个学生进行综合排名(对各个成绩指标确定权重并说明理由)。
注:代码注释尽量清楚一点,代码尽量简单一点点
import os
import pygame
import sys
import random
import pygame.font
import time
pygame.init()
clos = 10 #游戏网格列数,可以调整,>=8
rows = 20 #游戏网格行数,可以调整
cell_size = 40 #一个网格的大小
block_size = cell_size - 1 #一个方块的大小,小于等于cell_size
block_edge = int(block_size /2) #方块的立体感,数字>=1,数字越小立体感越强
fps = 40 #每秒帧数,建议范围20-60,越大难度递进越越缓
win_width = clos * 2 * cell_size + 6 * cell_size
win_hight = (rows + 1) * cell_size
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (400,40)
screen = pygame.display.set_mode((win_width, win_hight))
pygame.display.set_caption("Crystal方块")
#在4*4的小网格内,以左上角坐标为(0,0),7种方块及其各形态4个方块在小网格的相对坐标
#移动时记录小网络(0,0)点在游戏网格的(x,y),就知道4个方块在游戏网格中的位置
blocks = {
1: [[(0,1),(1,1),(2,1),(3,1)],
[(2,0),(2,1),(2,2),(2,3)]], #I型
2: [[(1,1),(2,1),(1,2),(2,2)]], #O型
3: [[(0,1),(1,1),(2,1),(1,2)],
[(1,0),(0,1),(1,1),(1,2)],
[(1,1),(0,2),(1,2),(2,2)],
[(1,0),(1,1),(2,1),(1,2)]], #T型
4: [[(0,1),(1,1),(2,1),(0,2)],
[(0,0),(1,0),(1,1),(1,2)],
[(2,1),(0,2),(1,2),(2,2)],
[(1,0),(1,1),(1,2),(2,2)]], #L型
5: [[(0,1),(1,1),(2,1),(2,2)],
[(1,0),(1,1),(0,2),(1,2)],
[(0,1),(0,2),(1,2),(2,2)],
[(1,0),(2,0),(1,1),(1,2)]], #J型
6: [[(1,1),(2,1),(0,2),(1,2)],
[(0,0),(0,1),(1,1),(1,2)]], #s型
7: [[(0,1),(1,1),(1,2),(2,2)],
[(2,0),(1,1),(2,1),(1,2)]],} #Z型
#第1个为网格底色,后7个为对应方块的颜色,因为要加和原色相近的明暗边,自定义色RGB值最小得不低于50,最高不超过205,否则出错。
#最后一个颜色(灰)用来画NEXT方块,也可以用NEXT方块的next_key值来指向本色
block_color = [(199,238,206),(200,50,50),(50,200,200),(50,50,200),(200,200,50),(200,50,200),(50,200,50),(125,50,125),(180,180,180)]
class Game_machine():
def __init__(self,x0,y0):
self.x0, self.y0 = x0, y0 #记录player游戏区(0,0)点在屏幕的坐标
self.rect = pygame.Rect(0,0,block_size, block_size) #方块矩形大小
self.display_array = [[0 for i in range(clos)] for j in range(rows)] #游戏区每格初始值设为0,为1时不能通过
self.color_array = [[0 for i in range(clos)] for j in range(rows)] #游戏区每格的颜色block_color的索引值
self.x, self.y = 0, 0 #记录移动方块(0,0)点在游戏网格的(clo,row)位置
self.key = 0 #记录移动方块在blocks的键,是哪种方块
self.index_ = 0 #记录移动方块形态的索引
self.next_key = self.rand_key() #记录NEXT方块在blocks的键
self.speed = fps #速度,和帧率一致
self.fall_buffer = self.speed #自动下落的缓冲时间,屏幕每刷一次自动减1
self.fall_speed_up = False #是否加速下落
self.score = 0
self.lines = 0
self.level = 0
self.creat_new_block()
def creat_new_block(self):
#产生新的移动方块和NEXT方块,以第一形态作为初始形态
self.key = self.next_key
self.next_key = self.rand_key()
self.index = 0
self.x = 4 #初始列设在第4列
self.y = -1 #初始高度设为-1,保证方块在最顶部位置出现,研究每种方块第一形态坐标可以找到答案
def rand_key(self):
keys = [1,1,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,7] #决定每种方块出现概率
return keys[random.randint(0,len(keys)-1)]
def move(self, dx, dy):
#方块左、右、下移动:左:dx=-1,dy=0 右:dx=1,dy=0 下:dx=0,dy=1
if self.can_move(self.index, dx, dy):
self.x += dx
self.y += dy
elif dy:
#不能下落:在顶部位置不能下落,游戏结束,以下位置则停止移动
if self.y <= 0:
self.game_over()
else:
self.stop_move()
def rotate(self):
#方块旋转至下一形态,使用的顺时针旋转,被注释的是逆时针旋转
next_index = (self.index + 1) % len(blocks[self.key])
#next_index = (self.index - 1 + len(blocks[self.key])) % len(blocks[self.key])
if self.can_move(next_index, 0, 0):
self.index = next_index
def can_move(self, index, dx, dy):
#方块能否移动:出界或碰到其他方块
for (x,y) in blocks[self.key][index]:
clo, row = self.x + x + dx , self.y + y + dy
if clo >= clos or clo < 0 or row >= rows or row < 0: #出界
return False
if self.display_array[row][clo]: #值等于1时不能移动
return False
return True
def stop_move(self):
#方块停止移动,停落区域赋值1和相应的颜色
self.score += 4
for (x,y) in blocks[self.key][self.index]:
self.display_array[y+self.y][x+self.x] = 1
self.color_array[y+self.y][x+self.x] = self.key
self.del_full_row()
self.creat_new_block()
def del_full_row(self):
#删除填满的行,记录成绩
lines = 0
for row in range(rows):
if sum(self.display_array[row]) == clos: #填满行判断
lines += 1 #记录一次连续删除的行数,实现多消多奖
self.lines += 1
if self.lines % 5 == 0: #每消5行等级升1,速度加快
self.level = self.lines / 5
self.speed = int(self.speed * 0.9) #越小越快
self.score += (self.level + clos * lines) * 5
del self.display_array[row]
self.display_array.insert(0,[0 for i in range(clos)])
def display(self):
self.display_stop_blocks()
self.display_next_blocks()
self.display_move_blocks()
self.display_score()
#每刷一次缓冲计数减1,缓冲计数=0,或按住了向下键则下落一格
self.fall_buffer -= 1
if self.fall_buffer == 0 or self.fall_speed_up:
self.fall_buffer = self.speed
self.move(0,1)
def display_stop_blocks(self):
#显示不移动的方块,值为1画彩色立体方块,值为0画底色块
for y in range(rows):
for x in range(clos):
self.rect.topleft = x * cell_size, y * cell_size
if self.display_array[y][x]:
self.draw_block(self.color_array[y][x], 1)
else:
self.draw_block(0, 0)
def display_next_blocks(self):
#显示下一个方块
for (x,y) in blocks[self.next_key][0]:
self.rect.topleft = x * cell_size , (y - 1) * cell_size
self.draw_block(8, 1)
def display_move_blocks(self):
#显示移动的方块
for (x,y) in blocks[self.key][self.index]:
self.rect.topleft = (self.x + x) * cell_size, (self.y + y) * cell_size
self.draw_block(self.key, 1)
def display_score(self):
#显示得分记录
text = "得分:%d 行数:%d 等级:%d" %(self.score,self.lines,self.level)
self.img = pygame.font.SysFont("kaiti",25).render(text, True, (0,0,255))
self.img_rect = self.img.get_rect()
self.img_rect.topleft = (self.x0, rows* cell_size)
screen.blit(self.img, self.img_rect)
def game_over(self):
#只是简单的数据重新初始化后立即重新开始
self.__init__(self.x0, self.y0)
def draw_block(self, color_index, draw_edge):
#在指定位置画方块
(r,g,b) = block_color[color_index]
self.rect.centerx = self.rect.left + self.x0 + int(cell_size / 2)
self.rect.centery = self.rect.top + self.y0 + int(cell_size / 2)
if draw_edge:
#画方块明暗过度边,增加立体感,x0~x4是方块四角和中心的坐标。
x0 = self.rect.center
x1 = self.rect.topleft
x2 = self.rect.topright
x3 = self.rect.bottomright
x4 = self.rect.bottomleft
pygame.draw.polygon(screen, (r+50, g+50, b+50), (x0,x1,x2), 0)
pygame.draw.polygon(screen, (r+20, g+20, b+20), (x0,x2,x3), 0)
pygame.draw.polygon(screen, (r-50, g-50, b-50), (x0,x3,x4), 0)
pygame.draw.polygon(screen, (r-20, g-20, b-20), (x0,x4,x1), 0)
pygame.draw.rect(screen, (r,g,b), self.rect.inflate(-block_edge, -block_edge), 0)
else:
pygame.draw.rect(screen, (r,g,b), self.rect, 0)
time = pygame.time.Clock()
player1 = Game_machine(0, 0)
player2 = Game_machine((clos + 6) * cell_size, 0)
while True:
time.tick(fps)
screen.fill((166,124,64))
player1.display()
player2.display()
pygame.display.update()
#移动旋转控制
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_g: #player1 :g键右移动一格
player1.move(1,0)
elif event.key == pygame.K_d: #player1 :d键左移动一格
player1.move(-1,0)
elif event.key == pygame.K_r: #player1 :r键旋转一次
player1.rotate()
elif event.key == pygame.K_f: #player1 :f键加速下移
player1.fall_speed_up = True
if event.key == pygame.K_RIGHT: #player2 :→键右移动一格
player2.move(1,0)
elif event.key == pygame.K_LEFT: #player2 :←键左移动一格
player2.move(-1,0)
elif event.key == pygame.K_UP: #player2 :↑键旋转一次
player2.rotate()
elif event.key == pygame.K_DOWN: #player2 :↓键加速下移
player2.fall_speed_up = True
elif event.key == pygame.K_q:
sys.exit()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_f:
player1.fall_speed_up = False
if event.key == pygame.K_DOWN:
player2.fall_speed_up = False
elif event.type == pygame.QUIT:
sys.exit()
可以简单参考一下
俄罗斯方块
import os
import pygame
import sys
import random
import pygame.font
import time
pygame.init()
clos = 10 #游戏网格列数,可以调整,>=8
rows = 20 #游戏网格行数,可以调整
cell_size = 40 #一个网格的大小
block_size = cell_size - 1 #一个方块的大小,小于等于cell_size
block_edge = int(block_size /2) #方块的立体感,数字>=1,数字越小立体感越强
fps = 40 #每秒帧数,建议范围20-60,越大难度递进越越缓
win_width = clos * 2 * cell_size + 6 * cell_size
win_hight = (rows + 1) * cell_size
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (400,40)
screen = pygame.display.set_mode((win_width, win_hight))
pygame.display.set_caption("Crystal方块")
#在4*4的小网格内,以左上角坐标为(0,0),7种方块及其各形态4个方块在小网格的相对坐标
#移动时记录小网络(0,0)点在游戏网格的(x,y),就知道4个方块在游戏网格中的位置
blocks = {
1: [[(0,1),(1,1),(2,1),(3,1)],
[(2,0),(2,1),(2,2),(2,3)]], #I型
2: [[(1,1),(2,1),(1,2),(2,2)]], #O型
3: [[(0,1),(1,1),(2,1),(1,2)],
[(1,0),(0,1),(1,1),(1,2)],
[(1,1),(0,2),(1,2),(2,2)],
[(1,0),(1,1),(2,1),(1,2)]], #T型
4: [[(0,1),(1,1),(2,1),(0,2)],
[(0,0),(1,0),(1,1),(1,2)],
[(2,1),(0,2),(1,2),(2,2)],
[(1,0),(1,1),(1,2),(2,2)]], #L型
5: [[(0,1),(1,1),(2,1),(2,2)],
[(1,0),(1,1),(0,2),(1,2)],
[(0,1),(0,2),(1,2),(2,2)],
[(1,0),(2,0),(1,1),(1,2)]], #J型
6: [[(1,1),(2,1),(0,2),(1,2)],
[(0,0),(0,1),(1,1),(1,2)]], #s型
7: [[(0,1),(1,1),(1,2),(2,2)],
[(2,0),(1,1),(2,1),(1,2)]],} #Z型
#第1个为网格底色,后7个为对应方块的颜色,因为要加和原色相近的明暗边,自定义色RGB值最小得不低于50,最高不超过205,否则出错。
#最后一个颜色(灰)用来画NEXT方块,也可以用NEXT方块的next_key值来指向本色
block_color = [(199,238,206),(200,50,50),(50,200,200),(50,50,200),(200,200,50),(200,50,200),(50,200,50),(125,50,125),(180,180,180)]
class Game_machine():
def __init__(self,x0,y0):
self.x0, self.y0 = x0, y0 #记录player游戏区(0,0)点在屏幕的坐标
self.rect = pygame.Rect(0,0,block_size, block_size) #方块矩形大小
self.display_array = [[0 for i in range(clos)] for j in range(rows)] #游戏区每格初始值设为0,为1时不能通过
self.color_array = [[0 for i in range(clos)] for j in range(rows)] #游戏区每格的颜色block_color的索引值
self.x, self.y = 0, 0 #记录移动方块(0,0)点在游戏网格的(clo,row)位置
self.key = 0 #记录移动方块在blocks的键,是哪种方块
self.index_ = 0 #记录移动方块形态的索引
self.next_key = self.rand_key() #记录NEXT方块在blocks的键
self.speed = fps #速度,和帧率一致
self.fall_buffer = self.speed #自动下落的缓冲时间,屏幕每刷一次自动减1
self.fall_speed_up = False #是否加速下落
self.score = 0
self.lines = 0
self.level = 0
self.creat_new_block()
def creat_new_block(self):
#产生新的移动方块和NEXT方块,以第一形态作为初始形态
self.key = self.next_key
self.next_key = self.rand_key()
self.index = 0
self.x = 4 #初始列设在第4列
self.y = -1 #初始高度设为-1,保证方块在最顶部位置出现,研究每种方块第一形态坐标可以找到答案
def rand_key(self):
keys = [1,1,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,7] #决定每种方块出现概率
return keys[random.randint(0,len(keys)-1)]
def move(self, dx, dy):
#方块左、右、下移动:左:dx=-1,dy=0 右:dx=1,dy=0 下:dx=0,dy=1
if self.can_move(self.index, dx, dy):
self.x += dx
self.y += dy
elif dy:
#不能下落:在顶部位置不能下落,游戏结束,以下位置则停止移动
if self.y <= 0:
self.game_over()
else:
self.stop_move()
def rotate(self):
#方块旋转至下一形态,使用的顺时针旋转,被注释的是逆时针旋转
next_index = (self.index + 1) % len(blocks[self.key])
#next_index = (self.index - 1 + len(blocks[self.key])) % len(blocks[self.key])
if self.can_move(next_index, 0, 0):
self.index = next_index
def can_move(self, index, dx, dy):
#方块能否移动:出界或碰到其他方块
for (x,y) in blocks[self.key][index]:
clo, row = self.x + x + dx , self.y + y + dy
if clo >= clos or clo < 0 or row >= rows or row < 0: #出界
return False
if self.display_array[row][clo]: #值等于1时不能移动
return False
return True
def stop_move(self):
#方块停止移动,停落区域赋值1和相应的颜色
self.score += 4
for (x,y) in blocks[self.key][self.index]:
self.display_array[y+self.y][x+self.x] = 1
self.color_array[y+self.y][x+self.x] = self.key
self.del_full_row()
self.creat_new_block()
def del_full_row(self):
#删除填满的行,记录成绩
lines = 0
for row in range(rows):
if sum(self.display_array[row]) == clos: #填满行判断
lines += 1 #记录一次连续删除的行数,实现多消多奖
self.lines += 1
if self.lines % 5 == 0: #每消5行等级升1,速度加快
self.level = self.lines / 5
self.speed = int(self.speed * 0.9) #越小越快
self.score += (self.level + clos * lines) * 5
del self.display_array[row]
self.display_array.insert(0,[0 for i in range(clos)])
def display(self):
self.display_stop_blocks()
self.display_next_blocks()
self.display_move_blocks()
self.display_score()
#每刷一次缓冲计数减1,缓冲计数=0,或按住了向下键则下落一格
self.fall_buffer -= 1
if self.fall_buffer == 0 or self.fall_speed_up:
self.fall_buffer = self.speed
self.move(0,1)
def display_stop_blocks(self):
#显示不移动的方块,值为1画彩色立体方块,值为0画底色块
for y in range(rows):
for x in range(clos):
self.rect.topleft = x * cell_size, y * cell_size
if self.display_array[y][x]:
self.draw_block(self.color_array[y][x], 1)
else:
self.draw_block(0, 0)
def display_next_blocks(self):
#显示下一个方块
for (x,y) in blocks[self.next_key][0]:
self.rect.topleft = x * cell_size , (y - 1) * cell_size
self.draw_block(8, 1)
def display_move_blocks(self):
#显示移动的方块
for (x,y) in blocks[self.key][self.index]:
self.rect.topleft = (self.x + x) * cell_size, (self.y + y) * cell_size
self.draw_block(self.key, 1)
def display_score(self):
#显示得分记录
text = "得分:%d 行数:%d 等级:%d" %(self.score,self.lines,self.level)
self.img = pygame.font.SysFont("kaiti",25).render(text, True, (0,0,255))
self.img_rect = self.img.get_rect()
self.img_rect.topleft = (self.x0, rows* cell_size)
screen.blit(self.img, self.img_rect)
def game_over(self):
#只是简单的数据重新初始化后立即重新开始
self.__init__(self.x0, self.y0)
def draw_block(self, color_index, draw_edge):
#在指定位置画方块
(r,g,b) = block_color[color_index]
self.rect.centerx = self.rect.left + self.x0 + int(cell_size / 2)
self.rect.centery = self.rect.top + self.y0 + int(cell_size / 2)
if draw_edge:
#画方块明暗过度边,增加立体感,x0~x4是方块四角和中心的坐标。
x0 = self.rect.center
x1 = self.rect.topleft
x2 = self.rect.topright
x3 = self.rect.bottomright
x4 = self.rect.bottomleft
pygame.draw.polygon(screen, (r+50, g+50, b+50), (x0,x1,x2), 0)
pygame.draw.polygon(screen, (r+20, g+20, b+20), (x0,x2,x3), 0)
pygame.draw.polygon(screen, (r-50, g-50, b-50), (x0,x3,x4), 0)
pygame.draw.polygon(screen, (r-20, g-20, b-20), (x0,x4,x1), 0)
pygame.draw.rect(screen, (r,g,b), self.rect.inflate(-block_edge, -block_edge), 0)
else:
pygame.draw.rect(screen, (r,g,b), self.rect, 0)
time = pygame.time.Clock()
player1 = Game_machine(0, 0)
player2 = Game_machine((clos + 6) * cell_size, 0)
while True:
time.tick(fps)
screen.fill((166,124,64))
player1.display()
player2.display()
pygame.display.update()
#移动旋转控制
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_g: #player1 :g键右移动一格
player1.move(1,0)
elif event.key == pygame.K_d: #player1 :d键左移动一格
player1.move(-1,0)
elif event.key == pygame.K_r: #player1 :r键旋转一次
player1.rotate()
elif event.key == pygame.K_f: #player1 :f键加速下移
player1.fall_speed_up = True
if event.key == pygame.K_RIGHT: #player2 :→键右移动一格
player2.move(1,0)
elif event.key == pygame.K_LEFT: #player2 :←键左移动一格
player2.move(-1,0)
elif event.key == pygame.K_UP: #player2 :↑键旋转一次
player2.rotate()
elif event.key == pygame.K_DOWN: #player2 :↓键加速下移
player2.fall_speed_up = True
elif event.key == pygame.K_q:
sys.exit()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_f:
player1.fall_speed_up = False
if event.key == pygame.K_DOWN:
player2.fall_speed_up = False
elif event.type == pygame.QUIT:
sys.exit()
俄罗斯方块
```python
# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import KEYDOWN,K_LEFT,K_RIGHT,K_UP,K_DOWN,K_SPACE
import pickle,os
ROW_COUNT=20
COL_COUNT=10
SCORE_MAP=(100,300,800,1600)
class Matrix(object):
rows = 0
cols = 0
data = []
def __init__(self, rows, cols, data=None):
self.rows = rows
self.cols = cols
if data is None: data = [0 for i in range(rows*cols)]
self.data = data
def set_val(self, x, y, val):
self.data[y*self.cols+x] = val
def get_val(self, x, y):
return self.data[y*self.cols+x]
def cross_block(self, rect_arr, xdiff=0, ydiff=0):
for x,y in rect_arr:
#if x+xdiff>=0 and x+xdiff<self.cols and y+ydiff>=0 and y+ydiff<self.rows:
if self.get_val(x+xdiff,y+ydiff) == 1: return True
return False
def get_block_above_hole(self):
blocks=0
for x in range(0,self.cols):
for y in range(1,self.rows):
if self.get_val(x,y) == 0 and self.get_val(x,y-1) == 1:
blocks += sum(self.data[x:(y*self.cols+x):self.cols])
return blocks
def get_hole_number(self):
hole_num=0
for x in range(0,self.cols):
for y in range(1,self.rows):
if self.get_val(x,y) == 0 and self.get_val(x,y-1) == 1:
hole_num+=1
return hole_num
def clone(self):
clone_matrix=Matrix(self.rows, self.cols, list(self.data))
return clone_matrix
def fill_block(self, rect_arr, xdiff=0, ydiff=0):
for x,y in rect_arr:
self.set_val(x+xdiff,y+ydiff, 1)
def do_clear(self):
clear_num = 0
for i in range(self.rows-1,-1,-1):
if sum(self.data[self.cols*i:self.cols*(i+1)])==self.cols:
self.data[self.cols:self.cols*(i+1)]=self.data[0:self.cols*i]
clear_num+=1
return clear_num
def get_empty_col(self):
miny_arr=[]
for x in range(self.cols):
miny=19
for y in range(self.rows):
miny=y
if self.get_val(x,y) == 1:break
miny_arr.append(miny)
empty_arr=[]
if miny_arr[1] - miny_arr[0] > 2: empty_arr.append((self.cols,miny_arr[1] - miny_arr[0]))
if miny_arr[self.cols-2] - miny_arr[self.cols-1] > 2: empty_arr.append((miny_arr[self.cols-2] - miny_arr[self.cols-1],self.cols))
for x in range(1,self.cols-1):
if miny_arr[x-1]-miny_arr[x]>2 or miny_arr[x+1]-miny_arr[x]>2: empty_arr.append((miny_arr[x-1]-miny_arr[x],miny_arr[x+1]-miny_arr[x]))
return empty_arr
def print_matrix(self):
for i in range(self.rows):
print self.data[self.cols*i:self.cols*(i+1)]
class Player(object):
auto_mode=False
def __init__(self):
pass
def run(self, panel):
pass
class HumanPlayer(Player):
def __init__(self):
super(Player, self).__init__()
class AIPlayer(Player):
cal_block_id=-1
ctl_arr=[] # control arr, 1=change、2=left、3=right、4=down
auto_mode=True
ai_diff_ticks = 100 #timespan between two controls
level=None
def __init__(self, level=None, ai_diff_ticks=100):
super(Player, self).__init__()
self.ai_diff_ticks=ai_diff_ticks
self.level=level
if level is not None:
level=int(level)
if level<1: level=1
if level>10:level=10
self.ai_diff_ticks=1000/level
self.ctl_ticks = pygame.time.get_ticks() + self.ai_diff_ticks
def get_cost_of_emptycol(self, empty_arr):
cost = 0
for l,r in empty_arr:
if l>2 and r>2: cost += (l+r)*2
elif l>2: cost += l
else: cost += r
return cost
def cal_best_arr(self, panel):
matrix = panel.get_rect_matrix()
cur_shape_id = panel.moving_block.shape_id
shape_num = panel.moving_block.shape_num
max_score = -10000
best_arr = []
for i in range(shape_num):
tmp_shape_id = cur_shape_id + i
if tmp_shape_id >= shape_num: tmp_shape_id = tmp_shape_id % shape_num
tmp_shape = panel.moving_block.get_shape(sid=tmp_shape_id)
center_shape = []
for x,y in tmp_shape: center_shape.append((x+COL_COUNT/2-2,y-2))
minx = COL_COUNT
maxx = 0
miny = ROW_COUNT
maxy = -2
for x,y in center_shape:
if x<minx: minx = x
if x>maxx: maxx = x
if y<miny: miny = y
if y>maxy: maxy = y
for xdiff in range(-minx,COL_COUNT-maxx):
arr = [1 for _ in range(i)]
if xdiff < 0: [arr.append(2) for _ in range(-xdiff)]
if xdiff > 0: [arr.append(3) for _ in range(xdiff)]
max_yindex = -miny
for yindex in range(-miny, ROW_COUNT-maxy):
if matrix.cross_block(center_shape, xdiff=xdiff, ydiff=yindex):
break
max_yindex = yindex
score = sum([y+max_yindex for x,y in center_shape])
# clone matrix and fill new block to calculate holes
clone_matrix = matrix.clone()
clone_matrix.fill_block(center_shape, xdiff=xdiff, ydiff=max_yindex)
clear_num = clone_matrix.do_clear()
score -= clone_matrix.get_block_above_hole()
empty_arr = clone_matrix.get_empty_col()
score -= self.get_cost_of_emptycol(empty_arr)
score += clear_num * 5
score -= clone_matrix.get_hole_number() * COL_COUNT
if score > max_score:
max_score = score
best_arr = arr
self.ctl_arr = best_arr+[4]
def run(self, panel):
if pygame.time.get_ticks() < self.ctl_ticks: return
self.ctl_ticks += self.ai_diff_ticks
if panel.block_id == self.cal_block_id: # block_id not change
if len(self.ctl_arr)>0:
ctl = self.ctl_arr.pop(0)
if ctl == 1: panel.change_block()
if ctl == 2: panel.control_block(-1,0)
if ctl == 3: panel.control_block(1,0)
if ctl == 4:
flag = panel.move_block()
while flag==1:
flag = panel.move_block()
else: # block_id is new
self.cal_block_id = panel.block_id
self.cal_best_arr(panel)
class RectInfo(object):
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
class BlockManage(object):
pnum=1
blocks = []
def __init__(self,pnum):
self.pnum=pnum
self.blocks=[[] for i in range(self.pnum)]
def get_block(self, pid=0):
if len(self.blocks[pid]) == 0:
block = create_block()
for arr in self.blocks:
arr.append(pickle.loads(pickle.dumps(block)))
return self.blocks[pid].pop(0)
class VirtualHintBox(object):
pid = 0
block_manage=None
next_block=None
def __init__(self, pid, block_manage):
print pid
self.pid=pid
self.block_manage=block_manage
def take_block(self):
block = self.next_block
if block is None: # make first block
block = block_manage.get_block(self.pid)
self.next_block = block_manage.get_block(self.pid)
return block
def paint(self):
pass
class HintBox(VirtualHintBox):
def __init__(self, bg, block_size, position, block_manage):
super(VirtualHintBox, self).__init__()
self._bg=bg;
self._x,self._y,self._width,self._height=position
self._block_size=block_size
self._bgcolor=[0,0,0]
def paint(self):
mid_x=self._x+self._width/2
pygame.draw.line(self._bg,self._bgcolor,[mid_x,self._y],[mid_x,self._y+self._height],self._width)
bz=self._block_size
if self.next_block:
arr = self.next_block.get_rect_arr()
minx,miny=arr[0]
maxx,maxy=arr[0]
for x,y in arr:
if x<minx: minx=x
if x>maxx: maxx=x
if y<miny: miny=y
if y>maxy: maxy=y
w=(maxx-minx)*bz
h=(maxy-miny)*bz
cx=self._width/2-w/2-minx*bz-bz/2
cy=self._height/2-h/2-miny*bz-bz/2
for rect in arr:
x,y=rect
pygame.draw.line(self._bg,self.next_block.color,[self._x+x*bz+cx+bz/2,self._y+cy+y*bz],[self._x+x*bz+cx+bz/2,self._y+cy+(y+1)*bz],bz)
pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz+cx,self._y+y*bz+cy,bz+1,bz+1],1)
class ScoreBox(object):
total_score = 0
high_score = 0
db_file = 'tetris.db'
def __init__(self, bg, block_size, position):
self._bg=bg;
self._x,self._y,self._width,self._height=position
self._block_size=block_size
self._bgcolor=[0,0,0]
if os.path.exists(self.db_file): self.high_score = pickle.load(open(self.db_file,'rb'))
def paint(self):
myfont = pygame.font.Font(None,36)
white = 255,255,255
textImage = myfont.render('High: %06d'%(self.high_score), True, white)
self._bg.blit(textImage, (self._x,self._y-10))
textImage = myfont.render('Score:%06d'%(self.total_score), True, white)
self._bg.blit(textImage, (self._x,self._y+20))
def add_score(self, score):
self.total_score += score
if self.total_score > self.high_score:
self.high_score=self.total_score
pickle.dump(self.high_score, open(self.db_file,'wb+'))
class VirtualScoreBox(object):
total_score = 0
def __init__(self, bg, position):
self._bg=bg;
self._x,self._y,self._width,self._height=position
self._bgcolor=[0,0,0]
def paint(self):
myfont = pygame.font.Font(None,22)
white = 255,255,255
textImage = myfont.render('Player2 Score:%06d'%(self.total_score), True, white)
self._bg.blit(textImage, (self._x,self._y))
def add_score(self, score):
self.total_score += score
class Panel(object):
attack_num=0
block_id=0
rect_arr=[]
moving_block=None
hint_box=None
score_box=None
def __init__(self,bg, block_size, position):
self._bg=bg;
self._x,self._y,self._width,self._height=position
self._block_size=block_size
self._bgcolor=[0,0,0]
self.block_id=0
self.rect_arr=[]
self.moving_block=None
def get_rect_matrix(self):
matrix = Matrix(ROW_COUNT, COL_COUNT)
for rect_info in self.rect_arr:
matrix.set_val(rect_info.x, rect_info.y, 1)
return matrix
def add_block(self,block):
print block.get_rect_arr()
for x,y in block.get_rect_arr():
self.rect_arr.append(RectInfo(x,y, block.color))
print len(self.rect_arr)
def create_move_block(self):
self.block_id+=1
block = self.hint_box.take_block()
#block = create_block()
block.move(COL_COUNT/2-2,-2) # move block to top center
self.moving_block=block
def check_overlap(self, diffx, diffy, check_arr=None):
if check_arr is None: check_arr = self.moving_block.get_rect_arr()
for x,y in check_arr:
for rect_info in self.rect_arr:
if x+diffx==rect_info.x and y+diffy==rect_info.y:
return True
return False
def control_block(self, diffx, diffy):
if self.moving_block.can_move(diffx,diffy) and not self.check_overlap(diffx, diffy):
self.moving_block.move(diffx,diffy)
def change_block(self):
if self.moving_block:
new_arr = self.moving_block.change()
if new_arr and not self.check_overlap(0, 0, check_arr=new_arr):
self.moving_block.rect_arr=new_arr
def move_block(self):
if self.moving_block is None: create_move_block()
if self.moving_block.can_move(0,1) and not self.check_overlap(0,1):
self.moving_block.move(0,1)
return 1
else:
self.add_block(self.moving_block)
self.check_clear()
for rect_info in self.rect_arr:
if rect_info.y<0: return 9 # gameover
self.create_move_block()
return 2
def check_clear(self):
tmp_arr = [[] for i in range(20)]
for rect_info in self.rect_arr:
if rect_info.y<0: return
tmp_arr[rect_info.y].append(rect_info)
clear_num=0
clear_lines=set([])
y_clear_diff_arr=[[] for i in range(20)]
for y in range(19,-1,-1):
if len(tmp_arr[y])==10:
clear_lines.add(y)
clear_num += 1
y_clear_diff_arr[y] = clear_num
if clear_num>0:
new_arr=[]
for y in range(19,-1,-1):
if y in clear_lines: continue
tmp_row = tmp_arr[y]
y_clear_diff=y_clear_diff_arr[y]
for rect_info in tmp_row:
#new_arr.append([x,y+y_clear_diff])
new_arr.append(RectInfo(rect_info.x, rect_info.y+y_clear_diff, rect_info.color))
self.rect_arr = new_arr
score = SCORE_MAP[clear_num-1]
self.score_box.add_score(score)
def get_attach_num(self):
if self.score_box.total_score /1000 > self.attack_num:
self.attack_num+=1
return 1
else:
return 0
def add_hinder(self):
hinder_lines=2
for tmp in self.rect_arr:
tmp.y-=hinder_lines
for y in range(hinder_lines):
arr=range(10)
for i in range(5):
n = random.randint(0,len(arr)-1)
arr.pop(n)
for x in arr:
self.rect_arr.append(RectInfo(x,19-y,[0,0,255]))
def paint(self):
mid_x=self._x+self._width/2
pygame.draw.line(self._bg,self._bgcolor,[mid_x,self._y],[mid_x,self._y+self._height],self._width) # 用一个粗线段来填充背景
bz=self._block_size
for rect_info in self.rect_arr:
x=rect_info.x
y=rect_info.y
pygame.draw.line(self._bg,rect_info.color,[self._x+x*bz+bz/2,self._y+y*bz],[self._x+x*bz+bz/2,self._y+(y+1)*bz],bz)
pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz,self._y+y*bz,bz+1,bz+1],1)
if self.moving_block:
for rect in self.moving_block.get_rect_arr():
x,y=rect
pygame.draw.line(self._bg,self.moving_block.color,[self._x+x*bz+bz/2,self._y+y*bz],[self._x+x*bz+bz/2,self._y+(y+1)*bz],bz)
pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz,self._y+y*bz,bz+1,bz+1],1)
self.score_box.paint()
self.hint_box.paint()
class Block(object):
sx=0
sy=0
def __init__(self):
self.rect_arr=[]
def get_rect_arr(self):
return self.rect_arr
def move(self,xdiff,ydiff):
self.sx+=xdiff
self.sy+=ydiff
self.new_rect_arr=[]
for x,y in self.rect_arr:
self.new_rect_arr.append((x+xdiff,y+ydiff))
self.rect_arr=self.new_rect_arr
def can_move(self,xdiff,ydiff):
for x,y in self.rect_arr:
if y+ydiff>=20: return False
if x+xdiff<0 or x+xdiff>=10: return False
return True
def change(self):
self.shape_id+=1
if self.shape_id >= self.shape_num:
self.shape_id=0
arr = self.get_shape()
new_arr = []
for x,y in arr:
if x+self.sx<0 or x+self.sx>=10:
self.shape_id -= 1
if self.shape_id < 0: self.shape_id = self.shape_num - 1
return None
new_arr.append([x+self.sx,y+self.sy])
return new_arr
class LongBlock(Block):
shape_id=0
shape_num=2
def __init__(self, n=None):
super(LongBlock, self).__init__()
if n is None: n=random.randint(0,1)
self.shape_id=n
self.rect_arr=self.get_shape()
self.color=(50,180,50)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
return [(1,0),(1,1),(1,2),(1,3)] if sid==0 else [(0,2),(1,2),(2,2),(3,2)]
class SquareBlock(Block):
shape_id=0
shape_num=1
def __init__(self, n=None):
super(SquareBlock, self).__init__()
self.rect_arr=self.get_shape()
self.color=(0,0,255)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
return [(1,1),(1,2),(2,1),(2,2)]
class ZBlock(Block):
shape_id=0
shape_num=2
def __init__(self, n=None):
super(ZBlock, self).__init__()
if n is None: n=random.randint(0,1)
self.shape_id=n
self.rect_arr=self.get_shape()
self.color=(30,200,200)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
return [(2,0),(2,1),(1,1),(1,2)] if sid==0 else [(0,1),(1,1),(1,2),(2,2)]
class SBlock(Block):
shape_id=0
shape_num=2
def __init__(self, n=None):
super(SBlock, self).__init__()
if n is None: n=random.randint(0,1)
self.shape_id=n
self.rect_arr=self.get_shape()
self.color=(255,30,255)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
return [(1,0),(1,1),(2,1),(2,2)] if sid==0 else [(0,2),(1,2),(1,1),(2,1)]
class LBlock(Block):
shape_id=0
shape_num=4
def __init__(self, n=None):
super(LBlock, self).__init__()
if n is None: n=random.randint(0,3)
self.shape_id=n
self.rect_arr=self.get_shape()
self.color=(200,200,30)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
if sid==0: return [(1,0),(1,1),(1,2),(2,2)]
elif sid==1: return [(0,1),(1,1),(2,1),(0,2)]
elif sid==2: return [(0,0),(1,0),(1,1),(1,2)]
else: return [(0,1),(1,1),(2,1),(2,0)]
class JBlock(Block):
shape_id=0
shape_num=4
def __init__(self, n=None):
super(JBlock, self).__init__()
if n is None: n=random.randint(0,3)
self.shape_id=n
self.rect_arr=self.get_shape()
self.color=(200,100,0)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
if sid==0: return [(1,0),(1,1),(1,2),(0,2)]
elif sid==1: return [(0,1),(1,1),(2,1),(0,0)]
elif sid==2: return [(2,0),(1,0),(1,1),(1,2)]
else: return [(0,1),(1,1),(2,1),(2,2)]
class TBlock(Block):
shape_id=0
shape_num=4
def __init__(self, n=None):
super(TBlock, self).__init__()
if n is None: n=random.randint(0,3)
self.shape_id=n
self.rect_arr=self.get_shape()
self.color=(255,0,0)
def get_shape(self, sid=None):
if sid is None: sid = self.shape_id
if sid==0: return [(0,1),(1,1),(2,1),(1,2)]
elif sid==1: return [(1,0),(1,1),(1,2),(0,1)]
elif sid==2: return [(0,1),(1,1),(2,1),(1,0)]
else: return [(1,0),(1,1),(1,2),(2,1)]
def create_block():
n = random.randint(0,18)
if n==0: return SquareBlock(n=0)
elif n==1 or n==2: return LongBlock(n=n-1)
elif n==3 or n==4: return ZBlock(n=n-3)
elif n==5 or n==6: return SBlock(n=n-5)
elif n>=7 and n<=10: return LBlock(n=n-7)
elif n>=11 and n<=14: return JBlock(n=n-11)
else: return TBlock(n=n-15)
block_manage = BlockManage(2) # two players
def run():
pygame.init()
addition_width = 160
space=30
main_block_size=30
main_panel_width=main_block_size*COL_COUNT
main_panel_height=main_block_size*ROW_COUNT
screencaption = pygame.display.set_caption('Tetris')
screen = pygame.display.set_mode((main_panel_width+addition_width+space*3,main_panel_height+space*2))
main_panel=Panel(screen,main_block_size,[space,space,main_panel_width,main_panel_height])
hint_box=HintBox(screen,main_block_size,[main_panel_width+space+space,space,addition_width,addition_width],block_manage)
score_box=ScoreBox(screen,main_block_size,[main_panel_width+space+space,addition_width+space*2,addition_width,addition_width])
main_panel.hint_box=hint_box
main_panel.score_box=score_box
pygame.key.set_repeat(200, 30)
main_panel.create_move_block()
battle_panel_width=160
battle_block_width=battle_panel_width/COL_COUNT
battle_panel_height=battle_block_width*ROW_COUNT
battle_panel_x = main_panel_width+space+space+(addition_width-battle_panel_width)
battle_panel_y = main_panel_height+space-battle_panel_height
battle_panel=Panel(screen,battle_block_width,[battle_panel_x,battle_panel_y,battle_panel_width,battle_panel_height])
battle_panel.hint_box=VirtualHintBox(1,block_manage)
battle_panel.score_box=VirtualScoreBox(screen,[battle_panel_x,battle_panel_y-16,addition_width,16])
battle_panel.create_move_block()
diff_ticks = 300
ticks = pygame.time.get_ticks() + diff_ticks
player1 = HumanPlayer()
#player1 = AIPlayer(ai_diff_ticks=100)
player2 = AIPlayer(level=5)
pause=0
game_state = 1 # game status 1.normal 2.gameover
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == KEYDOWN:
if event.key==97: pause=1-pause # press a to pause
if event.key==112: # for debug where press p
main_panel.get_rect_matrix().print_matrix()
if player1.auto_mode:continue
if event.type == KEYDOWN:
if event.key == K_LEFT: main_panel.control_block(-1,0)
if event.key == K_RIGHT: main_panel.control_block(1,0)
if event.key == K_UP: main_panel.change_block()
if event.key == K_DOWN: main_panel.control_block(0,1)
if event.key == K_SPACE:
flag = main_panel.move_block()
while flag==1:
flag = main_panel.move_block()
if flag == 9: game_state = 2
if main_panel.get_attach_num()>0: battle_panel.add_hinder()
screen.fill((100,100,100)) # make background gray
main_panel.paint()
battle_panel.paint()
if game_state == 2:
myfont = pygame.font.Font(None,30)
white = 255,255,255
textImage = myfont.render("Game over", True, white)
screen.blit(textImage, (160,190))
if game_state == 3:
myfont = pygame.font.Font(None,30)
white = 255,255,255
textImage = myfont.render("Player1 win", True, white)
screen.blit(textImage, (160,190))
pygame.display.update()
if pause==1: continue
if game_state == 1:
player1.run(main_panel)
player2.run(battle_panel)
if game_state == 1 and pygame.time.get_ticks() >= ticks:
ticks+=diff_ticks
if main_panel.move_block()==9: game_state = 2 # gameover
if main_panel.get_attach_num()>0: battle_panel.add_hinder()
if battle_panel.move_block()==9: game_state = 3 # gameover
if battle_panel.get_attach_num()>0: main_panel.add_hinder()
run()
```
my_dict={} #先定义一个空字典用来存放数据
#显示菜单函数
def show():
print("***学生成绩管理系统***")
print("***1.录入 成绩***")
print("***2.修改 成绩***")
print("***3.信息 查询***")
print("***4.增加学生信息***")
print("***5.删除学生信息***")
print("***6.成绩 统计***")
print("***7.退出 系统***")
print("---------------------------")
index=input('请输入你想要执行的操作:')
return int(index) if index in list('1234567') else 0
#录入模块
def asve_info():
j=eval(input("请输入您将要录入成绩的学生人数:"))
for i in range(0,j):
my_name=input("请输入学生姓名:")
my_no=(input("请输入学号:"))
while my_no in my_dict :
print('该学生已经存在!')
my_no=(input("请输入学号:"))
my_score1=int(input('请输入学生的数学成绩:'))
while my_score1<0 or my_score1>100:
print("很抱歉,您输入的成绩不符合规范,请重新输入!")
my_score1=int(input('请输入学生的数学成绩:'))
my_score2=int(input('请输入学生的语文成绩:'))
while my_score2<0 or my_score2>100:
print("很抱歉,您输入的成绩不符合规范,请重新输入!")
my_score2=int(input('请输入学生的语文成绩:'))
average=(my_score1+my_score2)/2
dict1={'no':my_no,'name':my_name,'score1':my_score1,'score2':my_score2,'average':average}
my_dict[my_no]=dict1
print('\n')
#修改模块
def change():
my_no=input('请输入要修改学生的学号:')
while my_no not in my_dict:
print('您输入的学号有误,请重新输入!')
my_no=input('请输入要修改学生的学号:')
new_name=input('请输入要修改学生的名字:')
a=input("是否要修改学生数学成绩(y/n):")
if a=='y':
new_score1=int(input('请输入学生的数学成绩:'))
elif a=='n':
new_score1=my_dict[my_no]["score1"]
b=input("是否要修改语文成绩(y/n):")
if b=='y':
new_score2=int(input('请输入学生的语文成绩:'))
elif b=='n':
new_score2=my_dict[my_no]["score2"]
average=(new_score1+new_score2)/2
dict2={'no':my_no,'name':new_name,'score1':new_score1,'score2':new_score2,'average':average}
my_dict[my_no]=dict2
print('\n')
# 查询模块
def reach():
my_no=input('请输入要查询学生的学号')
if my_no not in my_dict:
print('您所查找的学生不存在,请重新输入!')
else:
print('学号:{0}'.format(my_dict[my_no]["no"]))
print('姓名:{0}'.format(my_dict[my_no]['name']))
print('语文:{0}'.format(my_dict[my_no]['score1']))
print('数学:{0}'.format(my_dict[my_no]['score2']))
print('平均成绩:{0}'.format(my_dict[my_no]['average']))
print('\n')
#增添
def add_info():
dict4={}
my_no=input('请输入要添加学生的学号:')
while my_no in my_dict :
print('该学生已经存在,请重新输入!')
my_no=input('请输入要添加学生的学号:')
my_name=input('请输入学生的姓名:')
my_score1=int(input('请输入学生的数学成绩:'))
while my_score1<0 or my_score1>100:
print("很抱歉,您输入的成绩不符合规范!请重新输入!")
my_score1=int(input('请输入学生的数学成绩:'))
my_score2=int(input('请输入学生的语文成绩:'))
while my_score2<0 or my_score2>100:
print("很抱歉,您输入的成绩不符合规范!请重新输入!")
my_score2=int(input('请输入学生的语文成绩:'))
average=(my_score1+my_score2)/2
dict4={'no':my_no,'name':my_name,'score1':my_score1,'score2':my_score2,'average':average}
my_dict[my_no]=dict4
print("增添成功!")
print('\n')
#删除模块
def delete_info():
my_no=input('请输入要删除学生的学号:')
while my_no not in my_dict:
print('该学生不存在,请重新输入')
my_no=input('请输入要删除学生的学号:')
del my_dict[my_no]
print('删除成功!')
print('\n')
#成绩统计
def print_scene():
print('该班级学生信息如下:')
print('-------------------')
for value in my_dict.values():
print('学号:{0} 姓名:{1} 语文:{2} 数学:{3} 平均成绩:{4}'.format(value['no'],value['name'],value['score1'],value['score2'],value['average']))
print('\n')
#主函数用来调用其他模块
def main():
while True:
index = show()
if index==1:
asve_info()
elif index==2:
change()
print_scene()
elif index == 3:
reach()
elif index == 4:
add_info()
elif index == 5:
delete_info()
elif index == 6:
print_scene()
elif index == 7:
print("期待您下次使用!")
break
main()
import pygame
import random
import os
pygame.init()
GRID_WIDTH = 20
GRID_NUM_WIDTH = 15
GRID_NUM_HEIGHT = 25
WIDTH, HEIGHT = GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHT
SIDE_WIDTH = 200
SCREEN_WIDTH = WIDTH + SIDE_WIDTH
WHITE = (0xff, 0xff, 0xff)
BLACK = (0, 0, 0)
LINE_COLOR = (0x33, 0x33, 0x33)
CUBE_COLORS = [
(0xcc, 0x99, 0x99), (0xff, 0xff, 0x99), (0x66, 0x66, 0x99),
(0x99, 0x00, 0x66), (0xff, 0xcc, 0x00), (0xcc, 0x00, 0x33),
(0xff, 0x00, 0x33), (0x00, 0x66, 0x99), (0xff, 0xff, 0x33),
(0x99, 0x00, 0x33), (0xcc, 0xff, 0x66), (0xff, 0x99, 0x00)
]
screen = pygame.display.set_mode((SCREEN_WIDTH, HEIGHT))
pygame.display.set_caption("俄罗斯方块")
clock = pygame.time.Clock()
FPS = 30
score = 0
level = 1
screen_color_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)]
# 设置游戏的根目录为当前文件夹
base_folder = os.path.dirname(__file__)
def show_text(surf, text, size, x, y, color=WHITE):
font_name = os.path.join(base_folder, 'font/font.ttc')
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
class CubeShape(object):
SHAPES = ['I', 'J', 'L', 'O', 'S', 'T', 'Z']
I = [[(0, -1), (0, 0), (0, 1), (0, 2)],
[(-1, 0), (0, 0), (1, 0), (2, 0)]]
J = [[(-2, 0), (-1, 0), (0, 0), (0, -1)],
[(-1, 0), (0, 0), (0, 1), (0, 2)],
[(0, 1), (0, 0), (1, 0), (2, 0)],
[(0, -2), (0, -1), (0, 0), (1, 0)]]
L = [[(-2, 0), (-1, 0), (0, 0), (0, 1)],
[(1, 0), (0, 0), (0, 1), (0, 2)],
[(0, -1), (0, 0), (1, 0), (2, 0)],
[(0, -2), (0, -1), (0, 0), (-1, 0)]]
O = [[(0, 0), (0, 1), (1, 0), (1, 1)]]
S = [[(-1, 0), (0, 0), (0, 1), (1, 1)],
[(1, -1), (1, 0), (0, 0), (0, 1)]]
T = [[(0, -1), (0, 0), (0, 1), (-1, 0)],
[(-1, 0), (0, 0), (1, 0), (0, 1)],
[(0, -1), (0, 0), (0, 1), (1, 0)],
[(-1, 0), (0, 0), (1, 0), (0, -1)]]
Z = [[(0, -1), (0, 0), (1, 0), (1, 1)],
[(-1, 0), (0, 0), (0, -1), (1, -1)]]
SHAPES_WITH_DIR = {
'I': I, 'J': J, 'L': L, 'O': O, 'S': S, 'T': T, 'Z': Z
}
def __init__(self):
self.shape = self.SHAPES[random.randint(0, len(self.SHAPES) - 1)]
# 骨牌所在的行列
self.center = (2, GRID_NUM_WIDTH // 2)
self.dir = random.randint(0, len(self.SHAPES_WITH_DIR[self.shape]) - 1)
self.color = CUBE_COLORS[random.randint(0, len(CUBE_COLORS) - 1)]
def get_all_gridpos(self, center=None):
curr_shape = self.SHAPES_WITH_DIR[self.shape][self.dir]
if center is None:
center = [self.center[0], self.center[1]]
return [(cube[0] + center[0], cube[1] + center[1])
for cube in curr_shape]
def conflict(self, center):
for cube in self.get_all_gridpos(center):
# 超出屏幕之外,说明不合法
if cube[0] < 0 or cube[1] < 0 or cube[0] >= GRID_NUM_HEIGHT or \
cube[1] >= GRID_NUM_WIDTH:
return True
# 不为None,说明之前已经有小方块存在了,也不合法
if screen_color_matrix[cube[0]][cube[1]] is not None:
return True
return False
def rotate(self):
new_dir = self.dir + 1
new_dir %= len(self.SHAPES_WITH_DIR[self.shape])
old_dir = self.dir
self.dir = new_dir
if self.conflict(self.center):
self.dir = old_dir
return False
def down(self):
# import pdb; pdb.set_trace()
center = (self.center[0] + 1, self.center[1])
if self.conflict(center):
return False
self.center = center
return True
def left(self):
center = (self.center[0], self.center[1] - 1)
if self.conflict(center):
return False
self.center = center
return True
def right(self):
center = (self.center[0], self.center[1] + 1)
if self.conflict(center):
return False
self.center = center
return True
def draw(self):
for cube in self.get_all_gridpos():
pygame.draw.rect(screen, self.color,
(cube[1] * GRID_WIDTH, cube[0] * GRID_WIDTH,
GRID_WIDTH, GRID_WIDTH))
pygame.draw.rect(screen, WHITE,
(cube[1] * GRID_WIDTH, cube[0] * GRID_WIDTH,
GRID_WIDTH, GRID_WIDTH),
1)
def draw_grids():
for i in range(GRID_NUM_WIDTH):
pygame.draw.line(screen, LINE_COLOR,
(i * GRID_WIDTH, 0), (i * GRID_WIDTH, HEIGHT))
for i in range(GRID_NUM_HEIGHT):
pygame.draw.line(screen, LINE_COLOR,
(0, i * GRID_WIDTH), (WIDTH, i * GRID_WIDTH))
pygame.draw.line(screen, WHITE,
(GRID_WIDTH * GRID_NUM_WIDTH, 0),
(GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHT))
def draw_matrix():
for i, row in zip(range(GRID_NUM_HEIGHT), screen_color_matrix):
for j, color in zip(range(GRID_NUM_WIDTH), row):
if color is not None:
pygame.draw.rect(screen, color,
(j * GRID_WIDTH, i * GRID_WIDTH,
GRID_WIDTH, GRID_WIDTH))
pygame.draw.rect(screen, WHITE,
(j * GRID_WIDTH, i * GRID_WIDTH,
GRID_WIDTH, GRID_WIDTH), 2)
def draw_score():
show_text(screen, u'得分:{}'.format(score), 20, WIDTH + SIDE_WIDTH // 2, 100)
def remove_full_line():
global screen_color_matrix
global score
global level
new_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)]
index = GRID_NUM_HEIGHT - 1
n_full_line = 0
for i in range(GRID_NUM_HEIGHT - 1, -1, -1):
is_full = True
for j in range(GRID_NUM_WIDTH):
if screen_color_matrix[i][j] is None:
is_full = False
continue
if not is_full:
new_matrix[index] = screen_color_matrix[i]
index -= 1
else:
n_full_line += 1
score += n_full_line
level = score // 20 + 1
screen_color_matrix = new_matrix
def show_welcome(screen):
show_text(screen, u'俄罗斯方块', 30, WIDTH / 2, HEIGHT / 2)
show_text(screen, u'按任意键开始游戏', 20, WIDTH / 2, HEIGHT / 2 + 50)
running = True
gameover = True
counter = 0
live_cube = None
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if gameover:
gameover = False
live_cube = CubeShape()
break
if event.key == pygame.K_LEFT:
live_cube.left()
elif event.key == pygame.K_RIGHT:
live_cube.right()
elif event.key == pygame.K_DOWN:
live_cube.down()
elif event.key == pygame.K_UP:
live_cube.rotate()
elif event.key == pygame.K_SPACE:
while live_cube.down() == True:
pass
remove_full_line()
# level 是为了方便游戏的难度,level 越高 FPS // level 的值越小
# 这样屏幕刷新的就越快,难度就越大
if gameover is False and counter % (FPS // level) == 0:
# down 表示下移骨牌,返回False表示下移不成功,可能超过了屏幕或者和之前固定的
# 小方块冲突了
if live_cube.down() == False:
for cube in live_cube.get_all_gridpos():
screen_color_matrix[cube[0]][cube[1]] = live_cube.color
live_cube = CubeShape()
if live_cube.conflict(live_cube.center):
gameover = True
score = 0
live_cube = None
screen_color_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)]
# 消除满行
remove_full_line()
counter += 1
# 更新屏幕
screen.fill(BLACK)
draw_grids()
draw_matrix()
draw_score()
if live_cube is not None:
live_cube.draw()
if gameover:
show_welcome(screen)
pygame.display.update()
第二个是不是要求前后端来写?有什么要求吗?
csdn 中搜即可获得
代码如下
俄罗斯方块
import sys
import pygame
from pygame.locals import *
SIZE = 30 # 每个小方格大小
BLOCK_HEIGHT = 20 # 游戏区高度
BLOCK_WIDTH = 10 # 游戏区宽度
BORDER_WIDTH = 4 # 游戏区边框宽度
BORDER_COLOR = (40, 40, 200) # 游戏区边框颜色
SCREEN_WIDTH = SIZE * (BLOCK_WIDTH + 5) # 游戏屏幕的宽
SCREEN_HEIGHT = SIZE * BLOCK_HEIGHT # 游戏屏幕的高
BG_COLOR = (40, 40, 60) # 背景色
BLACK = (0, 0, 0)
def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText, (x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('俄罗斯方块')
font1 = pygame.font.SysFont('SimHei', 24) # 黑体24
font_pos_x = BLOCK_WIDTH * SIZE + BORDER_WIDTH + 10 # 右侧信息显示区域字体位置的X坐标
font1_height = int(font1.size('得分')[1])
score = 0 # 得分
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
# 填充背景色
screen.fill(BG_COLOR)
# 画游戏区域分隔线
pygame.draw.line(screen, BORDER_COLOR,
(SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, 0),
(SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, SCREEN_HEIGHT), BORDER_WIDTH)
# 画网格线 竖线
for x in range(BLOCK_WIDTH):
pygame.draw.line(screen, BLACK, (x * SIZE, 0), (x * SIZE, SCREEN_HEIGHT), 1)
# 画网格线 横线
for y in range(BLOCK_HEIGHT):
pygame.draw.line(screen, BLACK, (0, y * SIZE), (BLOCK_WIDTH * SIZE, y * SIZE), 1)
print_text(screen, font1, font_pos_x, 10, f'得分: ')
print_text(screen, font1, font_pos_x, 10 + font1_height + 6, f'{score}')
print_text(screen, font1, font_pos_x, 20 + (font1_height + 6) * 2, f'速度: ')
print_text(screen, font1, font_pos_x, 20 + (font1_height + 6) * 3, f'{score // 10000}')
print_text(screen, font1, font_pos_x, 30 + (font1_height + 6) * 4, f'下一个:')
pygame.display.flip()
if __name__ == '__main__':
main()