+ -
当前位置:首页 → 问答吧 → 字符挖地雷

字符挖地雷

时间:2011-01-06

来源:互联网

本帖最后由 bluepp 于 2011-01-06 23:23 编辑

比较简陋 但基本功能都实现了

棋盘雷数定制
挖格、标记、连在一起的空白点击后自动展开
成功失败判定

暂时没发现bug,新手,写得笨。大家看看给点儿建议啊,谢谢了!!
  1. import sys, re
  2. from random import randint

  3. pt_relations = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
  4. panel_height = 9
  5. panel_width = 9
  6. bombs = 9
  7. martrix = []
  8. mask = []

  9. def draw(content):
  10.     global bombs
  11.     print '--%d bombs game---' % bombs
  12.     for i in content:
  13.         for j in i:
  14.             print str(j).center(1),
  15.         print

  16. def area_check(x, y):
  17.     '''
  18.     check if the point in panel area
  19.     '''
  20.     global panel_width, panel_height
  21.     return 0 <= x <= (panel_width - 1) and 0 <= y <= (panel_height - 1)

  22. def init_panel():
  23.     global panel_width, panel_height, bombs, martrix, mask
  24.     martrix = [[0 for x in range(panel_width)][:] for y in range(panel_height)]
  25.     mask = [['-' for x in range(panel_width)][:] for y in range(panel_height)]
  26.     for i in range(bombs):
  27.         x = randint(0, panel_width - 1)
  28.         y = randint(0, panel_height - 1)
  29.         martrix[y][x] = 'x'
  30.     for r in range(len(martrix)):
  31.         row = martrix[r]
  32.         for c in range(len(row)):
  33.             col = martrix[r][c]
  34.             if col == 'x':
  35.                 for pt in pt_relations:
  36.                     y = r + pt[0]
  37.                     x = c + pt[1]
  38.                     if area_check(x, y) and martrix[y][x] != 'x':
  39.                         martrix[y][x] += 1
  40.     draw(mask)

  41. def zvirus(seedx, seedy):
  42.     '''
  43.     zero virus,explan all zero cells near by cell-self
  44.     '''
  45.     for pt in pt_relations:
  46.         c = seedx + pt[0]
  47.         r = seedy + pt[1]
  48.         if area_check(c, r) and martrix[c][r] != '*' and mask[c][r] == '-':
  49.             mask[c][r] = martrix[c][r]
  50.             if mask[c][r] == 0:
  51.                 zvirus(c, r)

  52. def click(loc):
  53.     global mask, martrix
  54.     if mask[loc[0]][loc[1]] == '#':
  55.         print 'Marked cell is not clickable'
  56.     else:
  57.         mask[loc[0]][loc[1]] = martrix[loc[0]][loc[1]]
  58.         if martrix[loc[0]][loc[1]] == 'x':
  59.             print '\n Game Over! The bombs:'
  60.             draw(martrix)
  61.             print 'starting a new game'
  62.             init_panel()
  63.         else:
  64.             if martrix[loc[0]][loc[1]] == 0:
  65.                 zvirus(loc[0], loc[1])
  66.     draw(mask)

  67. def mark(loc):
  68.     global mask, bombs
  69.     if mask[loc[0]][loc[1]] == '-':
  70.         mask[loc[0]][loc[1]] = '#'
  71.         print 'marked', loc[0], loc[1]
  72.     elif mask[loc[0]][loc[1]] == '#':
  73.         mask[loc[0]][loc[1]] = '-'
  74.         print 'unmarked', loc[0], loc[1]
  75.     draw(mask)

  76. def check_win():
  77.     global mask
  78.     uncomplet = 0
  79.     for i in mask:
  80.         if '-' in i:
  81.             uncomplet += 1
  82.             break
  83.     if not uncomplet:
  84.         print 'Weldone! you win the game!'
  85.         draw(martrix)
  86.         print 'starting a new game'
  87.         init_panel()

  88. def usage():
  89.     global panel_width,panel_height
  90.     print
  91.     print "Use: type 'click XY' (RET) to click a certan cell\n"
  92.     print "          'click 74' for example \n"
  93.     print "     type 'mark XY' (RET) to mark a bomb cell,\n"
  94.     print "          do this on marked cell means unmark \n"
  95.     print "          'mark 88' for example\n"
  96.     print "     type 'stop' (RET) or C-c to quit the program\n"
  97.     print "     NOTICE THAT:    X :[0,{0})  ; Y:[0,{1}).".format(panel_width,panel_height)
  98.     print

  99. if __name__ == "__main__":
  100.     init_panel()
  101.     p = re.compile(r'^stop$|(^click \d\d$)|(^mark [0-8][0-8]$)')
  102.     bRun = 1
  103.     while(bRun):
  104.         cmdl = sys.stdin.readline().strip()
  105.         if p.match(cmdl):
  106.             if cmdl == 'stop':
  107.                 bRun = 0
  108.             else:
  109.                 cmd = cmdl[:cmdl.find(' ')]
  110.                 y = int(cmdl[cmdl.find(' ') + ((panel_width/10)+1)])
  111.                 x = int(cmdl[cmdl.find(' ') + ((panel_height/10)+((panel_width/10)+1)+1)])
  112.                 if cmd == 'click':
  113.                     click([x, y])
  114.                 elif cmd == 'mark':
  115.                     mark([x, y])
  116.                 else:
  117.                     pass
  118.             check_win()
  119.         else:
  120.             usage()
复制代码

作者: bluepp   发布时间: 2011-01-06

The Zen of Python

    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!



代码中的若干写法,虽然简单,但是很大程度上降低了代码的可读性。
个人很反感这种写法。

作者: tubocurarine   发布时间: 2011-01-07



QUOTE:
The Zen of Python

    Beautiful is better than ugly.
    Explicit is better than implicit.
     ...
tubocurarine 发表于 2011-01-07 09:03




感谢回复!

我昨天找了几个其他脚本语言的挖雷,准备参考以后再修改一下。

这段代码确实有些写法很晦涩。我试着改改。

但是其实我感觉…… 用100+ lines 代码还是有些拖沓。

作者: bluepp   发布时间: 2011-01-07

应该会有一个偶发的 bug:
设置地雷的地方,直接用 rand 来设置,可能会在已经设置过地雷的地方重复设置,导致最后设置的地雷数量不足。

还有,也可以直接用一个二维数组 (list) 来实现,这个数组中每一个元素都是一个class 实例,每个这个实例都可以表述自我(例如自己是否是个地雷,自己周围有多少地雷之类)。

这样最后的代码长度也许会更长,但是可读性应该会更好一些。



QUOTE:
感谢回复!

我昨天找了几个其他脚本语言的挖雷,准备参考以后再修改一下。

这段代码确实有些写 ...
bluepp 发表于 2011-01-07 09:24

作者: tubocurarine   发布时间: 2011-01-07



QUOTE:
应该会有一个偶发的 bug:
设置地雷的地方,直接用 rand 来设置,可能会在已经设置过地雷的地方重复设置, ...
tubocurarine 发表于 2011-01-07 09:40




    哈哈哈 是的。

    我忘了加

作者: bluepp   发布时间: 2011-01-07