pygame实现俄罗斯方块游戏(对战篇1)


Posted in Python onOctober 29, 2019

上篇更新到pygame实现俄罗斯方块游戏(AI篇2) ,原本应该继续做优化,不过考虑到完成游戏完整性,这张就先把对战做好。

一、对战的方块管理

定义一个BlockManage管理对战的方块

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)

根据BlockManage根据传入的玩家id返回方块,保证每个玩家拿到的方块序列十一致的,所以在每次创建方块时存放了玩家数量相同的拷贝,拷贝是避免对象的引用造成对同一个方块对象操作混乱。

然后HintBox里加入block_manage的引用并且在take_block函数里将创建Block改为使用block_manage去取方块

class HintBox(object):
 block_manage=None
 next_block=None
 def __init__(self, bg, block_size, position, block_manage):
 self._bg=bg;
 self._x,self._y,self._width,self._height=position
 self._block_size=block_size
 self._bgcolor=[0,0,0]
 self.block_manage=block_manage

 def take_block(self):
 block = self.next_block
 if block is None: # make first block
 block = self.block_manage.get_block()
 
 self.next_block = self.block_manage.get_block()
 return block

分别定义一个VirtualHintBox和一个VirtualScoreBox,用于给右下角面板上的

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
class VirtualScoreBox(object):
 total_score = 0
 def __init__(self):
 pass

 def add_score(self, score):
 self.total_score += score

pygame实现俄罗斯方块游戏(对战篇1)

使用block_manage并分别传递给主面板的hint_box和右下角面板的VirtualHintBox,右下角面板的定义和初使设置完了以后,将下面的player改为player1和player2两个玩家。

pygame实现俄罗斯方块游戏(对战篇1)

在游戏主循环增加完相应的设置和操作,现在就可以玩人机对战了。

pygame实现俄罗斯方块游戏(对战篇1)

当然如果你把

player1 = HumanPlayer()
player2 = AIPlayer(ai_diff_ticks=350)

改成

player1 = AIPlayer(ai_diff_ticks=150)
player2 = AIPlayer(ai_diff_ticks=350)

当然就是一场机器人对机器人的战斗

pygame实现俄罗斯方块游戏(对战篇1)

二、记分和增加对抗性

增加记分显示比较容易,给VirtualScoreBox实现下paint就行。

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

增加对抗性的话先设置个规则,谁的分数满1000,就可以给另一方增加两层方块作为攻击,为便于计算,我们在Panel里增加一个数字,用于标记对对方攻击的次数。

Panel里增加一个添加障碍物的函数

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

Panel里再添加一个获取是否有攻击触发的函数

def get_attach_num(self):
 if self.score_box.total_score /1000 > self.attack_num:
 self.attack_num+=1
 return 1
 else:
 return 0

主循环里再增加攻击的处理

pygame实现俄罗斯方块游戏(对战篇1)

好了,现在对战效果也完成了。

pygame实现俄罗斯方块游戏(对战篇1)

最后再给AIPlayer一个level属性,将level映射为时间间隔

pygame实现俄罗斯方块游戏(对战篇1)

以现在的机器人水平,试了下大概能战胜5级的AIPlayer。

最后附下目前的代码。

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

更多关于俄罗斯方块的文章,请点击查看专题:《俄罗斯方块》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python的Django框架中包装视图函数
Jul 20 Python
python实现红包裂变算法
Feb 16 Python
Python内置函数delattr的具体用法
Nov 23 Python
python保存字典和读取字典的实例代码
Jul 07 Python
python3 selenium自动化测试 强大的CSS定位方法
Aug 23 Python
Django框架 查询Extra功能实现解析
Sep 04 Python
python网络爬虫 CrawlSpider使用详解
Sep 27 Python
Python 装饰器原理、定义与用法详解
Dec 07 Python
python字符串,元组,列表,字典互转代码实例详解
Feb 14 Python
如何使用repr调试python程序
Feb 28 Python
python使用for...else跳出双层嵌套循环的方法实例
May 17 Python
关于Python中*args和**kwargs的深入理解
Aug 07 Python
Numpy中对向量、矩阵的使用详解
Oct 29 #Python
pygame实现俄罗斯方块游戏(AI篇2)
Oct 29 #Python
pygame实现俄罗斯方块游戏(AI篇1)
Oct 29 #Python
基于Django统计博客文章阅读量
Oct 29 #Python
pygame实现俄罗斯方块游戏(基础篇3)
Oct 29 #Python
python安装gdal的两种方法
Oct 29 #Python
pygame实现俄罗斯方块游戏(基础篇2)
Oct 29 #Python
You might like
给php新手谈谈我的学习心得
2007/02/25 PHP
PHP获取url的函数代码
2011/08/02 PHP
举例讲解PHP面对对象编程的多态
2015/08/12 PHP
PHP实现的自定义数组排序函数与排序类示例
2016/11/18 PHP
jquery checkbox全选、取消全选实现代码
2010/03/05 Javascript
IE中jquery.form中ajax提交没反应解决方法分享
2012/09/11 Javascript
JavaScript的null和undefined区别示例介绍
2014/09/15 Javascript
20条学习javascript的编程规范的建议
2014/11/28 Javascript
jQuery中:input选择器用法实例
2015/01/03 Javascript
浅谈js中的闭包
2015/03/16 Javascript
Bootstrap每天必学之弹出框(Popover)插件
2016/04/25 Javascript
老生常谈JavaScript 函数表达式
2016/09/01 Javascript
AngularJs表单验证实例代码解析
2016/11/29 Javascript
Bootstrap基本插件学习笔记之Tooltip提示工具(18)
2016/12/08 Javascript
Angular2 路由问题修复详解
2017/03/01 Javascript
自制简易打赏功能的实例
2017/09/02 Javascript
Angular4自制一个市县二级联动组件示例
2017/11/21 Javascript
nodejs结合socket.io实现websocket通信功能的方法
2018/01/12 NodeJs
使用typescript开发angular模块并发布npm包
2018/04/19 Javascript
node.js基于socket.io快速实现一个实时通讯应用
2019/04/23 Javascript
React Hooks 实现和由来以及解决的问题详解
2020/01/17 Javascript
vue实现户籍管理系统
2020/05/29 Javascript
JavaScript实现移动小精灵的案例代码
2020/12/12 Javascript
JS实现百度搜索框
2021/02/25 Javascript
[06:43]DAC2018 4.5 SOLO赛 Maybe vs Paparazi
2018/04/06 DOTA
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
Python中dict和set的用法讲解
2019/03/28 Python
深度学习入门之Pytorch 数据增强的实现
2020/02/26 Python
Python3如何判断三角形的类型
2020/04/12 Python
python 统计list中各个元素出现的次数的几种方法
2021/02/20 Python
HTML5中通过li-canvas轻松实现单图、多图、圆角图绘制,单行文字、多行文字等
2018/11/30 HTML / CSS
客服工作职责
2013/12/11 职场文书
校园报刊亭的创业计划书
2014/01/02 职场文书
大二自我鉴定
2014/01/31 职场文书
音乐教学随笔感言
2014/02/19 职场文书
建党伟业的观后感
2015/06/01 职场文书