python - 2048小游戏

我们先玩一下2048游戏,看都有哪些特点需要完成
在这里插入图片描述
完成效果图:
在这里插入图片描述
现在开始编写游戏2048:
1.首先,画出棋盘

import random
def draw_sep():
    print("+-----" * 4 + '+')

# 2. 画每一行的格子
def draw_one_row(row):  # [0, 2, 0, 0]   |    |  2  |    |    |
    print("".join([ '|  %d  '%(item) if item != 0 else '|     ' for item in row ]) + '|')

# draw_one_row([0, 2, 0, 0])

# 3. 创建棋盘的数据, 默认情况下时4*4, 数值全为0;
field = [[0 for j in range(4)] for i in range(4)]
# print(field)
# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

# 4. 开始游戏时, 棋盘数据会随机生成2或者4,
def random_create():
    # field[0][2] = 2
    while True:
        firstIndex = random.choice(range(4))
        secondIndex = random.choice(range(4))
        # 随机生成索引值
        if field[firstIndex][secondIndex] == 0:
            value = random.choice([2, 4, 2, 2, 2]) # 让一开始游戏生成2的概率大
            field[firstIndex][secondIndex] = value
            break

def game():
    random_create()
    random_create()
    # 随机生成两个数字2或4
    print(field)
    # 打印棋盘
    for row in field:
        draw_sep()
        draw_one_row(row)
    draw_sep()


if __name__ == '__main__':
	game()

输出:
在这里插入图片描述
第一行列表就是field的内容

2.判断棋盘是否可以向左移动
判断棋盘是否可以向左移动?
1). 只要棋盘的任意一行可以向左移动, 就返回True;
目标: 如何判断棋盘的一行是否可以向左移动?
2). 只要这一行的任意两个元素可以向左移动, 则返回True;
目标: 如何两个元素可以向左移动?
# - 如果第一个数值为0, 第二个数值不为0, 则说明可以向左移动;
# - 如果第一个数值不为0, 第二个数值与第一个元素相等, 则说明可以向左移动;

首先,可以在python console,熟悉or any and all功能:

 True or False or True
输出True
any([True, False, True])
输出True
True and False and True
输出False
all([True, False, True])
输出False

 def is_row_left(row):  # [0, 2,2,0]
# 任意两个元素可以向左移动?
def is_change(index):  # index时索引值, [0,1,2,3]
    # - 如果第一个数值为0, 第二个数值不为0, 则说明可以向左移动;
    if row[index] == 0 and row[index + 1] != 0:
        return True
    # - 如果第一个数值不为0, 第二个数值与第一个元素相等, 则说明可以向左移动;
    if row[index] != 0 and row[index + 1] == row[index]:
        return True
    return False
# 只要这一行的任意两个元素可以向左移动, 则返回True;
return any([is_change(index) for index in range(3)])

def is_move_left(field):
    # 只要棋盘的任意一行可以向左移动, 就返回True;
    return any([is_row_left(row) for row in field])

测试这段程序:

if __name__ == "__main__":
    try:
        assert is_move_left([[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 4]]) == True, "棋盘向左移动失败"
        assert is_row_left([2, 2, 2, 2]) == True, 'Error'
        assert is_row_left([2, 4, 2, 4]) == False, 'Error'
    except AssertionError as e:
        print(e)
    else:
        print("测试用例完成.....")

输出:

测试用例完成.....
  1. 棋盘是否可以向左完成之后,可以延伸到判断棋盘是否可以向右,向下,向上。
    可以画一个矩阵想一下:
    是否向右:翻转以后是否可以向左移动
    是否向上:转置->向左
    是否向下:转置->向右

我们先来实现翻转和转置功能:

def invert(field):
    """矩阵反转"""
    return [row[::-1] for row in field]

测试:

if __name__ == '__main__':
    print(invert([[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 4]]))

在这里插入图片描述

def transpose(field):
    """实现矩阵的转置"""
    # zip: 实现转置
    # *field对列表进行解包;
    return  list(zip(*field))

测试:

if __name__ == '__main__':
    print(transpose([[0, 0, 1, 0], [0, 2, 0, 1], [0, 0, 0, 1], [0, 0, 0, 4]]))

输出:
在这里插入图片描述

zip的功能,就是实现转置,但是要先把列表解包。zip转置后,需要转换为列表形式输出,否则输出是一个对象。
在这里插入图片描述

转置和翻转会了接下来就来完成判断棋盘是否可以向右、向下、向上。

def is_move_right(field):
    # 对棋盘的每一行元素进行反转;
    invertField = invert(field)
    return  is_move_left(invertField)
def is_move_up(field):
    # 对棋盘的每一行元素进行转置;
    transposeField = transpose(field)
    return  is_move_left( transposeField)
def is_move_down(field):
    # 判断能否向下移动, 也就是对于元素进行转置, 判断转置后的棋盘能否向右移动;
    # 对棋盘的每一行元素进行反转;
    transposeField = transpose(field)
    return is_move_right(transposeField)

测试:

if __name__ == '__main__':
    try:
        assert  is_move_right([[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 4]]) == True, 'Error'
        assert is_move_up([[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 4]]) == True, 'Error'
        assert is_move_down([[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值