请老师检查!

请老师检查!

请老师检查!

目标:

打怪兽游戏的日志,日志分为两类,包括用户日志和怪兽日志。

  • 当用户登录游戏、操作游戏发起攻击、闪躲与加血操作,会记录到用户日志中。

  • 当怪兽的发起攻击、闪躲、加血与用户攻击怪兽时,记录在怪兽日志中。


1.发送类Test

package topic_hw;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;

/**
 *  用于发送消息
 */
public class Test {
    private static final String EXCHANGE_NAME = "topic_hw_logs";         // 给交换机起个名儿
    // 实例方法1:
    private static void loginList(){
        System.out.println("********* 欢迎来小怪物游戏中心 **********");
        System.out.println("*********   请先您的操作  **************");
        System.out.println("*********   1.登陆  *******************");
        System.out.println("*********   2.开启游戏  ****************");
        System.out.println("*********   0.退出  *******************");
        System.out.println("请输入对应数字进行操作:");
    }
    // 实例方法2:
    private static void gameList(){
        System.out.println("*********   游戏开始     ***************");
        System.out.println("*********   1.用户发起攻击  *************");
        System.out.println("*********   2.开启闪躲   ***************");
        System.out.println("*********   3.用户加血   ****************");
        System.out.println("*********   4.怪兽发起攻击  **************");
        System.out.println("*********   5.怪兽闪躲   ****************");
        System.out.println("*********   6.怪兽加血   ****************");
        System.out.println("*********   0.结束游戏   ****************");
        System.out.println("请输入对应数字进行操作:");
    }

    // 主方法
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2.设置RabbitMQ地址
        factory.setHost("121.199.31.220");              // 填入ip地址,即之前安装了MQ的阿里云服务器的实例
        factory.setUsername("admin");
        factory.setPassword("password");
        // 3.建立连接
        Connection connection = factory.newConnection();        // 通过连接工厂,建立连接
        // 4.获得信道
        Channel channel = connection.createChannel();           // 通过连接,建立信道
        // 5.声明定义一个topic类型的交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);  // 通过信道,声明交换机
        // 6.把消息发送到交换机上
        String message = "Animal World";
        // 7.建立String类型的数组,模拟需要发出很多类型的消息:10个路由键
        String[] routingKeys1 = new String[3];
        routingKeys1[1] = "user.login.success";
        routingKeys1[2] = "user.start.success";
        routingKeys1[0] = "user.exit.success";

