Hi All,

For college assignment i was developing UNO game . here is my code

Java Code:
package game;
public class Card {
    public enum Color { YELLOW, BLUE, GREEN, RED; }

    public enum CardValue { ZERO,ONE,TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, 
                       NINE, PICK_TWO, REVERSE, SKIP, WILD, WILD_FOUR; }
    
    CardValue cardValue;
    Color color;
   

    public Card ( CardValue cardValue, Color color) {
        this.cardValue = cardValue;
        this.color = color;
       
    }
    
    public String toString(){
    	if(cardValue.equals(CardValue.WILD)||cardValue.equals(CardValue.WILD_FOUR)){
    		return cardValue.name();
    	}
    	else{
        return cardValue.name()+"-"+color.name();
    	}
    	}
    
    public boolean canPlay(Card otherCard) {
    	
		return this.cardValue == otherCard.cardValue || this.color == otherCard.color;
	}
    
  public boolean canPlayColor(Card otherCard) {
    	
		return this.color == otherCard.color;
	}
	
} 


package game;

import game.Card.CardValue;
import game.Card.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;



public class DeckMain {
	final private static int MAXCARDS  = 108;
	private static List<Card> deck= new ArrayList<Card>();
	private static List<Card>specialCard=new ArrayList<Card>();
	private static List<Card>normalCard=new ArrayList<Card>();
	  
    public List<Card> prepareDeck(){
    	
    	initCards();
    	shuffleCards();
		return deck;
    }
    
    
 public List<Card> prepareDeckSpecial(){
    	
    	initSpecialCards();
    	shuffleCards();
		return specialCard;
    }
 
 public List<Card> prepareDeckNormal(){
 	
 	initNormalCards();
 	shuffleCards();
		return normalCard;
 }
    
    public void initCards(){
    	for(Color color:Color.values()){
    	for(int j=0; j<2;j++){
    		for(CardValue cardValue:Card.CardValue.values()){
    			 if(j==1 && cardValue.equals(CardValue.ZERO)||j==1 && (cardValue.equals(CardValue.WILD)||cardValue.equals(CardValue.WILD_FOUR))){
    				continue;	 
    			 }
    			 else if (cardValue.equals(CardValue.WILD)||cardValue.equals(CardValue.WILD_FOUR)) {
    				 deck.add(new Card(cardValue, null));
				}
    			 else{
    				 deck.add(new Card(cardValue, color));
    			 }
    		
    		}
    	 }
    	}
    	
    }

    
    public void initSpecialCards(){
    	for(Color color:Color.values()){
    	for(int j=0; j<2;j++){
    		for(CardValue cardValue:Card.CardValue.values()){
    			 if(j==1 && (cardValue.equals(CardValue.WILD)||cardValue.equals(CardValue.WILD_FOUR))){
    				continue;	 
    			 }
    			 else if (cardValue.equals(CardValue.WILD)||cardValue.equals(CardValue.WILD_FOUR)) {
    				 specialCard.add(new Card(cardValue, null));
				}
    			 else if(cardValue.equals(CardValue.PICK_TWO)||cardValue.equals(CardValue.REVERSE)||cardValue.equals(CardValue.SKIP))
    				 specialCard.add(new Card(cardValue, color));
    			 }
    		
    		}
    	 }
    	}
    	
    public void initNormalCards(){
    	for(Color color:Color.values()){
    	for(int j=0; j<2;j++){
    		for(CardValue cardValue:Card.CardValue.values()){
    			 if(j==1 && cardValue.equals(CardValue.ZERO)){
     				continue;	 
     			 }
    			if (!(cardValue.equals(CardValue.WILD)||cardValue.equals(CardValue.WILD_FOUR)||cardValue.equals(CardValue.PICK_TWO)||cardValue.equals(CardValue.SKIP)||cardValue.equals(CardValue.REVERSE))) {
    				 normalCard.add(new Card(cardValue, color));
    			 }
    		}
    	}
    	}
    		
    		
    	 
    	}
    public boolean canPlay(List<Card> list1,Card card) {

	for (int i=0; i<list1.size(); i++)
		if (((Card)list1.get(i)).canPlay(card))
			return true;
			
	// If we get here, no card was found.
	return false;
}

public boolean canPlay(Card card,Card otherCard) {
	
	// Try to find a card in our collection that can be played on c.
	if(card.canPlay(otherCard))
			return true;
			
		
	return false;
			
}

public boolean canPlayColor(List<Card> list1,Color otherCardColor) {
	for(Card tempCard :list1){
		if(tempCard.color.equals(otherCardColor)){
			return true;
		}
	}
	return false;
}
    public void shuffleCards(){
    	Collections.shuffle(deck);
    	Collections.shuffle(specialCard);
    	Collections.shuffle(normalCard);
    }
   
}


