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)