python 命令行 俄罗斯方块

import time
import os 
import sys
import numpy as np

from pynput.keyboard import Listener as kLis
from pynput.keyboard import Key as kKey
from pynput.keyboard import Controller as kCtl
import keyboard
from pynput.mouse import Button as mBut
from pynput.mouse import Controller as mCtl
import random

# 游戏界面定义
shape = [15, 10]
data = np.zeros((shape[0]+2, shape[1]+2), dtype=int, order='C')
data[:, 0] = 2 # 左
data[:, data.shape[1] - 1] = 2 # 右
data[0] = 3 # 上
data[data.shape[0] - 1] = 4  # 下

# 方块
shape01 = [
    [
        [
            [0, 0, 0],
            [1, 0, 0],
            [1, 1, 1]
        ], [
            [1, 1, 0],
            [1, 0, 0],
            [1, 0, 0]
        ], [
            [0, 0, 0],
            [1, 1, 1],
            [0, 0, 1]
        ], [
            [0, 0, 1],
            [0, 0, 1],
            [0, 1, 1]
        ],
    ],
    [
        [
            [0, 0, 0],
            [0, 0, 1],
            [1, 1, 1]
        ], [
            [1, 0, 0],
            [1, 0, 0],
            [1, 1, 0]
        ], [
            [0, 0, 0],
            [1, 1, 1],
            [1, 0, 0]
        ], [
            [0, 1, 1],
            [0, 0, 1],
            [0, 0, 1]
        ],
    ], [
        [
            [0, 0, 0],
            [0, 1, 0],
            [1, 1, 1]
        ], [
            [0, 1, 0],
            [0, 1, 1],
            [0, 1, 0]
        ], [
            [0, 0, 0],
            [1, 1, 1],
            [0, 1, 0]
        ], [
            [0, 1, 0],
            [1, 1, 1],
            [0, 0, 0]
        ],
    ], [
        [
            [0, 1, 0],
            [0, 1, 0],
            [0, 1, 0]
        ], [
            [0, 0, 0],
            [1, 1, 1],
            [0, 0, 0]
        ], [
            [0, 1, 0],
            [0, 1, 0],
            [0, 1, 0]
        ], [
            [0, 0, 0],
            [1, 1, 1],
            [0, 0, 0]
        ],
    ], [
        [
            [1, 0],
            [1, 1]
        ], [
            [1, 1],
            [1, 0]
        ], [
            [1, 1],
            [0, 1]
        ], [
            [0, 1],
            [1, 1]
        ],
    ], [
        [[1]],
        [[1]],
        [[1]],
        [[1]]
    ]
]

shape01_len = 24

shape_id = 24 -1 

b_h = '^------------------^'
b_b = '|                  |'
b_f = 'v------------------v'
ds = data.shape

