不多说,拷贝就能用
package com;
import java.awt.event.ActionEvent;
import javax.swing.*;
import main.MahjongTileInitWrongTypeAndTypeIdException;
public class MahJongGame extends JFrame {
/**
*
*/
private static final long serialVersionUID = -37364652653193128L;
MyPanel myp = null;
public static void main(String[] args) throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {
// TODO Auto-generated method stub
MahJongGame mhg = new MahJongGame();
}
public MahJongGame() throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {
myp = new MyPanel();
// 启动了mypanel线程
Thread myt = new Thread(myp);
myt.start();
// 先删除旧的面板
this.remove(myp);
// 加入新面板
this.add(myp);
this.setSize(1000, 600);
// 刷新JFrame面板
this.setVisible(true);
}
public void actionPerformed(ActionEvent arg0) {
}
}
package com;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import javax.swing.*;
import com.jbutton.RotateImage;
import com.time.TimerLabel;
import main.InitPlayer;
import main.MahjongTileInitWrongTypeAndTypeIdException;
import main.Player;
import main.ShuffleMahJong;
/**
* 1-9存万 21-29存条 31-39存筒 0,10,20,30,40存东南西北 41-43存中,发,白
*
* @author LiHai
*
*/
public class MyPanel extends JPanel implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
public static long timedate = 3;
Image image = null;
// 初始化按钮
ArrayList<JButton> bt = new ArrayList<JButton>();
JButton b0, b1, b2, b3;
// 定义存放麻将的集合
Vector<Image> tupWeizhi = new Vector<Image>();
// 初始化玩家
InitPlayer initPlayer = null;
// 四个玩家
Player player = new Player();
Player computer1 = new Player();
Player computer2 = new Player();
Player computer3 = new Player();
// 麻将
ShuffleMahJong shuffleMahJong = new ShuffleMahJong();
int t = 1;
TimerLabel tlaber = new TimerLabel(5);
public MyPanel() throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {
// Scanner scanner = new Scanner(System.in);
setLayout(null);// 必须为设置为null,你的setBouds();才可以有作用
// 初始化按钮
this.jbutton();
this.setOpaque(false);
// 设置整副牌的开始位置
ShuffleMahJong.maJiangsIndex = 0;
// 移动起始位置前的牌到list末尾
ShuffleMahJong.moveMahJongs();
// 玩家
initPlayer = new InitPlayer();
// 第一次起牌
initPlayer.haveFirstBoard();
// 输出牌局中的整副牌(剩余的牌)
System.out.println("【此时牌局中的剩余的牌:】");
ShuffleMahJong.printMahJongs();
// 第二次起牌:跳庄
initPlayer.haveJumpBoard();
// 输出此时玩家手中的牌
initPlayer.printPlayer();
player = InitPlayer.players.get(0);
// 摸第一张牌
player.gainMaJiang(0);
// 设置为出牌状态
player.setRunzt(true);
initPlayer.printPlayer(player);
// 输出牌局中的整副牌(剩余的牌)
System.out.println("【此时牌局中的剩余的牌:】");
ShuffleMahJong.printMahJongs();
player = InitPlayer.players.get(0);
computer1 = InitPlayer.players.get(1);
computer2 = InitPlayer.players.get(2);
computer3 = InitPlayer.players.get(3);
System.out.println("【您先出牌:[待打出牌对应的顺序,例如:1表示打出第一张牌],[非数字输入:退出游戏]】");
image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/image/image1.jpg"));
for (int i = 0; i <= 43; i++) {
// System.out.println("/image/"+i+".jpg");
tupWeizhi.add(Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/image/" + i + ".png")));
}
// tlaber.setBounds(220, 220, 220, 220);
this.add(tlaber, BorderLayout.CENTER);
tlaber.start();
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 400, 300);
// 重绘子组件,不然会出现异常“有个按钮需要鼠标移动到它上边才显示”
super.paintChildren(g);
// 固定背景图片,允许这个JPanel可以在图片上添加其他组件
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);
// 画出牌文字信息
this.drawenzi(g);
// 确保该函数只能被调用一次
for (int i = 0; i < t; i++) {
// deal(g);
t--;
// System.out.println("该集合牌的数量" + tupWeizhi.size());
}
// int i1=player.getPlayerMaJiangs().get(0).getType();
// int i2=player.getPlayerMaJiangs().get(0).getTypeId();
// System.out.println(i1+"-"+i2);
// 画玩家麻将
this.drawmajiang(g);
}
private void drawmajiang(Graphics g) {
// 画西家的牌
for (int i = 0; i < InitPlayer.players.get(2).getPlayerMaJiangs().size(); i++) {
int p = ((InitPlayer.players.get(2).getPlayerMaJiangs().get(i).getType() * 10)
+ InitPlayer.players.get(2).getPlayerMaJiangs().get(i).getTypeId());
// JButton b= new JButton(); // // 实例化按钮对象,并且设置按钮上显示图片
// ImageIcon ico = new ImageIcon(getClass().getResource("/image/"+p+".png"));
// ico.setImage(ico.getImage().getScaledInstance(32, 70, Image.SCALE_DEFAULT));
// Image image = ico.getImage(); b.setBounds(110 + 33 * u,40,34, 70);
// b.setIcon(ico); this.add(b);
if (i < 13) {
g.drawImage(RotateImage.Rotate(tupWeizhi.get(p), 180), 600 - 30 * i, 50, 31, 70, this);
} else {
g.drawImage(RotateImage.Rotate(tupWeizhi.get(p), 180), 600 - 50 - 30 * i, 50, 31, 70, this);
}
}
// 画电脑东家
for (int i = 0; i < InitPlayer.players.get(0).getPlayerMaJiangs().size(); i++) {
int p = ((InitPlayer.players.get(0).getPlayerMaJiangs().get(i).getType() * 10)
+ InitPlayer.players.get(0).getPlayerMaJiangs().get(i).getTypeId());
if (i >= 13) {
g.drawImage(tupWeizhi.get(p), 143 + 50 + 30 * i, 430, 29, 70, this);
} else {
g.drawImage(tupWeizhi.get(p), 143 + 30 * i, 430, 30, 70, this);
}
}
// 画电脑北家
for (int i = 0; i < InitPlayer.players.get(1).getPlayerMaJiangs().size(); i++) {
int p = ((InitPlayer.players.get(1).getPlayerMaJiangs().get(i).getType() * 10)
+ InitPlayer.players.get(1).getPlayerMaJiangs().get(i).getTypeId());
new RotateImage();
if (i < 13) {
g.drawImage(RotateImage.Rotate(tupWeizhi.get(p), 270), 680, 480 - 30 * i, 70, 30, this);
} else {
g.drawImage(RotateImage.Rotate(tupWeizhi.get(p), 270), 680, 480 - 50 - 30 * i, 70, 30, this);
}
}
// 画电脑南家
for (int i = 0; i < InitPlayer.players.get(3).getPlayerMaJiangs().size(); i++) {
int p = ((InitPlayer.players.get(3).getPlayerMaJiangs().get(i).getType() * 10)
+ InitPlayer.players.get(3).getPlayerMaJiangs().get(i).getTypeId());
new RotateImage();
if (i < 13) {
g.drawImage(RotateImage.Rotate(tupWeizhi.get(p), 90), 50, 50 + 30 * i, 70, 30, this);
} else {
g.drawImage(RotateImage.Rotate(tupWeizhi.get(p), 90), 50, 50 + 50 + 30 * i, 70, 30, this);
}
}
}
private void drawenzi(Graphics g) {
Font ft = new Font("宋体", Font.BOLD, 30);
g.setFont(ft);
g.setColor(Color.LIGHT_GRAY);
if (InitPlayer.players.get(0).isRunzt()) {
g.setColor(Color.green);
g.drawString(InitPlayer.players.get(0).getPlayerMaJiangs().size() + "东", 300, 420);
g.setColor(Color.LIGHT_GRAY);
} else {
g.drawString(InitPlayer.players.get(0).getPlayerMaJiangs().size() + "东", 300, 420);
}
if (InitPlayer.players.get(1).isRunzt()) {
g.setColor(Color.green);
g.drawString(InitPlayer.players.get(1).getPlayerMaJiangs().size() + "南", 560, 300);
g.setColor(Color.LIGHT_GRAY);
} else {
g.drawString(InitPlayer.players.get(1).getPlayerMaJiangs().size() + "南", 560, 300);
}
if (InitPlayer.players.get(2).isRunzt()) {
g.setColor(Color.green);
g.drawString(InitPlayer.players.get(2).getPlayerMaJiangs().size() + "西", 300, 160);
g.setColor(Color.LIGHT_GRAY);
} else {
g.drawString(InitPlayer.players.get(2).getPlayerMaJiangs().size() + "西", 300, 160);
}
if (InitPlayer.players.get(3).isRunzt()) {
g.setColor(Color.green);
g.drawString(InitPlayer.players.get(3).getPlayerMaJiangs().size() + "北", 120, 300);
g.setColor(Color.LIGHT_GRAY);
} else {
g.drawString(InitPlayer.players.get(3).getPlayerMaJiangs().size() + "北", 120, 300);
}
g.setFont(new Font("宋体", Font.BOLD, 50));
g.setColor(Color.red);
if (player.isHul()) {
g.drawString("胡", 360, 420);
}
if (computer1.isHul()) {
g.drawString("胡", 630, 300);
}
if (computer2.isHul()) {
g.drawString("胡", 360, 160);
}
if (computer3.isHul()) {
g.drawString("胡", 180, 300);
}
// 出牌倒计时
if (tlaber.getCount() > 0) {
g.setColor(Color.BLUE);
g.drawString(tlaber.getCount() + "", 380, 300);
}
g.setColor(Color.darkGray);
g.drawString("剩:" + ShuffleMahJong.maJiangs.size(), 380, 250);
}
/**
* 设置按钮图片缩放
*
* @param file
* @param iconButton
*/
public void setIcon(String file, JButton iconButton) {
ImageIcon icon = new ImageIcon(file);
icon.getImage();
Image temp = icon.getImage().getScaledInstance(iconButton.getWidth(), iconButton.getHeight(),
Image.SCALE_DEFAULT);
icon = new ImageIcon(temp);
iconButton.setIcon(icon);
}
public void jbutton() {
// 创建按钮对象
for (int i = 0; i < 14; i++) {
b2 = new JButton("b2 " + i);
b2.addMouseListener(new EventListeners(b2));
// 把按钮容器添加到JFrame容器上
if (i < 13) {
b2.setBounds(600 - 30 * i, 50, 31, 70);
} else {
b2.setBounds(600 - 50 - 30 * i, 50, 31, 70);
}
// 设置按钮透明
b2.setContentAreaFilled(false);
add(b2);
}
for (int i = 0; i < 14; i++) {
b0 = new JButton("b0 " + i);
b0.addMouseListener(new EventListeners(b0));
// 把按钮容器添加到JFrame容器上
if (i < 13) {
b0.setBounds(143 + 30 * i, 430, 31, 70);
} else {
b0.setBounds(193 + 30 * i, 430, 31, 70);
}
// 设置按钮透明
b0.setContentAreaFilled(false);
add(b0);
}
for (int i = 0; i < 14; i++) {
b3 = new JButton("b3 " + i);
b3.addMouseListener(new EventListeners(b3));
// 把按钮容器添加到JFrame容器上
if (i < 13) {
b3.setBounds(50, 50 + 30 * i, 70, 31);
} else {
b3.setBounds(50, 50 + 50 + 30 * i, 70, 31);
}
// 设置按钮透明
b3.setContentAreaFilled(false);
add(b3);
}
for (int i = 0; i < 14; i++) {
b1 = new JButton("b1 " + i);
b1.addMouseListener(new EventListeners(b1));
// 把按钮容器添加到JFrame容器上
if (i < 13) {
b1.setBounds(680, 480 - 30 * i, 70, 31);
} else {
b1.setBounds(680, 480 - 50 - 30 * i, 70, 31);
}
// 设置按钮透明
b1.setContentAreaFilled(false);
add(b1);
}
}
public void run() {
while (true) {
try {
this.repaint();
Thread.sleep(100);
synchronized (this) {
// 检测是否胡牌
if (player != null) {
player.huCards();
computer1.huCards();
computer2.huCards();
computer3.huCards();
}
// 判断玩家是否超时 超时自动打牌
if (tlaber.getCount() == 0 && tlaber.isStart()) {
int numb = 0;
if (initPlayer.zdchupai() > 1 && initPlayer.zdchupai() != 0) {
numb = initPlayer.zdchupai();
}
// 判断该哪一个玩家出牌
if (InitPlayer.players.get(0).isRunzt()) {
int jj;
// 打牌
InitPlayer.players.get(0).discardMaJiang(numb);
// 把该牌删掉
InitPlayer.players.get(0).Remove(numb);
// 排序
InitPlayer.players.get(0).printMaJiangs();
// 关闭上一个线程
tlaber.stop();
InitPlayer.players.get(0).setRunzt(false);
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(1).gainMaJiang(0);
InitPlayer.players.get(1).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
// tlaber=new TimerLabel(5);
// tlaber.start();
} else if (InitPlayer.players.get(1).isRunzt()) {
InitPlayer.players.get(1).discardMaJiang(numb);
// 排序
InitPlayer.players.get(1).printMaJiangs();
// 把该牌删掉
InitPlayer.players.get(1).Remove(numb);
// 关闭上一个线程
tlaber.stop();
InitPlayer.players.get(1).setRunzt(false);
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(2).gainMaJiang(0);
InitPlayer.players.get(2).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
// tlaber=new TimerLabel(5);
// tlaber.start();
} else if (InitPlayer.players.get(2).isRunzt()) {
InitPlayer.players.get(2).discardMaJiang(numb);
// 排序
InitPlayer.players.get(2).printMaJiangs();
// 把该牌删掉
InitPlayer.players.get(2).Remove(numb);
// 关闭上一个线程
tlaber.stop();
InitPlayer.players.get(2).setRunzt(false);
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(3).gainMaJiang(0);
InitPlayer.players.get(3).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
// tlaber=new TimerLabel(5);
// tlaber.start();
} else if (InitPlayer.players.get(3).isRunzt()) {
InitPlayer.players.get(3).discardMaJiang(numb);
// 排序
InitPlayer.players.get(3).printMaJiangs();
// 把该牌删掉
InitPlayer.players.get(3).Remove(numb);
// 关闭上一个线程
tlaber.stop();
InitPlayer.players.get(3).setRunzt(false);
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(0).gainMaJiang(0);
InitPlayer.players.get(0).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
// tlaber =new TimerLabel(5);
// tlaber.start();
}
// 没牌了停止线程
if (ShuffleMahJong.maJiangs.size() <= 0) {
tlaber.stop();
} else {
// 启动新线程
tlaber = new TimerLabel(0);
tlaber.start();
}
}
}
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
class EventListeners extends MouseAdapter {
// 获取按钮信息
JButton b;
TimerLabel label;
public EventListeners(JButton b) {
this.b = b;
}
public void mouseClicked(MouseEvent e) {
String outStr = "";
if (e.getClickCount() == 2) {
// 获取后两位数
int btnum = Integer
.parseInt((b.getText().substring(b.getText().length() - 2, b.getText().length())).trim());
// 拿到前两位字符串
String btstr = b.getText().substring(0, 2);
int numb = 3;
// 检测是否胡牌
if (player != null) {
player.huCards();
computer1.huCards();
computer2.huCards();
computer3.huCards();
}
// 满足牌数为二倍,判断是否是该玩家,判断是否到该玩家出牌
if (btstr.equals("b0") && InitPlayer.players.get(0).isRunzt()) {
// 打牌
InitPlayer.players.get(0).discardMaJiang(btnum);
// 把该牌删掉
InitPlayer.players.get(0).Remove(btnum);
// 排序
InitPlayer.players.get(0).printMaJiangs();
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
tlaber.stop();
InitPlayer.players.get(0).setRunzt(false);
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(1).gainMaJiang(0);
InitPlayer.players.get(1).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
tlaber = new TimerLabel(numb);
tlaber.start();
} else if (btstr.equals("b1") && InitPlayer.players.get(1).isRunzt()) {
// 打牌
InitPlayer.players.get(1).discardMaJiang(btnum);
// 把该牌删掉
InitPlayer.players.get(1).Remove(btnum);
// 排序
InitPlayer.players.get(1).printMaJiangs();
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
tlaber.stop();
InitPlayer.players.get(1).setRunzt(false);
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(2).gainMaJiang(0);
InitPlayer.players.get(2).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
tlaber = new TimerLabel(numb);
tlaber.start();
} else if (btstr.equals("b2") && InitPlayer.players.get(2).isRunzt()) {
// 打牌
InitPlayer.players.get(2).discardMaJiang(btnum);
// 把该牌删掉
InitPlayer.players.get(2).Remove(btnum);
// 排序
InitPlayer.players.get(2).printMaJiangs();
// 碰牌检测
tlaber.stop();
InitPlayer.players.get(2).setRunzt(false);
Player playerto = InitPlayer.touchDetection();
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(3).gainMaJiang(0);
InitPlayer.players.get(3).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
tlaber = new TimerLabel(numb);
tlaber.start();
} else if (btstr.equals("b3") && InitPlayer.players.get(3).isRunzt()) {
// 打牌
InitPlayer.players.get(3).discardMaJiang(btnum);
// 把该牌删掉
InitPlayer.players.get(3).Remove(btnum);
// 排序
InitPlayer.players.get(3).printMaJiangs();
tlaber.stop();
InitPlayer.players.get(3).setRunzt(false);
// 碰牌检测
Player playerto = InitPlayer.touchDetection();
if (playerto == null) {
// 下一家摸牌
InitPlayer.players.get(0).gainMaJiang(0);
InitPlayer.players.get(0).setRunzt(true);
} else {
playerto.setRunzt(true);
}
// //启动新线程
tlaber = new TimerLabel(numb);
tlaber.start();
}
outStr = outStr + "双击" + b.getText();
}
// System.out.print("label=="+label);
}
}
}
package com.jbutton;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* 图片旋转工具类
*/
public class RotateImage {
/**
* 对图片进行旋转
*
* @param src 被旋转图片
* @param angel 旋转角度
* @return 旋转后的图片
*/
public static BufferedImage Rotate(Image src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
// 计算旋转后图片的尺寸
Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
src_width, src_height)), angel);
BufferedImage res = null;
try {
res = new BufferedImage(rect_des.width, rect_des.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = res.createGraphics();
// 进行转换
g2.translate((rect_des.width - src_width) / 2,
(rect_des.height - src_height) / 2);
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
} catch (Exception e) {
// TODO: handle exception
}
return res;
}
/**
* 计算旋转后的图片
*
* @param src 被旋转的图片
* @param angel 旋转角度
* @return 旋转后的图片
*/
public static Rectangle CalcRotatedSize(Rectangle src, int angel) {
// 如果旋转的角度大于90度做相应的转换
if (angel >= 90) {
if (angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new Rectangle(new Dimension(des_width, des_height));
}
}
package com.time;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.lang.Thread.State;
/**
* 计时标签package text.run;
*
* @author Jeky
*/
public class TimerLabel extends JLabel {
private int maxTime;
public Thread getThread() {
return thread;
}
private int count;
private static final int SECOND = 1000;
private static final int FONT_SIZE = 36;
private Thread thread;
private boolean pause;
private boolean start;
/**
* 新建一个计时标签
*
* @param maxTime 倒计时起始时间
*/
public TimerLabel(int maxTime) {
this.setHorizontalAlignment(JLabel.CENTER);
this.setFont(new Font("Times New Roman", Font.BOLD, FONT_SIZE));
this.pause = false;
setMaxTime(maxTime);
}
/**
* 修改倒计时起始时间
*
* @param maxTime 新的起始时间
*/
public void setMaxTime(int maxTime) {
if (this.start) {
return;
}
this.maxTime = maxTime;
this.count = maxTime;
initText();
this.thread = new Thread(new Runnable() {
@Override
public void run() {
while (count != 0) {
try {
if (!start) {
count = 0;
//initText();
//System.out.println("count=11="+count+start);
break;
}
if (!pause) {
Thread.sleep(SECOND);
count--;
//System.out.println("pause=11="+count+pause);
//initText();
}
} catch (InterruptedException ex) {
pause = true;
}
}
//done();
}
});
this.start = false;
}
/**
* 倒计时完成后调用此方法
*/
public void done() {
JOptionPane.showMessageDialog(this, "结束!");
}
/**
* 标签字符由此方法设置
*/
public void initText() {
String min = String.valueOf(count / 60);
String sec = String.valueOf(count % 60);
while (min.length() < 2) {
min = "0" + min;
}
while (sec.length() < 2) {
sec = "0" + sec;
}
this.setText(sec);
}
/**
* 暂停
*/
public void pause() {
if (start) {
thread.interrupt();
}
}
/**
* 检测标签倒计时是否开始
*
* @return 如果开始返回true
*/
public boolean isStart() {
return start;
}
/**
* 得到倒计时起始时间
*
* @return 倒计时起始时间
*/
public int getMaxTime() {
return maxTime;
}
/**
* 检测标签倒计时是否暂停
*
* @return 倒计时暂停返回true
*/
public boolean isPause() {
return pause;
}
/**
* 从暂停中恢复计时
*/
public void continueDo() {
if (this.pause) {
this.pause = false;
}
}
/**
* 取消计时
*/
public void stop() {
if (start) {
//thread.interrupt();
this.count=-11;
start = false;
}
}
/**
* 开始计时
*/
public void start() {
if (thread.getState().equals(State.NEW)) {
start = true;
thread.start();
} else if (thread.getState().equals(State.TERMINATED)) {
setMaxTime(maxTime);
start = true;
thread.start();
}
}
public int getCount() {
// TODO 自动生成的方法存根
return count;
}
}
//演示程序 Test.java
package main;
import java.util.*;
/**
*
* @author Administrator 初始化玩家:创建四个玩家(包括3个电脑)
*/
public class InitPlayer {
/**
* 4个玩家的信息都存放在List中,下标为0是人,其余的为电脑
*/
public static List<Player> players = new ArrayList<Player>();
private static Player player = null;
private static Player computer1 = null;
private static Player computer2 = null;
private static Player computer3 = null;
public InitPlayer() {
// 创建4个玩家
createPlayer();
}
/**
* 自动打出其他玩家能碰,杠的牌
* @return
*/
public int zdchupai() {
if(player.isRunzt()) {
List<MahjongTile> list=player.getPlayerMaJiangs();
//遍历自己的集合
for (MahjongTile mahjongTile : list) {
if(Player.frequency(computer1.getPlayerMaJiangs(), mahjongTile)>1) {
//System.out.println(computer1+"="+list.indexOf(mahjongTile)+"="+Player.frequency(computer1.getPlayerMaJiangs(), mahjongTile));
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile)>1) {
//System.out.println(computer2+"="+list.indexOf(mahjongTile)+"="+Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile));
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile)>1) {
//System.out.println(computer2+"="+list.indexOf(mahjongTile)+"="+Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile));
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
}
}
if(computer1.isRunzt()) {
List<MahjongTile> list=computer1.getPlayerMaJiangs();
//遍历自己的集合
for (MahjongTile mahjongTile : list) {
if(Player.frequency(player.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
}
}
if(computer2.isRunzt()) {
List<MahjongTile> list=computer2.getPlayerMaJiangs();
//遍历自己的集合
for (MahjongTile mahjongTile : list) {
if(Player.frequency(player.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer1.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
}
}
if(computer3.isRunzt()) {
List<MahjongTile> list=computer3.getPlayerMaJiangs();
//遍历自己的集合
for (MahjongTile mahjongTile : list) {
if(Player.frequency(player.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
if(Player.frequency(computer1.getPlayerMaJiangs(), mahjongTile)>1) {
return list.indexOf(mahjongTile);//返回第一个出现元素 O 的位置;
}
}
}
return 0;
}
/**
* 检测是否有可以碰的牌
* @return
*/
public static Player touchDetection() {
//检测是否有杠的牌 不做处理直接杠牌
if(player.barCards()) {
//摸牌
player.gainMaJiang(0);
return player;
}
else if(computer1.barCards()) {
computer1.gainMaJiang(0);
return computer1;
}
else if(computer2.barCards()) {
computer2.gainMaJiang(0);
return computer2;
}
else if(computer3.barCards()) {
computer3.gainMaJiang(0);
return computer3;
}
//检测是否有碰的牌 不做处理直接碰牌
if(player.touchCards()) {
return player;
}
if(computer1.touchCards()) {
return computer1;
}
if(computer2.touchCards()) {
return computer2;
}
if(computer3.touchCards()) {
return computer3;
}
return null;
}
/**
* 创建4个玩家
*/
private void createPlayer() {
player = new Player();
computer1 = new Player();
computer2 = new Player();
computer3 = new Player();
player.setName("玩家");
computer1.setName("电脑1");
computer2.setName("电脑2");
computer3.setName("电脑3");
players.add(player);
players.add(computer1);
players.add(computer2);
players.add(computer3);
}
/**
* 输出四个玩家手中的牌
*/
public void printPlayer() {
// 输出当前玩家手中的牌
System.out.println("【当前玩家手中的牌如下:】");
System.out.print(player);
player.printMaJiangs();
System.out.print(computer1);
computer1.printMaJiangs();
System.out.print(computer2);
computer2.printMaJiangs();
System.out.print(computer3);
computer3.printMaJiangs();
}
public void printPlayer(Player players) {
// 输出当前玩家手中的牌
//System.out.println("【当前玩家手中的牌如下:】");
System.out.println(players.getPlayerMaJiangs());
}
/**
* 输出四个玩家手中的牌
*/
/**
* 第一次起牌:轮流起牌,每次起4张,一共起3轮
*/
public void haveFirstBoard() {
// 共3轮
for (int i = 0; i < 3; i++) {
// 玩家,每次起4张
for (int j = 0; j < 4; j++) {
player.gainMaJiang(ShuffleMahJong.maJiangsIndex);
}
// 电脑1,每次起4张
for (int j = 0; j < 4; j++) {
computer1.gainMaJiang(ShuffleMahJong.maJiangsIndex);
}
// 电脑2,每次起4张
for (int j = 0; j < 4; j++) {
computer2.gainMaJiang(ShuffleMahJong.maJiangsIndex);
}
// 电脑3,每次起4张
for (int j = 0; j < 4; j++) {
computer3.gainMaJiang(ShuffleMahJong.maJiangsIndex);
}
}
}
/**
* 第二次起牌:跳庄(玩家拿第1和第5张,电脑1拿第2张,电脑2拿第3张,电脑3拿第4张)
*/
public void haveJumpBoard() {
player.gainMaJiang(0);
computer1.gainMaJiang(1);
computer2.gainMaJiang(2);
computer3.gainMaJiang(3);
}
/**
* 翻癞子(癞子可以当成是任何一张牌)
*/
public void haveWildBoard() {
System.out.println("【癞子是:" + ShuffleMahJong.maJiangs.get(5) + "】");
// 直接移除第6张牌
ShuffleMahJong.maJiangs.remove(5);
}
}
package main;
import java.util.*;
/**
*
* @author LiHai
*
*/
public class MahjongStaticTool {
static int nextPlayer = 0;
/**
* 复制牌的集合
*
* @param mahjongTiles
* @param indexs
* @return
*/
private static MahjongTile[] removeSomeMahjongTiles(MahjongTile[] mahjongTiles, int[] indexs) {
/*
* indexs表示万筒条的大小1~9的数组; mahjongTiles.length原来长度为14 indexs.length长度为3
*/
int lenNew = mahjongTiles.length - indexs.length;
// System.out.println("mahjongTiles.length=="+mahjongTiles.length+"
// indexs.length=="+indexs.length);
if (lenNew > 0) {
MahjongTile[] mahjongTilesNew = new MahjongTile[lenNew];
int index = 0;
for (int i = 0; i < mahjongTiles.length; i++) {
boolean isAppend = true;
for (int j = 0; j < indexs.length; j++) {
/*
* 如果i==indexs[j]该函数将不参与mahjongTilesNew的复制
*/
if (i == indexs[j]) {
//System.out.println("indexs[" + i + "]==" + indexs[j] + "mahjongTiles[i]=" + mahjongTiles[i]);
isAppend = false;
break;
}
}
if (isAppend) {
/*
* 把mahjongTiles集合复制到mahjongTilesNew数组 实现删除
*/
mahjongTilesNew[index] = mahjongTiles[i];
//System.out.println("mahjongTilesNew[" + index + "]==" + mahjongTilesNew[index]);
index++;
}
}
return mahjongTilesNew;
}
return null;
}
/**
* 比较一对将 从数组长度为arrayLen的整形数组中任意抽取两个元素,
* 把所有可能的组合的索引列成一个二位数组返回出来
*
* @param arrayLen
* @return
*/
private static int[][] siphonTwoIndexs(int arrayLen) {
int len = (arrayLen * (arrayLen - 1)) / 2;
if (len > 0) {
int[][] indexs = new int[len][2];
int index = 0;
for (int i = 0; i < arrayLen; i++) {
for (int j = (i + 1); j < arrayLen; j++) {
indexs[index][0] = i;
indexs[index][1] = j;
index++;
}
}
return indexs;
} else {
return null;
}
}
/**
* 比较三张连牌或者三张同样的牌 从数组长度为arrayLen的整形数组中任意抽取两个元素, 把所有可能的组合的索引列成一个二位数组返回出来
*
* @param arrayLen
* @return
*/
private static int[][] siphonThreeIndexs(int arrayLen) {
int len = (arrayLen * (arrayLen - 1) * (arrayLen - 2)) / 6;
// System.out.println("循环次数len====="+len+"="+arrayLen+"*"+(arrayLen-1)+"*"+(arrayLen-2)+"/6");
if (len > 0) {
int[][] indexs = new int[len][3];
int index = 0;
for (int i = 0; i < arrayLen; i++) {
for (int j = (i + 1); j < arrayLen; j++) {
for (int k = (j + 1); k < arrayLen; k++) {
indexs[index][0] = i;
indexs[index][1] = j;
indexs[index][2] = k;
// System.out.println("indexs["+index+"][0],indexs["+index+"][1],indexs["+index+"][2]="+indexs[index][0]+","+indexs[index][1]+","+indexs[index][2]);
index++;
}
}
}
return indexs;
} else {
return null;
}
}
/**
* 传进玩家牌的二维集合,和三张牌 复制集合
*
* @param saveMahjongTileses
* @param mahjongTiles
* @return
*/
private static MahjongTile[][] appendSomeMahjongTiles(MahjongTile[][] saveMahjongTileses,
MahjongTile[] mahjongTiles) {
if (saveMahjongTileses == null) {
MahjongTile[][] mahjongTilesesReturn = new MahjongTile[1][];
mahjongTilesesReturn[0] = mahjongTiles;
return mahjongTilesesReturn;
} else {
// 创建一个比原来集合更长的集合
MahjongTile[][] mahjongTilesesReturn = new MahjongTile[saveMahjongTileses.length + 1][];
/*
* arraycopy(Object src,int srcPos,Object dest, int destPos,int length)
* src表示源数组,srcPos表示源数组要复制的起始位置, desc表示目标数组,length表示要复制的长度。
*/
//System.arraycopy(saveMahjongTileses, 0, mahjongTilesesReturn, 0, saveMahjongTileses.length);
mahjongTilesesReturn[saveMahjongTileses.length] = mahjongTiles;
return mahjongTilesesReturn;
}
}
public static MahjongTile[][] tryCombination(MahjongTile[] mahjongTiles, int twoNum, int threeNum) {
// mahjongTiles表示玩家手中的所有牌的
return MahjongStaticTool.tryCombination(mahjongTiles, twoNum, threeNum, null);
}
/**
* 把数组牌转为list牌集
*
* @param paiArr
*/
public static List<Integer> arrToList(int[][] paiArr) {
List<Integer> paiList = new ArrayList<>();
for (int i = 0; i < paiArr.length; i++) {
for (int j = 0; j < paiArr[i].length; j++) {
int paiNum = paiArr[i][j];// 根据每一张牌的数量逆转
if (paiNum <= 0) {
continue;
}
for (int k = 0; k < paiArr[i][j]; k++) {
paiList.add((i + 1) + j);
}
}
}
return paiList;
}
/**
* 判断是否胡牌的方法 mahjongTiles玩家所有的牌 twoNum表示一对将 threeNum表示3个连着的牌或者三张同样的牌
*
* @param mahjongTiles
* @param twoNum
* @param threeNum
* @param saveMahjongTileses
* @return
*/
private static MahjongTile[][] tryCombination(MahjongTile[] mahjongTiles, int twoNum, int threeNum,
MahjongTile[][] saveMahjongTileses) {
if (mahjongTiles == null) {
if (twoNum == 0 && threeNum == 0) {
return saveMahjongTileses;
} else {
return null;
}
}
// 第一次固定twoNum=1 threeNum=4
if (mahjongTiles.length == ((twoNum * 2) + (threeNum * 3))) {
if (threeNum > 0) {
// 通过siphonThreeIndexs获得十三张牌的所有三张顺子或者刻子的组合
int[][] indexs = siphonThreeIndexs(mahjongTiles.length);
// System.out.println("indexs大小==" + indexs.length);
for (int i = 0; i < indexs.length; i++) {
for (int j = 0; j < indexs[i].length; j++) {
if (i != 0) {
// System.out.print(" ");
}
// System.out.print(indexs[i][j]);
}
}
// 遍历indexs数组
for (int[] index : indexs) {
/*
* 如果mahjongTiles[index[0]],mahjongTiles[index[1]],
* mahjongTiles[index[2]]相等返回true 三张牌相同
* 如果mahjongTiles[index[0]],mahjongTiles[index[1]], mahjongTiles[index[2]]是顺子
* 返回true 三张牌为 1,2,3或者5,6,7
*
*/
// 当出现三张同样或者顺子时
if (mahjongTiles[index[0]].isCanThree(mahjongTiles[index[1]], mahjongTiles[index[2]])) {
// System.out.println("mahjongTiles[" + index[0] + "]==" + mahjongTiles[index[0]]
// + " mahjongTiles[" + index[1] + "]==" + mahjongTiles[index[1]] + " mahjongTiles["
// + index[2] + "]==" + mahjongTiles[index[2]] + " mahjongTiles.length=="
// + mahjongTiles.length);
// 传进一个牌的集合,三张同样的麻将
// 利用该函数appendSomeMahjongTiles把三张牌重新复制到二维集合saveMahjongTilesesCache中
MahjongTile[][] saveMahjongTilesesCache = appendSomeMahjongTiles(saveMahjongTileses,
new MahjongTile[] { mahjongTiles[index[0]], mahjongTiles[index[1]],
mahjongTiles[index[2]] });
// 使用removeSomeMahjongTiles获得新的MahjongTile[]
MahjongTile[][] mahjongTilesesReturn = MahjongStaticTool.tryCombination(
removeSomeMahjongTiles(mahjongTiles, new int[] { index[0], index[1], index[2] }),
twoNum, threeNum - 1, saveMahjongTilesesCache);
if (mahjongTilesesReturn != null) {
return mahjongTilesesReturn;
}
}
}
} else if (twoNum > 0) {
// 通过该数据获得所有可能是一对 将 的组合
int[][] indexs = siphonTwoIndexs(mahjongTiles.length);
if (indexs == null) {
return null;
}
for (int[] index : indexs) {
if (mahjongTiles[index[0]].isCanTwo(mahjongTiles[index[1]])) {
MahjongTile[][] saveMahjongTilesesCache = appendSomeMahjongTiles(saveMahjongTileses,
new MahjongTile[] { mahjongTiles[index[0]], mahjongTiles[index[1]] });
MahjongTile[][] mahjongTilesesReturn = MahjongStaticTool.tryCombination(
removeSomeMahjongTiles(mahjongTiles, new int[] { index[0], index[1] }), twoNum - 1,
threeNum, saveMahjongTilesesCache);
if (mahjongTilesesReturn != null) {
return mahjongTilesesReturn;
}
}
}
} else {
return saveMahjongTileses;
}
}
return null;
}
/**
* 测试
*
* @param args
* @throws MahjongTileInitWrongTypeAndTypeIdException
* @throws MahjongTileInitWrongNameException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {
MahjongTile[] mahjongTiles = new MahjongTile[] {
new MahjongTile(1, 1),
new MahjongTile(1, 1),
};
//System.out.println("检查所有下列牌:");
for (int i = 0; i < mahjongTiles.length; i++) {
if (i != 0) {
System.out.print(",");
}
System.out.print(mahjongTiles[i]);
}
System.out.println("");
MahjongTile[][] mahjongTileses = tryCombination(mahjongTiles, 1, 0);
if (mahjongTileses != null) {
System.out.println("检查通过!");
System.out.println("组合结果如下:");
int twoIndex = 1;
int threeIndex = 1;
for (MahjongTile[] mahjongTilesRow : mahjongTileses) {
if (mahjongTilesRow.length == 2) {
System.out.print("第" + twoIndex + "对组合:");
for (int j = 0; j < mahjongTilesRow.length; j++) {
if (j != 0) {
System.out.print(",");
}
//System.out.print(mahjongTilesRow[j]);
}
System.out.println("");
twoIndex++;
} else if (mahjongTilesRow.length == 3) {
System.out.print("第" + threeIndex + "趟组合:");
for (int j = 0; j < mahjongTilesRow.length; j++) {
if (j != 0) {
System.out.print(",");
}
//System.out.print(mahjongTilesRow[j]);
}
System.out.println("");
threeIndex++;
}
}
} else {
System.out.println("检查未通过!");
}
}
}
package main;
import java.util.*;
import java.util.Comparator;
/**
* 单张麻将牌
* @author LiHai
*
*/
public class MahjongTile implements Comparable<MahjongTile>
{
//万
public static int MAHJONG_TILE_TYPE_TEN_THOUSAND = 1;
//筒
public static int MAHJONG_TILE_TYPE_PIE = 3;
//条
public static int MAHJONG_TILE_TYPE_STRIP = 2;
public static int MAHJONG_TILE_TYPE_WIND = 4;
public static int MAHJONG_TILE_TYPE_MESS = 5;
public static int MAHJONG_TILE_TYPE_FLOWER = 6;
/**
* 标准麻将的各种牌的名称,该名称为一个三维数组,第一维为各套独立的名称
* 第二维为每套名称中的不同类别,例如万和桶属于不同类型的牌
* 第三维维具体的名称
* String[1][1][1] 表示一万
* String[2][1][1] 表示一万
* String[2][2][2]表示二饼
*/
public final static String[][][] STANDARD_MAHJONG_NAMES = {
new String[][]{
{"一万","二万","三万","四万","五万","六万","七万","八万","九万"},
{"一条","二条","三条","四条","五条","六条","七条","八条","九条"},
{"一桶","二桶","三桶","四桶","五桶","六桶","七桶","八桶","九桶"},
{"东风","南风","西风","北风"},
{"红中","发财","白板"},
{"春","夏","秋","冬","梅","兰","竹","菊"}
},
new String[][]{
{"一万","二万","三万","四万","五万","六万","七万","八万","九万"},
{"一条","二条","三条","四条","五条","六条","七条","八条","九条"},
{"一饼","二饼","三饼","四饼","五饼","六饼","七饼","八饼","九饼"},
{"东风","南风","西风","北风"},
{"红中","发财","白板"},
{"春","夏","秋","冬","梅","兰","竹","菊"}
}
};
//表示麻将种类 共两种
private final int type;
//表示麻将ID号 万筒条的一万还是二万
private final int typeId;
private final int uniqueId;
public MahjongTile(int type, int typeId) throws MahjongTileInitWrongTypeAndTypeIdException
{
this.uniqueId = computeUniqueId(type, typeId);
this.type = type;
this.typeId = typeId;
}
public MahjongTile(String name) throws MahjongTileInitWrongTypeAndTypeIdException, MahjongTileInitWrongNameException
{
for (String[][] standardMahjongName : STANDARD_MAHJONG_NAMES)
{
for (int j = 0; j < standardMahjongName.length; j++)
{
for (int k = 0; k < standardMahjongName[j].length; k++)
{
if (standardMahjongName[j][k].equals(name))
{
this.type = j + 1;
this.typeId = k + 1;
this.uniqueId = computeUniqueId(type, typeId);
return;
}
}
}
}
throw new MahjongTileInitWrongNameException(name);
}
/**
* 排序
*/
public int compareTo(MahjongTile o) {
// TODO Auto-generated method stub
return this.typeId-o.typeId;
}
private int computeUniqueId(int type, int typeId) throws MahjongTileInitWrongTypeAndTypeIdException
{
initCheck(type, typeId);
if (type == MAHJONG_TILE_TYPE_TEN_THOUSAND)//MAHJONG_TILE_TYPE_TEN_THOUSAND=1
{
return typeId;
//万 1 2 3 4 5 6 7 8 9
}
else if (type == MAHJONG_TILE_TYPE_PIE)//MAHJONG_TILE_TYPE_PIE=3
{
return typeId + 18;
//筒 10 11 12 13 14 15 16 17 18
}
else if (type == MAHJONG_TILE_TYPE_STRIP)//2
{
return typeId + 9;
//条 19 20 21 22 23 24 25 26 27
}
else if (type == MAHJONG_TILE_TYPE_WIND)//4
{
return typeId + 27;
//东南西北 28 29 30 31
}
else if (type == MAHJONG_TILE_TYPE_MESS)//5
{
return typeId + 31;
//红中发财白板 32 33 34
}
else
{
return typeId + 34;
//35 36 37 38 39 40 41 42
}
}
public int getType()
{
return type;
}
public int getTypeId()
{
return typeId;
}
public int getUniqueId()
{
return typeId;
}
private void initCheck(int type, int typeId) throws MahjongTileInitWrongTypeAndTypeIdException
{
if (STANDARD_MAHJONG_NAMES[0].length < type || type < 1)
{
throw new MahjongTileInitWrongTypeAndTypeIdException(type, typeId, true);
}
else if (STANDARD_MAHJONG_NAMES[0][type - 1].length < typeId || typeId < 1)
{
throw new MahjongTileInitWrongTypeAndTypeIdException(type, typeId, false);
}
}
//表示百搭
public boolean isCanAny()
{
if (type == 1 && typeId == 9)
{
return true;
}
return false;
}
public boolean isCanThree(MahjongTile mahjongTileOne, MahjongTile mahjongTileTwo)
{
//判断第一个和第二个是否是 万筒条 的同一种类型
if (type == mahjongTileOne.type && type == mahjongTileTwo.type)
{
//判断是否是刻子
if (typeId == mahjongTileOne.typeId && typeId == mahjongTileTwo.typeId)
{
return true;
}
//isIdLink判断是否是顺子 如果是返回true并且type不等于 4,5,6 因为4,5,6不表示万筒条
else if (isIdLink(typeId, mahjongTileOne.typeId, mahjongTileTwo.typeId) && type != MAHJONG_TILE_TYPE_WIND && type != MAHJONG_TILE_TYPE_MESS && type != MAHJONG_TILE_TYPE_FLOWER)
{
return true;
}
}
//isCanAny()表示百搭
// if (isCanAny())
// {
// if (mahjongTileOne.isCanAny() || mahjongTileTwo.isCanAny())
// {
// return true;
// }
// else if (Math.abs(mahjongTileOne.typeId - mahjongTileTwo.typeId) <= 2 && mahjongTileOne.type == mahjongTileTwo.type)
// {
// return true;
// }
// }
// else if (mahjongTileOne.isCanAny())
// {
// if (isCanAny() || mahjongTileTwo.isCanAny())
// {
// return true;
// }
// else if (Math.abs(typeId - mahjongTileTwo.typeId) <= 2 && type == mahjongTileTwo.type)
// {
// return true;
// }
// }
// else if (mahjongTileTwo.isCanAny())
// {
// if (mahjongTileOne.isCanAny() || isCanAny())
// {
// return true;
// }
// else if ((Math.abs(typeId - mahjongTileOne.typeId) <= 2) && type == mahjongTileOne.type)
// {
// return true;
// }
// }
return false;
}
public boolean isCanTwo(MahjongTile mahjongTile)
{
if (isCanAny() || mahjongTile.isCanAny())
{
return true;
}
else
{
return uniqueId == mahjongTile.uniqueId;
}
}
//判断是否是顺子 如果是返回true
private boolean isIdLink(int id1, int id2, int id3)
{
int[] ids =
{
id1, id2, id3
};
Arrays.sort(ids);
if (ids[2] - ids[1] != 1)
{
return false;
}
else if (ids[1] - ids[0] != 1)
{
return false;
}
return true;
}
@Override
public String toString()
{
String name = STANDARD_MAHJONG_NAMES[0][type - 1][typeId - 1];
if (isCanAny())
{
name = name + "(百搭)";
}
return name;
}
}
package main;
/**
*
* @author LiHai
*
*/
@SuppressWarnings("serial")
public class MahjongTileInitWrongNameException extends Exception
{
private final String wrongName;
public MahjongTileInitWrongNameException(String wrongName)
{
this.wrongName = wrongName;
}
public String getWrongName()
{
return wrongName;
}
public String[][][] standardMahjongNames()
{
return MahjongTile.STANDARD_MAHJONG_NAMES;
}
}
package main;
/**
* 麻将参数
* @author LiHai
*
*/
@SuppressWarnings("serial")
public class MahjongTileInitWrongTypeAndTypeIdException extends Exception
{
private final int type;
private final int typeId;
private final boolean isTypeWrong;
public MahjongTileInitWrongTypeAndTypeIdException(int type,int typeId,boolean isTypeWrong)
{
this.type = type;
this.typeId = typeId;
this.isTypeWrong = isTypeWrong;
}
public int type()
{
return type;
}
public int typeId()
{
return typeId;
}
public boolean isTypeWrong()
{
return isTypeWrong;
}
}
package main;
import java.util.*;
/**
* 玩家信息和牌 判断碰,杠,胡 及摸牌,出牌
* @author LiHai
*
*/
public class Player {
/**
* 玩家姓名
*/
private String name;
/**
* 每个玩家的牌都放在playerMaJiangs中
*/
private List<MahjongTile> playerMaJiangs = new ArrayList<MahjongTile>();
/**
* 用来指示“每个玩家的牌”在playerMaJiangs中的下标
*/
private int playerMaJiangsIndex = 0;
/**
* 是否到该玩家出牌 运行状态
*/
private boolean runzt = false;
//玩家没胡
private boolean hul=false;
public boolean isHul() {
return hul;
}
public void setHul(boolean hul) {
this.hul = hul;
}
public boolean isRunzt() {
return runzt;
}
public void setRunzt(boolean runzt) {
this.runzt = runzt;
}
public int getPlayerMaJiangsIndex() {
return playerMaJiangsIndex;
}
public void setPlayerMaJiangsIndex(int playerMaJiangsIndex) {
this.playerMaJiangsIndex = playerMaJiangsIndex;
}
public Player() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<MahjongTile> getPlayerMaJiangs() {
return playerMaJiangs;
}
public void setPlayerMaJiangs(List<MahjongTile> playerMaJiangs) {
this.playerMaJiangs = playerMaJiangs;
}
@Override
public String toString() {
return "[" + name + "]";
}
/**
* 摸牌:从ShuffleMaJiang中的maJiangs中取一粒麻将,放入到自己的playerMaJiangs中
* @param index
* @return
*/
public boolean gainMaJiang(int index) {
// System.out.println("剩余 "+ShuffleMahJong.maJiangs.size()+" 张牌");
if (ShuffleMahJong.maJiangs.size() != 0) {
if (ShuffleMahJong.maJiangs.get(index) != null) {
playerMaJiangs.add(playerMaJiangsIndex, ShuffleMahJong.maJiangs.get(index));
playerMaJiangsIndex++;
// 原来的ShuffleMaJiang的maJiangs中的牌减少这一张
//System.out.println(this.getName() + "摸到: " +ShuffleMahJong.maJiangs.get(index));
ShuffleMahJong.maJiangs.remove(index);
}
} else {
System.out.println("没牌了");
return true;
}
return false;
}
/**
* 打牌:从自己的playerMaJiangs中取一张牌,放入到ShuffleMaJiang中的river中
* @param index
* @return
*/
public MahjongTile discardMaJiang(int index) {
// System.out.println(playerMaJiangs + " 数入的数" + index);
if ((index > playerMaJiangs.size()) || (index < 0)) {
System.out.println(index + "输入的牌不存在" + playerMaJiangs.size());
return null;
}
// 从自己的playerMaJiangs中取一粒牌,放入到ShuffleMaJiang中的river中
ShuffleMahJong.river.add(ShuffleMahJong.riverIndex, playerMaJiangs.get(index));
ShuffleMahJong.riverIndex++;
// 自己的playerMaJiangs中减少这一粒牌
//System.out.println(this.getName() + "打出:" + playerMaJiangs.get(index));
// playerMaJiangs.remove(index);
// 出牌后下标减少
playerMaJiangsIndex--;
return playerMaJiangs.get(index);
}
/**
* 该玩家拥有的牌进行排序
*/
public void printMaJiangs() {
// 第一次排序牌的顺序
// Collections.sort(playerMaJiangs);
// 第一次排序牌的顺序
for (int i = 0; i < playerMaJiangs.size(); i++) {
for (int j = 0; j < playerMaJiangs.size() - 1 - i; j++) {
if (playerMaJiangs.get(j).getType() > playerMaJiangs.get(j + 1).getType()) {
MahjongTile temp = playerMaJiangs.get(j);
playerMaJiangs.set(j, playerMaJiangs.get(j + 1));
playerMaJiangs.set(j + 1, temp);
}
}
}
// 第二次排序牌数值小到大,例如:从1万到9万排序
for (int i = 0; i < playerMaJiangs.size(); i++) {
for (int j = 0; j < playerMaJiangs.size() - 1 - i; j++) {
if (playerMaJiangs.get(j).getType() == playerMaJiangs.get(j + 1).getType()) {
MahjongTile temp = playerMaJiangs.get(j);
if (playerMaJiangs.get(j).getTypeId() > playerMaJiangs.get(j + 1).getTypeId()) {
playerMaJiangs.set(j, playerMaJiangs.get(j + 1));
playerMaJiangs.set(j + 1, temp);
}
}
}
}
// 输出玩家拥有的牌
for (MahjongTile maJiang : playerMaJiangs) {
int type = maJiang.getType();
// System.out.print(maJiang + ",");
}
// System.out.println("共" + playerMaJiangs.size() + "张");
}
/**
* 碰牌:河里刚打出的牌,在玩家手中有两张同样的牌,就可以碰牌
* @return
*/
public boolean touchCards() {
// 获取河里刚打出的牌
MahjongTile riverLastJiang = ShuffleMahJong.river.get(ShuffleMahJong.riverIndex - 1);
// 遍历自己的所有的牌,是否包含上面的牌,并且有两张
int frequency = frequency(playerMaJiangs, riverLastJiang);
if (frequency >= 2&&!runzt) {
Iterator<MahjongTile> it = playerMaJiangs.iterator();
while (it.hasNext()) {
MahjongTile mj = it.next();
if ((mj.getType() == riverLastJiang.getType()) && (mj.getTypeId() == riverLastJiang.getTypeId())) {
it.remove();
System.out.println(this.name + "【碰牌成功】【删牌】"+mj);
playerMaJiangsIndex--;
}
}
return true;
} else {
// System.out.println("河里的牌=" + riverLastJiang+" "+this.name + "该牌数量=" +
// frequency+"【碰牌失败】");
return false;
}
}
/**
* 取得玩家相同牌的数量
* @param c
* @param o
* @return
*/
public static int frequency(List<MahjongTile> c, MahjongTile o) {
int result = 0;
if (o == null) {
for (MahjongTile e : c)
if (e == null)
result++;
} else {
for (MahjongTile e : c)
if ((o.getType() == e.getType()) && (o.getTypeId() == e.getTypeId()))
result++;
}
return result;
}
/**
* 杠牌:河里刚打出的牌,在玩家手中有3张同样的牌,就可以杠牌
* @return
*/
public boolean barCards() {
// 获取河里刚打出的牌
MahjongTile riverLastJiang = ShuffleMahJong.river.get(ShuffleMahJong.riverIndex - 1);
// 遍历自己的所有的牌,是否包含上面的牌,并且有三张
int frequency = frequency(playerMaJiangs, riverLastJiang);
if (frequency >= 3&&!runzt) {
Iterator<MahjongTile> it = playerMaJiangs.iterator();
while (it.hasNext()) {
MahjongTile mj = it.next();
if ((mj.getType() == riverLastJiang.getType()) && (mj.getTypeId() == riverLastJiang.getTypeId())) {
System.out.println(name + "【杠牌成功】【删除】"+mj);
it.remove();
playerMaJiangsIndex--;
}
}
return true;
} else {
// System.out.println("河里的牌=" + riverLastJiang+" "+this.name + "该牌数量=" +
// frequency+"【碰牌失败】");
return false;
}
}
/**
* 胡牌:满足胡牌的规则
* @return
*/
public boolean huCards() {
int mjnumber = 0;
MahjongTile[] mahjong = playerMaJiangs.toArray(new MahjongTile[1]);
if (mahjong.length == 14) {
mjnumber = 4;
} else if (mahjong.length == 11) {
mjnumber = 3;
} else if (mahjong.length == 8) {
mjnumber = 2;
} else if (mahjong.length == 5) {
mjnumber = 1;
} else if (mahjong.length == 3) {
mjnumber = 0;
} else {
}
// System.out.println("【留局】="+mjnumber);
MahjongTile[][] mahjongTileses = MahjongStaticTool.tryCombination(mahjong, 1, mjnumber);
if (mahjongTileses != null) {
System.out.println(this.getName() + "胡了!");
hul=true;
int twoIndex = 1;
int threeIndex = 1;
for (MahjongTile[] mahjongTilesRow : mahjongTileses) {
// if (mahjongTilesRow.length == 2) {
// System.out.print("第" + twoIndex + "对组合:");
// for (int j = 0; j < mahjongTilesRow.length; j++) {
//
// if (j != 0) {
// System.out.print(",");
// }
// System.out.print(mahjongTilesRow[j]);
// }
// System.out.println("");
// twoIndex++;
// } else if (mahjongTilesRow.length == 3) {
// System.out.print("第" + threeIndex + "趟组合:");
// for (int j = 0; j < mahjongTilesRow.length; j++) {
//
// if (j != 0) {
// System.out.print(",");
// }
// System.out.print(mahjongTilesRow[j]);
// }
// System.out.println("");
// threeIndex++;
// }
}
return true;
} else {
// System.out.println("\n没有胡!");
return false;
}
}
/**
* 删除该牌
*/
public void Remove(int integer) {
playerMaJiangs.remove(integer);
}
}
package main;
import java.util.*;
/**
* 创建麻将
* @author LiHai
*
*/
public class ShuffleMahJong {
/**
* 牌局中所有的牌:使用List放所有的牌
*/
public static List<MahjongTile> maJiangs=new ArrayList<MahjongTile>();
/**
* 用来指示“牌局中所有的牌”的当前下标
*/
public static int maJiangsIndex=0;
/**
* 河:用来存放玩家打出的牌
*/
public static List<MahjongTile> river=new ArrayList<MahjongTile>();
/**
* 用来指示“河”的当前下标
*/
public static int riverIndex=0;
public static List<MahjongTile> getMaJiangs() {
return maJiangs;
}
public ShuffleMahJong() throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {
//创建一副麻将
createMahJongs();
//输出此时的所有的牌
System.out.println("【初始化所有的牌:】");
printMahJongs();
//把初始牌打乱
chaosMahJongs();
//输出此时的所有的牌
//System.out.println("【洗牌后所有的牌:】");
printMahJongs();
// System.out.println("【按照东南西北四个方向输出的牌(牌局里的牌):】");
//printMaJiangs(1);
//下标恢复
riverIndex=0;
maJiangsIndex=135;
}
/*
* 创建一副麻将
*/
private void createMahJongs() throws MahjongTileInitWrongTypeAndTypeIdException {
MahjongTile mj=null;
//i代表万筒条 j代表1~9 k代表有几张同样的牌
for(int i=1;i<=3;i++) {
if(i<=3) {
for(int j=1;j<=4;j++) {
for(int k=1;k<=30;k++) {
mj=new MahjongTile(i,j);
maJiangs.add(maJiangsIndex,mj);
maJiangsIndex++;
}
}
}else if(i==4) {
//东南西北
for(int j=1;j<=4;j++) {
for(int k=1;k<=4;k++) {
mj=new MahjongTile(i,j);
maJiangs.add(maJiangsIndex,mj);
maJiangsIndex++;
}
}
}else if(i==5) {
//红中发财白板
for(int j=1;j<=3;j++) {
for(int k=1;k<=4;k++) {
mj=new MahjongTile(i,j);
maJiangs.add(maJiangsIndex,mj);
maJiangsIndex++;
}
}
}
}
}
/**
* 整副麻将
*/
public static void printMahJongs() {
for (Iterator iterator = maJiangs.iterator(); iterator.hasNext();) {
MahjongTile mahjongTile = (MahjongTile) iterator.next();
//System.out.print(mahjongTile+"="+mahjongTile.getType()+"-"+mahjongTile.getTypeId()+"-"+mahjongTile.getUniqueId()+" ");
}
System.out.println("剩:"+maJiangs.size()+"");
}
/**
* 把初始牌打乱
*/
private void chaosMahJongs() {
Collections.shuffle(maJiangs);
}
/**
* 由于第一次起牌很有可能是在整副牌的中间位置开始起牌的,然后再向后起牌。此时需要把起始位置前的牌,重新放到maJiangs中的最后,来保证整副牌的完整性
* @throws InterruptedException
*/
public static void moveMahJongs() throws InterruptedException{
//把开始位置前的牌复制到list的末尾
for (int i = 0; i < maJiangsIndex; i++) {
maJiangs.add(maJiangs.size(),maJiangs.get(i));
}
//复制后,把开始位置前的牌删除
for (int i = 0; i < maJiangsIndex; i++) {
maJiangs.remove(i);
}
//输出移动位置后的整副牌
System.out.println("【移动位置后的整副牌:】");
printMahJongs();
//移动过后,起始位置变为了第一张牌,需要把下标复位
maJiangsIndex=0;
}
}