Python 控制台版 2048

现在 2048 游戏这么火,我也尝试着用 Python 做了一个(控制台版),貌似 Python 实现的代码行数都是 100 行左右。

现在 2048 游戏这么火,我也尝试着用 Python 做了一个(控制台版),貌似 Python 实现的代码行数都是 100 行左右。

image

由于采用了 cls 命令清屏 和 msvcrt 的按键检测,所以下面代码只能在 Windows 平台上运行

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
#coding:utf-8

import os, sys, random, msvcrt

class Game:
    def __init__(self, size):
        self.size  = size
        self.score = 0
        self.state = [0] * (self.size * self.size)
        self.add_random()

    def blank(self):
        return self.state.count(0)

    def add(self, num):
        pos = random.randint(0, self.blank()-1)
        for i in range(self.size * self.size):
            if self.state[i] == 0:
                if pos == 0:
                    self.state[i] = num
                    break
                else:
                    pos -= 1
        return self.blank()

    def add_random(self):
        numbers = [2,2,2,2,2,2,4]
        return self.add(random.choice(numbers))

    def show(self):
        os.system("cls")
        print "[%s]\n%s" % (self.score, "-" * (self.size * 5 + 3))
        for i in range(self.size):
            print "|",
            for j in range(self.size):
                print "%4d" % self.state[i * self.size + j] if self.state[i * self.size + j] else "    ",
            print "|"
            if i == self.size - 1:
                print "-" * (self.size * 5 + 3)
            else:
                print "|%s |" %  ("     " * self.size)

    def move(self, d):
        old_state = self.state[:]
        if   d == "a": pass
        elif d == "w": self.rotate()
        elif d == "d": self.rotate() or self.rotate()
        elif d == "s": self.rotate() or self.rotate() or self.rotate()
        else: return False
        for i in range(self.size): self.move_line(i)
        if d == "s": self.rotate()
        if d == "d": self.rotate() or self.rotate()
        if d == "w": self.rotate() or self.rotate() or self.rotate()
        if old_state == self.state: return False
        return True

    def move_line(self, line_no):
        moved, merged = [], False
        for i in range(self.size):
            n = self.state[line_no * self.size + i]
            if n:
                if not merged and moved and moved[-1] == n :
                    moved[-1] = n * 2
                    merged = True
                    self.score += n * 2
                else: moved.append(n)
        moved.extend([0]*(self.size - len(moved)))
        self.state[line_no * self.size: line_no * self.size + self.size] = moved

    def can_move(self):
        for d in ["w", "a", "s", "d"]:
            old_state = self.state
            try:
                if self.move(d):
                    return True
            finally:
                self.state = old_state
        return False



    def rotate(self):
        new_state = []
        for i in range(self.size - 1, -1, -1):
            for j in range(self.size):
                new_state.append(self.state[j * self.size + i])
        self.state = new_state

game = Game(5)
while 1:
    game.show()
    if 2048 in game.state:
        print "u win!!"
        break
    if game.move(msvcrt.getch()):
        if not game.add_random():
            if not game.can_move():
                game.show()
                print "game over"
                break

主要的逻辑是随机生成数字填充到空格,当按下方向键(WASD)时,数字按照指定方向合并, 为了简化逻辑,数字合并只实现了一个方向的,要合并其他方向时先旋转整个棋盘合并后再旋转回去。

Licensed under CC BY-NC-SA 4.0
Last updated on 2025-11-11 00:00