近日,使用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
2、洗完牌后,进入发牌阶段。
public void publishCard() {
for(int i=0;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.x20;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 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();
}
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 list) {
int[] count=new int[14];
for(int i=0;i list) {
Collections.sort(list,new Comparator() {
@Override
public 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 list) {
for(Card card : list) {
card.setVisible(false);
}
}
public static int checkCards(List c,List[] current) {
List 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 c1=getOrder(c);
List c2=getOrder(currList);
if(getValue(c1.get(0)) getOrder(List list){
List newList=new ArrayList<>();
int[] count=new int[18];
for(int i=0;icount[max]) {
max=j+1;
}
}
for(int k=0;k
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 currentList[]=new ArrayList[3];
List playerList[]=new ArrayList[3];
List 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() {
@Override
public 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();
}
lordList=new ArrayList();
int t=0;
for(int i=0;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, "发牌阶段不可重开");
}
}
@Override
public 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 c=new ArrayList<>();
for(int i=0;i
5.完成后启动main方法即可。
效果如下:
完整源码:
斗地主游戏完整源码(含图片资源)
创作不易,望大家多多支持。