《游戏学习》 java经典纸牌类小游戏《斗地主》源码
Posted 洛阳泰山
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《游戏学习》 java经典纸牌类小游戏《斗地主》源码相关的知识,希望对你有一定的参考价值。
游戏截图
项目代码目录结构
游戏主类 ,ide编辑器运行
package com;
import java.awt.Color;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Main extends JFrame implements ActionListener {
public Container container = null;// 定义容器
JMenuItem start, exit, about;// 定义菜单按钮
JButton landlord[]=new JButton[2];//抢地主按钮
JButton publishCard[]=new JButton[2];//出牌按钮
int dizhuFlag;//地主标志
int turn;
JLabel dizhu; //地主图标
List<Card> currentList[] =new ArrayList[3]; // 当前的出牌
List<Card> playerList[] = new ArrayList[3]; // 定义3个玩家表
List<Card> lordList;//地主牌
Card card[] = new Card[56]; // 定义54张牌
JTextField time[]=new JTextField[3]; //计时器
Time t; //定时器(线程)
boolean nextPlayer=false; //转换角色
public Main(){
Init();// 初始化
SetMenu();// 创建菜单 按钮(抢地主,发牌,计时器)
this.setVisible(true);
CardInit();//发牌
getLord(); //发完牌开始抢地主
time[1].setVisible(true);
//线程安全性,把非主线程的UI控制放到里面
SwingUtilities.invokeLater(new NewTimer(this,10));
}
// 抢地主
public void getLord(){
//System.out.println(CardType.c0.toString());
for(int i=0;i<2;i++)
landlord[i].setVisible(true);
}
//初始化牌
// 发牌洗牌
public void CardInit() {
int count = 1;
//初始化牌
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 13; j++) {
if ((i == 5) && (j > 2))
break;
else {
card[count] = new Card(this, i + "-" + j, false);
card[count].setLocation(300+(i*20), 50);
container.add(card[count]);
count++;
}
}
}
//打乱顺序
for(int i=0;i<200;i++){
Random random=new Random();
int a=random.nextInt(54)+1;
int b=random.nextInt(54)+1;
Card k=card[a];
card[a]=card[b];
card[b]=k;
}
//
System.out.println("开始发牌...");
long start=System.currentTimeMillis();
for(int i=0;i<3;i++)
playerList[i]=new ArrayList<Card>(); //玩家牌
lordList=new ArrayList<Card>();//地主牌三张
int t=0;
for(int i=1;i<=54;i++)
{
if(i>=52)//地主牌
{
Common.move(card[i], card[i].getLocation(),new Point(300+(i-52)*80,16),t);
lordList.add(card[i]);
continue;
}
switch ((t++)%3) {
case 0:
//左边玩家
Common.move(card[i], card[i].getLocation(),new Point(50,60+i*5),t);
playerList[0].add(card[i]);
//card[i].turnFront(); //显示正面
break;
case 1:
//我
Common.move(card[i], card[i].getLocation(),new Point(180+i*7,450),t);
playerList[1].add(card[i]);
card[i].turnFront(); //显示正面
break;
case 2:
//右边玩家
Common.move(card[i], card[i].getLocation(),new Point(700,60+i*5),t);
playerList[2].add(card[i]);
//card[i].turnFront(); //显示正面
break;
}
//card[i].turnFront(); //显示正面
container.setComponentZOrder(card[i], 0);
}
System.out.println("结束发牌...");
System.out.println(System.currentTimeMillis()-start);
//发完牌排序,从大到小
for(int i=0;i<3;i++)
{
Common.order(playerList[i]);
Common.rePosition(this,playerList[i],i);//重新定位
}
dizhu=new JLabel(new ImageIcon("images/dizhu.gif"));
dizhu.setVisible(false);
dizhu.setSize(40, 40);
container.add(dizhu);
}
// 初始化窗体
public void Init() {
this.setTitle("斗地主游戏");
this.setSize(830, 620);
setResizable(false);
setLocationRelativeTo(getOwner()); // 屏幕居中
container = this.getContentPane();
container.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
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++)
{
publishCard[i].setBounds(320+i*100, 400, 60, 20);
landlord[i].setBounds(320+i*100, 400,75,20);
container.add(landlord[i]);
landlord[i].addActionListener(this);
landlord[i].setVisible(false);
container.add(publishCard[i]);
publishCard[i].setVisible(false);
publishCard[i].addActionListener(this);
}
for(int i=0;i<3;i++){
time[i]=new JTextField("倒计时:");
time[i].setVisible(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<Card>();
}
}
//点击鼠标事件
public void actionPerformed(ActionEvent e) {
if (e.getSource() == exit) {
this.dispose();
}
if (e.getSource() == about) {
JOptionPane.showMessageDialog(this, "QQ361106306,小柒");
}
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;
currentList[1].clear();
time[1].setText("不要");
}
//如果是出牌按钮
if(e.getSource()==publishCard[0]){
List<Card> c = new ArrayList<Card>();
//点选出牌
for(int i=0;i<playerList[1].size();i++)
{
Card card=playerList[1].get(i);
if(card.clicked)
{
c.add(card);//把点中的牌放入新集合
}
}
/** 给点选的牌排序 */
/*for(int i=0;i<c.size();i++){
System.out.println("点选的牌是:"+c.get(i).name);
}*/
int flag=0;
//如果我主动出牌
if(time[0].getText().equals("不要")&&time[2].getText().equals("不要"))
{
if(Common.jugdeType(c)!=CardType.c0)
flag=1;//表示可以出牌
}//如果我跟牌
else{
flag=Common.checkCards(c,currentList);
}
//判断是否符合出牌
if(flag==1)
{
currentList[1]=c;
playerList[1].removeAll(currentList[1]);//移除走的牌
//定位出牌
Point point=new Point();
point.x=(770/2)-(currentList[1].size()+1)*15/2;;
point.y=310;
for(int i=0,len=currentList[1].size();i<len;i++)
{
Card card=currentList[1].get(i);
Common.move(card, card.getLocation(), point,10);
point.x+=15;
}
//抽完牌后重新整理牌
Common.rePosition(this, playerList[1], 1);
time[1].setVisible(false);
this.nextPlayer=true;
}
}
}
private void restart() {
System.out.println("重新开始");
/* for(int i=0;i<3;i++){
currentList[i]=null;
}
for(int i=0;i<3;i++){
playerList[i]=null;
}
lordList=null;
for(int i=0;i<card.length;i++){
card[i]=null;
}
nextPlayer=false;*/
// this.CardInit();//发牌
}
public static void main(String args[]) {
new Main();
}
}
class NewTimer implements Runnable{
Main main;
int i;
public NewTimer(Main m,int i){
this.main=m;
this.i=i;
}
@Override
public void run() {
// TODO Auto-generated method stub
main.t=new Time(main,12);//从10开始倒计时
main.t.start();
}
}
Card类
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class Card extends JLabel implements MouseListener{
Main main;//Main类的引用
String name;//图片url名字
boolean up;//是否正反面
boolean canClick=false;//是否可被点击
boolean clicked=false;//是否点击过
public Card(Main m,String name,boolean up){
this.main=m;
this.name=name;
this.up=up;
if(this.up)
this.turnFront();
else {
this.turnRear();
}
this.setSize(71, 96);
this.setVisible(true);
this.addMouseListener(this);
}
//正面
public void turnFront() {
this.setIcon(new ImageIcon("images/" + name + ".gif"));
this.up = true;
}
//反面
public void turnRear() {
this.setIcon(new ImageIcon("images/rear.gif"));
this.up = false;
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(canClick)
{
Point from=this.getLocation();
int step; //移动的距离
if(clicked)
step=-30;
else {
step=30;
}
clicked=!clicked; //反向
//当被选中的时候,向前移动一步/后退一步
Common.move(this,from,new Point(from.x,from.y-step),10);
}
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
}
CardType 枚举类
public enum CardType {
c1,//单牌。
c2,//对子。
c3,//3不带。
c4,//炸弹。
c31,//3带1。
c32,//3带2。
c411,//4带2个单,或者一对
c422,//4带2对
c123,//连子。
c1122,//连队。
c111222,//飞机。
c11122234,//飞机带单排.
c1112223344,//飞机带对子.
c0//不能出牌
}
common类
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Common {
//判断牌型
public static CardType jugdeType(List<Card> list){
//因为之前排序过所以比较好判断
int len=list.size();
//单牌,对子,3不带,4个一样炸弹
if(len<=4)
{ //如果第一个和最后个相同,说明全部相同
if(list.size()>0&&Common.getValue(list.get(0))==Common.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&&Common.getColor(list.get(1))==5&&Common.getColor(list.get(0))==5)
return CardType.c4;
//当第一个和最后个不同时,3带1
if(len==4 &&((Common.getValue(list.get(0))==Common.getValue(list.get(len-2)))||
Common.getValue(list.get(1))==Common.getValue(list.get(len-1))))
return CardType.c31;
else {
return CardType.c0;
}
}
//当5张以上时,连字,3带2,飞机,2顺,4带2等等
if(len>=5)
{//现在按相同数字最大出现次数
Card_index card_index=new Card_index();
for(int i=0;i<4;i++)
card_index.a[i]=new ArrayList<Integer>();
//求出各种数字出现频率
Common.getMax( card_index,list); //a[0,1,2,3]分别表示重复1,2,3,4次的牌
//3带2 -----必含重复3次的牌
if(card_index.a[2].size()==1 &&card_index.a[1].size()==1 && len==5)
return CardType.c32;
//4带2(单,双)
if(card_index.a[3].size()==1 && len==6)
return CardType.c411;
//4带2对
if(card_index.a[3].size()==1 && card_index.a[1].size()==2 &&len==8)
return CardType.c422;
//顺子,保证不存在王
if((Common.getColor(list.get(0))!=5)&&(card_index.a[0].size()==len) &&
(Common.getValue(list.get(0))-Common.getValue(list.get(len-1))==len-1))
return CardType.c123;
//连队
if(card_index.a[1].size()==len/2 && len%2==0 && len/2>=3
&&(Common.getValue(list.get(0))-Common.getValue(list.get(len-1))==(len/2-1)))
return CardType.c1122;
//飞机
if(card_index.a[2].size()==len/3 && (len%3==0) &&
(Common.getValue(list.get(0))-Common.getValue(list.get(len-1))==(len/3-1)))
return CardType.c111222;
//飞机带n单,n/2对
if(card_index.a[2].size()==len/4 &&
((Integer)(card_index.a[2].get(len/4-1))-(Integer)(card_index.a[2].get(0))==len/4-1))
return CardType.c11122234;
//飞机带n双
if(card_index.a[2].size()==len/5 && card_index.a[2].size()==len/5 &&
((Integer)(card_index.a[2].get(len/5-1))-(Integer)(card_index.a[2].get(0))==len/5-1))
return CardType.c1112223344;
}
return CardType.c0;
}
//移动效果的函数,用于发牌
public static void move(Card card,Point from,Point to,int t){
if(to.x!=from.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){
if(t%3==2){
flag=3;
}else{
flag=10;
}
}else {
if(t%3==2){
flag=-3;
}else{
flag=-10;
}
}
for(int i=from.x;Math.abs(i-to.x)>20;i+=flag)
{
double y=k*i+b;//这里主要用的数学中的线性函数
//System.out.println(y+"="+k+"*"+i+"+"+b);
card.setLocation(i,(int)y);
try {
Thread.sleep(5); //延迟,可自己设置
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//位置校准
card.setLocation(to);
}
//对list排序
public static void order(List<Card> list){
Collections.sort(list,new Comparator<Card>() {
public int compare(Card o1, Card o2) {
// TODO Auto-generated method stub
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(a1==5&&b1==1) b1+=50;
if(a2==5) b2+=100;
if(a2==5&&b2==1) b2+=50;
//如果是A或者2
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;
}
}
});
}
//重新定位 flag代表电脑1 ,2 或者是我
public static void rePosition(Main m,List<Card> list,int flag){
Point p=new Point();
if(flag==0)
{
p.x=50;
p.y=(450/2)-(list.size()+1)*15/2;
}
if(flag==1)
{//我的排序 _y=450 width=830
p.x=(800/2)-(list.size()+1)*21/2;
p.y=450;
}
if(flag==2)
{
p.x=700;
p.y=(450/2)-(list.size()+1)*15/2;
}
int len=list.size();
for(int i=0;i<len;i++){
Card card=list.get(i);
Common.move(card, card.getLocation(), p,10);
m.container.setComponentZOrder(card, 0);
if(flag==1)p.x+=21;
else p.y+=15;
}
}
//地主牌权值,看是否抢地主
public static int getScore(List<Card> list){
int count=0;
for(int i=0,len=list.size();i<len;i++){
Card card=list.get(i);
if(card.name.substring(0, 1).equals("5"))
{
//System.out.println(card.name.substring(0, 1));
count+=5;
}
if(card.name.substring(2, card.name.length()).equals("2"))
{
//System.out.println(2);
count+=2;
}
}
return count;
}
//返回花色
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(card.name.substring(2,card.name.length()).equals("2"))
i+=13;
if(card.name.substring(2,card.name.length()).equals("1"))
i+=13;
if(Common.getColor(card)==5)
i+=2;//是王
return i;
}
//得到最大相同数
public static void getMax(Card_index card_index,List<Card> list){
int count[]=new int[14];//1-13各算一种,王算第14种
for(int i=0;i<14;i++)
count[i]=0;
for(int i=0; i<list.size(); i++){
if(Common.getColor(list.get(i))==5)
count[13]++;
else
count[Common.getValue(list.get(i))-1]++;
}
for(int i=0;i<14;i++)
{
switch (count[i]) {
case 1:
card_index.a[0].add(i+1);
break;
case 2:
card_index.a[1].add(i+1);
break;
case 3:
card_index.a[2].add(i+1);
break;
case 4:
card_index.a[3].add(i+1);
break;
}
}
}
//拆牌
public static Model getModel(List<Card> list){
//先复制一个list
List<Card> list2=new ArrayList<Card>(list);
Model model=new Model();
//------先拆炸弹
Common.getBoomb(list2, model); //ok
//------拆3带
Common.getThree(list2, model);
//拆飞机
Common.getPlane(list2, model);
//------拆对子
Common.getTwo(list2, model);
//拆连队
Common.getTwoTwo(list2, model);
//拆顺子
Common.get123(list2, model);
//拆单
Common.getSingle(list2, model);
return model;
}
//拆连子
public static void get123(List<Card> list,Model model){
List<Card> del=new ArrayList<Card>();//要删除的Cards
if(list.size()>0&&(Common.getValue(list.get(0))<7 ||Common.getValue(list.get(list.size()-1))>10))
return;
if(list.size()<5)
return;
for(int i=0,len=list.size();i<len;i++)
{
int k=i;
for(int j=i;j<len;j++){
if(Common.getValue(list.get(i))-Common.getValue(list.get(j))==j-i)
{
k=j;
}
}
if(k-i>=4)
{
String s="";
for(int j=i;j<k;j++)
{
s+=list.get(j).name+",";
del.add(list.get(j));
}
s+=list.get(k).name;
del.add(list.get(k));
model.a123.add(s);
i=k;
}
}
list.removeAll(del);
}
//拆双顺
public static void getTwoTwo(List<Card> list,Model model){
List<String> del=new ArrayList<String>();//要删除的Cards
//从model里面的对子找
List<String> l=model.a2;
if(l.size()<3)
return ;
Integer s[]=new Integer[l.size()];
for(int i=0,len=l.size();i<len;i++){
String []name=l.get(i).split(",");
s[i]=Integer.parseInt(name[0].substring(2,name[0].length()));
}
//s0,1,2,3,4 13,9,8,7,6
for(int i=0,len=l.size();i<len;i++){
int k=i;
for(int j=i;j<len;j++)
{
if(s[i]-s[j]==j-i)
k=j;
}
if(k-i>=2)//k=4 i=1
{//说明从i到k是连队
String ss="";
for(int j=i;j<k;j++)
{
ss+=l.get(j)+",";
del.add(l.get(j));
}
ss+=l.get(k);
model.a112233.add(ss);
del.add(l.get(k));
i=k;
}
}
l.removeAll(del);
}
//拆飞机
public static void getPlane(List<Card> list,Model model){
List<String> del=new ArrayList<String>();//要删除的Cards
//从model里面的3带找
List<String> l=model.a3;
if(l.size()<2)
return ;
Integer s[]=new Integer[l.size()];
for(int i=0,len=l.size();i<len;i++){
String []name=l.get(i).split(",");
s[i]=Integer.parseInt(name[0].substring(2,name[0].length()));
}
for(int i=0,len=l.size();i<len;i++){
int k=i;
for(int j=i;j<len;j++)
{
if(s[i]-s[j]==j-i)
k=j;
}
if(k!=i)
{//说明从i到k是飞机
String ss="";
for(int j=i;j<k;j++)
{
ss+=l.get(j)+",";
del.add(l.get(j));
}
ss+=l.get(k);
model.a111222.add(ss);
del.add(l.get(k));
i=k;
}
}
l.removeAll(del);
}
//拆炸弹
public static void getBoomb(List<Card> list,Model model){
List<Card> del=new ArrayList<Card>();//要删除的Cards
//王炸
if(list.size()>=2 &&Common.getColor(list.get(0))==5 && Common.getColor(list.get(1))==5)
{
model.a4.add(list.get(0).name+","+list.get(1).name); //按名字加入
del.add(list.get(0));
del.add(list.get(1));
}
//如果王不构成炸弹咋先拆单
if(Common.getColor(list.get(0))==5&&Common.getColor(list.get(1))!=5)
{
del.add(list.get(0));
model.a1.add(list.get(0).name);
}
list.removeAll(del);
//一般的炸弹
for(int i=0,len=list.size();i<len;i++){
if(i+3<len && Common.getValue(list.get(i))==Common.getValue(list.get(i+3)))
{
String s=list.get(i).name+",";
s+=list.get(i+1).name+",";
s+=list.get(i+2).name+",";
s+=list.get(i+3).name;
model.a4.add(s);
for(int j=i;j<=i+3;j++)
del.add(list.get(j));
i=i+3;
}
}
list.removeAll(del);
}
//拆3带
public static void getThree(List<Card> list,Model model){
List<Card> del=new ArrayList<Card>();//要删除的Cards
//连续3张相同
for(int i=0,len=list.size();i<len;i++){
if(i+2<len&&Common.getValue(list.get(i))==Common.getValue(list.get(i+2)))
{
String s=list.get(i).name+",";
s+=list.get(i+1).name+",";
s+=list.get(i+2).name;
model.a3.add(s);
for(int j=i;j<=i+2;j++)
del.add(list.get(j));
i=i+2;
}
}
list.removeAll(del);
}
//拆对子
public static void getTwo(List<Card> list,Model model){
List<Card> del=new ArrayList<Card>();//要删除的Cards
//连续2张相同
for(int i=0,len=list.size();i<len;i++){
if(i+1<len&&Common.getValue(list.get(i))==Common.getValue(list.get(i+1)))
{
String s=list.get(i).name+",";
s+=list.get(i+1).name;
model.a2.add(s);
for(int j=i;j<=i+1;j++)
del.add(list.get(j));
i=i+1;
}
}
list.removeAll(del);
}
//拆单牌
public static void getSingle(List<Card> list,Model model){
List<Card> del=new ArrayList<Card>();//要删除的Cards
//1
for(int i=0,len=list.size();i<len;i++){
model.a1.add(list.get(i).name);
del.add(list.get(i));
}
list.removeAll(del);
}
//隐藏之前出过的牌
public static void hideCards(List<Card> list){
for(int i=0,len=list.size();i<len;i++){
list.get(i).setVisible(false);
}
}
//检查牌的是否能出
public static int checkCards(List<Card> c,List<Card>[] current){
//找出当前最大的牌是哪个电脑出的,c是点选的牌
List<Card> currentlist=(current[0].size()>0)?current[0]:current[2];
CardType cType=Common.jugdeType(c);
//如果张数不同直接过滤
if(cType!=CardType.c4&&c.size()!=currentlist.size())
return 0;
//比较我的出牌类型
if(Common.jugdeType(c)!=Common.jugdeType(currentlist))
{
return 0;
}
//比较出的牌是否要大
//王炸弹
if(cType==CardType.c4)
{
if(c.size()==2)
return 1;
if(currentlist.size()==2)
return 0;
}
//单牌,对子,3带,4炸弹
if(cType==CardType.c1||cType==CardType.c2||cType==CardType.c3||cType==CardType.c4){
if(Common.getValue(c.get(0))<=Common.getValue(currentlist.get(0)))
{
return 0;
}else {
return 1;
}
}
//顺子,连队,飞机裸
if(cType==CardType.c123||cType==CardType.c1122||cType==CardType.c111222)
{
if(Common.getValue(c.get(0))<=Common.getValue(currentlist.get(0)))
return 0;
else
return 1;
}
//按重复多少排序
//3带1,3带2 ,飞机带单,双,4带1,2,只需比较第一个就行,独一无二的
if(cType==CardType.c31||cType==CardType.c32||cType==CardType.c411||cType==CardType.c422
||cType==CardType.c11122234||cType==CardType.c1112223344){
List<Card> a1=Common.getOrder2(c); //我出的牌
List<Card> a2=Common.getOrder2(currentlist);//当前最大牌
if(Common.getValue(a1.get(0))<Common.getValue(a2.get(0)))
return 0;
}
return 1;
}
//按照重复次数排序
public static List getOrder2(List<Card> list){
List<Card> list2=new ArrayList<Card>(list);
List<Card> list3=new ArrayList<Card>();
// List<Integer> list4=new ArrayList<Integer>();
int len=list2.size();
int a[]=new int[20];//记录数
for(int i=0;i<20;i++)
a[i]=0;
for(int i=0;i<len;i++)
{
a[Common.getValue(list2.get(i))]++;
}
int max=0;
for(int i=0;i<20;i++){
max=0;
for(int j=19;j>=0;j--){
if(a[j]>a[max])
max=j;
}
for(int k=0;k<len;k++){
if(Common.getValue(list2.get(k))==max){
list3.add(list2.get(k));
}
}
list2.remove(list3);
a[max]=0;
}
return list3;
}
}
class Card_index{
List a[]=new ArrayList[4];//单张
}
Model类
import java.util.ArrayList;
import java.util.List;
public class Model {
//一组牌
int value; //权值
int num;// 手数 (几次能够走完,没有挡的情况下)
List<String> a1=new ArrayList<String>(); //单张
List<String> a2=new ArrayList<String>(); //对子
List<String> a3=new ArrayList<String>(); //3带
List<String> a123=new ArrayList<String>(); //连子
List<String> a112233=new ArrayList<String>(); //连牌
List<String> a111222=new ArrayList<String>(); //飞机
List<String> a4=new ArrayList<String>(); //炸弹
}
time 类
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
public class Time extends Thread {
Main main;
boolean isRun = true;
int i = 10;
public Time(Main m, int i) {
this.main = m;
this.i = i;
}
@Override
public void run() {
while (i > -1 && isRun) {
main.time[1].setText("倒计时:" + i--);
second(1);// 等一秒
}
if (i == -1)// 正常终结,说明超时
main.time[1].setText("不抢");
main.landlord[0].setVisible(false);
main.landlord[1].setVisible(false);
for (Card card2 : main.playerList[1])
card2.canClick = true;// 可被点击
// 如果自己抢到地主
if (main.time[1].getText().equals("抢地主")) {
// 得到地主牌
main.playerList[1].addAll(main.lordList);
openlord(true);
second(2);// 等待五秒
Common.order(main.playerList[1]);
Common.rePosition(main, main.playerList[1], 1);
setlord(1);
} else {
// 电脑选地主
if (Common.getScore(main.playerList[0]) < Common
.getScore(main.playerList[2])) {
main.time[2].setText("抢地主");
main.time[2].setVisible(true);
setlord(2);// 设定地主
openlord(true);//把地主牌翻开
second(3);
main.playerList[2].addAll(main.lordList);
Common.order(main.playerList[2]);
Common.rePosition(main, main.playerList[2], 2);
openlord(false);
} else {
main.time[0].setText("抢地主");
main.time[0].setVisible(true);
setlord(0);// 设定地主
openlord(true);
second(3);
main.playerList[0].addAll(main.lordList);
Common.order(main.playerList[0]);
Common.rePosition(main, main.playerList[0], 0);
//openlord(false);
}
}
// 选完地主后 关闭地主按钮
main.landlord[0].setVisible(false);
main.landlord[1].setVisible(false);
turnOn(false);
for (int i = 0; i < 3; i++)
{
main.time[i].setText("不要");
main.time[i].setVisible(false);
}
// 开始游戏 根据地主不同顺序不同
main.turn=main.dizhuFlag;
while (true) {
if(main.turn==1) //我
{
turnOn(true);// 出牌按钮 --我出牌
timeWait(30, 1);// 我自己的定时器
System.out.println("我出牌");
turnOn(false);//选完关闭
main.turn=(main.turn+1)%3;
if(win())//判断输赢
break;
}
if (main.turn==0)
{
computer0();
main.turn=(main.turn+1)%3;
if(win())//判断输赢
break;
}
if(main.turn==2)
{
computer2();
main.turn=(main.turn+1)%3;
if(win())//判断输赢
break;
}
}
}
// 等待i秒
public void second(int i) {
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 地主牌翻看
public void openlord(boolean is) {
for (int i = 0; i < 3; i++) {
if (is)
main.lordList.get(i).turnFront(); // 地主牌翻看
else {
main.lordList.get(i).turnRear(); // 地主牌闭合
}
main.lordList.get(i).canClick = true;// 可被点击
}
}
// 设定地主
public void setlord(int i) {
Point point = new Point();
if (i == 1)// 我是地主
{
point.x = 80;
point.y = 430;
main.dizhuFlag = 1;// 设定地主
}
if (i == 0) {
point.x = 80;
point.y = 20;
main.dizhuFlag = 0;
}
if (i == 2) {
point.x = 700;
point.y = 20;
main.dizhuFlag = 2;
}
main.dizhu.setLocation(point);
main.dizhu.setVisible(true);
}
// 打开出牌按钮
public void turnOn(boolean flag) {
main.publishCard[0].setVisible(flag);
main.publishCard[1].setVisible(flag);
}
// 电脑0走牌(我代表1)
public void computer0() {
timeWait(3, 0); // 定时
ShowCard(0); // 出牌
}
// 电脑2走牌(我代表1)
public void computer2() {
timeWait(3, 2); // 定时
ShowCard(2); // 出牌
}
// 走牌
public void ShowCard(int role) {
Model model = Common.getModel(main.playerList[role]);
// 待走的牌
List<String> list = new ArrayList<String>();
// 如果是主动出牌
if (main.time[(role + 1) % 3].getText().equals("不要")
&& main.time[(role + 2) % 3].getText().equals("不要")) {
// 有单出单 (除开3带,飞机能带的单牌)
if (model.a1.size() > (model.a111222.size() * 2 + model.a3.size())) {
list.add(model.a1.get(model.a1.size() - 1));
}// 有对子出对子 (除开3带,飞机)
else if (model.a2.size() > (model.a111222.size() * 2 + model.a3
.size())) {
list.add(model.a2.get(model.a2.size() - 1));
}// 有顺子出顺子
else if (model.a123.size() > 0) {
list.add(model.a123.get(model.a123.size() - 1));
}// 有3带就出3带,没有就出光3
else if (model.a3.size() > 0) {
// 3带单,且非关键时刻不能带王,2
if (model.a1.size() > 0) {
list.add(model.a1.get(model.a1.size() - 1));
}// 3带对
else if (model.a2.size() > 0) {
list.add(model.a2.get(model.a2.size() - 1));
}
list.add(model.a3.get(model.a3.size() - 1));
}// 有双顺出双顺
else if (model.a112233.size() > 0) {
list.add(model.a112233.get(model.a112233.size() - 1));
}// 有飞机出飞机
else if (model.a111222.size() > 0) {
String name[] = model.a111222.get(0).split(",");
// 带单
if (name.length / 3 <= model.a1.size()) {
list.add(model.a111222.get(model.a111222.size() - 1));
for (int i = 0; i < name.length / 3; i++)
list.add(model.a1.get(i));
} else if (name.length / 3 <= model.a2.size())// 带双
{
list.add(model.a111222.get(model.a111222.size() - 1));
for (int i = 0; i < name.length / 3; i++)
list.add(model.a2.get(i));
}
// 有炸弹出炸弹
} else if (model.a4.size() > 0) {
// 4带2,1
int sizea1 = model.a1.size();
int sizea2 = model.a2.size();
if (sizea1 >= 2) {
list.add(model.a1.get(sizea1 - 1));
list.add(model.a1.get(sizea1 - 2));
list.add(model.a4.get(0));
} else if (sizea2 >= 2) {
list.add(model.a2.get(sizea1 - 1));
list.add(model.a2.get(sizea1 - 2));
list.add(model.a4.get(0));
} else {// 直接炸
list.add(model.a4.get(0));
}
}
}// 如果是跟牌
else {
List<Card> player = main.currentList[(role + 2) % 3].size() > 0
? main.currentList[(role + 2) % 3]
: main.currentList[(role + 1) % 3];//当前出的牌
CardType cType=Common.jugdeType(player);//桌面别人出的牌
//如果是单牌
if(cType==CardType.c1)
{
AI_1(model.a1, player, list, role);
}//如果是对子
else if(cType==CardType.c2)
{
AI_1(model.a2, player, list, role);
}//3带
else if(cType==CardType.c3)
{
AI_1(model.a3, player, list, role);
}//炸弹
else if(cType==CardType.c4)
{
AI_1(model.a4, player, list, role);
}//如果是3带1
else if(cType==CardType.c31){
//偏家 涉及到拆牌
//if((role+1)%3==main.dizhuFlag)
AI_2(model.a3, model.a1, player, list, role);
}//如果是3带2
else if(cType==CardType.c32){
//偏家
//if((role+1)%3==main.dizhuFlag)
AI_2(model.a3, model.a2, player, list, role);
}//如果是4带11
else if(cType==CardType.c411){
AI_5(model.a4, model.a1, player, list, role);
}
//如果是4带22
else if(cType==CardType.c422){
AI_5(model.a4, model.a2, player, list, role);
}
//顺子
else if(cType==CardType.c123){
AI_3(model.a123, player, list, role);
}
//双顺
else if(cType==CardType.c1122){
AI_3(model.a112233, player, list, role);
}
//飞机带单
else if(cType==CardType.c11122234){
AI_4(model.a111222,model.a1, player, list, role);
}
//飞机带对
else if(cType==CardType.c1112223344){
AI_4(model.a111222,model.a2, player, list, role);
}
//炸弹
if(list.size()==0)
{
int len4=model.a4.size();
if(len4>0)
list.add(model.a4.get(len4-1));
}
}
// 定位出牌
main.currentList[role].clear();
if (list.size() > 0) {
Point point = new Point();
if (role == 0)
point.x = 200;
if (role == 2)
point.x = 550;
point.y = (400 / 2) - (list.size() + 1) * 15 / 2;// 屏幕中部
// 将name转换成Card
for (int i = 0, len = list.size(); i < len; i++) {
List<Card> cards = getCardByName(main.playerList[role],
list.get(i));
for (Card card : cards) {
Common.move(card, card.getLocation(), point,10);
point.y += 15;
main.currentList[role].add(card);
main.playerList[role].remove(card);
}
}
Common.rePosition(main, main.playerList[role], role);
} else {
main.time[role].setVisible(true);
main.time[role].setText("不要");
}
for(Card card:main.currentList[role])
card.turnFront();
}
// 按name获得Card,方便从Model取出
public List<Card> getCardByName(List<Card> list, String n) {
String[] name = n.split(",");
List<Card> cardsList = new ArrayList<Card>();
int j = 0;
for (int i = 0, len = list.size(); i < len; i++) {
if (j < name.length && list.get(i).name.equals(name[j])) {
cardsList.add(list.get(i));
i = 0;
j++;
}
}
return cardsList;
}
//顺子
public void AI_3(List<String> model,List<Card> player,List<String> list,int role){
for(int i=0,len=model.size();i<len;i++)
{
String []s=model.get(i).split(",");
if(s.length==player.size()&&getValueInt(model.get(i))>Common.getValue(player.get(0)))
{
list.add(model.get(i));
return;
}
}
}
//飞机带单,双
public void AI_4(List<String> model1,List<String> model2,List<Card> player,List<String> list,int role){
//排序按重复数
player=Common.getOrder2(player);
int len1=model1.size();
int len2=model2.size();
if(len1<1 || len2<1)
return;
for(int i=0;i<len1;i++){
String []s=model1.get(i).split(",");
String []s2=model2.get(0).split(",");
if((s.length/3<=len2)&&(s.length*(3+s2.length)==player.size())&&getValueInt(model1.get(i))>Common.getValue(player.get(0)))
{
list.add(model1.get(i));
for(int j=1;j<=s.length/3;j++)
list.add(model2.get(len2-j));
}
}
}
//4带1,2
public void AI_5(List<String> model1,List<String> model2,List<Card> player,List<String> list,int role){
//排序按重复数
player=Common.getOrder2(player);
int len1=model1.size();
int len2=model2.size();
if(len1<1 || len2<2)
return;
for(int i=0;i<len1;i++){
if(getValueInt(model1.get(i))>Common.getValue(player.get(0)))
{
list.add(model1.get(i));
for(int j=1;j<=2;j++)
list.add(model2.get(len2-j));
}
}
}
//单牌,对子,3个,4个,通用
public void AI_1(List<String> model,List<Card> player,List<String> list,int role){
//顶家
if((role+1)%3==main.dizhuFlag)
{
for(int i=0,len=model.size();i<len;i++)
{
if(getValueInt(model.get(i))>Common.getValue(player.get(0)))
{
list.add(model.get(i));
break;
}
}
}else {//偏家
for(int len=model.size(),i=len-1;i>=0;i--)
{
if(getValueInt(model.get(i))>Common.getValue(player.get(0)))
{
list.add(model.get(i));
break;
}
}
}
}
//3带1,2,4带1,2
public void AI_2(List<String> model1,List<String> model2,List<Card> player,List<String> list,int role){
//model1是主牌,model2是带牌,player是玩家出的牌,,list是准备回的牌
//排序按重复数
player=Common.getOrder2(player);
int len1=model1.size();
int len2=model2.size();
//如果有王直接炸了
if(len1>0&&model1.get(0).length()<10)
{
list.add(model1.get(0));
System.out.println("王炸");
return;
}
if(len1<1 || len2<1)
return;
for(int len=len1,i=len-1;i>=0;i--)
{
if(getValueInt(model1.get(i))>Common.getValue(player.get(0)))
{
list.add(model1.get(i));
break;
}
}
list.add(model2.get(len2-1));
if(list.size()<2)
list.clear();
}
// 延时,模拟时钟
public void timeWait(int n, int player) {
if (main.currentList[player].size() > 0)
Common.hideCards(main.currentList[player]);
if (player == 1)// 如果是我,10秒到后直接下一家出牌
{
int i = n;
while (main.nextPlayer == false && i >= 0) {
// main.container.setComponentZOrder(main.time[player], 0);
main.time[player].setText("倒计时:" + i);
main.time[player].setVisible(true);
second(1);
i--;
}
if (i == -1) {
main.time[player].setText("超时");
}
main.nextPlayer = false;
} else {
for (int i = n; i >= 0; i--) {
second(1);
// main.container.setComponentZOrder(main.time[player], 0);
main.time[player].setText("倒计时:" + i);
main.time[player].setVisible(true);
}
}
main.time[player].setVisible(false);
}
//通过name估值
public int getValueInt(String n){
String name[]=n.split(",");
String s=name[0];
int i=Integer.parseInt(s.substring(2, s.length()));
if(s.substring(0, 1).equals("5"))
i+=3;
if(s.substring(2, s.length()).equals("1")||s.substring(2, s.length()).equals("2"))
i+=13;
return i;
}
//判断输赢
public boolean win(){
for(int i=0;i<3;i++){
if(main.playerList[i].size()==0)
{
String s;
if(i==1)
{
s="恭喜你,胜利了!";
}else {
s="恭喜电脑"+i+",赢了! 你的智商有待提高哦";
}
JOptionPane.showMessageDialog(main, s);
return true;
}
}
return false;
}
}
项目纸牌图片集瞎下载
以上是关于《游戏学习》 java经典纸牌类小游戏《斗地主》源码的主要内容,如果未能解决你的问题,请参考以下文章