近日,使用Java编写了斗地主单机小游戏,作为经典小游戏,它也给大家带来不少乐趣,通过对这款游戏的简单实现,加深了我对对Java基础算法的理解。

一.思路:
1、首先要了解斗地主的游戏规则,针对游戏整个过程来考虑。从游戏开始后的洗牌,发牌,抢地主,出牌,到游戏结束整个过程。
2、其中要用到的如洗牌算法,出牌时判牌规则编写,电脑端出牌等一系列。
3、发完牌后及出牌需要用排序算法进行排序。

二.代码实现:
1.初始化牌时的洗牌,代码如下:

public void initCard() {     int count=0;if(card[0]==null) {for(int i=1;i<=5;i++) {for(int j=1;j<=13;j++) {if(i==5 && j>2) {break;}card[count]=new Card(i+"-"+j, false);card[count].setLocation(350, 50);container.add(card[count]);count++;}}}if(this.t!=null) {this.t.isPublish=true;for(int i=0;i<card.length;i++) {card[i].canClick=false;card[i].clicked=false;}}Random rand=new Random();for(int i=0;i<card.length;i++) {  //洗牌算法int j=rand.nextInt(card.length-i);Card k=card[i];card[i]=card[j];card[j]=k;}}

2、洗完牌后,进入发牌阶段。

public void publishCard() {  for(int i=0;i<card.length;i++) {if(i>=51) {Common.move(card[i], card[i].getLocation(), new Point(300+(i-51)*80, 10));lordList.add(card[i]);continue;}switch (t++%3) {case 0:Common.move(card[i], card[i].getLocation(), new Point(50, 60+i*5));playerList[0].add(card[i]);break;case 1:Common.move(card[i], card[i].getLocation(), new Point(180+i*7, 450));playerList[1].add(card[i]);card[i].turnFront();break;case 2:Common.move(card[i], card[i].getLocation(), new Point(700, 60+i*5));playerList[2].add(card[i]);break;}container.setComponentZOrder(card[i], 0);}
}
public static void move(Card card,Point from,Point to) {  //这个是发牌的牌的移动算法,利用线性函数实现。if(from.x!=to.x) {double k=1.0*(to.y-from.y)/(to.x-from.x);double b=to.y-to.x*k;int flag=0;if(from.x<to.x) {flag=20;}else {flag=-20;}for(int i=from.x;Math.abs(i-to.x)>20;i+=flag) {double y=k*i+b;card.setLocation(i, (int)y);try {Thread.sleep(5);}catch (InterruptedException e) {//e.printStackTrace();return;}                           }}card.setLocation(to);}

3、在出牌时,针对玩家需要对各种牌型进行判定,代码如下:

public class Common {@SuppressWarnings("rawtypes")private static List a[]=new List[4];public static CardType judgeType(List<Card> list) {int len=list.size();if(len<=4) {if(len>0 && getValue(list.get(0))==getValue(list.get(len-1))) {switch (len) {case 1:return CardType.c1;  //单牌case 2:return CardType.c2; //对子case 3:return CardType.c3;  //三张case 4:return CardType.c4; //炸弹}}if(len==2 && getColor(list.get(0))==5 && getColor(list.get(1))==5) {return CardType.c4;}if(len==4 && (getValue(list.get(0))==getValue(list.get(len-2)) || getValue(list.get(1))==getValue(list.get(len-1)))) {return CardType.c31;}else {return CardType.c0;}}else {for(int i=0;i<a.length;i++) {a[i]=new ArrayList<Integer>();}getMax(list);if(a[2].size()==1 && a[1].size()==1 && len==5) {return CardType.c32;}if(a[3].size()==1 && len==6) {return CardType.c411;}if(a[3].size()==1 && a[1].size()==2 && len==8) {return CardType.c422;}if(getValue(list.get(0))<15 && a[0].size()==len && (getValue(list.get(0))-getValue(list.get(len-1))==len-1)) {return CardType.c123;}if(getColor(list.get(0))!=5 && a[1].size()==len/2 && len%2==0 && (getValue(list.get(0))-getValue(list.get(len-1))==len/2-1)) {return CardType.c1122;}if(a[2].size()==len/3 && len%3==0 && (getValue(list.get(0))-getValue(list.get(len-1))==len/3-1)) {return CardType.c111222;}if(a[2].size()==len/4 && len%4==0 && ((Integer)a[2].get(len/4-1)-(Integer)a[2].get(0)==len/4-1)) {return CardType.c11122234;}if(a[2].size()==len/5 && len%5==0 && a[1].size()==len/5 && ((Integer)a[2].get(len/5-1)-(Integer)a[2].get(0)==len/5-1)){return CardType.c1112223344;}}return CardType.c0;}public static int getColor(Card card) {return Integer.parseInt(card.name.substring(0,1));}public static int getValue(Card card) {int i=Integer.parseInt(card.name.substring(2, card.name.length()));if(i==2 || i==1) {i+=13;}if(getColor(card)==5) {i+=2;}return i;}public static void getMax(List<Card> list) {int[] count=new int[14];for(int i=0;i<list.size();i++) {if(getColor(list.get(i))==5) {count[count.length-1]++;}else {count[getValue(list.get(i))-3]++;}}for(int i=0;i<count.length;i++) {if(count[i]==0) {continue;}switch (count[i]) {case 1:a[0].add(i+3);break;case 2:a[1].add(i+3);break;case 3:a[2].add(i+3);break;case 4:a[3].add(i+3);break;}}}public static void cardSort(List<Card> list) {Collections.sort(list,new Comparator<Card>() {@Overridepublic int compare(Card o1, Card o2) {int a1=Integer.parseInt(o1.name.substring(0, 1));int a2=Integer.parseInt(o2.name.substring(0, 1));int b1=Integer.parseInt(o1.name.substring(2,o1.name.length()));int b2=Integer.parseInt(o2.name.substring(2,o2.name.length()));int flag=0;if(a1==5) {b1+=100;if(b1==2) {b1+=50;}}if(a2==5) {b2+=100;if(b2==2) {b2+=50;}}if(b1==1) {b1+=20;}if(b2==1) {b2+=20;}if(b1==2) {b1+=30;}if(b2==2) {b2+=30;}flag=b2-b1;if(flag==0) {return a2-a1;}else {return flag;}}});}public static void hideCards(List<Card> list) {for(Card card : list) {card.setVisible(false);}}public static int checkCards(List<Card> c,List<Card>[] current) {List<Card> currList=current[0].size()>0 ? current[0] : current[2];CardType cType=judgeType(c);CardType currType=judgeType(currList);if(cType!=CardType.c4 && (c.size()!=currList.size() || cType!=currType)) {return 0;}if(cType==CardType.c4 && (c.size()==2 || currType!=CardType.c4)) {       return 1;}if(currType==CardType.c4 && currList.size()==2) {return 0;}if(cType==CardType.c1 || cType==CardType.c2 || cType==CardType.c3 || cType==CardType.c4) {if(getValue(c.get(0))>getValue(currList.get(0))) {return 1;}else {return 0;}}if(cType==CardType.c123 || cType==CardType.c1122 || cType==CardType.c111222) {if(getValue(c.get(0))<=getValue(currList.get(0))) {return 0;}else {return 1;}}if(cType==CardType.c31 || cType==CardType.c32 || cType==CardType.c411 || cType==CardType.c422 || cType==CardType.c1112223344 || cType==CardType.c11122234) {List<Card> c1=getOrder(c);List<Card> c2=getOrder(currList);if(getValue(c1.get(0))<getValue(c2.get(0))) {return 0;}        }return 1;  }public static List<Card> getOrder(List<Card> list){List<Card> newList=new ArrayList<>();int[] count=new int[18];for(int i=0;i<list.size();i++) {count[getValue(list.get(i))]++;}f:for(int i=3;i<count.length-1;i++) {int max=3;for(int j=3;j<count.length-i-1;j++) {if(count[j+1]>count[max]) {max=j+1;}}for(int k=0;k<list.size();k++) {if(getValue(list.get(k))==max) {newList.add(list.get(k));break f;}}}return newList;}
}

3、对于电脑端,也有专门的代码处理,这里就不做过多描述了。
4、编写Swing图形界面。

public class Game extends JFrame implements ActionListener{private static final long serialVersionUID = 1L;public Container container;JMenuItem start,exit,about;JButton[] landlord=new JButton[2]; JButton[] publishCard=new JButton[2]; int dizhuFlag;int turn;boolean nextPlayer;JLabel dizhu;Time t;List<Card> currentList[]=new ArrayList[3];List<Card> playerList[]=new ArrayList[3];List<Card> lordList;Card[] card=new Card[54];JTextField[] time=new JTextField[3];Thread thread=null;public Game() {init();setMenu();this.setVisible(true);initCard();showLord();    time[1].setVisible(true);this.t=new Time(this, 10);    SwingUtilities.invokeLater(new Runnable() {     @Overridepublic void run() {thread=new Thread(t);thread.start();          }});    }   public void showLord() {for(int i=0;i<2;i++) {landlord[i].setVisible(true);}} public void initCard() {        int count=0;if(card[0]==null) {for(int i=1;i<=5;i++) {for(int j=1;j<=13;j++) {if(i==5 && j>2) {break;}card[count]=new Card(i+"-"+j, false);card[count].setLocation(350, 50);container.add(card[count]);count++;}}}if(this.t!=null) {this.t.isPublish=true;for(int i=0;i<card.length;i++) {card[i].canClick=false;card[i].clicked=false;}}Random rand=new Random();for(int i=0;i<card.length;i++) {int j=rand.nextInt(card.length-i);Card k=card[i];card[i]=card[j];card[j]=k;}for(int i=0;i<3;i++) {playerList[i]=new ArrayList<>();}lordList=new ArrayList<Card>();int t=0;for(int i=0;i<card.length;i++) {if(i>=51) {Common.move(card[i], card[i].getLocation(), new Point(300+(i-51)*80, 10));lordList.add(card[i]);continue;}switch (t++%3) {case 0:Common.move(card[i], card[i].getLocation(), new Point(50, 60+i*5));playerList[0].add(card[i]);break;case 1:Common.move(card[i], card[i].getLocation(), new Point(180+i*7, 450));playerList[1].add(card[i]);card[i].turnFront();break;case 2:Common.move(card[i], card[i].getLocation(), new Point(700, 60+i*5));playerList[2].add(card[i]);break;}container.setComponentZOrder(card[i], 0);} if(this.t!=null) {this.t.isPublish=false;}for(int i=0;i<3;i++) {Common.cardSort(playerList[i]);Common.rePosition(playerList[i], i,this);}dizhu=new JLabel(new ImageIcon("images/dizhu.gif"));dizhu.setVisible(false);dizhu.setSize(40, 40);container.add(dizhu);}public void init() {this.setTitle("斗地主");ImageIcon icon=new ImageIcon(this.getClass().getResource("/images/斗地主.jpg"));ImageIcon icon1=new ImageIcon(this.getClass().getResource("/images/card.png"));this.setResizable(false);this.setIconImage(icon1.getImage());this.setSize(700, 900);JLabel jl = new JLabel(icon);jl.setSize(700, 900);container=this.getContentPane();container.setLayout(null);container.add(jl);this.setLocationRelativeTo(getOwner());this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}this.remove(jl);this.setSize(830, 620);this.setLocationRelativeTo(getOwner());container.setBackground(new Color(0, 112, 26));}public void setMenu() {JMenuBar jMenuBar=new JMenuBar();JMenu game=new JMenu("游戏");JMenu help=new JMenu("帮助");start=new JMenuItem("重新开始");exit=new JMenuItem("退出");about=new JMenuItem("关于");start.addActionListener(this);exit.addActionListener(this);about.addActionListener(this);game.add(start);game.add(exit);help.add(about);jMenuBar.add(game);jMenuBar.add(help);this.setJMenuBar(jMenuBar);landlord[0]=new JButton("抢地主");landlord[1]=new JButton("不抢");publishCard[0]=new JButton("出牌");publishCard[1]=new JButton("不要");for(int i=0;i<2;i++) {landlord[i].setBounds(320+i*100, 400, 75, 20);landlord[i].setBorder(BorderFactory.createRaisedBevelBorder());publishCard[i].setBounds(320+i*100, 400, 60, 20);publishCard[i].setBorder(BorderFactory.createRaisedBevelBorder());container.add(landlord[i]);landlord[i].addActionListener(this);landlord[i].setVisible(false);container.add(publishCard[i]);publishCard[i].addActionListener(this);publishCard[i].setVisible(false);}for(int i=0;i<3;i++) {time[i]=new JTextField("倒计时:");time[i].setVisible(false);time[i].setBorder(BorderFactory.createRaisedBevelBorder());time[i].setBackground(new Color(255,215,0));time[i].setFont(new Font("微软雅黑",Font.BOLD,11));time[i].setHorizontalAlignment(JTextField.CENTER);time[i].setEditable(false);container.add(time[i]);}time[0].setBounds(140, 230, 60, 20);time[1].setBounds(374, 360, 60, 20);time[2].setBounds(620, 230, 60, 20);for(int i=0;i<3;i++) {currentList[i]=new ArrayList<>();}}public void restart() {    if(t!=null && t.isPublish) {JOptionPane.showMessageDialog(this, "发牌阶段不可重开");return;}if(t!=null && thread!=null) {  t.i=10;if(!t.isOver) {t.stopFlag=true;thread.interrupt(); for(int i=0;i<54;i++) {//card[i].setVisible(false);card[i].setLocation(350, 50);card[i].turnRear();}                  }else { for(int i=0;i<54;i++) {card[i].setVisible(true);card[i].setLocation(350, 50);card[i].turnRear();} for(int i=0;i<3;i++) {time[i].setVisible(false);time[i].setText("倒计时:");}t.isGameOver=true;    }}else {JOptionPane.showMessageDialog(this, "发牌阶段不可重开");}}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource()==exit) {this.dispose();}if(e.getSource()==about) {JOptionPane.showMessageDialog(this, "QQ88888888");}if(e.getSource()==start) {this.restart();}if(e.getSource()==landlord[0]) {time[1].setText("抢地主");t.isRun=false;}if(e.getSource()==landlord[1]) {time[1].setText("不抢");t.isRun=false;}if(e.getSource()==publishCard[1]) {this.nextPlayer=true;time[1].setText("不要");currentList[1].clear();}if(e.getSource()==publishCard[0]) {List<Card> c=new ArrayList<>();for(int i=0;i<playerList[1].size();i++) {Card card=playerList[1].get(i);if(card.clicked) {c.add(card);}}int flag=0;if("不要".equals(time[0].getText()) && "不要".equals(time[2].getText())) {if(Common.judgeType(c)!=CardType.c0) {flag=1;}}else {flag=Common.checkCards(c, currentList);}if(flag==1) {currentList[1]=c;playerList[1].removeAll(currentList[1]);Point p=new Point();p.x=(770/2)-(currentList[1].size()+1)*15/2;p.y=300;for(int i=0;i<currentList[1].size();i++) {Card card=currentList[1].get(i);Common.move(card, card.getLocation(), p);p.x+=15;}Common.rePosition(playerList[1], 1, this);time[1].setVisible(false);this.nextPlayer=true;}}}public static void main(String[] args) {new Game();}
}

5.完成后启动main方法即可。
效果如下:


完整源码:
斗地主游戏完整源码(含图片资源)

创作不易,望大家多多支持。

有趣的游戏,Java版斗地主游戏实现相关推荐

  1. java写枪战游戏,Java版星球大战游戏(横向射击)

    Java版星球大战游戏(横向射击) 准备逐步整理一下手中的第三方Java游戏代码,将能用的部分融入到LGame里去,没有能用部分的就直接删掉. 但无论程式难易如何,也是原作者一番心血,不应将它们弃如敝 ...

  2. Java版SLG游戏 竜退治2

    剣と魔法の世界のターン制シミュレーションゲーム.マップは小規模ながら完成度は高いです. ストーリーは希薄で.ひたすら仲間やアイテムを集めつつ.淡々とステージクリアしていきます.   アイテムの経験値が ...

  3. 仙剑java_xianjian 仙剑游戏JAVA版源码,早期练习保存的资料 Develop 244万源代码下载- www.pudn.com...

    文件名称: xianjian下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 636 KB 上传时间: 2015-10-06 下载次数: 0 提 供 者: 黄 详 ...

  4. 拼图java源码_拼图游戏Java版源代码JAVA游戏源码下载

    Java版的拼图游戏,玩家能够自己更换图片,只需你把它分成块,另外它是以成绩=1000-时间(秒)-移动步数*10来决意你是否输了,按F1键起头游戏,Y健预览图片. 拼图游戏Java版源代码 (1 f ...

  5. Java版AVG游戏开发入门示例 3 ——脚本引擎的制作及应用

    源码下载地址:http://code.google.com/p/loon-simple/downloads/list 根据wikipedia的解释:脚本语言(Script language,scrip ...

  6. Java版AVG游戏开发入门示例[3]——脚本引擎的制作及应用

    源码下载地址:http://code.google.com/p/loon-simple/downloads/list 根据wikipedia的解释:脚本语言(Script language,scrip ...

  7. cts游戏手机版_cts游戏手机版下载-cts游戏手机版下载中文版v1.6-完全实况

    cts游戏手机版下载,cts(遨游中国)是一款超逼真超真实的模拟驾驶游戏,玩过驾驶类模拟游戏的伙伴一定不要错过这款cts游戏,玩家在游戏中驾驶货车前往不同的城市,路途中可以欣赏到非常多的美丽风景,这款 ...

  8. 简易贪吃蛇小游戏java版_用GUI实现java版贪吃蛇小游戏

    本文实例为大家分享了java版贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public stat ...

  9. java斗地主随机发牌_使用Java实现斗地主游戏的发牌过程

    package com.review.test; import java.util.ArrayList; import java.util.Collections; import java.util. ...

最新文章

  1. Linux 系统启动流程及其介绍
  2. penalized_tanh可视化
  3. 360企业版终端安装说明
  4. 主机关机后第二天就无法开机_手机关机后“开机”,跟直接“重启”有区别吗?看完又涨知识了...
  5. Websocket协议的学习、调研和实现
  6. org.json的使用详解
  7. 码云上传项目时出现空目录的解决办法
  8. 堆、栈、堆栈详谈--复习
  9. 使用 v-cloak 防止页面加载时出现 vuejs 的变量名
  10. 计算机系统更新从哪关闭,电脑总提示系统更新,怎么关闭?
  11. 魔方:公式记忆(三字诀)
  12. drupal8 修改主题_Drupal 8主题修订版-更新和新功能
  13. 批处理命令--call和start
  14. 闲鱼如何高效打造一个多业务、低侵入的搜索链路
  15. basic计算机编程基础,计算机编程基础(Visual Basic)
  16. 还在纠结程序员能不能干一辈子吗?有答案了!!
  17. KNN算法原理与自实现电影分类
  18. python爬虫win10程序_Python爬虫教程:批量提取Win10锁屏壁纸
  19. cf12月9日服务器维护时间,cf12月9、10日全区全服维护更新公告_穿越火线更新公告_7k7k穿越火线...
  20. vc中定时器并非多线程

热门文章

  1. 文字字体如何合适的运用到海报设计当中
  2. 【故障诊断】基于粒子群和多元宇宙算法优化最大相关峭度解卷积(MCKD)实现信号处理附matlab代码
  3. Task03 session和cookie、代理、selenium自动化 拔高:丁香园留言板爬取
  4. steam账号分享工具、迅游账号分享工具说明:
  5. stc89c51单片机音乐盒系统设计_基于单片机STC89C52的数字音乐盒设计
  6. linux atheros 驱动程序,又是一个难题 Atheros 5007 无线网卡 LINUX 下的驱动
  7. 【基于ChatGPT的API】实现一个响应速度比官方更快的在线问答网站并通过宝塔上线全网可访问
  8. go 框架 —— beego安装
  9. mycat全局表一致性检查
  10. 程序猿之歌 PHP,程序猿之歌