当前位置:   article > 正文

用python实现2048小游戏_python2048

python2048

2048游戏规则:简单的移动方向键让数字叠加,并且获得这些数字每次叠加后的得分,当出现2048这个数字时游戏胜利。同时每次移动方向键时,都会在这个4*4的方格矩阵的空白区域随机产生一个数字2或者4,如果方格被数字填满了,那么就GameOver了
来一步步的进行刨析:
1) 生成4*4的棋盘, 其中数据结构为列表嵌套列表

field = [[0 for j in range(4)] for i in range(4)]
  • 1

2) 创建函数random_create, 在棋盘的一个随机位置插入一个数字2或者4,其中2的几率大

import random
def random_create():
    i = random.choice(range(4))
    j = random.choice(range(4))
    value = random.choice([2224])
    field[i][j] = value
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3) 如果随机插入数字的位置已经有内容, 如何解决覆盖原有数字的问题

def random_creat():
    while True:
        i = random.choice(range(4))
        j = random.choice(range(4))
        if li[i][j] == 0:
            li[i][j] = 4 if random.randint(1, 100) > 80 else 2
            break


random_creat()
random_creat()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4) 将生成的数据, 通过图像画出来

def draw_sep():
    print('+-----' * 4 + '+')


def draw_num(row):
    print(''.join('|{:^5}'.format(num) if num != 0 else '|     ' for num in row) + '|')


for row in li:
    draw_sep()
    draw_num(row)
draw_sep()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

5) 矩阵的反转

def invert(field):
    return [row[::-1] for row in field]
  • 1
  • 2

6) 矩阵的转秩

def transpose(field):
    return [list(row) for row in zip(*field)]
  • 1
  • 2

6) 判断棋盘是否可移动

def is_row_change(row):
    # row
    # 判断一行内容是否可以移动
    def is_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
        else:
            return False

    return any([is_change(index) for index in range(len(row) - 1)])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

判断这个棋盘是否可左右上下移动

def is_move_left(field):
    return any([is_row_change(row) for row in field])


def is_move_right(field):
    #  对于列表元素进行反转
    field = invert(field)
    print(field)
    return is_move_left(field)

def is_move_up(field):
    # 对于列表元素进行转置
    field = transpose(field)
    return is_move_left(field)

def is_move_down(field):
    # 反转+ 转置
    field = transpose(field)
    return is_move_right(field)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

7) 棋盘的移动,相加

def tight(row):   # [2, 0, 2, 0]
    # 最快的方式, 通过排序实现...........
    return sorted(row, key=lambda x: if  x == 0 )
score = 0
# 相加
def merge(row): # [2,2,0,0]
    # [0,1,2]
    for i in range(len(row)-1):
        # 如果两个值相等, 前一个元素*2, 后一个元素改为0。
        if row[i] == row[i+1]:
            row[i] *= 2
            row[i+1] = 0
            # 如果覆盖成功, 就给得分
            global score
            score += row[i]
    return row
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

棋盘左右上下移动相加

    def move_row_left(self, row):
        return self.tight(self.merge(self.tight(row)))

    def move_left(self, field):
        return [self.move_row_left(row) for row in field]

    def move_right(self, field):
        field = self.invert(field)
        return self.invert([self.move_row_left(row) for row in field])

    def move_up(self, field):
        return self.transpose([self.move_row_left(row) for row in self.transpose(field)])

    def move_down(self, field):
        return self.invert(self.transpose([self.move_row_left(row)
                                           for row in self.invert(self.transpose(field))]))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

8) 判断游戏的胜利与结束

#判断游戏何时胜利:当棋盘中出现2048时,就代表着游戏胜利
def victory(field):
    li = [y for row in li for y in row]
    if max(li) >= 2048:
        print('Victory')
def game_over(filed):
    if all((is_move_left(filed), is_move_right(filed), is_move_up(filed), is_move_down(filed))) == False:
        print('Game Over')   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这样程序的各个部分就写好了,将各个部分封装到一个类里面,再导入curses模块来控制游戏,就可以了
下面是完整的代码:

import curses
from itertools import chain
from random import choice


