心得体会
- 今天主要写了关于扑克的demo,这对我来说很复杂,总而言之,就是今天上了那么久的课,课后我回想起来,在我脑海中留下的印象很少很少,整天下来我是云里雾里,刚开始,还能跟上进度,老师讲到哪,代码敲到哪,但在最后面的一段时间,我发现自己错误率越来越多,然后只能无奈的停下了手。老师一边讲课,我一边跟着敲代码,有时候会把精力放在跟着老师敲上面,往往知识点会听一半漏一半,可能我不太习惯边敲边听吧,应该还有一部分原因就是自己手速太慢,我已在慢慢尝试快捷键的使用,但还不太熟练,但我会努力加快自己手速的^^,今天有很多 东西都没听懂,所以晚上得重温一遍 今天的课,哈哈,今天晚上任重而道远呀
技术
-
1.单例设计模式
----a.单例设计模式的特点
----b.单例模式的要点
----c.饿汉式单例和懒汉式单例 - 2.数组引用
-
3.扑克demo
----a.封装实现文本输出
----b.创建Poker类
----c.创建PokerManager管理牌的操作
----d.优化生成一副牌的操作
----e.创建玩家类Player
----f.创建玩家管理理器器PlayerManager 管理理玩家信息
----g.游戏中⼼心管理理游戏
----h.实现发牌
具体操作
1.单例设计模式
- a.单例设计模式的特点
- 1.单例类只能有一个实例。
- 2.单例类必须自己创建自己的唯一实例。
- 3.单例类必须给所有其他对象提供这一实例。
- b.单例模式的要点
- 1.私有的构造方法
- 2.指向自己实例的私有静态引用
- 3.以自己实例为返回值的静态的公有的方法
- c.单例模式根据实例化对象时机的不同分为两种
- 一种是饿汉式单例,一种是懒汉式单例。
- 饿汉式单例在单例类被加载时候,就实例化一个对象交给自己用;
懒汉式在调用取得实例方法的时候才会实例化对象。
-----------饿汉式单例
class Poker{
//defalt,share,Instance,manager
//2.定义一个静态的成员变量 记录这个单例对象
//饿汉式
public static final Poker shared = new Poker();
//1.默认构造函数
private Poker() { }
public void test() {
}
}
- 步骤:1.默认构造方法 ----2.定义一个静态的成员变量 记录这个单例对象
-----------懒汉式单例
class Player {
public int count;
//2.创建静态变量
private static Player shared = null;
//1.私有化
private Player() { }
//3.提供给外部一个访问的方法
public static Player getInstance() {
Object b = new Object();
synchronized (b) {
if (shared == null) {
//如果没有创建 那么就创建一个
shared = new Player();
}
}
return shared;
}
}
步骤:1.私有化构造函数------2.创建静态变量------ 3.提供给外部一个访问的方法
解析:懒汉式单例先将构造函数私有化,外部无法直接访问,要让外部访问到,就必须提供提供给外部一个访问的方法,给外部一个 getInstance()方法。
懒汉式的缺点是:没有考虑到线程安全,可能存在多个访问者同时访问,并同时构造了多个对象的问题。之所以叫做懒汉模式,主要是因为此种方法可以非常明显的lazy loading。
2.数组引用
class Test2{
public static void main(String[] args){
//泛型
/** 数组里面保存的都是对象的引用(指针)
* 改变数组里面对象的属性变量
* 原始对象的值也跟着改变
* 因为大家都是指向同一个内存空间
*/
ArrayList<Person> people=new ArrayList<>();
//添加数据
Person xw=new Person();
people.add(xw);
Person zs=new Person();
people.add(zs);
//访问数据
Person xw2=people.get(0);
xw2.name="小王";
System.out.println(xw2.name);
}
}
class Person{
public String name;
}
1.上图中用
ArrayList<Person> people=new ArrayList<>();
实现了动态分布数组内存空间
Person xw=new Person();
people.add(xw);
Person zs=new Person();
people.add(zs);
这里分别创建了xw,zs两个对象,并通过add()把这两个对象加到数组里面去了
3.上图中
System.out.println(xw2.name);
打印了xw2,得到结果是小王,如果换成System.out.println(xw.name);
,得到结果同样是小王
xw和xw2指向的是同一个内容,本来xw的打印结果应该是null的,但通过xw2将“小王”赋给了数组的第一个,于是xw指向的内容也就变成了“小王”,数组里面存的是地址
3.扑克demo
- a.输出语句的封装
输出语句:完成如下指令
- 1.输出语句不换行/换行
- 2.输出语句加分隔符/不加分隔符
- 3.输出语句一行/多行
package Demo;
import java.util.Scanner;
public class Utils {
public static void showText(boolean hasStar,boolean lineBreak,String...contents){
//判断是否需要显示分割线
System.out.print(hasStar?"**********************\n":" ");
//判断输出的内容是一行还是多行
if(contents.length==1){
System.out.print(contents[0]);
System.out.print(hasStar?"\n":" ");
}else{
//输出带编号的多行数据
for(int i=0;i<contents.length;i++){
System.out.println((i+1)+". "+contents[i]);
}
}
System.out.print(hasStar?"**********************\n":" ");
System.out.print(lineBreak?"\n":" ");
}
public static int getInput(){
Scanner scanner=new Scanner(System.in);
return scanner.nextInt();
}
}
1.如果不需要保存数据,没有成员变量,提供静态方法,访问方便
2.
System.out.print(hasStar?"**********************\n":" ");
这里采用三目运算符实现有无分隔符的操作
public static int getInput(){
Scanner scanner=new Scanner(System.in);
return scanner.nextInt();
}
这里将scanner输入语句封装起来
b.创建Poker类
- 1.创建Constant类管理一些常量
用数组保存牌的点数
public static final String[] DOTS = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
- 2.定义PokerType类管理理牌的花⾊色和id号
- 因为pic和Id都是私有的,所以外部无法直接访问,为了使外部能够访问数据,使用了
setter/getter
方法
getter
方法不需要参数,有返回值
setter
方法需要参数,没有返回值
public class PokerType {
private String pic;
private int id;
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
- 3.定义Poker类
private String dot;
private PokerType type;
public PokerType getType() {
return type;
}
public void setType(PokerType type) {
this.type = type;
}
//setter/getter方法
public void setDot(String dot){
this.dot=dot;
}
public String getDot(){
return dot;
}
}
c.创建PokerManager管理牌的操作
- 1.生成一副牌
- 1.首先用ArrayList保存一副牌。
- 2.定义一个方法生成一副牌
public class PokerManager {
//保存一副牌
private ArrayList<Poker> pokers = new ArrayList<>();
//创建静态的变量
public static final PokerManager manager =new PokerManager();
//私有化构造方法
private PokerManager(){
}
//定义一个方法生成一副牌
public void deal() {
//遍历整个点数的数组
for (int i = 0; i < Constant.DOTS.length;i++){
String dot=Constant.DOTS[i];
//生成4种花色
for(int j=0 ; j<Constant.TYPES.length; j++){
//创建一张牌
Poker poker=new Poker(dot,Constant.TYPES[j]);
//将这张牌保存起来
pokers.add(poker);
}
2.为Poker类和PokerType类提供构造方法
- 并不是所有的对象创建的时候都知道具体的值
当提供一个自定义的构造方法时,默认的构造方法就被屏蔽了,此时就需要自己写一个默认的构造方法
- 3.创建花色
PokerType spades=new PokerType("♠",4);
PokerType hearts=new PokerType("♥",3);
PokerType clubs=new PokerType("♣",2);
PokerType diamonds=new PokerType("♦",1);
- 创建四张牌
public Poker(){}
public Poker(String dot,PokerType type){
this.dot=dot;
this.type=type;
}
//创建4张牌
// Poker ps=new Poker();
// ps.setDot(dot);
// ps.setType(spades);
Poker ps=new Poker(dot,spades);
Poker ph=new Poker(dot,hearts);
Poker pc=new Poker(dot,clubs);
Poker pd=new Poker(dot,diamonds);
- 将产⽣的四张牌添加到数组
//加到数组里面去
pokers.add(ps);
pokers.add(ph);
pokers.add(pc);
pokers.add(pd);
- d.优化生成一副牌的操作
- 1.在PokerType⾥面提供4个静态常量对象
- 1.静态成员变量:把大家公有的东西抽出来,在对象没有创建前,这个东西已经有了
- 2.此时进行花色比较,只要比花色所对应的id就可以了
//静态的常量
public static final PokerType SPADES=new PokerType("♠",4);
public static final PokerType HEARTS=new PokerType("♥",3);
public static final PokerType CLUBS=new PokerType("♣",2);
public static final PokerType DIAMONDS=new PokerType("♦",1);
- 2.在Constant⾥里里⾯面提供数组保存这4个常量
//保存固定的几个花色
public static final PokerType[] TYPES = {PokerType.SPADES, PokerType.HEARTS, PokerType.CLUBS, PokerType.DIAMONDS};
3.实现功能
- Collections.shuffle(),方法,打乱顺序
//生成4种花色
for(int j=0 ; j<Constant.TYPES.length; j++){
//创建一张牌
Poker poker=new Poker(dot,Constant.TYPES[j]);
//将这张牌保存起来
pokers.add(poker);
}
//洗牌
Collections.shuffle(pokers);
}
4.提供⼀一个方法输出这副牌 :拼接每张牌的输出格式
//显示一副牌
public void show(){
for(Poker poker:pokers){
System.out.print(poker.getDot()+poker.getType().getPic()+" ");
}
System.out.println();
}
5.使⽤
//生成一副牌
PokerManager.manager.deal();
//显示一副牌
PokerManager.manager.show();
e.创建玩家类Player
public class Player {
public String name;
public int id;
public int money;
public Player(){}
public Player(String name, int id, int money){
this.name=name;
this.money=money;
this.id=id;
}
f.创建玩家管理理器器PlayerManager 管理理玩家信息
- 1.Constant里⾯添加常量 保存默认提供的姓名和金币数
//保存默认的玩家姓名
public static final String[] DEFAULT_NAMES={"张三","李四","王二","麻子"};
- 初始化玩家信息
public class PlayerManager {
public ArrayList<Player> players = new ArrayList<>();
public void initPlayer(int count){
for(int i=0; i<count; i++){
//创建玩家
String name=Constant.DEFAULT_NAMES[i];
Player player=new Player(name,i+1,Constant.MONEY);
//保存玩家
players.add(player);
}
}
- 3.实现toString⽅法, 方便打印
- 当打印一个对象的时候 就会默认去调用对象的toString方法
- 如果当前里面没有实现这个方法 就到父类里面去查找
- object里面默认实现就是打印对象的首地址
public String toString() {
return id+" 号玩家 "+name+" 筹码:"+money+pkString;
}
- 4.输出玩家信息
//输出玩家信息
public void show(){
for(Player player:players){
System.out.println(player);
}
}
- 5.使用
Utils.showText(false, false, new String[]{"请输入参与人数"});
int count=Utils.getInput();
//初始化玩家
PlayerManager.manager.initPlayer(count);
PlayerManager.manager.show();
- 6.结果
g.游戏中⼼心管理理游戏
1.PlayerManager和PokerManager 提供单例对象
//创建静态的变量
public static final PokerManager manager =new PokerManager();
//私有化构造方法
private PokerManager(){
}
2.PlayerManager实现打底注的方法
* 打底
* @param count 每局消耗的金币
* @return -1:失败 >0 成功
*/
public int betAll(int count){
int total=0;
for(Player player:players){
player.bet(count);
int result =player.bet(count);
if(result==-1){
return -1;
}
}
return count * players.size();
}
public Player currentPlayer(){
//获取当前玩家
return players.get(currentPlayerIndex);
}
3.Player实现下注⽅方法
public int bet(int count){
//判断自己的金币是否大于下注金额
if(money>= count){
money -=count;
return count;
}else{
return -1;
}
}
}
4.Gamecenter 开始游戏
public void start(){
//扣除底注
System.out.println("游戏开始,请打底:");
PlayerManager.manager.betAll(Constant.BASE);
PlayerManager.manager.show();
}
h.实现发牌
1.在Player类⾥里里⾯面添加Poker对象 每个⼈人有⼀一张牌
- 2.PokerManager类添加发牌⽅方法
public void dealCards(ArrayList<Player> players){
for(int i=0; i<players.size();i++){
Player player=players.get(i);
//将数组里面对应的扑克牌给对应玩家
player.poker=pokers.get(i);
}
}
- 3.GameCenter的start⽅方法调⽤用发牌
System.out.println("开始发牌");
PokerManager.manager.dealCards(PlayerManager.manager.players);
PokerManager.manager.show();