V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
200
V2EX  ›  Python

写了一个命令行版的 2048

  •  
  •   200 · 2014-03-15 00:00:32 +08:00 · 4895 次点击
    这是一个创建于 4000 天前的主题,其中的信息可能已经有所发展或是发生改变。
    原版: http://gabrielecirulli.github.io/2048/

    可以考虑跑些搜索 看看有没有好的策略啥的 (¬_¬)

    import random
    import sys
    def print_grid(grid):
    print ("\n%s\n" % "+".join([('-' * 4)] * 4)).join(
    ["|".join(["%4d" % item if item > 0 else " " * 4 for item in line]) for line in grid])
    def get_available_cells(grid):
    return [(y, x) for y in range(4) for x in range(4) if not grid[y][x]]
    def insert_new_item(grid):
    available_cells = get_available_cells(grid)
    if len(available_cells) == 0:
    return False
    y, x = random.choice(available_cells)
    grid[y][x] = 2 if random.random() < 0.9 else 4
    return True
    def is_legal_position(y, x):
    return 0 <= y <= 3 and 0 <= x <= 3
    def get_next_position(y, x, (y_offset, x_offset)):
    return y + y_offset, x + x_offset
    def get_next_nonzero_cell(grid, y, x, (y_offset, x_offset)):
    next_y, next_x = get_next_position(y, x, (y_offset, x_offset))
    if is_legal_position(next_y, next_x):
    if grid[next_y][next_x]:
    return next_y, next_x
    else:
    return get_next_nonzero_cell(grid, next_y, next_x, (y_offset, x_offset))
    else:
    return None, None
    def merge_cells(grid, (write_y, write_x), (read_y, read_x), direction, virtual, winning=False):
    if (write_y, write_x) == (read_y, read_x):
    read_y, read_x = get_next_nonzero_cell(grid, read_y, read_x, direction)
    if not is_legal_position(write_y, write_x) or not is_legal_position(read_y, read_x):
    return winning if not virtual else False
    if grid[write_y][write_x]:
    if grid[read_y][read_x] == grid[write_y][write_x]:
    if virtual:
    return True
    grid[write_y][write_x] *= 2
    grid[read_y][read_x] = 0
    return merge_cells(grid, get_next_position(write_y, write_x, direction),
    get_next_nonzero_cell(grid, read_y, read_x, direction), direction, virtual,
    winning or grid[write_y][write_x] > 1024)
    else:
    return merge_cells(grid, get_next_position(write_y, write_x, direction),
    (read_y, read_x), direction, virtual, winning)
    else:
    if virtual:
    return True
    grid[write_y][write_x] = grid[read_y][read_x]
    grid[read_y][read_x] = 0
    return merge_cells(grid, (write_y, write_x),
    get_next_nonzero_cell(grid, read_y, read_x, direction), direction, virtual, winning)
    def get_movable_directions(grid):
    return [direction for direction in ["a", "d", "w", "s"] if move(grid, direction, True)]
    def move(grid, direction, virtual):
    if direction == "a": #left
    return any([merge_cells(grid, (i, 0), (i, 0), (0, 1), virtual) for i in range(4)])
    elif direction == "d": #right
    return any([merge_cells(grid, (i, 3), (i, 3), (0, -1), virtual) for i in range(4)])
    elif direction == "w": #up
    return any([merge_cells(grid, (0, i), (0, i), (1, 0), virtual) for i in range(4)])
    elif direction == "s": #down
    return any([merge_cells(grid, (3, i), (3, i), (-1, 0), virtual) for i in range(4)])
    grid = [[0 for x in range(4)] for y in range(4)]
    insert_new_item(grid)
    while True:
    insert_new_item(grid)
    print_grid(grid)
    movable_directions = get_movable_directions(grid)
    if len(movable_directions) == 0:
    print "You lose!"
    break
    direction_name = sys.stdin.readline().strip().lower()
    while direction_name not in movable_directions:
    print "Invalid direction."
    direction_name = sys.stdin.readline().strip().lower()
    if move(grid, direction_name, False):
    print_grid(grid)
    print "You win!"
    break
    view raw 2048.py hosted with ❤ by GitHub
    7 条回复    2014-05-01 09:02:07 +08:00
    ericls
        1
    ericls  
       2014-03-15 15:25:41 +08:00
    这游戏一不小心玩儿了3个小时 我LGQ
    yangff
        2
    yangff  
       2014-03-15 21:32:16 +08:00 via Android
    早就有ai了。。
    jprovim
        3
    jprovim  
       2014-03-16 09:37:31 +08:00
    挑個毛病,使用AWSD操作,而且還需要輸入Enter。
    總體來說還是很好的。
    patricksong1993
        4
    patricksong1993  
       2014-03-16 23:44:49 +08:00
    2048升级版4096
    自带超快机器人
    http://patricksong1993.github.io/4096/
    rex
        5
    rex  
       2014-03-18 14:14:31 +08:00
    @jprovim @200
    可以使用

    ```
    def getkey():
    "get key press without Enter"

    import termios, sys, os

    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
    new[6][TERMIOS.VMIN] = 1
    new[6][TERMIOS.VTIME] = 0
    termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
    c = None
    try:
    c = os.read(fd, 1)
    finally:
    termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
    return c
    ```

    代替sys.stdin.readline().strip().lower(),这样就不必 enter 了。
    rex
        6
    rex  
       2014-03-18 14:16:09 +08:00
    排版乱了。
    贴个链接试试

    https://gist.github.com/zhasm/9614482
    jprovim
        7
    jprovim  
       2014-05-01 09:02:07 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   986 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 21:56 · PVG 05:56 · LAX 13:56 · JFK 16:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.