【华为OD机试真题 python】贪吃蛇

贪吃蛇是一个经典游戏,蛇的身体由若干方格连接而成,身体随蛇头移动。蛇头触碰到食物时,蛇的长度会增加一格。

蛇头和身体的任一方格或者游戏版图边界碰撞时,游戏结束。

下面让我们来完成贪吃蛇游戏的模拟。

给定一个N*M的数组arr,代表N*M个方格组成的版图,贪吃蛇每次移动一个方格。

若arr[i][j] == ‘H’,表示该方格为贪吃蛇的起始位置;

若arr[i][j] == ‘F’,表示该方格为食物,

若arr[i][j] == ‘E’,表示该方格为空格。

贪吃蛇初始长度为1,初始移动方向为向左。

为给定一系列贪吃蛇的移动操作,返回操作后蛇的长度,如果在操作执行完之前已经游戏结束,返回游戏结束时蛇的长度。

贪吃蛇移动、吃食物和碰撞处理的细节见下面图示:

图1:截取了贪吃蛇移动的一个中间状态,H表示蛇头,F表示食物,数字为蛇身体各节的编号,蛇为向左移动,此时蛇头和食物已经相邻

图2:蛇头向左移动一格,蛇头和食物重叠,注意此时食物的格子成为了新的蛇头,第1节身体移动到蛇头位置,第2节身体移动到第1节身体位置,以此类推,

最后添加第4节身体到原来第3节身体的位置。

图3:蛇头继续向左移动一格,身体的各节按上述规则移动,此时蛇头已经和边界相邻,但还未碰撞。

图4:蛇头继续向左移动一格,此时蛇头已经超过边界,发生碰撞,游戏结束。

图5和图6给出一个蛇头和身体碰撞的例子,蛇为向上移动。

图5时蛇头和第7节身体相邻,但还未碰撞;

图6蛇头向上移动一格,此时蛇头和第8节身体都移动到了原来第7节身体的位置,发生碰撞,游戏结束。

输入描述

  • 输入第一行为空格分隔的字母,代表贪吃蛇的移动操作。
  • 字母取值为U、D、L、R和G,
  • U、D、L、R分别表示贪吃蛇往上、下、左、右和转向,转向时贪吃蛇不移动 ,G表示贪吃蛇按当前的方向移动一格。
  • 用例保证输入的操作正确。
  • 第二行为空格分隔的两个数,指定N和M,为数组的行和列数。
  • 余下N行每行是空格分隔的M个字母。字母取值为H、F和E,H表示贪吃蛇的起始位置,F表示食物,E表示该方格为空。
  • 用例保证有且只有一个H,而F和E会有多个。

输出描述

  • 输出一个数字,为蛇的长度。

示例 1 输入输出示例仅供调试,后台判题数据一般不包含示例

输入

D G G
3 3
F F F
F F H
E F E

 输出

1

解题思路:

try:
    di = input().split() # 方向和移动指令
    size = [int(i) for i in input().split()] 
    dp = []
    snk = []
    A = size[1]
    while A:   # 将画面布局转为列表
        ex = input().split()
        dp.append(ex)
        A -= 1
    for i in dp:  # 寻找蛇初始位置
        if "H" in i:
            sx = i.index("H")
            sy = dp.index(i)
            snk.append(f'dp[{sy}][{sx}]') # 添加蛇的初始位置
            break
    for j in di:
        if j in "UDLR": # 判断指令列表中的方向指令
            k = j  # 保存方向指令
            continue
        elif 0 <= sx < size[0] and 0 <= sy < size[1]: # 根据指令得出移动后的蛇头的位置
            if k == "D":
                sy += 1
            elif k == "U":
                sy -= 1
            elif k == "L":
                sx -= 1
            elif k == "R":
                sx += 1
            if f'dp[{sy}][{sx}]' not in snk: # 判断移动后蛇的位置是否与已经存在的位置重叠(碰头测试)
                if dp[sy][sx] == "F":
                    snk.append(f'dp[{sy}][{sx}]') # 如果是食物 那么食物成为蛇头
                if dp[sy][sx] == "E":
                    snk.append(f'dp[{sy}][{sx}]') # 如果是空格 那么蛇头的位置覆盖空格位置并删除列表中第一个位置(蛇尾)。
                    del(snk[0])
            else: # 碰到自身 游戏结束
                print(len(snk))
                break
    print(len(snk)) # 指令循环完毕 游戏结束
except:
    print(len(snk)) # 碰到边界 游戏结束

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北方肆歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值