# 游戏主界面, [当前形状编码, 形状位置], 下一个形状编码, 分数
def print_game(data, es, dn, score):
    sc_x = 2
    sc_y = int(ds[0] * 0.2)
    dn_x = 2
    dn_y = int(ds[0] * 0.5)

    # ------------- 分数显示 -------------
    bl = len(b_b)
    sc_l = 'score: '+str(score)
    sc_l = '| ' + sc_l + ' ' * (bl - len(sc_l) - 4) + ' |'
    # ------------- ------------- -------------
    
    # ------------- 下一个形状 -------------
    dn_l = 'next:'
    dn_l = '| ' + dn_l + ' ' * (bl - len(dn_l) - 4) + ' |'
    dn_s = []
    for i in shape01[dn // 4][dn % 4]:
        s = '|      ' 
        for j in i:
            if j == 0:
                s += '  '
            elif j == 1:
                s += 'x '
        s += ' ' * (bl - len(s) - 3) + '  |'
        dn_s.append(s)
    # ------------- ------------- -------------

    # ------------- 移动图像位置 -------------
    tes = []
    for ei, i in enumerate(shape01[es[0] // 4][es[0] % 4]):
        if ei + es[1] < 0:
            ts = '  '
        else:
            ts = '0 '
            pass
        s = ts * es[2]
        for j in i:
            if j == 0:
                s += ts
            elif j == 1:
                s += 'x '
        s += ts * (ds[1] - len(s)//2)
        tes.append(s)
    # ------------- ------------- -------------

    # ------------- 游戏界面 -------------
    for ei, i in enumerate(data):
        # ------- 显示界面 -------
        print('%2s' % ei,end=' ')
        gd = []
        for j in i:
            if j == 0: gd.append( '  ')
            elif j == 1: gd.append('x ')
            elif j == 2: gd.append('| ')
            elif j == 3: gd.append('  ')
            elif j == 4: gd.append('--')
        if ei >= es[1] - 2 and ei < es[1] + len(shape01[es[0] // 4][es[0] % 4]) - 2:
            for em, m in enumerate(shape01[es[0] // 4][es[0] % 4][ei + 2-es[1]]):
                if m == 1 and (es[2]+em)-1 < len(gd):
                    gd[(es[2]+em)-1] = 'x '
        print(''.join(gd), end='')
        
        # ------ 状态界面 -------
        if ei == 0:
            print(b_h,end='')
        elif ei == ds[0]-1:
            print(b_f, end='')
        elif ei == sc_y:
            print(sc_l, end='')
        elif ei == dn_y:
            print(dn_l, end='')
        elif ei > dn_y + 1 and ei < dn_y + len(dn_s) + 2:
            print(dn_s[ei-dn_y-2], end='')
        else:
            print(b_b, end='')
        print()
    # ------------- ------------- -------------



def is_stand (data, es):
    for ei,i in enumerate(shape01[es[0]//4][es[0] % 4]):
        for ej, j in enumerate(i):
            dt = data[es[1]+ei-1, es[2]+ej-1]
            if j == 1 and (dt == 1 or dt == 4):
                return True
    return False


def is_over(data, es):
    for ei, i in enumerate(shape01[es[0]//4][es[0] % 4]):
        for ej, j in enumerate(i):
            dt = data[es[1] + ei - 2, es[2] + ej - 2]
            # print(dt, end = ' ')
            if j == 1 and dt == 3:
                return True
        # print()
    return False

score = 0

def do_clean(data):在这里插入代码片
    global score
    line_count = []
    line = np.ones([shape[1]], dtype=int)
    for ea, a in enumerate(data[1:-1]):
        if np.equal(a[1:-1], line).all():
            line_count.append(ea)
    for li in line_count:
        data[2: li + 2, 1:-1] = data[1: li + 1, 1:-1]
    data[1][1:-1] = np.zeros([shape[1]], dtype=int)
    score += len(line_count)
    # pass 


def can_change(data, es):
    for ei, i in enumerate(shape01[es[0]//4][es[0] % 4]):
        for ej, j in enumerate(i):
            dt = data[es[1] + ei - 2, es[2] + ej - 2]
            if j == 1 and (dt in [1,2,4]):
                return False
    return True


nx_sh_id = random.randrange(0, shape01_len)

ps_y = 0
ps_x = 0
sh_id =0
stime = 1

def press(key):
    global ps_x
    global ps_y
    global sh_id
    global nx_sh_id
    global stime
    
    if str(key).strip('\'') == 'a':
        if can_change(data, [sh_id, ps_y, ps_x]):
            ps_x -= 1
    elif str(key).strip('\'') == 'd':
        if can_change(data, [sh_id, ps_y, ps_x+2]):
            ps_x += 1
    elif str(key).strip('\'') == 'w':
        t1 = sh_id % 4
        t2 = sh_id // 4
        t3 = t2*4 + (t1+1)%4
        if can_change(data, [t3, ps_y, ps_x+]):
            sh_id = t3
    elif str(key).strip('\'') == 's':
        # ps_y = 
        stime = 0.2

    print('\033[2K\033[1A \033[1C')
    print("\033[2J")
    print_game(data, [sh_id, ps_y, ps_x], nx_sh_id, score)
    sys.stdout.flush()


listener = kLis(on_press=press) 
listener.start()

while True:
    sh_id = nx_sh_id
    nx_sh_id = random.randrange(0, shape01_len)
    ps_y = 0
    ps_x = ds[1]//2-len(shape01[sh_id//4][sh_id % 4][0])//2
    stime = 1
    while True:
        ps_y += 1
        print("\033[2J")
        print_game(data, [sh_id, ps_y, ps_x], nx_sh_id, score)
        time.sleep(stime)
        
        # 判断是否结束下坠
        df = is_stand(data, [sh_id, ps_y, ps_x])
        if df:
            print('done')
            break
    s_w = len(shape01[sh_id // 4][sh_id % 4][0])
    s_h = len(shape01[sh_id // 4][sh_id % 4])
    # 判断是否完结
    if is_over(data, [sh_id, ps_y, ps_x]):
        print('game over')
        break
        
    data[ps_y-2:ps_y+s_h-2, ps_x-1:ps_x +
         s_w-1] += np.array(shape01[sh_id // 4][sh_id % 4], dtype=int)
    # 判断是否消行
    do_clean(data)

listener.join()

按键功能备注
a向左
d向右
w变形
s加速下落

代码运行需要 pynput

pip install pynput

运行效果

 0                         ^------------------^
 1 |                     | |                  |
 2 |                     | |                  |
 3 |       x x x         | | score: 3         |
 4 |         x           | |                  |
 5 |                     | |                  |
 6 |                     | |                  |
 7 |                     | |                  |
 8 |                     | | next:            |
 9 |                     | |                  |
10 |                     | |      x           |
11 | x                   | |                  |
12 | x                   | |                  |
13 | x   x           x x | |                  |
14 | x x x x x x x x   x | |                  |
15 | x x   x x x x x x x | |                  |
16 ------------------------v------------------v

学习了一些库的使用,实现还是挺简单的,供大家参考。
一个小游戏,难度不大,我也是给朋友展示python的功能,促进学习兴趣。


项目 上传到 gitee 上了 https://gitee.com/hocker/tetris

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值