class GameField(object):
    # 初始化信息
    def __init__(self, width=4, height=4, win_value=8):
        self.width = width
        self.height = height
        self.win_value = win_value
        self.score = 0  # 当前得分
        self.highscore = 0  # 最高分
        self.moves = {}
        self.moves['Left'] = self.is_move_left
        self.moves['Right'] = self.is_move_right
        self.moves['Down'] = self.is_move_down
        self.moves['Up'] = self.is_move_up

        self.movesDict = {}
        self.movesDict['Left'] = self.move_left
        self.movesDict['Right'] = self.move_right
        self.movesDict['Down'] = self.move_down
        self.movesDict['Up'] = self.move_up

    def reset(self):  # 重置棋盘
        if self.score > self.highscore:
            self.highscore = self.score  # 更新最高分
        self.score = 0
        # 需求1: 生成4*4的棋盘, 其中数据结构选择列表嵌套列表;
        self.field = [[0 for j in range(self.width)]
                      for i in range(self.height)]

        # 在棋盘的一个随机位置插入一个数字2或者4
        self.random_create()
        self.random_create()

    def random_create(self):
        # 在棋盘的一个随机位置插入一个数字2或者4
        # field[0][3] = 2
        while True:
            i, j = choice(range(self.height)), choice(range(self.width))
            if self.field[i][j] == 0:
                self.field[i][j] = choice([2, 2, 2, 4])
                break

    def draw(self, stdscr):
        def draw_sep():
            stdscr.addstr('+' + "-----+" * self.width + '\n')

        def draw_one_row(row):
            stdscr.addstr("".join('|{:^5}'.format(num) if num != 0 else "|     " for num in row) + '|' + '\n')

        # 清屏
        stdscr.clear()
        stdscr.addstr("2048".center(50, '-') + '\n')
        stdscr.addstr("当前分数:" + str(self.score) + '\n')
        if self.highscore != 0:
            stdscr.addstr("最高分:" + str(self.highscore) + '\n')
        for row in self.field:
            draw_sep()
            draw_one_row(row)
        draw_sep()

        # 判断是否赢或者输
        if self.is_win():
            stdscr.addstr("胜利!!!!" + '\n')
        if self.is_gameover():
            stdscr.addstr("游戏结束!!!!" + '\n')
        stdscr.addstr(" 游戏帮助: 上下左右键  (R)Restart     Q(Quit)")

    def is_win(self):
        return max(chain(*self.field)) >= self.win_value

    def is_gameover(self):
        # 任何方向都不能移动的时候, 游戏结束
        return not any([self.move_is_possible(direction)
                        for direction in self.moves])

    @staticmethod
    def invert(field):
        # 矩阵进行反转
        return [row[::-1] for row in field]
        # print(invert(li))

    @staticmethod
    # 矩阵的转置
    def transpose(field):
        return [list(row) for row in zip(*field)]

    @staticmethod
    def is_row_change(row):
        # row
        # 需求3. 判断一行内容是否可移动。
        def is_change(i):  # 0
            # 判断每两个元素之间是否可移动
            if row[i] == 0 and row[i + 1] != 0:
                return True
            if row[i] != 0 and row[i] == row[i + 1]:
                return True
            return False

        return any([is_change(index) for index in range(len(row) - 1)])

    # 判断这个棋盘是否可向左移动
    def is_move_left(self, field):
        return any([self.is_row_change(row) for row in field])

    def is_move_right(self, field):
        #  对于列表元素进行反转
        field = self.invert(field)
        print(field)
        return self.is_move_left(field)

    def is_move_up(self, field):
        # 对于列表元素进行转置
        field = self.transpose(field)
        return self.is_move_left(field)

    def is_move_down(self, field):
        # 反转+ 转置
        field = self.transpose(field)
        return self.is_move_right(field)

    def move_is_possible(self, direction):  # 'left'
        # 判断用户选择的方向是否可移动
        if direction in self.moves:
            return self.moves[direction](self.field)
        else:
            return False

    # 将棋盘每一行的非0数向前移动, 0向后移动;
    @staticmethod
    def tight(row):  # [2, 0, 2, 0]
        # 最快的方式, 通过排序实现...........
        return sorted(row, key=lambda x: 1 if x == 0 else 0)

    def merge(self, row):  # [2,2,0,0]
        # [0,1,2]
        for i in range(len(row) - 1):
            # 如果两个值相等, 前一个元素*2, 后一个元素改为0。
            if row[i] == row[i + 1]:
                row[i] *= 2
                row[i + 1] = 0
                # 如果覆盖成功, 就给得分

                self.score += row[i]
        return row  # [4, 0, 0, 0]

    def move_row_left(self, row):
        return self.tight(self.merge(self.tight(row)))

    def move_left(self, field):
        return [self.move_row_left(row) for row in field]

    def move_right(self, field):
        field = self.invert(field)
        return self.invert([self.move_row_left(row) for row in field])

    def move_up(self, field):
        return self.transpose([self.move_row_left(row) for row in self.transpose(field)])

    def move_down(self, field):
        return self.invert(self.transpose([self.move_row_left(row)
                                           for row in self.invert(self.transpose(field))]))

    def move(self, direction):  # 'left'
        # 判断用户选择的方向是否可移动

        if direction in self.movesDict:
            # 判断是否可移动
            if self.move_is_possible(direction):
                self.field = self.movesDict[direction](self.field)
                self.random_create()
                return True
        else:
            return False


