Java(龟兔赛跑)

龟兔赛跑要求:

--普通格,共100格   _ _

龟:每次随机移动1至3格
兔子:每次随机移动1至6格

每20格会随机出现以下功能格各一次(不会在同一格内出现两种或两种以上功能)

功能格:(**和^^可以连续执行,@@和==不能连续执行)
1.**幸运星格:选手可再行动一次
2.@@地雷格:兔子回到上数两个地雷格,龟回到上一地雷格(若后方无地雷格则回到起点)
3.==传送格:兔子到达下一传送格,龟到达下数两个传送格(若前方无传送格则到达终点)
4.||树格:兔子停止三次行动
5.^^下坡格:龟前进10格

 

注意:

在此程序中会有以下情况发生数组越界问题

1.随机数会越界
2.传送门、地雷会越界  
3.幸运星会越界  
4.下坡会越界  

 

思考:

首先思考一共需要创建几个类,在思考每个类中有什么

需要的类有:游戏地图类,动物类(里面包括兔子和乌龟共有的方法),兔子类,乌龟类,游戏测试类一共五个类

动物类动物都共有的方法,因此类的方法都需要在子类中重写,所以可以定义为抽象类:

1.兔子和乌龟都能跑

2.兔子和乌龟在地图上都有位置

3.幸运格、地雷格、传送格都是共有的方法,区别则在于具体跳转几个,如果跳转个数大于1则可以多次调用

 

Map

游戏地图

//Map
import java.util.Arrays;

public class Map {
    public String[] getMap(){
        //普通格,共100格
        String[] map = new String[100];
        //每20个格子内含有五个功能格,所以一共有25个功能格   
        //保存方式为二维数组,每一个一维数组保存一种功能格
        int[][] gn = new int[5][5];
        //用于获取25个功能格的辅助数组    创建了100个0
        int[] index = new int[100];
        //向100个格内添加__  普通格子数组初始化
        Arrays.fill(map,"__ ");
        //获取功能格,将100等分为5份,每份长度为20
        for(int i = 0; i < 5; i++){
            //辅助数组初始化,让索引跟数组中的值一致   数组中赋值为0-99
            for(int j = 0+i*20; j < 20+i*20; j++){
                index[j] = j;
            }
            //获取随机数
            for(int k = 0; k < 5; k++){
                int a = (int)(Math.random()*(20-k))+i*20;
                int temp = index[a];
                index[a] = index[19-k+i*20];
                index[19-k+i*20] = temp;
                gn[k][i] = temp;
            }
        }
        //给地图设置五种功能格
        for(int i = 0; i < 5; i++){
            map[gn[0][i]] = "** ";
            map[gn[1][i]] = "@@ ";
            map[gn[2][i]] = "== ";
            map[gn[3][i]] = "|| ";
            map[gn[4][i]] = "^^ ";
        }
        return map;
    }
    //显示地图
    public void showMap(String[] map,Rabbit R,Tortoise T){
        //先复制一个新的地图,为了使兔子和乌龟能显示在新地图上,仅用于输出使用,
        //每一次完事之后地图会销毁也就是原本的地图不会被改动,保持完好
        String[] maps = Arrays.copyOf(map,map.length);
        if(R.position == T.position){
            maps[R.position] = "遇 ";
        }else {
            maps[R.position] = "兔 ";
            maps[T.position] = "龟 ";
        }
        for(int i = 0; i < maps.length; i++){
            if(i%20 == 0){
                System.out.println();
            }
            System.out.print(maps[i]);
        }
        System.out.println();
    }
}

 获取随机数讲解

//获取随机数
for(int k = 0; k < 5; k++){
    int a = (int)(Math.random()*(20-k))+i*20;
    int temp = index[a];
    index[a] = index[19-k+i*20];
    index[19-k+i*20] = temp;
    gn[k][i] = temp;  //图示
}

471488dd39b04a41b757bbf8085824dc.png38aa309cc7964fa780de1ede7f02de25.png

8bd621c157cc4e7ca3e543819d630099.png

随机数随机的是一段连续的数组,不论放大多少倍。

假设有10个数,抽每个数的概率是1/10,剩余数被抽中的概率是1/9,因为不放回的抽取,有一个数已经被抽出去了,以此类推。数据不连续也无所谓,因为是纯随机,数据被抽取的概率不变。每次拿出的数据都是1/数据的个数。

将第一次拿到的数据和最后一个数置换,以保证每次拿到的数据不重复。

控制放大倍数,控制结束,只要放大倍数小于数据个数-1,最后一个数就永远取不到

但需要注意的是:

1.随机数取出的数不能是数组的索引值,也就是随机出来的数不能是最终获得的随机数的索引,可以做一个初始化保证随出来的数据和索引值是一样的

2.随机数的索引值和最后要的数没有关系,例如:第一次要第三个数据的数和第二次要第三个数据的数没有关系,可以随便取,因为只是索引值一样但是里边存的数据不一样

3.最终要的数据一定是里面的值而不是索引

65881dbf7994445c8a06e5774923275b.png

假设第一次拿的是索引为2真实数据为3的数,与最后一个数据置换,再将最后一个数据砍掉,则之后再取就永远都取不到3这个真实的数了

第二次在随机每一个数的概率就为1/9,因为最后一个数已经被砍掉了,即使第二次还取到索引为2的数,可以里面的值也已经改变了,然后再将这次拿到的值与剩余数据的最后一个数进行置换,则这次的数在下次也不会取到,而剩余数据被拿去的概率就变为了1/8,以此类推

随机数随机的值是索引,但真正的值是里面存的数据

 

Animal

