【Java】利用多线程实现斗地主发牌

做这个之前在网看了很久,斗地主发牌的代码小伙伴们大多是用集合来实现的,现在给大家分享一个利用多线程实现的斗地主发牌,代码如下:

扑克类:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Poker {
	// 定义集合,存储扑克
	private static List<String> poker = new ArrayList<String>();
	//区分玩家,即线程
	private int player = (int)(Math.random() * 3 + 1);
	//取牌索引
	private int index = 0;
	//地主
	private int landlord = (int)(Math.random() * 3 + 1);
	
	// 组合扑克牌
	public static void make() {
		String[] colors = { "♠", "♣", "♥", "♦" };
		String[] charsA = { "A" };
		String[] charsJQK = { "J", "Q", "K" };
 
		for (int i = 0; i < colors.length; i++) {
			for (int j = 0; j < charsA.length; j++) {
				poker.add(colors[i] + charsA[j]);
			}
			for (int j = 2; j <= 10; j++) {
				poker.add(colors[i] + j);
			}
			for (int j = 0; j < charsJQK.length; j++) {
				poker.add(colors[i] + charsJQK[j]);
			}
		}
		poker.add("大王");
		poker.add("小王");

		System.out.println(poker);
	}

	// 洗牌
	public static void shuffle() {
		Collections.shuffle(poker);
		System.out.println(poker);
	}

	public static List<String> getPoker() {
		return poker;
	}

	public static void setPoker(List<String> poker) {
		Poker.poker = poker;
	}

	public int getPlayer() {
		return player;
	}

	public void setPlayer(int player) {
		this.player = player;
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public int getLandlord() {
		return landlord;
	}

	public void setLandlord(int landlord) {
		this.landlord = landlord;
	}
}

第一个玩家:

import java.util.ArrayList;

public class Player1 implements Runnable{
	private ArrayList<String> data = new ArrayList<String>();

	private Poker poker;
	private String name;
	
	public Player1(Poker poker, String name) {
		this.poker = poker;
		this.name = name;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (poker) {
				if (poker.getIndex() > 50) {
					//如果该玩家是地主,把最后三张发给该玩家
					if (poker.getLandlord() == 1) {
						System.out.println(this.name + "是地主");
						data.add(Poker.getPoker().get(51));
						data.add(Poker.getPoker().get(52));
						data.add(Poker.getPoker().get(53));
					}
					System.out.println(this.name + ":" + this.data);
					break;
				}
				if (poker.getPlayer() == 1) {
					//获取到该摸第几张牌
					int index = poker.getIndex();
					//摸牌
					data.add(Poker.getPoker().get(index));
					System.out.println(this.name + "摸了一张" + Poker.getPoker().get(index));
					//告诉第二个线程进行摸牌
					poker.setPlayer(2);
					poker.setIndex(index + 1);
				}
				try {
					Thread.sleep(10);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

第二个玩家:

import java.util.ArrayList;

public class Player2 implements Runnable{
	private ArrayList<String> data = new ArrayList<String>();

	private Poker poker;
	private String name;
	
	public Player2(Poker poker, String name) {
		this.poker = poker;
		this.name = name;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (poker) {
				if (poker.getIndex() > 50) {
					if (poker.getLandlord() == 2) {
						System.out.println(this.name + "是地主");
						data.add(Poker.getPoker().get(51));
						data.add(Poker.getPoker().get(52));
						data.add(Poker.getPoker().get(53));
					}
					System.out.println(this.name + ":" + this.data);
					break;
				}
				if (poker.getPlayer() == 2) {
					//获取到该摸第几张牌
					int index = poker.getIndex();
					//摸牌
					data.add(Poker.getPoker().get(index));
					System.out.println(name + "摸了一张" + Poker.getPoker().get(index));
					//告诉第三个线程进行摸牌
					poker.setPlayer(3);
					poker.setIndex(index + 1);
				}
				try {
					Thread.sleep(10);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

第三个玩家:

import java.util.ArrayList;

public class Player3 implements Runnable{
	private ArrayList<String> data = new ArrayList<String>();

	private Poker poker;
	private String name;
	
	public Player3(Poker poker, String name) {
		this.poker = poker;
		this.name = name;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (poker) {
				if (poker.getIndex() > 50) {
					if (poker.getLandlord() == 3) {
						System.out.println(this.name + "是地主");
						data.add(Poker.getPoker().get(51));
						data.add(Poker.getPoker().get(52));
						data.add(Poker.getPoker().get(53));
					}
					System.out.println(this.name + ":" + this.data);
					break;
				}
				if (poker.getPlayer() == 3) {
					//获取到该摸第几张牌
					int index = poker.getIndex();
					//摸牌
					data.add(Poker.getPoker().get(index));
					System.out.println(name + "摸了一张" + Poker.getPoker().get(index));
					//告诉第一个线程进行摸牌
					poker.setPlayer(1);
					poker.setIndex(index + 1);
				}
				try {
					Thread.sleep(10);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

测试类:

public class Test {
	public static void main(String[] args) {
		Poker poker = new Poker();
		
		Poker.make(); //制作牌
		Poker.shuffle(); //洗牌
		
		Player1 p1 = new Player1(poker, "张三");
		Player2 p2 = new Player2(poker, "李四");
		Player3 p3 = new Player3(poker, "王五");
		
		Thread pp1 = new Thread(p1);
		Thread pp2 = new Thread(p2);
		Thread pp3 = new Thread(p3);
		
		pp1.start();
		pp2.start();
		pp3.start();
	}
}

控制台:

在这里插入图片描述

思路总结及解释:

  1. 制作一副牌存放到list集合中,然后通过Collections的shuffle()方法打乱扑克牌。
  2. 设置三个玩家然后有顺序的进行摸牌,摸牌的实现方法是通过索引遍历存放整副牌的集合,将对应索引的牌分别放到每个玩家的小集合里,这样就实现了摸牌步骤,那怎么能通过线程实现有顺序的摸呢,这里我首先在扑克类里设置一个玩家变量,然后在具体玩家里用一个判断,第一个玩家的话判断poker.getPlayer() == 1的话,然后将poker.setPlayer(2),玩家二三也一样,如此一来,线程就会按照顺序来执行。
  3. 随机一个地主,顺序发完牌之后还剩三张,将它发给地主。
  4. 最后将三名玩家添加到线程里,开启线程。
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的多线实现地主的代码示例: ```python import threading import time import random class Player: def __init__(self, name): self.name = name self.cards = [] class Card: def __init__(self, suit, rank): self.suit = suit self.rank = rank class Game: def __init__(self, players): self.players = players self.cards = [] self.landlord = None def shuffle_cards(self): # 生成一副 for suit in ["Spades", "Hearts", "Diamonds", "Clubs"]: for rank in range(1, 14): card = Card(suit, rank) self.cards.append(card) # 洗 random.shuffle(self.cards) def deal_cards(self): # for i in range(51): player = self.players[i % 3] card = self.cards.pop() player.cards.append(card) # 地主 self.landlord = self.players[random.randint(0, 2)] for i in range(3): card = self.cards.pop() self.landlord.cards.append(card) def start_game(self): # 输出每个玩家的 for player in self.players: print(player.name, player.cards) if __name__ == "__main__": player1 = Player("Player 1") player2 = Player("Player 2") player3 = Player("Player 3") players = [player1, player2, player3] game = Game(players) game.shuffle_cards() # 创建一个线程池 pool = [] for player in players: t = threading.Thread(target=game.deal_cards, args=()) pool.append(t) # 启动线程 for t in pool: t.start() # 等待线程结束 for t in pool: t.join() game.start_game() ``` 在这个示例代码中,我们使用了线程池的方式来实现线。首先创建一个线程池,然后将每个玩家的操作放入线程池中。在启动线程之前,需要先洗,然后等待所有线程结束之后,输出每个玩家的。需要注意的是,为了防止多个线程同时操作同一个数据,需要使用线程同步机制来保证数据的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值