jpanel麻将自动打牌,碰牌,杠牌
生活随笔
收集整理的這篇文章主要介紹了
jpanel麻将自动打牌,碰牌,杠牌
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?不多說(shuō),拷貝就能用
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 stubMahJongGame mhg = new MahJongGame();}public MahJongGame() throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {myp = new MyPanel();// 啟動(dòng)了mypanel線(xiàn)程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存萬(wàn) 21-29存條 31-39存筒 0,10,20,30,40存東南西北 41-43存中,發(fā),白* * @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;// 四個(gè)玩家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);// 必須為設(shè)置為null,你的setBouds();才可以有作用// 初始化按鈕this.jbutton();this.setOpaque(false);// 設(shè)置整副牌的開(kāi)始位置ShuffleMahJong.maJiangsIndex = 0;// 移動(dòng)起始位置前的牌到list末尾ShuffleMahJong.moveMahJongs();// 玩家initPlayer = new InitPlayer();// 第一次起牌initPlayer.haveFirstBoard();// 輸出牌局中的整副牌(剩余的牌)System.out.println("【此時(shí)牌局中的剩余的牌:】");ShuffleMahJong.printMahJongs();// 第二次起牌:跳莊initPlayer.haveJumpBoard();// 輸出此時(shí)玩家手中的牌initPlayer.printPlayer();player = InitPlayer.players.get(0);// 摸第一張牌player.gainMaJiang(0);// 設(shè)置為出牌狀態(tài)player.setRunzt(true);initPlayer.printPlayer(player);// 輸出牌局中的整副牌(剩余的牌)System.out.println("【此時(shí)牌局中的剩余的牌:】");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("【您先出牌:[待打出牌對(duì)應(yīng)的順序,例如:1表示打出第一張牌],[非數(shù)字輸入:退出游戲]】");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);// 重繪子組件,不然會(huì)出現(xiàn)異常“有個(gè)按鈕需要鼠標(biāo)移動(dòng)到它上邊才顯示”super.paintChildren(g);// 固定背景圖片,允許這個(gè)JPanel可以在圖片上添加其他組件g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);// 畫(huà)出牌文字信息this.drawenzi(g);// 確保該函數(shù)只能被調(diào)用一次for (int i = 0; i < t; i++) {// deal(g);t--;// System.out.println("該集合牌的數(shù)量" + tupWeizhi.size());} // int i1=player.getPlayerMaJiangs().get(0).getType(); // int i2=player.getPlayerMaJiangs().get(0).getTypeId(); // System.out.println(i1+"-"+i2);// 畫(huà)玩家麻將this.drawmajiang(g);}private void drawmajiang(Graphics g) {// 畫(huà)西家的牌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(); // // 實(shí)例化按鈕對(duì)象,并且設(shè)置按鈕上顯示圖片// 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);}}// 畫(huà)電腦東家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);}}// 畫(huà)電腦北家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);}}// 畫(huà)電腦南家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);}// 出牌倒計(jì)時(shí)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);}/*** 設(shè)置按鈕圖片縮放* * @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() {// 創(chuàng)建按鈕對(duì)象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);}// 設(shè)置按鈕透明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);}// 設(shè)置按鈕透明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);}// 設(shè)置按鈕透明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);}// 設(shè)置按鈕透明b1.setContentAreaFilled(false);add(b1);}}public void run() {while (true) {try {this.repaint();Thread.sleep(100);synchronized (this) {// 檢測(cè)是否胡牌if (player != null) {player.huCards();computer1.huCards();computer2.huCards();computer3.huCards();}// 判斷玩家是否超時(shí) 超時(shí)自動(dòng)打牌if (tlaber.getCount() == 0 && tlaber.isStart()) {int numb = 0;if (initPlayer.zdchupai() > 1 && initPlayer.zdchupai() != 0) {numb = initPlayer.zdchupai();}// 判斷該哪一個(gè)玩家出牌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();// 關(guān)閉上一個(gè)線(xiàn)程tlaber.stop();InitPlayer.players.get(0).setRunzt(false);// 碰牌檢測(cè)Player playerto = InitPlayer.touchDetection();if (playerto == null) {// 下一家摸牌InitPlayer.players.get(1).gainMaJiang(0);InitPlayer.players.get(1).setRunzt(true);} else {playerto.setRunzt(true);} // //啟動(dòng)新線(xiàn)程 // 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);// 關(guān)閉上一個(gè)線(xiàn)程tlaber.stop();InitPlayer.players.get(1).setRunzt(false);// 碰牌檢測(cè)Player playerto = InitPlayer.touchDetection();if (playerto == null) {// 下一家摸牌InitPlayer.players.get(2).gainMaJiang(0);InitPlayer.players.get(2).setRunzt(true);} else {playerto.setRunzt(true);} // //啟動(dòng)新線(xiàn)程 // 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);// 關(guān)閉上一個(gè)線(xiàn)程tlaber.stop();InitPlayer.players.get(2).setRunzt(false);// 碰牌檢測(cè)Player playerto = InitPlayer.touchDetection();if (playerto == null) {// 下一家摸牌InitPlayer.players.get(3).gainMaJiang(0);InitPlayer.players.get(3).setRunzt(true);} else {playerto.setRunzt(true);} // //啟動(dòng)新線(xiàn)程 // 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);// 關(guān)閉上一個(gè)線(xiàn)程tlaber.stop();InitPlayer.players.get(3).setRunzt(false);// 碰牌檢測(cè)Player playerto = InitPlayer.touchDetection();if (playerto == null) {// 下一家摸牌InitPlayer.players.get(0).gainMaJiang(0);InitPlayer.players.get(0).setRunzt(true);} else {playerto.setRunzt(true);} // //啟動(dòng)新線(xiàn)程 // tlaber =new TimerLabel(5); // tlaber.start();}// 沒(méi)牌了停止線(xiàn)程if (ShuffleMahJong.maJiangs.size() <= 0) {tlaber.stop();} else {// 啟動(dòng)新線(xiàn)程tlaber = new TimerLabel(0);tlaber.start();}}}} catch (InterruptedException e) {// TODO 自動(dòng)生成的 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) {// 獲取后兩位數(shù)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;// 檢測(cè)是否胡牌if (player != null) {player.huCards();computer1.huCards();computer2.huCards();computer3.huCards();}// 滿(mǎn)足牌數(shù)為二倍,判斷是否是該玩家,判斷是否到該玩家出牌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();// 碰牌檢測(cè)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);} // //啟動(dòng)新線(xiàn)程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();// 碰牌檢測(cè)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);} // //啟動(dòng)新線(xiàn)程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();// 碰牌檢測(cè)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);} // //啟動(dòng)新線(xiàn)程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);// 碰牌檢測(cè)Player playerto = InitPlayer.touchDetection();if (playerto == null) {// 下一家摸牌InitPlayer.players.get(0).gainMaJiang(0);InitPlayer.players.get(0).setRunzt(true);} else {playerto.setRunzt(true);} // //啟動(dòng)新線(xiàn)程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;/*** 圖片旋轉(zhuǎn)工具類(lèi)*/ public class RotateImage {/*** 對(duì)圖片進(jìn)行旋轉(zhuǎn)** @param src 被旋轉(zhuǎn)圖片* @param angel 旋轉(zhuǎn)角度* @return 旋轉(zhuǎn)后的圖片*/public static BufferedImage Rotate(Image src, int angel) {int src_width = src.getWidth(null);int src_height = src.getHeight(null);// 計(jì)算旋轉(zhuǎn)后圖片的尺寸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();// 進(jìn)行轉(zhuǎn)換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;}/*** 計(jì)算旋轉(zhuǎn)后的圖片** @param src 被旋轉(zhuǎn)的圖片* @param angel 旋轉(zhuǎn)角度* @return 旋轉(zhuǎn)后的圖片*/public static Rectangle CalcRotatedSize(Rectangle src, int angel) {// 如果旋轉(zhuǎn)的角度大于90度做相應(yīng)的轉(zhuǎn)換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;/*** 計(jì)時(shí)標(biāo)簽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;/*** 新建一個(gè)計(jì)時(shí)標(biāo)簽* * @param maxTime 倒計(jì)時(shí)起始時(shí)間*/public TimerLabel(int maxTime) {this.setHorizontalAlignment(JLabel.CENTER);this.setFont(new Font("Times New Roman", Font.BOLD, FONT_SIZE));this.pause = false;setMaxTime(maxTime);}/*** 修改倒計(jì)時(shí)起始時(shí)間* * @param maxTime 新的起始時(shí)間*/public void setMaxTime(int maxTime) {if (this.start) {return;}this.maxTime = maxTime;this.count = maxTime;initText();this.thread = new Thread(new Runnable() {@Overridepublic 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;}/*** 倒計(jì)時(shí)完成后調(diào)用此方法*/public void done() {JOptionPane.showMessageDialog(this, "結(jié)束!");}/*** 標(biāo)簽字符由此方法設(shè)置*/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();}}/*** 檢測(cè)標(biāo)簽倒計(jì)時(shí)是否開(kāi)始* * @return 如果開(kāi)始返回true*/public boolean isStart() {return start;}/*** 得到倒計(jì)時(shí)起始時(shí)間* * @return 倒計(jì)時(shí)起始時(shí)間*/public int getMaxTime() {return maxTime;}/*** 檢測(cè)標(biāo)簽倒計(jì)時(shí)是否暫停* * @return 倒計(jì)時(shí)暫停返回true*/public boolean isPause() {return pause;}/*** 從暫停中恢復(fù)計(jì)時(shí)*/public void continueDo() {if (this.pause) {this.pause = false;}}/*** 取消計(jì)時(shí)*/public void stop() {if (start) {//thread.interrupt();this.count=-11;start = false;}}/*** 開(kāi)始計(jì)時(shí)*/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 自動(dòng)生成的方法存根return count;} }//演示程序 Test.java package main;import java.util.*; /*** * @author Administrator 初始化玩家:創(chuàng)建四個(gè)玩家(包括3個(gè)電腦)*/ public class InitPlayer {/*** 4個(gè)玩家的信息都存放在List中,下標(biāo)為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() {// 創(chuàng)建4個(gè)玩家createPlayer();}/*** 自動(dòng)打出其他玩家能碰,杠的牌* @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);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile)>1) {//System.out.println(computer2+"="+list.indexOf(mahjongTile)+"="+Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile));return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile)>1) {//System.out.println(computer2+"="+list.indexOf(mahjongTile)+"="+Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile));return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}}}if(computer1.isRunzt()) {List<MahjongTile> list=computer1.getPlayerMaJiangs();//遍歷自己的集合for (MahjongTile mahjongTile : list) {if(Player.frequency(player.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}}}if(computer2.isRunzt()) {List<MahjongTile> list=computer2.getPlayerMaJiangs();//遍歷自己的集合for (MahjongTile mahjongTile : list) {if(Player.frequency(player.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer1.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer3.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}}}if(computer3.isRunzt()) {List<MahjongTile> list=computer3.getPlayerMaJiangs();//遍歷自己的集合for (MahjongTile mahjongTile : list) {if(Player.frequency(player.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer2.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}if(Player.frequency(computer1.getPlayerMaJiangs(), mahjongTile)>1) {return list.indexOf(mahjongTile);//返回第一個(gè)出現(xiàn)元素 O 的位置;}}}return 0;}/*** 檢測(cè)是否有可以碰的牌* @return*/public static Player touchDetection() {//檢測(cè)是否有杠的牌 不做處理直接杠牌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;}//檢測(cè)是否有碰的牌 不做處理直接碰牌if(player.touchCards()) {return player;}if(computer1.touchCards()) {return computer1;}if(computer2.touchCards()) {return computer2;}if(computer3.touchCards()) {return computer3;}return null;}/*** 創(chuàng)建4個(gè)玩家*/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);}/*** 輸出四個(gè)玩家手中的牌*/public void printPlayer() {// 輸出當(dāng)前玩家手中的牌System.out.println("【當(dāng)前玩家手中的牌如下:】");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) {// 輸出當(dāng)前玩家手中的牌//System.out.println("【當(dāng)前玩家手中的牌如下:】");System.out.println(players.getPlayerMaJiangs());}/*** 輸出四個(gè)玩家手中的牌*//*** 第一次起牌:輪流起牌,每次起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);}/*** 翻癩子(癩子可以當(dāng)成是任何一張牌)*/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;/*** 復(fù)制牌的集合* * @param mahjongTiles* @param indexs* @return*/private static MahjongTile[] removeSomeMahjongTiles(MahjongTile[] mahjongTiles, int[] indexs) {/** indexs表示萬(wàn)筒條的大小1~9的數(shù)組; mahjongTiles.length原來(lái)長(zhǎng)度為14 indexs.length長(zhǎng)度為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]該函數(shù)將不參與mahjongTilesNew的復(fù)制*/if (i == indexs[j]) {//System.out.println("indexs[" + i + "]==" + indexs[j] + "mahjongTiles[i]=" + mahjongTiles[i]);isAppend = false;break;}}if (isAppend) {/** 把mahjongTiles集合復(fù)制到mahjongTilesNew數(shù)組 實(shí)現(xiàn)刪除*/mahjongTilesNew[index] = mahjongTiles[i];//System.out.println("mahjongTilesNew[" + index + "]==" + mahjongTilesNew[index]);index++;}}return mahjongTilesNew;}return null;}/*** 比較一對(duì)將 從數(shù)組長(zhǎng)度為arrayLen的整形數(shù)組中任意抽取兩個(gè)元素, * 把所有可能的組合的索引列成一個(gè)二位數(shù)組返回出來(lái)* * @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;}}/*** 比較三張連牌或者三張同樣的牌 從數(shù)組長(zhǎng)度為arrayLen的整形數(shù)組中任意抽取兩個(gè)元素, 把所有可能的組合的索引列成一個(gè)二位數(shù)組返回出來(lái)* * @param arrayLen* @return*/private static int[][] siphonThreeIndexs(int arrayLen) {int len = (arrayLen * (arrayLen - 1) * (arrayLen - 2)) / 6;// System.out.println("循環(huán)次數(shù)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;}}/*** 傳進(jìn)玩家牌的二維集合,和三張牌 復(fù)制集合* * @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 {// 創(chuàng)建一個(gè)比原來(lái)集合更長(zhǎng)的集合MahjongTile[][] mahjongTilesesReturn = new MahjongTile[saveMahjongTileses.length + 1][];/** arraycopy(Object?src,int?srcPos,Object?dest, int?destPos,int?length)* src表示源數(shù)組,srcPos表示源數(shù)組要復(fù)制的起始位置, desc表示目標(biāo)數(shù)組,length表示要復(fù)制的長(zhǎng)度。*///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);}/*** 把數(shù)組牌轉(zhuǎn)為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];// 根據(jù)每一張牌的數(shù)量逆轉(zhuǎn)if (paiNum <= 0) {continue;}for (int k = 0; k < paiArr[i][j]; k++) {paiList.add((i + 1) + j);}}}return paiList;}/*** 判斷是否胡牌的方法 mahjongTiles玩家所有的牌 twoNum表示一對(duì)將 threeNum表示3個(gè)連著的牌或者三張同樣的牌* * @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=4if (mahjongTiles.length == ((twoNum * 2) + (threeNum * 3))) {if (threeNum > 0) {// 通過(guò)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數(shù)組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* */// 當(dāng)出現(xiàn)三張同樣或者順子時(shí)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);// 傳進(jìn)一個(gè)牌的集合,三張同樣的麻將// 利用該函數(shù)appendSomeMahjongTiles把三張牌重新復(fù)制到二維集合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) {// 通過(guò)該數(shù)據(jù)獲得所有可能是一對(duì) 將 的組合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;}/*** 測(cè)試* * @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("檢查通過(guò)!");System.out.println("組合結(jié)果如下:");int twoIndex = 1;int threeIndex = 1;for (MahjongTile[] mahjongTilesRow : mahjongTileses) {if (mahjongTilesRow.length == 2) {System.out.print("第" + twoIndex + "對(duì)組合:");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("檢查未通過(guò)!");}} } package main;import java.util.*; import java.util.Comparator;/*** 單張麻將牌* @author LiHai**/public class MahjongTile implements Comparable<MahjongTile> {//萬(wàn)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;/*** 標(biāo)準(zhǔn)麻將的各種牌的名稱(chēng),該名稱(chēng)為一個(gè)三維數(shù)組,第一維為各套獨(dú)立的名稱(chēng)* 第二維為每套名稱(chēng)中的不同類(lèi)別,例如萬(wàn)和桶屬于不同類(lèi)型的牌* 第三維維具體的名稱(chēng)* String[1][1][1] 表示一萬(wàn)* String[2][1][1] 表示一萬(wàn)* String[2][2][2]表示二餅*/public final static String[][][] STANDARD_MAHJONG_NAMES = {new String[][]{{"一萬(wàn)","二萬(wàn)","三萬(wàn)","四萬(wàn)","五萬(wàn)","六萬(wàn)","七萬(wàn)","八萬(wàn)","九萬(wàn)"},{"一條","二條","三條","四條","五條","六條","七條","八條","九條"},{"一桶","二桶","三桶","四桶","五桶","六桶","七桶","八桶","九桶"},{"東風(fēng)","南風(fēng)","西風(fēng)","北風(fēng)"},{"紅中","發(fā)財(cái)","白板"},{"春","夏","秋","冬","梅","蘭","竹","菊"}},new String[][]{{"一萬(wàn)","二萬(wàn)","三萬(wàn)","四萬(wàn)","五萬(wàn)","六萬(wàn)","七萬(wàn)","八萬(wàn)","九萬(wàn)"},{"一條","二條","三條","四條","五條","六條","七條","八條","九條"},{"一餅","二餅","三餅","四餅","五餅","六餅","七餅","八餅","九餅"},{"東風(fēng)","南風(fēng)","西風(fēng)","北風(fēng)"},{"紅中","發(fā)財(cái)","白板"},{"春","夏","秋","冬","梅","蘭","竹","菊"}}};//表示麻將種類(lèi) 共兩種private final int type;//表示麻將ID號(hào) 萬(wàn)筒條的一萬(wàn)還是二萬(wàn)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 stubreturn 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;//萬(wàn) 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;//紅中發(fā)財(cái)白板 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){//判斷第一個(gè)和第二個(gè)是否是 萬(wàn)筒條 的同一種類(lèi)型if (type == mahjongTileOne.type && type == mahjongTileTwo.type){//判斷是否是刻子if (typeId == mahjongTileOne.typeId && typeId == mahjongTileTwo.typeId){return true;}//isIdLink判斷是否是順子 如果是返回true并且type不等于 4,5,6 因?yàn)?,5,6不表示萬(wàn)筒條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;}}//判斷是否是順子 如果是返回trueprivate 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;}@Overridepublic 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; /*** 麻將參數(shù)* @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;/*** 每個(gè)玩家的牌都放在playerMaJiangs中*/private List<MahjongTile> playerMaJiangs = new ArrayList<MahjongTile>();/*** 用來(lái)指示“每個(gè)玩家的牌”在playerMaJiangs中的下標(biāo)*/private int playerMaJiangsIndex = 0;/*** 是否到該玩家出牌 運(yùn)行狀態(tài)*/private boolean runzt = false;//玩家沒(méi)胡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;}@Overridepublic 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++;// 原來(lái)的ShuffleMaJiang的maJiangs中的牌減少這一張//System.out.println(this.getName() + "摸到: " +ShuffleMahJong.maJiangs.get(index));ShuffleMahJong.maJiangs.remove(index);}} else {System.out.println("沒(méi)牌了");return true;}return false;}/*** 打牌:從自己的playerMaJiangs中取一張牌,放入到ShuffleMaJiang中的river中* @param index* @return*/public MahjongTile discardMaJiang(int index) {// System.out.println(playerMaJiangs + " 數(shù)入的數(shù)" + 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);// 出牌后下標(biāo)減少playerMaJiangsIndex--;return playerMaJiangs.get(index);}/*** 該玩家擁有的牌進(jìn)行排序*/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);}}}// 第二次排序牌數(shù)值小到大,例如:從1萬(wàn)到9萬(wàn)排序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 + "該牌數(shù)量=" +// frequency+"【碰牌失敗】");return false;}}/*** 取得玩家相同牌的數(shù)量* @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 + "該牌數(shù)量=" +// frequency+"【碰牌失敗】");return false;}}/*** 胡牌:滿(mǎn)足胡牌的規(guī)則* @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 + "對(duì)組合:"); // 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沒(méi)有胡!");return false;}}/*** 刪除該牌*/public void Remove(int integer) {playerMaJiangs.remove(integer);} } package main; import java.util.*;/*** 創(chuàng)建麻將* @author LiHai**/ public class ShuffleMahJong {/*** 牌局中所有的牌:使用List放所有的牌*/public static List<MahjongTile> maJiangs=new ArrayList<MahjongTile>();/*** 用來(lái)指示“牌局中所有的牌”的當(dāng)前下標(biāo)*/public static int maJiangsIndex=0;/*** 河:用來(lái)存放玩家打出的牌*/public static List<MahjongTile> river=new ArrayList<MahjongTile>();/*** 用來(lái)指示“河”的當(dāng)前下標(biāo)*/public static int riverIndex=0;public static List<MahjongTile> getMaJiangs() {return maJiangs;}public ShuffleMahJong() throws InterruptedException, MahjongTileInitWrongTypeAndTypeIdException {//創(chuàng)建一副麻將createMahJongs();//輸出此時(shí)的所有的牌System.out.println("【初始化所有的牌:】");printMahJongs();//把初始牌打亂chaosMahJongs();//輸出此時(shí)的所有的牌//System.out.println("【洗牌后所有的牌:】");printMahJongs();// System.out.println("【按照東南西北四個(gè)方向輸出的牌(牌局里的牌):】");//printMaJiangs(1);//下標(biāo)恢復(fù)riverIndex=0;maJiangsIndex=135;}/** 創(chuàng)建一副麻將*/private void createMahJongs() throws MahjongTileInitWrongTypeAndTypeIdException {MahjongTile mj=null;//i代表萬(wàn)筒條 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) {//紅中發(fā)財(cái)白板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);}/*** 由于第一次起牌很有可能是在整副牌的中間位置開(kāi)始起牌的,然后再向后起牌。此時(shí)需要把起始位置前的牌,重新放到maJiangs中的最后,來(lái)保證整副牌的完整性* @throws InterruptedException */public static void moveMahJongs() throws InterruptedException{//把開(kāi)始位置前的牌復(fù)制到list的末尾for (int i = 0; i < maJiangsIndex; i++) {maJiangs.add(maJiangs.size(),maJiangs.get(i));}//復(fù)制后,把開(kāi)始位置前的牌刪除for (int i = 0; i < maJiangsIndex; i++) {maJiangs.remove(i);}//輸出移動(dòng)位置后的整副牌System.out.println("【移動(dòng)位置后的整副牌:】");printMahJongs();//移動(dòng)過(guò)后,起始位置變?yōu)榱说谝粡埮?#xff0c;需要把下標(biāo)復(fù)位maJiangsIndex=0;} }總結(jié)
以上是生活随笔為你收集整理的jpanel麻将自动打牌,碰牌,杠牌的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 软交所助力国家级软件评测中心
- 下一篇: 百度云盘功能需求分析