package game;

import game.Card.Color;

import java.util.ArrayList;

import java.util.List;
import java.util.Scanner;



public class UNOGame {
	final private static int NUMCARDSHAND = 7;

	private DeckMain deckMain;
	private Boolean cardSpecialFlag;
	private List <Card>finalDeck;
	private List<Card> discardPile;
	private List<Card> hand1;
	private List<Card> hand2;
	private List<Card> specialCards;
	private List<Card> normalCards;
	private String player1name;
	private String player2name;
	private Color colorChosen;
	private int cardNumber;
	private boolean wildColorFlagFirst;
	private boolean wildColorFlagSecond;
	private boolean firstTimePlay;
	int turn=0;
	public UNOGame(){
		initVariables();
		for (int i=0; i<NUMCARDSHAND; i++) {
			hand1.add((Card)finalDeck.get(finalDeck.size()-1));
			finalDeck.remove(finalDeck.size()-1);
			hand2.add((Card)finalDeck.get(finalDeck.size()-1));
			finalDeck.remove(finalDeck.size()-1);
		}
	}
	
public void playGame() {
		
		Scanner stdin = new Scanner(System.in);
		System.out.print("player1 Enter your name:\n");
		player1name=stdin.nextLine();
		System.out.print("player2 Enter your name:\n");
		player2name=stdin.nextLine();
		turn=1;
		while (finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0) {
			  cardSpecialFlag=false;	
              playTurn(turn);
			if (turn == 1)
				turn = 2;
			else
				turn = 1;	
		}
		 printResult();
		}
		
