策略模式实战 - 猜拳游戏
**可以整体的替换一套算法,这就是策略模式。**这样对于同一个问题,可以有多种解决方案——算法实现的时候,可以通过策略模式来非常方便的进行算法的整体替换,而各种算法是独立封装好的,不用修改其内部逻辑。
具体的实战,下面给出一个经典案例——“猜拳游戏”。该示例来自于【日】结城浩的《图解设计模式》,策略算法做了一些简化调整。
“石头剪刀布”的游戏每轮出什么样的手势,可以遵循一定的策略。比如可以按照下面两种策略来出手势:
- 看上一轮自己出的手势,如果赢了,继续用上一轮出的手势;否则出任意的手势
- 看上一轮对方出的手势
- 如果赢了,就出和上一轮不一样的手势;
- 如果上一轮平了(比如出的剪刀),本轮就出石头;
- 如果上一轮输了,本轮就出上一轮和对方一样的手势
文章目录
- 整体类图设计
- 出手势策略接口
- 手势类
- 玩家类
- 策略实现类
- 测试类
整体类图设计
出手势策略接口
因此抽象出一个出手势的策略接口:
/*** Java小卷带你轻松高效学编程,一对一辅导加q1372569394*/
package com.juan.java.designpattern.strategy;/**** @author Java小卷* @date 2024-12-04 14:16* @since 1.0*/
public interface Strategy {/*** 下一回合出手势的方法* @author Java小卷* @date 2024/12/5 14:04* @return 出的手势* @since 1.0*/Hand nextHand();/*** 仔细考虑上一轮的结果,作为下一轮出手势的策略的依据* @author Java小卷* @date 2024/12/5 14:07* @param result 上一轮的结果 0-打平 1-胜 -1-负* @param other 上一轮对方的手势* @since 1.0*/void study(int result, Hand other);}
手势类
封装了手势具体信息和比手势的方法。
这里会维护3个公开的静态常量来分别维护“石头、剪刀、布”的手势数值。
/** 出的石头 */
public static final int HANDVALUE_STONE = 0;
/** 出的剪刀 */
public static final int HANDVALUE_SCISSORS = 1;
/** 出的布 */
public static final int HANDVALUE_PAPER = 2;
为方便对三种手势对象的获取,这里的手势值和三种手势对象的数组的索引值保持一致。
在Hand
类中维护一个私有的静态数组常量,初始化3个手势对象:
/** 初始化三种手势:石头、剪刀、布 */
private static final Hand[] HANDS = {new Hand(HANDVALUE_STONE),new Hand(HANDVALUE_SCISSORS),new Hand(HANDVALUE_PAPER)
};
同时维护一个对应手势名称的静态数组常量:
/** 描述出的手势的名称数组 */
private static final String[] HAND_NAMES = {"石头", "剪刀", "布"};
提供一个代表所出的手势值的成员变量,并提供相应的构造方法完成其初始化,注意Hand
类不能在外部实例化,只能在内部维护,因此用private
修饰:
/** 出的当前手势值 */
private final int handValue;/** 私有的带有手势值的构造 */
private Hand(int handValue) {this.handValue = handValue;
}
提供几个获取手势信息的方法:
/*** 根据手势值获取对应的手势对象* @param handValue 手势值* @return 对应的手势对象*/
public static Hand getHand(int handValue) {return HANDS[handValue];
}/*** 返回当前实例的手势名称* @author Java小卷* @date 2024/12/4 10:57* @return 手势名称* @since 1.0
*/
@Override
public String toString() {return HAND_NAMES[handValue];
}/*** 获取手势数值* @author Java小卷* @date 2024/12/5 15:14* @return int 手势数值* @since 1.0
*/
public int getHandValue() {return handValue;
}
提供比较手势的方法
/*** 手势对战方法* @author Java小卷* @date 2024/12/4 10:42* @param hand 对方出的手势* @return int 0-平局 1-胜 -1-负* @since 1.0
*/
private int fight(Hand hand) {// 自身比较无意义,但这里也记为平局if (this == hand) {return 0;} else if ((this.handValue + 1) % 3 == hand.handValue) {// 游戏规则:石头>剪刀>布>石头// 因此,只要按照数组的顺序,当前手势的下一个元素与对方手势相等,就认为自己赢了return 1;} else {// 其他情况都是判负return -1;}
}/*** 对外提供的判断赢了方法* @author Java小卷* @date 2024/12/4 10:55* @param hand 对方手势* @return boolean* @since 1.0
*/
public boolean isStrongThan(Hand hand) {return this.fight(hand) == 1;
}
玩家类
Player
类在策略模式的类设计中,作为Context
,由它负责设置和切换策略并调用策略的行为。
该玩家类除了name
、strategy
属性外,还包含了全局的状态信息(比赛总轮数、胜的轮数、败的轮数)。另外提供了调用策略对象完成出手势的方法以及对一轮比赛结果处理的方法。
策略实现类
正如前面一开始介绍的出手势的两种实现策略,这里提供两种具体的实现:
/*** Java小卷带你轻松高效学编程,一对一辅导加q1372569394*/
package com.juan.java.designpattern.strategy.impl;import .../**** @author Java小卷* @date 2024-12-04 14:21* @since 1.0*/
public class WinningStrategy implements Strategy {private final Random random;private int prevResult;private Hand prevHand;public WinningStrategy() {random = new Random();}@Overridepublic Hand nextHand() {// 前一轮不胜,则随意出if (prevResult != 1) {prevHand = Hand.getHand(random.nextInt(3));}// 否则出上一轮的手势return prevHand;}@Overridepublic void study(int result, Hand other) {this.prevResult = result;}
}
/*** Java小卷带你轻松高效学编程,一对一辅导加q1372569394*/
package com.juan.java.designpattern.strategy.impl;import .../**** @author Java小卷* @date 2024-12-04 15:38* @since 1.0*/
public class SmartStrategy implements Strategy {private final Random random;private int prevResult = 1;private Hand prevOtherHand;public SmartStrategy() {this.random = new Random();}@Overridepublic Hand nextHand() {// 如果前一轮平,则出比它大的if (prevResult == 0) {return Hand.getHand(Math.floorMod(prevOtherHand.getHandValue() - 1, 3));} else if (prevResult == -1) {// 输了则出和对方一样的return Hand.getHand(prevOtherHand.getHandValue());} else {// 赢了,则出不一样的if (prevOtherHand == null) {return Hand.getHand(random.nextInt(3));} else {Hand prevHand = Hand.getHand(Math.floorMod(prevOtherHand.getHandValue() - 1, 3));// 出和prevHand不一样的随机手势return Hand.getHand(Math.floorMod(prevHand.getHandValue() + random.nextInt(2) + 1, 3));}}}@Overridepublic void study(int result, Hand other) {this.prevResult = result;this.prevOtherHand = other;}
}
测试类
/*** Java小卷带你轻松高效学编程,一对一辅导加q1372569394*/
package com.juan.java.designpattern.strategy;import .../**** @author Java小卷* @date 2024-12-04 14:46* @since 1.0*/
public class Main {public static void main(String[] args) {Player player1 = new Player("糖宝", new WinningStrategy());Player player2 = new Player("小卷", new SmartStrategy());// 比赛10轮for (int i = 0; i < 10; i++) {Hand hand1 = player1.nextHand();Hand hand2 = player2.nextHand();if (hand1.isStrongThan(hand2)) {System.out.println("胜者: " + player1);player1.win(hand2);player2.lose(hand1);} else if (hand2.isStrongThan(hand1)) {System.out.println("胜者: " + player2);player2.win(hand1);player1.lose(hand2);} else {System.out.println("打平...");player1.even(hand2);player2.even(hand1);}}System.out.println("最终结果:");System.out.println(player1);System.out.println(player2);}}
程序输出:
相关文章:
策略模式实战 - 猜拳游戏
**可以整体的替换一套算法,这就是策略模式。**这样对于同一个问题,可以有多种解决方案——算法实现的时候,可以通过策略模式来非常方便的进行算法的整体替换,而各种算法是独立封装好的,不用修改其内部逻辑。 具体的实…...
VoCo-LLaMA: Towards Vision Compression with Large Language Models
视觉语言模型在各种多模态任务上取得了显著的成功,但经常受到有限上下文窗口和处理高分辨率图像输入和视频的高计算成本的瓶颈。视觉压缩可以通过减少视觉令牌数量避免该问题。先前方法使用额外模块压缩视觉令牌并强制LLM理解压缩的令牌。然而,LLM对视觉…...
每日小知识
Kafka是一个分布式流平台,具有高性能、高可靠性和可扩展性的特点。它主要用于处理实时的数据流,将数据以高吞吐量的方式进行发布和订阅。以下是关于Kafka的几个基本概念和优势的介绍: 概念: 生产者(Producer…...
Linux其二设置端口号,静态ip以及命令
目录 1、VI编辑器 【linux版本的文本文件】 2) 补充的vi编辑器的其他内容(了解) 2、ln 连接的意思 link的缩写 3、文件的查看 【重点】 4、压缩与解压(重点) 5、find 查找命令 6、which & whereis 作用是一样的,表示某…...
吉林大学23级数据结构上机实验(第7周)
A 去火车站 寒假到了,小明准备坐火车回老家,现在他从学校出发去火车站,CC市去火车站有两种方式:轻轨和公交车。小明为了省钱,准备主要以乘坐公交为主。CC市还有一项优惠政策,持学生证可以免费乘坐一站轻轨&…...
SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)
文章目录 1.整合MyBatis 1.需求分析2.数据库表设计3.数据库环境配置 1.新建maven项目2.pom.xml 引入依赖3.application.yml 配置数据源4.Application.java 编写启动类5.测试6.配置类切换druid数据源7.测试数据源是否成功切换 4.Mybatis基础配置 1.编写映射表的bean2.MonsterMap…...
【2024最新】基于Springboot+Vue的网上图书商城平台Lw+PPT
作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...
JAVA-面向对象基础
文章目录 概要封装多态抽象类接口内部类为什么需要内部类 概要 面向对象是一种编程范式或设计哲学,它将软件系统设计为由多个对象组成,这些对象通过特定的方式相互作用 封装 将数据和操作数据的方法封装在一个类中,并通过访问修饰符控制对…...
Y3编辑器官方文档1:编辑器简介及菜单栏详解(文件、编辑、窗口、细节、调试)
文章目录 一、新建项目二、 编辑器主界面2.1 游戏场景2.2 导航栏/菜单栏2.3 功能栏三、菜单栏详细介绍3.1 文件3.1.1 版本管理3.1.2 项目管理(多关卡)3.1.2.1 多关卡功能说明3.1.2.2 关卡切换与关卡存档3.2 编辑3.2.1 通用设置3.2.2 键位设置3.3 窗口(日志)3.4 细节3.4.1 语言…...
力扣94题:二叉树的中序遍历
力扣94题:二叉树的中序遍历(C语言实现详解) 题目描述 给定一个二叉树的根节点 root ,返回它的中序遍历(Inorder Traversal)。 中序遍历的规则是: 先访问左子树;再访问根节点&…...
【数据结构】二叉树的性质和存储结构
性质 在二叉树的第i层上至多有2^{i-1}个结点,至少有1个结点 深度为k的二叉树至多有2^{k-1}个结点(k≥1),至少有k个结点 对任何一棵二叉树T,如果其叶子数为n0,度为2的结点数为n2,则n0n21 具有n个结点的完…...
【Spring项目】图书管理系统
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:项目实现准备 1:需求 (1)登录 2:准备…...
TCP编程案例
笔记:(本题可能需要的) TCP协议: TCP协议进行通信的两个应用进程:客户端、服务端。 使用TCP协议前,须先建立TCP连接,形成基于字节流的传输数据通道 传输前,采用“三次握手”方式…...
PyTorch 实现动态输入
使用 PyTorch 实现动态输入:支持训练和推理输入维度不一致的 CNN 和 LSTM/GRU 模型 在深度学习中,处理不同大小的输入数据是一个常见的挑战。许多实际应用需要模型能够灵活地处理可变长度的输入。本文将介绍如何使用 PyTorch 实现支持动态输入的 CNN 和…...
网络数据库
创建删除修改模式create schemadrop schema表create tabledrop tablealter table视图create view drop view索引create indexdrop index alter index 定义模式:create schema 《模式名》 authorization 《用户名》表定义语句 视图定义语句 授权定义语句//未指…...
【软考速通笔记】系统架构设计师⑲——专业英语
文章目录 一、前言二、常用名词三、架构风格四、非功能需求五、应用架构六、软件架构重用 一、前言 笔记目录大纲请查阅:【软考速通笔记】系统架构设计师——导读 二、常用名词 名词翻译architecture架构system系统design设计requirements需求components组件constr…...
Android APP自学笔记
摘抄于大学期间记录在QQ空间的一篇自学笔记,当前清理空间,本来想直接删除掉的,但是感觉有些舍不得,因此先搬移过来。 Android导入已有外部数据库 2015.06.26在QQ空间记录:在Android中不能直接打开res aw目录中的数据…...
Spring 事务和事务传播机制
Spring 事务和事务传播机制 一、Spring 事务的基本概念 事务是一组操作,被视为一个不可分割的工作单元,要么全部完成,要么全部失败回滚,以此来确保数据的一致性和完整性。Spring事务管理允许我们在应用程序中声明式地或编程式地…...
VSCode(四)CMake调试
1. 工具准备 1.1 C环境插件 1.2 CMake插件 2. Cmake工程 2.1 创建项目文件夹 ex:CMAKE_TEST 2.2 创建CMake工程 (shift ctl P), 选择"CMAKE: Quick Start": 2.3 填写project name: (ex: test_cmake) 2.4 选择”Executable“ 项目文件内会自动…...
创建存储过程
在student数据库中,创建一个名为ST_CHAXUN_01的存储过程,该存储过程返回计算机系学生的“姓名”、“性别”、“出生日期”信息。 操作步骤如下: ① 在“对象资源管理器”窗格中,展开“数据库”结点。 ② 单击相应的数据库&#…...
macOS 15.1.1 (24B2091) 系统中快捷键符号及其代表的按键的对照表
以下是 macOS 15.1.1 (24B2091) 系统中快捷键符号及其代表的按键的对照表: 符号按键名称描述⌘Command (Cmd)常用的功能键,用于执行大多数快捷操作。⌥Option (Alt)Option 键,常用于辅助操作和特殊字符输入。⇧ShiftShift 键,常用…...
ftp服务器搭建-安装、配置及验证
ftp服务器搭建-安装、配置及验证 #安装 sudo apt-get install vsftpd #配置文件 cat > /etc/vsftpd.conf << "EOF" listenNO listen_ipv6YES anonymous_enableNO local_enableYES write_enableYES dirmessage_enableYES use_localtimeYES xferlog_enable…...
windows ping 执行过程分析
控制台 PS C:\Users\Admin> ping mcs.zijieapi.com正在 Ping mcs.zijieapi.com [223.109.117.226] 具有 32 字节的数据: 来自 223.109.117.226 的回复: 字节32 时间31ms TTL49 来自 223.109.117.226 的回复: 字节32 时间30ms TTL49 来自 223.109.117.226 的回复: 字节32 时…...
强大的远程同步工具-rsync
rsync 强大的远程同步工具,也可用于本地目录和本地目录的同步,它最大的特点就是会自动判断进行增量同步; # “演示文档”后加了/,代表传输的是文件,建议destination也指定一个目录,该目录可以不存在&…...
蝉联第一 | IDC云系统软件市场报告2024H1,云轴科技ZStack独立云厂商第一
2024年12月,根据全球知名的IT市场研究和咨询公司IDC最新发布的《中国云系统软件市场跟踪报告2024H1》显示,2024年上半年中国云系统软件市场规模达到27.93亿元人民币,同比增长11.6%。在这一增长趋势中,云轴科技ZStack作为云系统软件…...
【IPV6改造解读】
座右铭:我们每一个心怀希望的人,就像是一颗种子一样! 文章目录 前言一、IPV6改造基本情况分析二、IPV6针对不同场景改造方案1.网站/APP场景-IPV6云网关升级改造方案2.局域网专网(互联网侧)场景-安全大脑IPV6改造方案 总结 前言 提示…...
常用的Kali命令Top10
Kali Linux是一种基于Debian的Linux发行版,被广泛用于渗透测试和网络安全。以下是一些常用的Kali Linux命令的详细解释: ifconfig:显示和配置网络接口的信息。可以用于查看当前系统的IP地址、网关和子网掩码等。 apt-get:用于安装…...
阿里巴巴正式发布了全新大型语言模型Marco-o1
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
【AI日记】24.12.07 kaggle 比赛 Titanic-10
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 内容: 学习 kaggle 入门比赛 Titanic - Machine Learning from Disaster学习机器学习(pandas,numpy,sklearn,seaborn,matplotlib&a…...
《QT 示例宝库:探索丰富的编程世界》
《QT 示例宝库:探索丰富的编程世界》 一、QT 基础示例(一)QRadioButton 示例(二)拦截关闭事件示例 二、QT 常用代码示例(一)QObject 相关操作(二)Qt 基本容器遍历&#x…...
子类有多个父类的情况下Super不支持指定父类来调用方法
1、Super使用方法 super()函数在Python中用于调用父类的方法。它返回一个代理对象,可以通过该对象调用父类的方法。 要使用super()方法,需要在子类的方法中调用super(),并指定子类本身以及方法的名称。这样就可以在子类中调用父类的方法。 …...
鸿蒙UI开发——渐变色效果
1、概 述 ArkTs可以通过颜色渐变接口,设置组件的背景颜色渐变效果,实现在两个或多个指定的颜色之间进行平稳的过渡。 目前提供三种渐变类型:线性渐变、角度渐变、径向渐变。 我们在鸿蒙UI布局实战 —— 个人中心页面开发中,默认…...
java基础概念47-ArrayList、LinkList和迭代器
一、ArrayList集合 1-1、ArrayList的两种添加信息的方式 1-2、ArrayList集合底层逻辑 1、利用空参创建的集合,在底层创建一个默认长度为0的数组 2、添加第一个元素时,底层会创建一个新的长度为10的数组 3、存满时,会扩容1.5倍。 4、如果…...
java编程1.5.4 - 失而复得
前言 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往复以至无穷&a…...
R语言使用“纽约市数据集中的优步皮卡”数据创建不同年度时间范围的可视化
一、项目背景 为了分析纽约市优步(https://baike.baidu.com/item/Uber/14900884)皮卡在不同年度的使用情况,需要利用R语言进行数据可视化。通过对比不同年度的数据,可以揭示出优步皮卡使用的趋势和变化。 二、数据准备 数据集&a…...
韩企研学团造访图为科技:共探人工智能创新前沿
今日,一支由韩国知名企业研学专家组成的代表团莅临图为科技深圳总部,展开了一场深度技术交流与研讨活动。 此次访问旨在通过实地探访中国领先的科技企业,促进中韩两国在科技创新领域的深入合作与交流。 韩国游学团合影 图为科技作为一家在人…...
Windows设备go环境安装配置
一、下载go安装包 官网链接:All releases - The Go Programming Language (google.cn) 安装过程比较简单,这里不再赘述,可参考这位博主的文章。本文重点在环境配置。golang环境详细安装、配置_golang安装-CSDN博客 二、环境变量配置 1.添…...
THREE.js 入门(一)xyz坐标系
一、坐标系概念 在 three.js 中,相机的默认朝向是沿着 Z 轴的负方向。也就是说,默认情况下,相机会沿着 Z 轴的负方向“看”到场景中的对象,而 X 轴和 Y 轴分别对应水平方向和垂直方向。换句话说,相机的默认位置是 (0,…...
Android仿美团左右联动购物列表
Android仿美团左右联动购物列表 左右联动购物列表,不难。 一、思路: 两个RecycleView 二、效果图: 三、关键代码: public class MainActivity extends AppCompatActivity {private RecyclerView rl_left;private RecyclerVie…...
HTML 标签语义化指南:让网页更易读
HTML 语义化标签是指在 HTML 中使用具有明确含义的标签来标记网页内容的结构和意义。这些标签可以提供更多的语义信息,有助于搜索引擎理解网页内容,并为使用辅助技术的用户提供更好的访问体验。 以下是一些常见的HTML语义化标签及其含义和用途ÿ…...
Java日志记录几种实现方案
在平时使用到一些软件中,比如某宝或者某书,通过记录用户的行为来构建和分析用户的行为数据,同时也能更好优化产品设计和提升用户体验。比如在一个订单系统中,需要确定追踪用户的行为,比如: 登录/登出浏览商…...
【C++算法】32.前缀和_矩阵区域和
文章目录 题目链接:题目描述:解法C 算法代码: 题目链接: 1314. 矩阵区域和 题目描述: 解法 防止有人看不明白题目,先解释一下题目 二维前缀和思想: 使用前缀和矩阵 ret [x1,y1]~[x2,y2] D …...
30天学会Go--第7天 GO语言 Redis 学习与实践
30天学会Go–第7天 GO语言 Redis 学习与实践 文章目录 30天学会Go--第7天 GO语言 Redis 学习与实践前言一、Redis 基础知识1.1 Redis 的核心特性1.2 Redis 常见使用场景 二、安装 Redis2.1 在 Linux 上安装2.2 在 Windows 上安装2.3 使用 Docker 安装 Redis 三、Redis 常用命令…...
面经自测——死锁/死锁的必要条件/死锁的预防/进程通信的方式
前言 本文是作者专门用来自测Java后端相关面试题的,所有问题都是在牛客、知识星球或网上找到的最近最新的面试题,全文回答都是作者按自己的真实水平仿照真实环境的回答,所以答案不一定真实(但回答一定真诚🤣࿰…...
Mysql索引,聚簇索引,非聚簇索引,回表查询
什么是索引 数据库索引是为了实现高效数据查询的一种有序的数据数据结构,类似于书的目录,通过目录可以快速的定位到想要的数据,因为一张表中的数据会有很多,如果直接去表中检索数据效率会很低,所以需要为表中的数据建立…...
Spring完整知识三(完结)
Spring集成MyBatis 注意 Spring注解形式集成MyBatis时,若SQL语句比较复杂则仍采用映射文件形式书写SQL语句;反之则用注解形式书写SQL语句,具体可详见Spring注解形式 环境准备相同步骤 Step1: 导入相关坐标,完整pom.…...
kafka-clients之ConsumerConfig
Kafka ConsumerConfig 中的配置项用于定义消费者的行为,如消费方式、偏移管理、组协调等。以下是ConsumerConfig中的关键配置项及其详细说明: 1. bootstrap.servers 类型:List<String>说明:Kafka集群的地址列表࿰…...
关于“浔川AI翻译”使用情况的调研报告
关于“浔川 AI 翻译”使用情况的调研报告 随着全球化进程加速及外语学习需求攀升,AI 翻译工具愈发普及。“浔川 AI 翻译”作为行业产品之一,为了解其市场表现与用户反馈,特开展本次问卷调查,现将关键结果汇报如下。 一、样本概…...
第一节、电路连接【51单片机-TB6600驱动器-步进电机教程】
摘要:本节介绍如何搭建一个51单片机TB6600驱动器步进电机控制电路,所用材料均为常见的模块,简单高效的方式搭建起硬件环境 一、硬件清单 ①51单片机最小控制系统 ②USB转TTL模块 ③开关电源 ④TB6600步进电机驱动器 ⑤二相四线步进电机 ⑥电…...
编程之路,从0开始:补充篇
Hello大家好!很高兴和大家又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《题海拾贝》、《数据结构与算法之美》 欢迎点赞,关注! 这篇…...