def get_user_action(stdscr):
    action = stdscr.getch()
    if action == curses.KEY_UP:
        return 'Up'
    if action == curses.KEY_DOWN:
        return 'Down'
    if action == curses.KEY_LEFT:
        return 'Left'
    if action == curses.KEY_RIGHT:
        return 'Right'
    if action == ord('r'):
        return 'Restart'
    if action == ord('q'):
        return 'Exit'


def main(stdscr):
    action = stdscr.getch()

    def init():
        # 初始化棋盘的操作
        game_field.reset()
        game_field.draw(stdscr)
        return 'Game'

    def game():
        game_field.draw(stdscr)
        action = get_user_action(stdscr)
        if action == 'Restart':
            return 'Init'
        if action == 'Exit':
            return 'Exit'
        if game_field.move(action):
            if game_field.is_win():
                return 'Win'
            if game_field.is_gameover():
                return 'GameOver'
        return 'Game'

    def not_game():
        game_field.draw(stdscr)
        while True:
            action = get_user_action(stdscr)
            if action == 'Restart':
                return 'Init'
            if action == 'Exit':
                return 'Exit'

    state_actions = {
        'Init': init,
        'Game': game,
        'Win': not_game,
        'GameOver': not_game,

    }
    game_field = GameField()
    state = 'Init'

    # 如果当前状态不是退出, 那么一直执行
    while state != 'Exit':
        # 执行当前状态需要操作的内容, 并返回, 下一次的状态为什么.
        state = state_actions[state]()


curses.wrapper(main)
  • 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
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244

实现双人版的2048游戏

import curses
import random
from itertools import chain


class GameField(object):
    def __init__(self, width=4, height=4, win_value=2048):
        self.width = width
        self.height = height
        self.win_value = win_value
        self.score1 = 0
        self.score2 = 0
        self.highscore = 0
        self.moves = {}
        self.moves['Left1'] = self.is_left_move
        self.moves['Right1'] = self.is_right_move
        self.moves['Up1'] = self.is_up_move
        self.moves['Down1'] = self.is_down_move
        self.moves['Left2'] = self.is_left_move
        self.moves['Right2'] = self.is_right_move
        self.moves['Up2'] = self.is_up_move
        self.moves['Down2'] = self.is_down_move
        self.movesDict1 = {}
        self.movesDict2 = {}
        self.movesDict1['Left1'] = self.left_move
        self.movesDict1['Right1'] = self.right_move
        self.movesDict1['Up1'] = self.up_move
        self.movesDict1['Down1'] = self.down_move
        self.movesDict2['Left2'] = self.left_move
        self.movesDict2['Right2'] = self.right_move
        self.movesDict2['Up2'] = self.up_move
        self.movesDict2['Down2'] = self.down_move

    def random_create1(self):
        while True:
            i, j = random.randint(0, self.height - 1), random.randint(0, self.width - 1)
            if self.field1[i][j] == 0:
                self.field1[i][j] = random.choice([2, 2, 2, 4])
                break

    def random_create2(self):
        while True:
            i, j = random.randint(0, self.height - 1), random.randint(0, self.width - 1)
            if self.field2[i][j] == 0:
                self.field2[i][j] = random.choice([2, 2, 2, 4])
                break

    def reset(self):
        self.field1 = [[0 for j in range(self.width)] for i in range(self.height)]
        self.score1 = 0
        self.field2 = [[0 for j in range(self.width)] for i in range(self.height)]
        self.score2 = 0
        self.random_create1()
        self.random_create1()
        self.random_create2()
        self.random_create2()

    def draw(self, stdscr):
        stdscr.clear()
        self.score1 = sum(chain(*self.field1))
        self.score2 = sum(chain(*self.field2))
        if max(self.score1, self.score2) > self.highscore:
            self.highscore = max(self.score1, self.score2)
        stdscr.addstr('最高分:' + str(self.highscore) + ' ')
        stdscr.addstr('玩家1分数:' + str(self.score1) + ' ')
        stdscr.addstr('玩家2分数:' + str(self.score2) + '\n')
        for row in self.field1:
            stdscr.addstr('+' + '-----+' * self.width + '\n')
            stdscr.addstr("".join('|{:^5}'.format(num) if num != 0 else "|     " for num in row) + '|' + '\n')
        stdscr.addstr('+' + '-----+' * self.width + '\n')
        if self.is_win1():
            stdscr.addstr('胜利\n')
        if self.is_gameover1():
            stdscr.addstr('游戏结束\n')
        for row in self.field2:
            stdscr.addstr('+' + '-----+' * self.width + '\n')
            stdscr.addstr("".join('|{:^5}'.format(num) if num != 0 else "|     " for num in row) + '|' + '\n')
        stdscr.addstr('+' + '-----+' * self.width + '\n')
        if self.is_win2():
            stdscr.addstr('胜利\n')
        if self.is_gameover2():
            stdscr.addstr('游戏结束\n')
        stdscr.addstr("玩家1:上下左右键 玩家2:wasd键(R)重置(Q)退出")

    def is_win1(self):
        return max(chain(*self.field1)) >= self.win_value

    def is_win2(self):
        return max(chain(*self.field2)) >= self.win_value

    def is_gameover1(self):
        return not any([self.is_move_possible1(direction) for direction in self.moves])

    def is_gameover2(self):
        return not any([self.is_move_possible2(direction) for direction in self.moves])

    @staticmethod
    def invert(field):
        return [row[::-1] for row in field]

    @staticmethod
    def transpose(field):
        return [list(row) for row in zip(*field)]

    @staticmethod
    def is_row_change(row):
        for i in range(len(row) - 1):
            if row[i] == 0 and row[i + 1] != 0:
                return True
            elif row[i] != 0 and row[i] == row[i + 1]:
                return True
        else:
            return False

    def is_left_move(self, field):
        return any([self.is_row_change(i) for i in field])

    def is_right_move(self, field):
        return any([self.is_row_change(i) for i in self.invert(field)])

    def is_up_move(self, field):
        return any([self.is_row_change(i) for i in self.transpose(field)])

    def is_down_move(self, field):
        return any([self.is_row_change(i) for i in self.invert(self.transpose(field))])

    def is_move_possible1(self, direction):
        if direction in self.moves:
            return self.moves[direction](self.field1)
        else:
            return False

    def is_move_possible2(self, direction):
        if direction in self.moves:
            return self.moves[direction](self.field2)
        else:
            return False

    @staticmethod
    def row_move(row):
        row = sorted(row, key=lambda x: 1 if x == 0 else 0)
        for i in range(len(row) - 1):
            if row[i] == row[i + 1]:
                row[i] *= 2
                row[i + 1] = 0
        return sorted(row, key=lambda x: 1 if x == 0 else 0)

    def left_move(self, field):
        return [self.row_move(i) for i in field]

    def right_move(self, field):
        return self.invert([self.row_move(i) for i in self.invert(field)])

    def up_move(self, field):
        return self.transpose([self.row_move(i) for i in self.transpose(field)])

    def down_move(self, field):
        return self.transpose(self.invert([self.row_move(i) for i in self.invert(self.transpose(field))]))

    def move1(self, direction):
        if direction in self.movesDict1 and self.is_move_possible1(direction):
            self.field1 = self.movesDict1[direction](self.field1)
            self.random_create1()
            return True
        else:
            return False

    def move2(self, direction):
        if direction in self.movesDict2 and self.is_move_possible2(direction):
            self.field2 = self.movesDict2[direction](self.field2)
            self.random_create2()
            return True
        else:
            return False


