0810(028天 面向对象练习题03 双色球出机器码+挖坑发牌)

0810(028天 面向对象练习题03 双色球出机器码+挖坑发牌)

每日一狗(田园犬西瓜瓜

28

大标题

1. 双色球模拟

对问题的理解是螺旋递增的

1.1 第一版(模拟拿球)

需要有一个存放球的容器(变长数组),拿出来就没有了,实现元素的增删改查

package com.yang1;

import java.util.Arrays;

public class ArrayList {
	private int[] arr;
	private int count;

	public ArrayList() {
		this(10);
	}

	public ArrayList(int length) {
		if (length < 2) {
			length = 10;
		}
		arr = new int[10];
		count = 0;
	}

	public void add(int data) {
		if (count >= arr.length) {
			swell();
		}
		arr[count++] = data;
	}

	public int[] getArr() {
		return arr;
	}

	public int getCount() {
		return count;
	}

	private void swell() {
		int[] newArr = new int[count * 3 / 2];
		System.arraycopy(arr, 0, newArr, 0, count);
		arr = newArr;

	}

	public void delect(int index) {
		if (index >= count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		System.arraycopy(arr, index + 1, arr, index, arr.length - index - 1);
		arr[count - 1] = 0;
		count--;
	}

	public String toString() {
		return Arrays.toString(arr);
	}

	public void update(int index, int data) {
		if (index >= count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		arr[index] = data;
	}

	public int getData(int index) {
		if (index >= count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		return arr[index];
	}
}

package com.yang1;

import java.util.Random;

public class Test01 {

	public static void main(String[] args) {
		ArrayList list1 = new ArrayList(); // 红球
		for (int i = 1; i < 34; i++) {
			list1.add(i);
		}
		ArrayList list3 = new ArrayList(7);
		Random r = new Random();
		for (int i = 0; i < 6; i++) {
			int index = r.nextInt(list1.getCount());
			list3.add(list1.getData(index));
			list1.delect(index);
		}
		list3.add(r.nextInt(16) + 1);
		System.out.println(list3);
	}

}

image-20220810105654796

1.2 第二版(带色球)

  • 将球的数据进行封装
  • 球色使用枚举类型
package com.yang2;

public class Ball {
	private int number;
	private BallColor color;

	public Ball(int number, BallColor color) {
		this.number = number;
		this.color = color;
	}

	@Override
	public String toString() {
		return "双色球 [号码=" + number + ", 球色=" + color + "]";
	}

}

package com.yang2;

public enum BallColor {
	RED("红球"), BLUE("蓝球");

	private String name;

	private BallColor(String name) {
		this.name = name;
	}

	public String toString() {
		return this.name;
	}
}

1.3 第三版(给球排序)

蓝色 > 红色

号码升序

排序接口Comparable<Ball>

表示改类型是可以进行大小比较的

需要实现public int compareTo(Ball o); 这个方法

小于为负数、相等为0、大于为正。

package com.yang3;

public class Ball implements Comparable<Ball> {
	private final int number;
	private final BallColor color;
	// 
	@Override
	public int compareTo(Ball o) {
		int res = this.color.compareTo(o.color);
		if (res == 0) {
			res = this.number - o.number;
		}
//		res*=-1;
		return res;
	}

	public Ball(int number, BallColor color) {
		this.number = number;
		this.color = color;
	}

	@Override
	public String toString() {
		return "(" + number + "," + color + ")";
	}
//

	public int getNumber() {
		return number;
	}

	public BallColor getColor() {
		return color;
	}

}
排序器Comparator<Ball>(不修改原来的类)
public Ball[] sort() {
    Ball[] res = getArr();
    //		// 局部内部类
    //		Comparator<Ball> com = new Comparator<Ball>() {
    //			@Override
    //			public int compare(Ball o1, Ball o2) {
    //				int res1 = o1.getColor().compareTo(o2.getColor());
    //				if (res1 == 0) {
    //					res1 = o1.getNumber() - o2.getNumber();
    //				}
    //				return res1;
    //			}
    //
    //		};
    //		Arrays.sort(res, com);
    // lambda
    Arrays.sort(res, (Ball o1, Ball o2) -> {

        int res1 = o1.getColor().compareTo(o2.getColor());
        if (res1 == 0) {
            res1 = o1.getNumber() - o2.getNumber();
        }
        return res1;
    });

    return res;

}

2. 发牌小案例

需求

不要大小王

留四个底

三个人玩 + 一个底牌

  • 把个人手里的排排个序(先数字后花色)

    • 黑 > 红 > 梅 > 方

    • 3>2>1>K

名词:牌、牌色、玩家、玩家手中的牌、发牌员手中的牌、底牌

    • 牌色
    • 号码
  • 牌色
    • 黑 > 红 > 梅 > 方
    • 枚举
  • 玩家
    • 玩家序号
    • 手中的牌
  • 存储牌的容器

2.1 各个对象

package com.yang5;

import java.util.Objects;

public class Board implements Comparable<Board> {
	// 用来判定用户挖坑的优先级的
	public static final Board[] Floor = { new Board(4, FlowerColor.HEARTS), new Board(5, FlowerColor.HEARTS),
			new Board(6, FlowerColor.HEARTS), new Board(7, FlowerColor.HEARTS), new Board(8, FlowerColor.HEARTS) };
	private int num;
	private FlowerColor color;

	public Board(int num, FlowerColor color) {
		this.num = num;
		this.color = color;
	}

	@Override
	public int hashCode() {
		return Objects.hash(color, num);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Board other = (Board) obj;
		return color == other.color && num == other.num;
	}

	@Override
	public String toString() {
		String numStr = num + "";
		if (num > 10) {
			switch (num) {

			case 11:
				numStr = "J";
				break;
			case 12:
				numStr = "Q";
				break;
			case 13:
				numStr = "K";
				break;
			case 14:
				numStr = "A";
				break;
			case 15:
				numStr = "2";
				break;
			case 16:
				numStr = "3";
				break;
			default:
				break;
			}
		}

		return "(" + color + " " + numStr + ")";
	}

	@Override
	public int compareTo(Board o) {
		int res = this.num - o.num;
		if (res == 0) {
			res = this.getColor().compareTo(o.getColor());
		}
		return res;
	}

/
	public int getNum() {
		return num;
	}

	public FlowerColor getColor() {
		return color;
	}

}

  • 牌色
package com.yang5;

public enum FlowerColor {
	SPADES("黑桃"), HEARTS("红心"), CLUBS("梅花"), DIAMONDS("方片");

	private String name;

	private FlowerColor(String name) {
		this.name = name;
	}

	@Override
	public String toString() {

		return this.name;
	}

}

  • 玩家
package com.yang5;

import java.util.Arrays;

public class ArrayList {
	private Board[] arr;
	private int count;

	public void sort() {
		arr = getArr();
		Arrays.sort(arr);
	}

	// 默认数组长度为10
	public ArrayList() {
		this(10);
	}

	public ArrayList(int length) {
		if (length < 2) {
			length = 10;
		}
		arr = new Board[length];
		count = 0;
	}

	// 获取指定索引位置上的对象
	public Board getIndexData(int index) {
		if (index > count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		return arr[index];
	}

	// 修改指定索引位置上的数据为指定对象
	public void update(int index, Board data) {
		if (index > count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		arr[index] = data;
	}

	// 删除指定索引位置的数据
	public void delect(int index) {
		if (index > count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		System.arraycopy(arr, index + 1, arr, index, count - index - 1);
		arr[count - 1] = null;
		count--;
	}

	// 追加数据 自动扩容
	public void add(Board data) {
		if (count == arr.length) {
			swell();
		}
		arr[count++] = data;

	}

	// 获取指定对象在当前数组中存在的索引
	public int select(Board data) {
		int res = -1;
		for (int i = 0; i < count; i++) {
			if (arr[i].equals(data)) {
				res = i;
				break;
			}
		}
		return res;
	}

	// 扩容
	private void swell() {
		Board[] newArr = new Board[count * 3 / 2];
		System.arraycopy(arr, 0, newArr, 0, count);
		arr = newArr;
	}

	// 将非空部分拷贝一份给他使用(这里应该使用深克隆)
	public Board[] getArr() {
		Board[] res = new Board[count];
		System.arraycopy(arr, 0, res, 0, count);
		return res;
	}

	public int getCount() {
		return count;
	}

	// 将当前容器中存储的牌展示到终端
	public void show() {
		Board[] res = getArr();
		int sepNum = 0;
		System.out.println("手牌");
		for (Board tmp : res) {

			System.out.print(tmp);
			if ((++sepNum) % 5 == 0) {
				System.out.println();
			}
		}
		System.out.println("");
	}

}

  • 存储牌的容器
package com.yang5;

import java.util.Arrays;

public class ArrayList {
	private Board[] arr;
	private int count;

	public void sort() {
		arr = getArr();
		Arrays.sort(arr);
	}

	// 默认数组长度为10
	public ArrayList() {
		this(10);
	}

	public ArrayList(int length) {
		if (length < 2) {
			length = 10;
		}
		arr = new Board[length];
		count = 0;
	}

	// 获取指定索引位置上的对象
	public Board getIndexData(int index) {
		if (index > count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		return arr[index];
	}

	// 修改指定索引位置上的数据为指定对象
	public void update(int index, Board data) {
		if (index > count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		arr[index] = data;
	}

	// 删除指定索引位置的数据
	public void delect(int index) {
		if (index > count || index < 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		System.arraycopy(arr, index + 1, arr, index, count - index - 1);
		arr[count - 1] = null;
		count--;
	}

	// 追加数据 自动扩容
	public void add(Board data) {
		if (count == arr.length) {
			swell();
		}
		arr[count++] = data;

	}

	// 获取指定对象在当前数组中存在的索引
	public int select(Board data) {
		int res = -1;
		for (int i = 0; i < count; i++) {
			if (arr[i].equals(data)) {
				res = i;
				break;
			}
		}
		return res;
	}

	// 扩容
	private void swell() {
		Board[] newArr = new Board[count * 3 / 2];
		System.arraycopy(arr, 0, newArr, 0, count);
		arr = newArr;
	}

	// 将非空部分拷贝一份给他使用(这里应该使用深克隆)
	public Board[] getArr() {
		Board[] res = new Board[count];
		System.arraycopy(arr, 0, res, 0, count);
		return res;
	}

	public int getCount() {
		return count;
	}

	// 将当前容器中存储的牌展示到终端
	public void show() {
		Board[] res = getArr();
		int sepNum = 0;
		System.out.println("手牌");
		for (Board tmp : res) {

			System.out.print(tmp);
			if ((++sepNum) % 5 == 0) {
				System.out.println();
			}
		}
		System.out.println("");
	}

}

2.2 主控制程序

package com.yang5;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Random;

public class Test {

	public static void main(String[] args) {
		test();
	}

	public static void test() {
		// 创建牌池子
		ArrayList boardPool = new ArrayList(53);
		for (FlowerColor color : FlowerColor.values()) {
			for (int i = 4; i < 17; i++) {
				Board board = new Board(i, color);
				boardPool.add(board);
			}
		}
		System.out.println("============= 展示咱的牌 ============= ");
		boardPool.show();

		// 创建玩家池子:默认有三个玩家
		Player[] playerPool = { new Player(1), new Player(2), new Player(3) };

		int takeBoardIndex = 0; // 当前要拿牌的玩家索引
		int boardIndex; // 要发给当前玩家的的牌在牌池子中的索引
		Random r = new Random();
		// 发牌部分 已完成
		while (true) {
			// 留底
			if (boardPool.getCount() == 4) {
				break;
			}
			// 发牌
			boardIndex = r.nextInt(boardPool.getCount());
			Board board = boardPool.getIndexData(boardIndex); // 拿牌
			boardPool.delect(boardIndex); // 删牌
			playerPool[takeBoardIndex].takeBoard(board); // 玩家存牌

			// 换下一个人
			takeBoardIndex = (++takeBoardIndex) % 3;
		}
		System.out.println("=============  展示底牌 ============= ");
		boardPool.show();
		System.out.println("=============  展示未挖牌时玩家手牌 ============= ");
		for (Player p : playerPool) {
			p.sort();
			p.showBoard();
		}

		// 逐一获取玩家的挖坑优先级
		for (Player p : playerPool) {
			p.getFloorSelect();
		}
		// 按照用户手中的牌,进行坑的优先级排序
		Arrays.sort(playerPool, (Player o1, Player o2) -> {
			int res = o1.priority - o2.priority;
			res *= -1;
			return res;
		});

		int playerIndex = 0; // 当前选择的玩家索引
		int number = 0; // 用于记录不挖的人数,为3时表示所有人都不愿意挖,退出游戏
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			// 不挖计数器为3,都不想挖,就直接结束游戏
			if (number >= 3) {
				break;
			}
			// 询问当前玩家挖不挖坑
			System.out.println(playerPool[playerIndex].getId() + "号玩家挖不挖?(y?n)");
			String ss = "";
			try {

				ss = br.readLine();

			} catch (Exception e) {
				e.printStackTrace();
			}
			if ("y".equals(ss)) {
				playerPool[playerIndex].getFloor(boardPool); // 当前玩家挖了,将底牌都给他
				boardPool = null; // 底牌没有了
				break;
			}
			number++; // 不挖计数器加一
			playerIndex = (++playerIndex) % 3;
		}
		if (number >= 3) {
			System.out.println("============= 没人想挖,直接退出游戏 ============= ");
		} else {
			System.out.println(" ============= 开始本剧游戏 ============= ");
			for (Player p : playerPool) {
				p.sort();
				p.showBoard();
			}
		}
	}
}

测试:1号玩家挖了

============= 展示咱的牌 ============= 
手牌
(黑桃 4)(黑桃 5)(黑桃 6)(黑桃 7)(黑桃 8)
(黑桃 9)(黑桃 10)(黑桃 J)(黑桃 Q)(黑桃 K)
(黑桃 A)(黑桃 2)(黑桃 3)(红心 4)(红心 5)
(红心 6)(红心 7)(红心 8)(红心 9)(红心 10)
(红心 J)(红心 Q)(红心 K)(红心 A)(红心 2)
(红心 3)(梅花 4)(梅花 5)(梅花 6)(梅花 7)
(梅花 8)(梅花 9)(梅花 10)(梅花 J)(梅花 Q)
(梅花 K)(梅花 A)(梅花 2)(梅花 3)(方片 4)
(方片 5)(方片 6)(方片 7)(方片 8)(方片 9)
(方片 10)(方片 J)(方片 Q)(方片 K)(方片 A)
(方片 2)(方片 3)
=============  展示底牌 ============= 
手牌
(黑桃 7)(红心 3)(梅花 10)(方片 10)
=============  展示未挖牌时玩家手牌 ============= 
玩家编号1
手牌
(红心 4)(梅花 5)(黑桃 6)(方片 6)(红心 7)
(方片 7)(黑桃 8)(黑桃 9)(梅花 9)(黑桃 10)
(红心 10)(梅花 J)(黑桃 K)(黑桃 A)(梅花 3)
(方片 3)
玩家编号2
手牌
(黑桃 4)(梅花 4)(方片 4)(黑桃 5)(方片 5)
(红心 6)(梅花 8)(黑桃 J)(红心 J)(方片 J)
(黑桃 Q)(梅花 Q)(红心 A)(方片 A)(红心 2)
(方片 2)
玩家编号3
手牌
(红心 5)(梅花 6)(梅花 7)(红心 8)(方片 8)
(红心 9)(方片 9)(红心 Q)(方片 Q)(红心 K)
(梅花 K)(方片 K)(梅花 A)(黑桃 2)(梅花 2)
(黑桃 3)
2号玩家挖不挖?(y?n)
n
3号玩家挖不挖?(y?n)
n
1号玩家挖不挖?(y?n)
y
手牌
(黑桃 7)(红心 3)(梅花 10)(方片 10)
4
 ============= 开始本剧游戏 ============= 
玩家编号2
手牌
(黑桃 4)(梅花 4)(方片 4)(黑桃 5)(方片 5)
(红心 6)(梅花 8)(黑桃 J)(红心 J)(方片 J)
(黑桃 Q)(梅花 Q)(红心 A)(方片 A)(红心 2)
(方片 2)
玩家编号3
手牌
(红心 5)(梅花 6)(梅花 7)(红心 8)(方片 8)
(红心 9)(方片 9)(红心 Q)(方片 Q)(红心 K)
(梅花 K)(方片 K)(梅花 A)(黑桃 2)(梅花 2)
(黑桃 3)
玩家编号1
手牌
(红心 4)(梅花 5)(黑桃 6)(方片 6)(黑桃 7)
(红心 7)(方片 7)(黑桃 8)(黑桃 9)(梅花 9)
(黑桃 10)(红心 10)(梅花 10)(方片 10)(梅花 J)
(黑桃 K)(黑桃 A)(红心 3)(梅花 3)(方片 3)



扩展小芝士

  • 接口也能用来定义为数组类型Comparable[] arr;这个数组中就存储的时可比较数据类型,要存放的对象必须都要实现Comparable接口才行

快排

一个基准,大于该基准的放到右边,小于的放到左边

缩小范围,直到所有的数据都排完序为止

双指针实现

  • 时间复杂度O(longN)

  • 不稳定

  • 原地操作 O(1)

  • 选择一个基准值(index=min)

  • 右指针向左检索,当碰到一个比自己的,将其拷贝至指针

  • 左指针向右检索,当碰到一个比自己的,将其拷贝至指针

  • 当左指针和右指针重叠时将基准值付给当前指针索引位置,退出循环

  • 进行下一次迭代

image-20220810154011698

package com.test;

import java.util.Arrays;

public class 快排 {

	public static void main(String[] args) {
		int[] arr = { 7, 3, 5, 8, 6, 9 };
		sort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));
	}

	// 左右指针法
	public static void sort(int[] arr, int min, int max) {

		int start = min;
		int stop = max;
		int piv = arr[min];
		while (min < max) {
			// 右边指针向左边检索
			while (min < max && arr[max] >= piv) {
				max--;
			}
			arr[min] = arr[max];
			// 左边指针向右边检索
			while (max > min && arr[min] <= piv) {
				min++;
			}
			arr[max] = arr[min];
		}
		// 将基准放到当前指针位置
		arr[min] = piv;
		if (max + 1 < stop) {
			sort(arr, max + 1, stop);
		}
		if (min - 1 > start) {
			sort(arr, start, min - 1);
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值