找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 3633|回复: 1

[已回复] 找不到终端 curses

3

主题

7

帖子

7

积分

贫民

积分
7
jonjaypy 发表于 2016-12-7 20:44:51 | 显示全部楼层 |阅读模式
  1. 我在网上学习编写2048程序游戏,复制其代码后发现出现_curses.error: setupterm: could not find terminal的错误。请问是什么原因。



  2. import curses
  3. from random import randrange,choice
  4. from collections import defaultdict

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

  8.         #user input        
  9. def get_user_action(keyboard):
  10.         char = "N"
  11.         while char not in actions_dict:
  12.                 char = keyboard.getch()
  13.         return actions_dict[char]

  14. def transpose(field):
  15.         return [list(row) for row in zip(*field)]

  16. def invert(field):
  17.         return [row[::-1] for row in field]

  18. class GameField(object):
  19.         def __init__(self,height=4,width=4,win=2048):
  20.                 self.height = height
  21.                 self.width = width
  22.                 self.win_value = 2048
  23.                 self.score = 0
  24.                 self.highscore = 0
  25.                 self.reset()

  26.         def reset(self):
  27.                 if self.score > self.highscore:
  28.                         self.highscore = self.score
  29.                 self.score = 0
  30.                 self.field = [[0 for i in range(self.width)] for j in range(self.height)]
  31.                 self.spawn()
  32.                 self.spawn()

  33.         def move(self,direction):
  34.                 def move_row_left(row):
  35.                         def tighten(row):
  36.                                 new_row = [i for i in row if i!=0]
  37.                                 new_row += [0 for i in range(len(row) - len(new_row))]
  38.                                 return new_row

  39.                         def merge(row):
  40.                                 pair = False
  41.                                 new_row = []
  42.                                 for i in range(len(row)):
  43.                                         if pair:
  44.                                                 new_row.append(2*row[i])
  45.                                                 self.score += 2*row[i]
  46.                                                 pair = False
  47.                                         else:
  48.                                                 if i+1 < len(row) and row[i] == row[i +1]:
  49.                                                         pair = True
  50.                                                         new_row.append(0)
  51.                                                 else:
  52.                                                         new_row.append(row[i])
  53.                                 assert len(new_row) == len(row)
  54.                                 return new_row
  55.                         return tighten(merge(tighten(row)))        
  56.                 moves = {}
  57.                 moves['Left'] = lambda field: [move_row_left(row) for row in field]
  58.                 moves['Right'] = lambda field: invert(moves['Left'](invert(field)))
  59.                 moves['Up'] = lambda field: transpose(moves['Left'](transpose(field)))
  60.                 moves["Down"] = lambda field:transpose(moves['Right'](transpose(field)))

  61.                 if direction in moves:
  62.                         if self.move_is_possible(direction):
  63.                                 self.field = moves[direction](self.field)
  64.                                 self.spawn()
  65.                                 return True
  66.                         else:
  67.                                 return False

  68.         #win or lose
  69.         def is_win(self):
  70.                 return any(any(i>=self.win_value for i in row) for row in self.field)

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

  73.         #whether it can move

  74.         def draw(self,screen):
  75.                 help_string1 = 'wsad:means:up,down,left,right'
  76.                 help_string2 = '(R)restart,(Q)Exit'
  77.                 gameover_strings = 'you lose'
  78.                 win_strings = 'you win'
  79.                 def cast(string):
  80.                         screen.addstr(string + '\n')
  81.                 #DRAW horizon line
  82.                 def draw_hor_separator():
  83.                         line = '+' + ('+------'*self.width + '+')[1:]
  84.                         separator = defaultdict(lambda:line)
  85.                         if not hasattr(draw_hor_separator,"counter"):
  86.                                 draw_hor_separator.counter = 0
  87.                         cast(separator[draw_hor_separator.counter])
  88.                         draw_hor_separator.counter += 1

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

  92.                         cast('score:' + str(self.score))
  93.                         if 0 != self.highscore:
  94.                                 cast('highscore:'+str(self.highscore))

  95.                         for row in self.field:
  96.                                 draw_hor_separator()
  97.                                 draw_row()

  98.                         draw_hor_separator()
  99.                         if self.is_win():
  100.                                 cast(win_strings)
  101.                         else:
  102.                                 if self.is_gameover():
  103.                                         cast(gameover_strings)
  104.                                 else:
  105.                                         cast(help_string1)
  106.                         cast(help_string2)

  107.         def spawn(self):
  108.                 new_element = 4 if randrange(100) > 89 else 2
  109.                 (i,j) = choice([(i,j) for i in range(self.width) for j in range(self.height) if self.field[i][j] == 0])
  110.                 self.field[i][j] = new_element

  111.         def move_is_possible(self,direction):
  112.                 def row_is_left_movable(row):
  113.                         def change(i):
  114.                                 if row[i] == 0 and row[i+1] != 0:
  115.                                         return True
  116.                                 if row[i] !=0 and row[i+1] == row[i]:
  117.                                         return True
  118.                                 return False
  119.                         return any(change[i] for i in range(len(row)-1))

  120.                 check = {}
  121.                 check['Left'] = lambda field: any(row_is_left_movable(row) for row in field)
  122.                 check['Right'] = lambda field: check['Left'](invert(field))
  123.                 check['Left'] = lambda field: check['Left'](transpose(field))
  124.                 check['Down'] = lambda field: check['Right'](transpose(field))

  125.                 if direction in check:
  126.                         return check[direction][self.field]
  127.                 else:
  128.                         return False

  129. def main(stdscr):

  130.         def init():
  131.         #rebuild game table
  132.                 game_field.reset()
  133.                 return 'Game'

  134.         def not_game(state):
  135.         #draw gameover or win screen
  136.                 game_field.draw(stdscr)
  137.         #define actions
  138.                 action = get_user_action(stdscr)
  139.                 responses = defaultdict(lambda:state)
  140.                 responses['Restart'],responses['Exit'] = 'Init','Exit'
  141.                 return responses[action]

  142.         def game():
  143.                 #draw table
  144.                 game_field.draw(stdscr)
  145.                 #get action
  146.                 action = get_user_action(stdscr)

  147.                 if action == 'Restart':
  148.                         return 'Init'
  149.                 if action == 'Exit':
  150.                         return 'Exit'
  151.                 #if success move
  152.                 if game_field.move(action):
  153.                         if game_field.is_win():
  154.                                 return 'Win'
  155.                         if game_field.is_gameover():
  156.                                 return 'Gameover'
  157.                 return 'Game'

  158.         state_actions = {
  159.                         'Init': init,
  160.                         'Win': lambda:not_game('Win'),
  161.                         'Gameover':lambda:not_game('Gameover'),
  162.                         'Game': game
  163.                         }

  164.         curses.use_default_colors()
  165.         game_field = GameField(win = 32)
  166.         state = 'Init'
  167.         #circle
  168.         while state != 'Exit':
  169.                 state = state_actions[state]()

  170. curses.wrapper(main)
复制代码


回复

使用道具 举报

50

主题

1057

帖子

1108

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1108

活跃会员热心会员最佳导师默默耕耘突出贡献优秀版主荣誉管理论坛元老

blueelwang 发表于 2016-12-8 08:23:13 | 显示全部楼层
是在linux环境吗?
那么可以设置环境变量
export TERM=linux
export TERMINFO=/etc/terminfo
来解决
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表