java模拟UNO玩家对战

本文介绍了如何使用Java实现UNO牌游戏的模拟对战。通过静态变量定义和双向链表存储玩家信息,详细讲解了牌的编码规则、玩家出牌逻辑以及特殊情况的处理,如+2和反转牌的效果。文章还提到了在实现过程中应注意的游戏机制和链表节点关联等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


UNO牌简单介绍

UNO牌共有108张牌。包括76张数字牌,32张功能牌。
颜色:红、黄、蓝、绿、黑 5种。
每人先发牌7张,其余当作牌库。翻开牌库,作为第一张,每人轮流出牌。每个出牌的人,必需出与上一家出的牌,同样颜色或同样数字的牌。没有牌可出时需从牌库中拿一张到手上,如果还是不能出,则跳过,轮到下一个人。有功能牌及王牌,可以使其他的人增加手上的牌,也可帮自己快点将牌出光。最先把手中牌出光的人赢。

代码实现

若不是班里有同学中午玩UNO,这篇文章才不会写出来。
首先是静态变量的定义。

 static float second =0.0f;//对局时间,假设每次出牌为4秒
 static int playerNUM = 1;
 static int playerNUM2 = 1;
 static boolean isClockwise = true;//是顺时针
 static int k = 0;//记录最后一张有效数字牌!
 static int handCardsNum = 7;//手牌数
 static int playerNumber = 4;//玩家数量
 static int lib [] = new int[108];
 static int OrderLib [] = new int[108];
 static int free[] = new int [108];
 static ArrayStack Library = new ArrayStack(108);//牌堆 栈实现
 static ArrayStack lose = new ArrayStack(108);//弃牌区 栈实现

UNO牌就是几个玩家围成一圈,在桌子上进行的娱乐卡牌游戏,尽管没办法加入他们打牌的行列,加上月底还有考试,所以代码写的冗余就体谅一下还在读高中的萌新程序员吧。
双向链表用来存储玩家信息,节点保存玩家编号,姓名,上一个节点和下一个节点,顺便挂一个数组用来保存自己的手牌。

class BidirectionalLinkedManager{
   
 Node head = new Node(1,"玩家1");//头节点
 boolean k1 = true;
 Main m = new Main();
 public void add(Node nd) {
   //添加节点
  Node temp = head;
  while(true) {
   
   if(temp.next==(k1?null:head)) {
   //头结点的下一个节点
    temp.next = nd;
    nd.pre = temp;
    //头结点与此节点
    head.pre = nd;
    nd.next = head;
    k1 = false;
    break;
   }
   temp = temp.next;
  }
 }
 
 public void list() {
   //遍历节点
  Node temp = head.next;
  System.out.println("N:"+head);
  while(true) {
   
   if(temp==head) {
   
    return;
   }
   System.out.println("N:"+temp);
   temp = temp.next;
  }
 }
}
class Node{
   
 int Num;
 int index = 0;
 int handcard[] = new int [100];
 String name;
 Node next;
 Node pre;
 Node(int _Num,String _name){
   
  this.name = _name;
  this.Num = _Num;
 }
 @Override
 public String toString() {
   
  // TODO Auto-generated method stub
  return "<NODE--- Num--> "+Num+" Name--> "+name+"  >"+"上一个: "+pre.name+" 下一个: "+next.name;
 }
}

其中,反转牌的实现我是采用一个isClockwise变量保存顺时针逆时针,使用反转牌则顺时针变逆时针,逆时针变顺时针。
假设有1-5名玩家,编号分别为1-5,顺时针,5后为1,1前为5。则+2+4牌就需要以下方法。

public static void numTurn(int pN,boolean isclock) {
   
  if(isclock) {
   
   if(pN<playerNumber) {
   
    //System.out.println("playerNumber"+pN);
    playerNUM++;
   }else{
   
    playerNUM=1;
   }
  }else {
   
   if(pN>1) {
   
    playerNUM--;
   }else {
   
    playerNUM=playerNumber;
   }
  }
 }

玩家对战,NPC的逻辑部分,new一个节点,用节点管理器来寻找保存的节点。找到编号对应的Node,把它挂着的数组拿过来遍历。静态变量里面有个k变量,用来存放最后一张有效牌。遍历判断该牌是否与k代表的颜色相同,若颜色相同,则还要注意几张还带有颜色的功能牌。+2,禁止与反转。
如何让k代表所有牌呢?
我注意到了UNO牌有0-9,以及+2,禁止,反转,黑色王牌的万用和+4,有红黄蓝绿黑五种颜色。所以我的做法是给它们编号,0-9一样,+2为10,禁止11,反转12,则给颜色编号就是100,200,300这样。
黑色牌万用550,黑色牌+4 660.。
举例 红4 代表编号104,绿反转代表编号412
先展示一下其他的方法。


public boolean iSHave(Node nd,int preCard) 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值