        String[] routingKeys2 = new String[7];
        routingKeys2[1] = "user.attack.monster";
        routingKeys2[2] = "user.dodge";
        routingKeys2[3] = "user.add.blood";
        routingKeys2[4] = "monster.attack.user";
        routingKeys2[5] = "monster.dodge";
        routingKeys2[6] = "monster.add.blood";
        routingKeys2[0] = "end.game";
        // 8.主要程序逻辑,当输入对应的数字时,模拟向交换机发布消息
        Scanner sc=new Scanner(System.in);
        while(true) {                 // 只要用户不选0手动退出,就永远为true,一直循环、让你进行反复选择操作
            Test.loginList();           // 调用显示用户菜单方法

            int input;
            try {
                input=sc.nextInt();         // 将用户输入的数字,保存进input变量中
            }catch(InputMismatchException e) {
                System.out.println("输入格式有误,不能输入非数字!");
                sc.next();                         // 将异常的用户输入数据,装进垃圾桶
                continue;                          // 本次循环作废,重新下一次while循环
            }

            if(input==0) {                   // 注意1:退出程序(循环)的if分支,是在while循环里面!
                System.out.println("退出程序!");
                channel.basicPublish(EXCHANGE_NAME, routingKeys1[input], null, message.getBytes("UTF-8"));
                break;                      // 把本级的全部中断:把while全部中断
            }

            switch (input) {                        // 注意2:switch分支结构,也是在while循环里面!
                case 1:
                    System.out.println("登陆成功,可以开始游戏了哦~");
                    channel.basicPublish(EXCHANGE_NAME, routingKeys1[input], null, message.getBytes("UTF-8"));
                    break;                      // 把本级的全部中断:switch结构
                case 2:
                    channel.basicPublish(EXCHANGE_NAME, routingKeys1[input], null, message.getBytes("UTF-8"));
                    while (true) {                  // 注意3:switch分支结构中,还嵌套了一个while循环
                        Test.gameList();
                        int input2;
                        try {
                            input2=sc.nextInt();
                        }catch(InputMismatchException e) {
                            System.out.println("输入格式有误,不能输入非数字!");
                            sc.next();                         // 将异常的用户输入数据,装进垃圾桶
                            continue;                          // 本次循环作废,重新下一次while循环
                        }

                        if(input2==0) {
                            System.out.println("结束游戏");
                            channel.basicPublish(EXCHANGE_NAME, routingKeys2[input], null, message.getBytes("UTF-8"));
                            break;                      // 把本级的全部中断:把while全部中断
                        }

                        switch (input2) {
                            case 1:
                                channel.basicPublish(EXCHANGE_NAME, routingKeys2[input2], null, message.getBytes("UTF-8"));
                                System.out.println("用户发起攻击");
                                break;
                            case 2:
                                channel.basicPublish(EXCHANGE_NAME, routingKeys2[input2], null, message.getBytes("UTF-8"));
                                System.out.println("用户闪躲");
                                break;
                            case 3:
                                channel.basicPublish(EXCHANGE_NAME, routingKeys2[input2], null, message.getBytes("UTF-8"));
                                System.out.println("用户加血");
                                break;
                            case 4:
                                channel.basicPublish(EXCHANGE_NAME, routingKeys2[input2], null, message.getBytes("UTF-8"));
                                System.out.println("怪兽发起攻击");
                                break;
                            case 5:
                                channel.basicPublish(EXCHANGE_NAME, routingKeys2[input2], null, message.getBytes("UTF-8"));
                                System.out.println("怪兽闪躲");
                                break;
                            case 6:
                                channel.basicPublish(EXCHANGE_NAME, routingKeys2[input2], null, message.getBytes("UTF-8"));
                                System.out.println("怪兽加血");
                                break;
                        }

                    }
            }
            }
        // 关闭连接
        channel.close();
        connection.close();
    }

}

2.接受类1UserLogsTopic

package topic_hw;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;


public class UserLogsTopic {

    private static final String EXCHANGE_NAME = "topic_hw_logs";         // 给交换机起个名儿

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2.设置RabbitMQ的地址、连接用户
        factory.setHost("121.199.31.220");              // 填入ip地址,即之前安装了MQ的阿里云服务器的实例
        factory.setUsername("admin");
        factory.setPassword("password");
        // 3.建立连接
        Connection connection = factory.newConnection();
        // 4.获得信道
        Channel channel = connection.createChannel();
        // 5.声明定义一个topic类型的交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
        // 6.声明一个随机的临时队列(非持久的、能自动删除的队列)
        String queueName = channel.queueDeclare().getQueue();
        // 7.声明一个路由键
        String routingKey = "user.login.*";
        // 7.5 将上述的临时队列、路由键,绑定到1个交换机上
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey);

        String routingKey1 = "user.attack.*";
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey1);

        String routingKey2 = "user.dodge";
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey2);

        String routingKey3 = "user.add.*";
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey3);
        // 8.接收消息
        System.out.println("[*] Waiting for messages.To exit press CTRL+C");
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");         // 将字符转换为字符串
                System.out.println("[x] Received " + "'" + envelope.getRoutingKey() + "'" + ":" + "'" + message + "'");
            }
        };
        // 9.进行消息的消费
        channel.basicConsume(queueName, true, consumer);
    }
}


3.接受类2BossLogsTopic

package topic_hw;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;


public class BossLogsTopic {