	//}
public void printResult() {
	if (finalDeck.size() == 0)
		System.out.println("Sorry, the game has ended in a draw.");
	else if (hand1.size() == 0)
		System.out.println(player1name+" Congratulations, you win =)");
	else
		System.out.println(player2name+" Congratulations, you win =)");
}

// Plays one turn for the player number indicated.
public void playTurn(int player) {
	Scanner stdin = new Scanner(System.in);
	
	if(!wildColorFlagFirst){
		if(!firstTimePlay)
	System.out.println("The card at the top of the discard pile is "+discardPile.get(discardPile.size()-1));
	}
	else{
		System.out.println("Card you have to discard is of chosen color: "+colorChosen);
	}
	if(firstTimePlay){
		firstTimePlay=false;
		discardPile.add(normalCards.get(normalCards.size()-1));
		System.out.println("The card at the top of the discard pile is "+discardPile.get(discardPile.size()-1));
	}
			if (player == 1) {
				if(wildColorFlagFirst){
					if(deckMain.canPlayColor(hand1, colorChosen)){
						wildColorFlagFirst=false;
						System.out.println("\n"+ player1name+", here is your hand:\n"+hand1);
						System.out.println("Which card would you like to discard? Please give the associated number."); 
						try{
							cardNumber = stdin.nextInt();
						if(!(cardNumber>=0 && cardNumber<hand1.size()-1)){
							throw new Exception();
						}
						}
						catch (Exception e) {
							System.out.println("Number is not valid .it should be between 0 and "+hand1.size() +" \ngame is exiting now");
							System.exit(1);
						}
						       specialCardProcessing(cardNumber,hand1);
						       if(!cardSpecialFlag){
						     	discardPile.add(hand1.get(cardNumber));
					          	hand1.remove(cardNumber);
						       }
		                       
						    
			     	}
					else{
						System.out.println("Sorry that is not a valid card. You lost your opportunity to drop a card. A card has been drawn for you. "+finalDeck.get(finalDeck.size()-1));
			            finalDeck.remove(finalDeck.size()-1);
					    }
				       }
	          
				if (deckMain.canPlay(hand1,(Card)discardPile.get(discardPile.size()-1))) {
			            System.out.println("\n"+ player1name+", here is your hand:\n"+hand1);
		            	System.out.println("Which card would you like to discard? Please give the associated number.");
		            try	{	
		                	cardNumber = stdin.nextInt();
		                	if(!(cardNumber>=0 && cardNumber<hand1.size())){   throw new Exception();}
                         	}
			
			catch (Exception e) {
				System.out.println("Number is not valid .it should be between 0 and "+(hand1.size()-1) +" \ngame is exiting now");
				System.exit(1);
			}
			specialCardProcessing(cardNumber,hand1);
			
		
			if(!cardSpecialFlag){
			// Only play this card if it's really valid!
			if (deckMain.canPlay((Card)hand1.get(cardNumber),(Card)discardPile.get(discardPile.size()-1))){
				discardPile.add(hand1.get(cardNumber));
		       	hand1.remove(cardNumber);
			}
			else
				System.out.println("Sorry that is not a valid card. You lost your opportunity to drop a card.");
			
			// UNO =)
			if (hand1.size() == 1)
				System.out.println(player1name+" Player One says UNO!!!!");
		}
			
		}
		
		// Add a card and show the result.
		else {
			System.out.println("Sorry, you can't play on this card " +player1name+ " Your hand is --> "+ hand1);
			System.out.println("\n A card has been drawn for you. "+finalDeck.get(finalDeck.size()-1));
			hand1.add((Card)finalDeck.get(finalDeck.size()-1));
			finalDeck.remove(finalDeck.size()-1);
			System.out.println(player1name+", here is your resulting hand:\n"+hand1);
		}
	}
	else {
		if(wildColorFlagSecond){
			if(deckMain.canPlayColor(hand2, colorChosen)){
				wildColorFlagSecond=false;
				System.out.println("\n"+ player2name+", here is your hand:\n"+hand2);
				System.out.println("What card would you like to discard? Please give the associated number."); 
				try{
					cardNumber = stdin.nextInt();
				if(!(cardNumber>=0 && cardNumber<=hand1.size()-1)){
					throw new Exception();
				}
				}
				catch (Exception e) {
					System.out.println("Number is not valid .it should be between 0 and "+(hand1.size()-1) +" \ngame is exiting now");
					System.exit(1);
				}
				specialCardProcessing(cardNumber,hand2);
				       if(!cardSpecialFlag){
				     	discardPile.add(hand2.get(cardNumber));
			          	hand2.remove(cardNumber);
				         }
				   	
	     	}
			else{
				System.out.println("Sorry you dont have  a valid card. You lost your opportunity to drop a card. A card has been drawn for you. "+finalDeck.get(finalDeck.size()-1));
	            finalDeck.remove(finalDeck.size()-1);
			    }
		       }
		
	
		if (deckMain.canPlay(hand2,(Card)discardPile.get(discardPile.size()-1))) {
			System.out.println(player2name+", here is your hand:\n"+hand2);
			System.out.println("What card would you like to discard? Please give the associated number.");
			try{
				cardNumber = stdin.nextInt();
			if(!(cardNumber>0 && cardNumber<hand2.size())){
				throw new Exception();
			}
			}
			catch (Exception e) {
				System.out.println("Number is not valid .it should be between 0 and "+(hand2.size()-1) +" \ngame is exiting now");
				System.exit(1);
			}
			specialCardProcessing(cardNumber,hand2);
			if(!cardSpecialFlag){
			// Only play this card if it's really valid!
			if (deckMain.canPlay((Card)hand2.get(cardNumber),(Card)discardPile.get(discardPile.size()-1))){
				
		        discardPile.add(hand2.get(cardNumber));
		        hand2.remove(cardNumber);
			}
			else
				System.out.println("Sorry that is not a valid card. You lost your opportunity to drop a card.");
			
			// UNO =)
			if (hand2.size() == 1)
				System.out.println("Player Two says UNO!!!!");
		}
		}
		
		// Add a card and show the result.
		else {
			System.out.println("Sorry, you can't play on this card. A card has been drawn for you.");
			hand2.add((Card)finalDeck.get(finalDeck.size()-1));
			System.out.println(player1name+", here is your resutling hand:\n"+hand2);
		}
		
	}
}
public void initVariables(){
	wildColorFlagFirst=false;
	wildColorFlagSecond=false;
	player1name="";
	player2name="";
	cardSpecialFlag=false;
	firstTimePlay=true;
	deckMain=new DeckMain();
	finalDeck=deckMain.prepareDeck();
	hand1 = new ArrayList<Card>();
	hand2 = new ArrayList<Card>();
	discardPile=new ArrayList<Card>();
	specialCards=deckMain.prepareDeckSpecial();
	normalCards=deckMain.prepareDeckNormal();
}

public boolean checkCardSpecial(int value, List<Card> list){
	Card tmpCard=list.get(value);
	if(!(value>=0||value<=6)){
		System.out.println("Wrong input\n ");
		return false;
	}
	else if(specialCards.contains(tmpCard)){
		
	return true;	
	}
	return false;
}


public void specialCardProcessing(int value, List<Card> list){
	Card tmpCard=(Card)list.get(value);
		if(tmpCard.cardValue.equals(Card.CardValue.PICK_TWO)){
			if(turn==1){
			System.out.println("you have used PICK_TWO Card.\n. Two Cards have been drawn for "+player2name);
			
			hand2.add((Card)finalDeck.get(finalDeck.size()-1));
			hand2.add((Card)finalDeck.get(finalDeck.size()-1));
			
			
			}
			else{
				System.out.println("you have used PICK_TWO Card.\n. Two Cards have been drawn for "+player1name);
				hand1.add((Card)finalDeck.get(finalDeck.size()-1));
				hand1.add((Card)finalDeck.get(finalDeck.size()-1));
			}
			cardSpecialFlag=true;
			finalDeck.remove(finalDeck.size()-1);
			finalDeck.remove(finalDeck.size()-1);
			if(turn==1 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
			playTurn(turn);
			
			}
			else if(turn==2 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0))
				playTurn(turn)	;
			}
			
			
		
		
		if(tmpCard.cardValue.equals(Card.CardValue.SKIP)||tmpCard.cardValue.equals(Card.CardValue.REVERSE)){
			if(turn==1&&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
				cardSpecialFlag=true;
				discardPile.add(tmpCard);
				hand1.remove(tmpCard);
				playTurn(turn);
			}
				else if(turn==2 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
					cardSpecialFlag=true;
					discardPile.add(tmpCard);
					hand2.remove(tmpCard);
				
					playTurn(turn);
		}
				
			}
		if(tmpCard.cardValue.equals(Card.CardValue.WILD_FOUR)){
			cardSpecialFlag=true;
			if(turn==1 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
				System.out.println(player1name+ " has used WILD FOUR , 4 cards have been drawn for ."+player2name);
			
			for(int i=0;i<4;i++){
				hand2.add((Card)finalDeck.get(finalDeck.size()-1));
			    finalDeck.remove(finalDeck.size()-1);
			}
			playTurn(turn);
			}
		else if(turn==2 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
					System.out.println(player2name+" has used WILD FOUR , 4 cards have been drawn for "+player1name);
					
					for(int i=0;i<4;i++){
						hand1.add((Card)finalDeck.get(finalDeck.size()-1));
					    finalDeck.remove(finalDeck.size()-1);
					}
					playTurn(turn);
				}
		}
		if(tmpCard.cardValue.equals(Card.CardValue.WILD)){
			cardSpecialFlag=true;
			
				Scanner stdin= new Scanner(System.in);	
				System.out.println(" WILD card has been used by You. Choose Color from the following <0-3>\n");
				for(Color color:Color.values()){
					System.out.println(color.name());
					
				}
				
				int input=stdin.nextInt();
				if(input>=0 && input<=3){
					switch(input){
					case 0: System.out.println("you have selected Yellow color");
					         colorChosen=Color.YELLOW;
					         if(turn==1  &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
					        	 wildColorFlagSecond=true;
					        	 playTurn(2);
					         }
					         else{
					        	 wildColorFlagFirst=true;
					        	 playTurn(1);
					         }
					         break;
					case 1: System.out.println("you have selected Blue color");
					          colorChosen=Color.BLUE;
			                  if(turn==1 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
			                	  wildColorFlagSecond=true;
			                	  playTurn(2);
			                   }
			                else if(turn==2 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
			                	wildColorFlagFirst=true;
			                	playTurn(1);
			                      }
			                     break;
					case 2: System.out.println("you have selected Green color");
					          colorChosen=Color.GREEN;
			                  if(turn==1 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
			                	  wildColorFlagSecond=true;
			                	  playTurn(2);
			                break;
			                  }
			                 else{
			                	 wildColorFlagFirst=true;
			              	 playTurn(1);
			              	break;
			                   }
			                   
					case 3: System.out.println("you have selected Red color");
					        colorChosen=Color.RED;;
	                        if(turn==1 &&(finalDeck.size() > 0 && hand1.size() > 0 && hand2.size() > 0)){
	                        	wildColorFlagSecond=true;
	                        	playTurn(2);
	                        break;
	                         }
	                        else{
	                        	wildColorFlagFirst=true;
	              	        playTurn(1);
	                       	break;
					
					}
				}
					
				}
				
		}
	}
	public static void main(String[] args) {
	UNOGame myGame = new UNOGame();
	myGame.playGame();
}
}





As per my professor :

MVC architecuture should be followed and per me MainDeck and Card class falls under Model and UNOGame under controller ? please correct me.