def get_user_action(stdscr):
    action = stdscr.getch()
    if action == curses.KEY_UP:
        return 'Up1'
    elif action == curses.KEY_DOWN:
        return 'Down1'
    elif action == curses.KEY_LEFT:
        return 'Left1'
    elif action == curses.KEY_RIGHT:
        return 'Right1'
    elif action == ord('r'):
        return 'Restart'
    elif action == ord('q'):
        return 'Exit'
    elif action == ord('w'):
        return 'Up2'
    elif action == ord('s'):
        return 'Down2'
    elif action == ord('a'):
        return 'Left2'
    elif action == ord('d'):
        return 'Right2'


def main(stdscr):
    def init():
        game_field.reset()
        game_field.draw(stdscr)
        return 'Game'

    def game():
        game_field.draw(stdscr)
        action = get_user_action(stdscr)
        if action == 'Restart':
            return 'Init'
        if action == 'Exit':
            return 'Exit'
        if action in ('Up1', 'Down1', 'Left1', 'Right1'):
            if game_field.move1(action):
                if game_field.is_win1():
                    return 'Win'
                if game_field.is_gameover1():
                    return 'GameOver'
        if action in ('Up2', 'Down2', 'Left2', 'Right2'):
            if game_field.move2(action):
                if game_field.is_win2():
                    return 'Win'
                if game_field.is_gameover2():
                    return 'GameOver'
        return 'Game'

    def not_game():
        game_field.draw(stdscr)
        while True:
            action = get_user_action(stdscr)
            if action == 'Restart':
                return 'Init'
            if action == 'Exit':
                return 'Exit'

    game_field = GameField()
    state = 'Init'
    state_actions = {
        'Init': init,
        'Game': game,
        'Win': not_game,
        'GameOver': not_game
    }
    while state != 'Exit':
        state = state_actions[state]()


curses.wrapper(main)
  • 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
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/174727
推荐阅读
相关标签
  

闽ICP备14008679号