    private static final String EXCHANGE_NAME = "topic_hw_logs";         // 给交换机起个名儿

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2.设置RabbitMQ的地址、连接用户
        factory.setHost("121.199.31.220");              // 填入ip地址,即之前安装了MQ的阿里云服务器的实例
        factory.setUsername("admin");
        factory.setPassword("password");
        // 3.建立连接
        Connection connection = factory.newConnection();
        // 4.获得信道
        Channel channel = connection.createChannel();
        // 5.声明定义一个topic类型的交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
        // 6.声明一个随机的临时队列(非持久的、能自动删除的队列)
        String queueName = channel.queueDeclare().getQueue();
        // 7.声明一个路由键
        String routingKey = "user.attack.monster";
        // 7.5 将上述的临时队列、路由键,绑定到1个交换机上
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey);

        String routingKey1 = "monster.attack.*";
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey1);

        String routingKey2 = "monster.dodge";
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey2);

        String routingKey3 = "monster.add.*";
        channel.queueBind(queueName, EXCHANGE_NAME, routingKey3);

        // 8.接收消息
        System.out.println("[*] Waiting for messages.To exit press CTRL+C");
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");         // 将字符转换为字符串
                System.out.println("[x] Received " + "'" + envelope.getRoutingKey() + "'" + ":" + "'" + message + "'");
            }
        };
        // 9.进行消息的消费
        channel.basicConsume(queueName, true, consumer);
    }

}


4. 结果

发送类

 ********* 欢迎来小怪物游戏中心 **********
 *********   请先您的操作  **************
 *********   1.登陆  *******************
 *********   2.开启游戏  ****************
 *********   0.退出  *******************
 请输入对应数字进行操作:
 1
 登陆成功,可以开始游戏了哦~
 ********* 欢迎来小怪物游戏中心 **********
 *********   请先您的操作  **************
 *********   1.登陆  *******************
 *********   2.开启游戏  ****************
 *********   0.退出  *******************
 请输入对应数字进行操作:
 2
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 1
 用户发起攻击
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 2
 用户闪躲
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 3
 用户加血
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 4
 怪兽发起攻击
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 5
 怪兽闪躲
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 6
 怪兽加血
 *********   游戏开始     ***************
 *********   1.用户发起攻击  *************
 *********   2.开启闪躲   ***************
 *********   3.用户加血   ****************
 *********   4.怪兽发起攻击  **************
 *********   5.怪兽闪躲   ****************
 *********   6.怪兽加血   ****************
 *********   0.结束游戏   ****************
 请输入对应数字进行操作:
 0
 结束游戏
 ********* 欢迎来小怪物游戏中心 **********
 *********   请先您的操作  **************
 *********   1.登陆  *******************
 *********   2.开启游戏  ****************
 *********   0.退出  *******************
 请输入对应数字进行操作:
 0
 退出程序!
 
 Process finished with exit code 0
 


接受类1UserLogsTopic

[*] Waiting for messages.To exit press CTRL+C
[x] Received 'user.login.success':'Animal World'
[x] Received 'user.attack.monster':'Animal World'
[x] Received 'user.dodge':'Animal World'
[x] Received 'user.add.blood':'Animal World'
[x] Received 'user.dodge':'Animal World'

接受类2BossLogsTopic

[*] Waiting for messages.To exit press CTRL+C
[x] Received 'user.attack.monster':'Animal World'
[x] Received 'monster.attack.user':'Animal World'
[x] Received 'monster.dodge':'Animal World'
[x] Received 'monster.add.blood':'Animal World'



正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好,已完成练习,代码实现符合题目要求,很棒!继续加油!

祝学习愉快~

  • Jerry_Zheng24 提问者 #1

    老师,

    1. 请问你是否真的执行了上述代码?

    2. 对于上述发送类Test,我用的是嵌套循环的结构,关于这个类有哪些优化点呢?

    谢谢!:)

    2023-01-17 23:20:44
  • 好帮手慕小小 回复 提问者 Jerry_Zheng24 #2

    同学你好

    1. 程序测试是可以正确运行且符合题目要求的,同学是对哪部分代码有疑问呢,可以在问答区圈出疑问代码。测试结果如下:

      https://img1.sycdn.imooc.com//climg/63c75a02096e38e410991036.jpg

    2. 程序开发中是可以使用嵌套循环的,合理使用嵌套循环可使得程序逻辑更加清晰,不过需要注意的是循环不宜嵌套过多,嵌套过多会降低程序性能。

    祝学习愉快~

    2023-01-18 11:40:49
  • Jerry_Zheng24 提问者 回复 好帮手慕小小 #3

    学习愉快,感谢!~

    2023-01-18 14:20:16
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师