当前位置: 首页 > news >正文

【华为校招】【校招】【Java】【模拟】贪吃蛇

■ 题目描述
贪吃蛇是一个经典游戏,蛇的身体由若干方格连接而成,身体随蛇头移动。蛇头触碰到食物时,蛇的长度会增加一格。
蛇头和身体的任一方格或者游戏版图边界碰撞时,游戏结束。
下面让我们来完成贪吃蛇游戏的模拟。
给定一个NM的数组arr,代表NM个方格组成的版图,贪吃蛇每次移动一个方格。
若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
地图表示为:
蛇头 H(Head)
食物 F(Food)
E表示该方格为空
四个方向分别表示为:
向上 U(up)
向下 D(down)
向左 L(Left)
向右 R(Right)

public class SnakeGame {

    private static int m,n;
    private int maxLen;
    private Deque<int[]> visited;
    public int getBodyLength(String[] operation,String[][] grids,int x,int y){
        maxLen = 1;
        // 0表示向上 1表示下 2表示向左 3表示向右
        int direction = 0;
        visited = new ArrayDeque<>();
        visited.add(new int[]{x,y});
        for (int i=0;i<operation.length;i++){
            if ("U".equals(operation[i])){
                direction = 0;
            }else if ("D".equals(operation[i])){
                direction = 1;
            }else if ("L".equals(operation[i])){
                direction = 2;
            }else if ("R".equals(operation[i])){
                direction = 3;
            }else if ("G".equals(operation[i])){
                if (direction==0){
                    // 向上
                    int newX = x-1;
                    if (isGameOver(newX,y,grids)){
                        calculate(x,y,newX,y,grids);
                    }else {
                        break;
                    }
                    x = newX;
                }else if (direction==1){
                    // 向下
                    int newX = x+1;
                    if (isGameOver(newX,y,grids)){
                        calculate(x,y,newX,y,grids);
                    }else {
                        break;
                    }
                    x = newX;
                }else if (direction==2){
                    // 向左
                    int newY = y-1;
                    if (isGameOver(x,newY,grids)){
                        calculate(x,y,x,newY,grids);
                    }else {
                        break;
                    }
                    y = newY;
                }else {
                    // 向右
                    int newY = y+1;
                    if (isGameOver(x,newY,grids)){
                        calculate(x,y,x,newY,grids);
                    }else {
                        break;
                    }
                    y = newY;
                }
            }
        }
        return maxLen;
    }

    private void calculate(int x,int y,int newX,int newY,String[][] grids){
        if ("F".equals(grids[newX][newY])){
            grids[x][y] = "1";
            x = newX;
            y = newY;
            grids[x][y] = "H";
            visited.offer(new int[]{x,y});
            maxLen++;
        }else if ("E".equals(grids[x][newY])){
            if (!visited.isEmpty()){
                int[] last = visited.poll();
                int lastX = last[0];
                int lastY = last[1];
                grids[lastX][lastY] = "E";
                x = newX;
                y = newY;
                grids[x][y] = "H";
            }
        }
    }

    private boolean isGameOver(int i,int j,String[][] grids){
        // 边界+碰到身体
        return i<0||i>=m||j<0||j>=n||grids[i][j].equals("1");
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] operations = sc.nextLine().split(" ");
        m = sc.nextInt();
        n = sc.nextInt();
        String[][] grids = new String[m][n];
        sc.nextLine();
        int x=0;
        int y =0;
        for (int i=0;i<m;i++){
            String[] grid = sc.nextLine().split(" ");
            for (int j=0;j<n;j++){
                if (grid[j].equals("H")){
                    x = i;
                    y = j;
                }
                grids[i][j] = grid[j];
            }
        }
        int ans = new SnakeGame().getBodyLength(operations,grids,x,y);
        System.out.println(ans);
    }
}

相关文章:

  • 字节跳动校招——运维工程师-系统架构岗位面经分享
  • 自动控制原理9.4---李雅普诺夫稳定性分析
  • Java中的多线程概述、多线程实现、线程类常见的方法与线程安全问题详细使用(多线程上篇含Lock锁同步方法同步代码块)
  • MySQL数据库必会的增删查改操作(CRUD)
  • maven常用插件详解
  • 【JavaScript-事件②】表单元素的属性操作,密码显示隐藏的实现
  • 猿创征文 | 万字总结C文件
  • 【微信小程序入门到精通】— AppID和个性配置你学会了么?
  • 【Luogu P6902】[ICPC2014 WF] Surveillance(倍增,贪心)
  • 第一章 Java概述
  • c++的多态和虚函数
  • 第一章:Java第一阶段
  • 【iOS】MVC模式
  • 处理器美之华大170处理器
  • AX=0和AX=b的解向量线性相关吗?
  • [译]前端离线指南(上)
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 2017-08-04 前端日报
  • Android 控件背景颜色处理
  • iOS | NSProxy
  • js面向对象
  • linux安装openssl、swoole等扩展的具体步骤
  • - 概述 - 《设计模式(极简c++版)》
  • 前端之React实战:创建跨平台的项目架构
  • 容器服务kubernetes弹性伸缩高级用法
  • 如何合理的规划jvm性能调优
  • 实现简单的正则表达式引擎
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 由插件封装引出的一丢丢思考
  • 整理一些计算机基础知识!
  • !!java web学习笔记(一到五)
  • #define用法
  • #Z2294. 打印树的直径
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (二十四)Flask之flask-session组件
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (蓝桥杯每日一题)love
  • (五)MySQL的备份及恢复
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转) ns2/nam与nam实现相关的文件
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .htaccess配置常用技巧
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net 调用php,php 调用.net com组件 --
  • .net 流——流的类型体系简单介绍
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .ui文件相关
  • /etc/skel 目录作用
  • ::before和::after 常见的用法
  • @Autowired和@Resource的区别