动物都共有的方法,因此类的方法都需要在子类中重写,所以可以定义为抽象类

//Animal
//此类中的方法需要全部在子类中重写,所以可以定义为抽象类
public abstract class Animal {
    //初始位置为0  当前位置
    int position = 0;
    //跑的抽象方法,在子类中重写此方法,没有方法体   每次跑的步数
    public abstract int run();
    //功能格的验证  验证当前是不是功能格 传参过来才能验证
    public abstract void function(String[] map,Tortoise T);
    //跑需要在地图上跑  计算跑  地图上的移动
    public void move(String[] map,Tortoise T){
        //位置累加计算
//        position = position + run();
        //判断走完之后的位置是不是功能格,如果是则执行功能格代码
//        function(map,T);

        //改
        if(position < 99){
            position = position + run();
        }else {
            position = 99;
        }
        function(map,T);
    }
    //**幸运星格:选手可再行动一次  再摇一次筛子
    public void star(String[] map,Tortoise T){
        System.out.println("选手可再行动一次");
        move(map,T);
    }
    //@@地雷格:兔子回到上数两个地雷格
    //龟回到上一地雷格(若后方无地雷格则回到起点)  地雷:mine
    public void mine(String[] map) {
        position--;
        while (true) {
            if(position <= 0){
                position = 0;
                break;
            }else if (map[position].equals("@@ ")) {
                break;
            }else {
                position--;
            }
        }
    }
    //==传送格:兔子到达下一传送格
    //龟到达下数两个传送格(若前方无传送格则到达终点)
    public void door(String[] map){
        position++;
        while (true) {
            if(position >= 99){
                position = 99;
                break;
            }else if (map[position].equals("== ")) {
                break;
            }else {
                position++;
            }
        }
    }
}

 

Rabbit

兔子独有的方法

//Rabbit
public class Rabbit extends Animal {
    @Override
    public int run() {
        //放大六倍是0-5 +1是1-6  左闭右开  [0,6)   [1,7)
        int pace =(int)(Math.random()*6)+1;
        System.out.println("兔子走了"+pace+"步");
        return pace;
    }

    @Override
    public void function(String[] map,Tortoise T) {
        if(position < 99){
            if(map[position].equals("** ")){
                System.out.println("兔子遇到幸运星了");
                star(map,T); //调方法
            }else if(map[position].equals("== ")){
                System.out.println("兔子遇到传送门了");
                door(map);
            }else if(map[position].equals("@@ ")){
                System.out.println("兔子遇到地雷了");
                mine(map);
                mine(map);//遇见返回两个 调两次  兔子回到上数两个地雷格
            }else if(map[position].equals("|| ")){
                System.out.println("兔子遇到了树格,停三次");  //兔子停三次,乌龟走三次
                T.move(map, T);  //T对象中有一个跑 调的移动
                T.move(map, T);
                T.move(map, T);
            }
        }else {
            position = 99;
        }
    }
}

 

Tortoise

乌龟独有的方法

//Tortoise
public class Tortoise extends Animal{
    @Override
    public int run() {
        int pace =(int)(Math.random()*3)+1;
//        System.out.println("乌龟走了"+pace+"步");
        while (position < 99) {
            if(position >= 99){
                position = 99;
                break;
            }
//            int pace = (int)(Math.random() * 3) + 1;
            position++;
        }
        System.out.println("乌龟走了"+pace+"步");
        return pace;
    }

    @Override
    public void function(String[] map, Tortoise T) {
        if(position < 99){
            if(map[position].equals("** ")){
                System.out.println("乌龟遇到幸运星了");
                star(map,T); //调方法
            }else if(map[position].equals("== ")){
                System.out.println("乌龟遇到传送门了");
                door(map);
                door(map);
            }else if(map[position].equals("@@ ")){
                System.out.println("乌龟遇到地雷了");
                mine(map);
            }else if(map[position].equals("^^ ")){
                System.out.println("乌龟遇到了下坡,前进十格");  //兔子停三次,乌龟走三次
                position = position + 10;
                function(map, T);  //验证是否为功能格
            }
        }else if(position >= 99){
            position = 99;
        }
    }
}

 

Game

游戏测试类

//Game
public class Game {
    public static void main(String[] args) {
        //获取生成的游戏底图
//        String[] map = new Map().getMap();
        Map map = new Map();
        String[] m = map.getMap();
        //创建两个对象 游戏角色兔子和乌龟
        Rabbit R = new Rabbit();
        Tortoise T = new Tortoise();
        String maps[]=m;//将map的信息用maps记录下来,后面的地图就在maps的基础上改变
        //输出地图
//        for(int i = 0; i<m.length; i++){
//            if(i%20==0){
//                System.out.println();
//            }
//            System.out.print(m[i]);
//        }
//        System.out.println();
        map.showMap(maps,R,T);
        while (R.position < 99 && T.position < 99){  //位置表示索引位置
            R.move(maps,T);
            T.move(maps,T);
            //判断越界问题 如果越界了让其等于99就到终点了
//            if(R.position > 99 && T.position > 99){
//                R.position = 99;
//                T.position = 99;
//            }else if(R.position > 99){
//                R.position = 99;
//            }else if(T.position > 99){
//                T.position = 99;
//            }
            //或者
            if(R.position > 99){
                R.position = 99;
            }
            if(T.position > 99){
                T.position = 99;
            }
            map.showMap(maps,R,T);
        }
        if(R.position >= 99 && T.position >= 99){
            System.out.println("平局");
        }else if(R.position >= 99){
            System.out.println("兔子赢了");
        }else {
            System.out.println("乌龟赢了");
        }
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值