search

Home  >  Q&A  >  body text

python3.5 curses.error:setupterm: could not find terminal


! /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5

-- coding: utf-8 --

import curses
from random import randrange, choice
from collections import defaultdict

actions = ['Up', 'Left', 'Down', 'Right', 'Restart', 'Exit']
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq']
actions_dict = dict(zip(letter_codes, actions * 2))

def main(stdscr):

game_field = GameField()

def init():
    # 重置游戏棋盘
    game_field.reset()
    return 'Game'

def not_game(state):
    # 画出 GameOver 或者 Win 的界面
    game_field.draw(stdscr)
    # 读取用户输入得到action,判断是重启游戏还是结束游戏
    action = get_user_action(stdscr)

    responses = defaultdict(lambda: state)  # 默认是当前状态,没有行为就会一直在当前界面循环
    responses['Restart'], responses['Exit'] = 'Init', 'Exit'  # 对应不同的行为转换到不同的状态
    return responses[action]

def game():
    # 画出当前棋盘状态
    game_field.draw(stdscr)
    # 读取用户输入得到action
    action = get_user_action(stdscr)

    if action == 'Restart':
        return 'Init'
    if action == 'Exit':
        return 'Exit'
    if game_field.move(action):  # move successful
        if game_field.is_win():
            return 'Win'
        if game_field.is_gameover():
            return 'Gameover'
    return 'Game'

state_actions = {
    'Init': init,
    'Win': lambda: not_game('Win'),
    'Gameover': lambda: not_game('Gameover'),
    'Game': game
}
state = 'Init'
# 状态机开始循环
while state != 'Exit':
    state = state_actions[state]()

def get_user_action(keyboard):

char = "N"
while char not in actions_dict:
    char = keyboard.getch()
return actions_dict[char]

矩阵转置

def transpose(field):

return [list(row) for row in zip(*field)]

矩阵逆转(不是逆矩阵)

def invert(field):

return [row[::-1] for row in field]

class GameField(object):

def __init__(self, height=4, width=4, win=2048):
    self.height = height  # 高
    self.width = width  # 宽
    self.win_value = 2048  # 过关分数
    self.score = 0  # 当前分数
    self.highscore = 0  # 最高分
    self.reset()  # 棋盘重置

# 随机生成一个 2 或者 4
def spawn(self):
    new_element = 4 if randrange(100) > 89 else 2
    (i, j) = choice([(i, j) for i in range(self.width) for j in range(self.height) if self.field[i][j] == 0])
    self.field[i][j] = new_element

# 棋盘重置
def reset(self):
    if self.score > self.highscore:
        self.highscore = self.score
    self.score = 0
    self.field = [[0 for i in range(self.width)] for j in range(self.height)]
    self.spawn()
    self.spawn()

def move(self, direction):
    def move_row_left(row):
        # 一行向左合并
        def tighten(row):  # 把零散的非零单元挤到一块
            new_row = [i for i in row if i != 0]
            new_row += [0 for i in range(len(row) - len(new_row))]
            return new_row

        def merge(row):  # 对邻近元素进行合并
            pair = False
            new_row = []
            for i in range(len(row)):
                if pair:
                    new_row.append(2 * row[i])
                    self.score += 2 * row[i]
                    pair = False
                else:
                    if i + 1 < len(row) and row[i] == row[i + 1]:
                        pair = True
                        new_row.append(0)
                    else:
                        new_row.append(row[i])
            assert len(new_row) == len(row)
            return new_row

        # 先挤到一块再合并再挤到一块
        return tighten(merge(tighten(row)))

    moves = {}
    moves['Left'] = lambda field: [move_row_left(row) for row in field]
    moves['Right'] = lambda field: invert(moves['Left'](invert(field)))
    moves['Up'] = lambda field: transpose(moves['Left'](transpose(field)))
    moves['Down'] = lambda field: transpose(moves['Right'](transpose(field)))
    if direction in moves:
        if self.move_is_possible(direction):
            self.field = moves[direction](self.field)
            self.spawn()
            return True
        else:
            return False

def is_win(self):
    return any(any(i >= self.win_value for i in row) for row in self.field)

def is_gameover(self):
    return not any(self.move_is_possible(move) for move in actions)

def move_is_possible(self, direction):
    def row_is_left_movable(row):
        def change(i):
            if row[i] == 0 and row[i + 1] != 0:  # 可以移动
                return True
            if row[i] != 0 and row[i + 1] == row[i]:  # 可以合并
                return True
            return False

        return any(change(i) for i in range(len(row) - 1))

    check = {}
    check['Left'] = lambda field: any(row_is_left_movable(row) for row in field)
    check['Right'] = lambda field: check['Left'](invert(field))
    check['Up'] = lambda field: check['Left'](transpose(field))
    check['Down'] = lambda field: check['Right'](transpose(field))
    if direction in check:
        return check[direction](self.field)
    else:
        return False

def draw(self, screen):
    help_string1 = '(W)Up (S)Down (A)Left (D)Right'
    help_string2 = '     (R)Restart (Q)Exit'
    gameover_string = '           GAME OVER'
    win_string = '          YOU WIN!'

    def cast(string):
        screen.addstr(string + '\n')

    # 绘制水平分割线
    def draw_hor_separator():
        line = '+' + ('+------' * self.width + '+')[1:]
        separator = defaultdict(lambda: line)
        if not hasattr(draw_hor_separator, "counter"):
            draw_hor_separator.counter = 0
        cast(separator[draw_hor_separator.counter])
        draw_hor_separator.counter += 1

    def draw_row(row):
        cast(''.join('|{: ^5} '.format(num) if num > 0 else '|      ' for num in row) + '|')

    screen.clear()
    cast('SCORE: ' + str(self.score))
    if 0 != self.highscore:
        cast('HGHSCORE: ' + str(self.highscore))
    for row in self.field:
        draw_hor_separator()
        draw_row(row)
    draw_hor_separator()
    if self.is_win():
        cast(win_string)
    else:
        if self.is_gameover():
            cast(gameover_string)
        else:
            cast(help_string1)
    cast(help_string2)

curses.wrapper(main)

找不到终端? 求教

PHP中文网PHP中文网2804 days ago1352

reply all(1)I'll reply

  • 巴扎黑

    巴扎黑2017-04-17 17:39:40

    You should be able to run it directly without debugging
    or execute it directly in CMD on windows
    1) There is no curses under windows. This is used when there is no X11 server. You can try it under cygwin
    2) There is still a problem with typesetting

    reply
    0
  • Cancelreply