Commit 5bcd2be5 authored by kiana's avatar kiana

first attempt

parents
Pipeline #4333 failed with stages
/**
* Card object
*
* @author Kiana Agha Kasiri
*/
public class Card {
/**
* color of the card
*/
private String cardColor;
/**
* value of the card
*/
private String cardValue;
/**
* type of the card
*/
private CardType cardType;
/**
* score of the card
*/
private int cardScore;
/**
* Constructor
* @param cardType type
*/
public Card(CardType cardType) { initialize(cardType); }
/**
* Constructor
* @param cardColor color
* @param cardValue value
*/
public Card(String cardColor, String cardValue) {
for (CardType type : CardType.values())
if (type.name().equals(cardColor + "_" + cardValue)) {
initialize(type);
break;
}
}
/**
* initializing the card type, color, value, ...
* @param cardType type
*/
private void initialize(CardType cardType) {
this.cardType = cardType;
String cardType_string = cardType.toString();
if (cardType == CardType.WILD || cardType == CardType.WILD_DRAW4) { // Wild cards
cardScore = 50;
cardColor = "WILD";
if (cardType == CardType.WILD)
cardValue = "WILD";
else
cardValue = "DRAW4";
} else if (cardType_string.contains("_SKIP") || cardType_string.contains("_REVERSE") || cardType_string.contains("_DRAW2")) { // Action cards
cardScore = 20;
cardColor = cardType_string.split("_")[0];
cardValue = cardType_string.split("_")[1];
} else { // Ordinary cards
cardScore = Integer.parseInt(cardType_string.split("_")[1]);
cardColor = cardType_string.split("_")[0];
cardValue = cardType_string.split("_")[1];
}
// Adjust the card color according to the available Console Color
adjustConsoleColor();
}
/**
* Get card type
* @return type
*/
public CardType getCardType() {
return cardType;
}
/**
* Get card score
* @return score
*/
public int getCardScore() {
return cardScore;
}
/**
* Get card color
* @return color
*/
public String getCardColor() {
return cardColor;
}
/**
* sets the card's color
* @param cardColor
*/
public void setCardColor(String cardColor) {
cardColor = cardColor;
}
/**
* Get card value
* @return value
*/
public String getCardValue() { return cardValue; }
/**
* set back color
*/
private void adjustConsoleColor() {
if (cardColor.equals("RED")) {
cardColor = ConsoleColors.RED_BACKGROUND_BRIGHT;
} else if (this.cardColor.equals("BLUE")) {
cardColor = ConsoleColors.BLUE_BACKGROUND_BRIGHT;
} else if (this.cardColor.equals("GREEN")) {
cardColor = ConsoleColors.GREEN_BACKGROUND_BRIGHT;
} else if (this.cardColor.equals("YELLOW")) {
cardColor = ConsoleColors.YELLOW_BACKGROUND_BRIGHT;
}
}
}
\ No newline at end of file
import java.util.ArrayList;
import java.util.Random;
public class CardList {
private ArrayList <Card> cards = new ArrayList<>();
/**
* constructor
* adding all cards to the list
*/
public CardList(){
for (int j=0; j<4; j++){
cards.add(new Card(CardType.WILD_DRAW4));
}
for (int i=0; i<4; i++){
cards.add(new Card(CardType.WILD));
}
for(int k=0; k<2; k++){
cards.add(new Card(CardType.RED_REVERSE));
cards.add(new Card(CardType.BLUE_REVERSE));
cards.add(new Card(CardType.GREEN_REVERSE));
cards.add(new Card(CardType.YELLOW_REVERSE));
}
for(int k=0; k<2; k++){
cards.add(new Card(CardType.BLUE_SKIP));
cards.add(new Card(CardType.GREEN_SKIP));
cards.add(new Card(CardType.RED_SKIP));
cards.add(new Card(CardType.YELLOW_SKIP));
}
for(int k=0; k<2; k++){
cards.add(new Card(CardType.RED_DRAW2));
cards.add(new Card(CardType.BLUE_DRAW2));
cards.add(new Card(CardType.GREEN_DRAW2));
cards.add(new Card(CardType.YELLOW_DRAW2));
}
for (int z=0; z<2; z++){
cards.add(new Card(CardType.BLUE_1));
cards.add(new Card(CardType.BLUE_2));
cards.add(new Card(CardType.BLUE_3));
cards.add(new Card(CardType.BLUE_4));
cards.add(new Card(CardType.BLUE_5));
cards.add(new Card(CardType.BLUE_6));
cards.add(new Card(CardType.BLUE_7));
cards.add(new Card(CardType.BLUE_8));
cards.add(new Card(CardType.BLUE_9));
cards.add(new Card(CardType.GREEN_1));
cards.add(new Card(CardType.GREEN_2));
cards.add(new Card(CardType.GREEN_3));
cards.add(new Card(CardType.GREEN_4));
cards.add(new Card(CardType.GREEN_5));
cards.add(new Card(CardType.GREEN_6));
cards.add(new Card(CardType.GREEN_7));
cards.add(new Card(CardType.GREEN_8));
cards.add(new Card(CardType.GREEN_9));
cards.add(new Card(CardType.YELLOW_1));
cards.add(new Card(CardType.YELLOW_2));
cards.add(new Card(CardType.YELLOW_3));
cards.add(new Card(CardType.YELLOW_4));
cards.add(new Card(CardType.YELLOW_5));
cards.add(new Card(CardType.YELLOW_6));
cards.add(new Card(CardType.YELLOW_7));
cards.add(new Card(CardType.YELLOW_8));
cards.add(new Card(CardType.YELLOW_9));
cards.add(new Card(CardType.RED_1));
cards.add(new Card(CardType.RED_2));
cards.add(new Card(CardType.RED_3));
cards.add(new Card(CardType.RED_4));
cards.add(new Card(CardType.RED_5));
cards.add(new Card(CardType.RED_6));
cards.add(new Card(CardType.RED_7));
cards.add(new Card(CardType.RED_8));
cards.add(new Card(CardType.RED_9));
}
cards.add(new Card(CardType.GREEN_0));
cards.add(new Card(CardType.BLUE_0));
cards.add(new Card(CardType.RED_0));
cards.add(new Card(CardType.YELLOW_0));
}
/**
* sets the cards
* @param cards
*/
public void setCards(ArrayList<Card> cards) {
this.cards = cards;
}
/**
* gets the cards
* @return
*/
public ArrayList<Card> getCards() {
return cards;
}
/**
* adds card to the list
* @param card
*/
public void addCard(Card card){
cards.add(card);
}
/**
* gets a card from list
* remove the card that has been drawn
* @return
*/
public Card drawCard(){
int color = new Random().nextInt(cards.size());
Card card = cards.get(color);
cards.remove(card);
return card;
}
}
/**
* card types of the game
*
* @author Kiana Agha Kasiri
*/
public enum CardType {
WILD, WILD_DRAW4, YELLOW_0, YELLOW_1, YELLOW_2, YELLOW_3, YELLOW_4, YELLOW_5, YELLOW_6, YELLOW_7, YELLOW_8, YELLOW_9, RED_0, RED_1, RED_2, RED_3, RED_4, RED_5, RED_6, RED_7, RED_8, RED_9,
GREEN_0, GREEN_1, GREEN_2, GREEN_3, GREEN_4, GREEN_5, GREEN_6, GREEN_7, GREEN_8, GREEN_9, BLUE_0, BLUE_1, BLUE_2, BLUE_3, BLUE_4, BLUE_5, BLUE_6, BLUE_7, BLUE_8, BLUE_9,
YELLOW_SKIP, GREEN_SKIP, BLUE_SKIP, RED_SKIP, YELLOW_DRAW2, GREEN_DRAW2, BLUE_DRAW2, RED_DRAW2, YELLOW_REVERSE, GREEN_REVERSE, BLUE_REVERSE, RED_REVERSE,
}
/**
* ConsoleColors unicode
*/
public class ConsoleColors {
public static final String RESET = "\033[0m"; // Text Reset
public static final String WHITE_BOLD_BRIGHT = "\033[1;97m"; // WHITE
public static final String BLACK_BACKGROUND_BRIGHT = "\033[0;100m";// BLACK
public static final String RED_BACKGROUND_BRIGHT = "\033[0;101m";// RED
public static final String GREEN_BACKGROUND_BRIGHT = "\033[0;102m";// GREEN
public static final String YELLOW_BACKGROUND_BRIGHT = "\033[0;103m";// YELLOW
public static final String BLUE_BACKGROUND_BRIGHT = "\033[0;104m";// BLUE
}
\ No newline at end of file
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Game {
Scanner scanner = new Scanner(System.in);
CardList cardList = new CardList();
ArrayList<Player> players = new ArrayList<>();
int cartToDraw = 2;
Random random = new Random();
Show show = new Show();
int turn;
int rotation;
String color;
public Game() {
color = "";
System.out.print("How many human players? ");
int number = scanner.nextInt();
for (int i = 0; i < number; i++) {
System.out.print("Player name: ");
String name = scanner.next();
Player player = new Player(name, false);
players.add(player);
/**
*add 7 cards to each player
*/
for (int j = 0; j < 7; j++) {
int color = random.nextInt(cardList.getCards().size());
Card card = cardList.drawCard();
player.addCard(card);
}
}
System.out.print("How many Bot players? ");
int numbers = scanner.nextInt();
for (int i = 0; i < numbers; i++) {
System.out.print("Player name: ");
String name = scanner.next();
Player player = new Player(name, true);
players.add(player);
/**
*add 7 cards to each player
*/
for (int j = 0; j < 7; j++) {
int color = random.nextInt(cardList.getCards().size());
Card card = cardList.drawCard();
player.addCard(card);
}
}
while (true) {
int color = new Random().nextInt(cardList.getCards().size());
Card startCart = cardList.getCards().get(color);
if (!(startCart.getCardType().name().contains("SKIP") && startCart.getCardType().name().contains("REVERSE") && startCart.getCardType().name().contains("WILD") && startCart.getCardType().name().contains("WILD_DRAW") && startCart.getCardType().name().contains("DRAW2")))
break;
}
// initialize
turn = new Random().nextInt(players.size());
rotation = (new Random().nextInt(2) == 0) ? 1 : -1;
}
public void rotate(int turn, int rotation) {
turn += rotation;
if (turn < 0)
turn = players.size() - 1;
else if (turn >= players.size())
turn = 0;
}
public void play(Card table) {
while (!isGameOver(players)) {
show.show(players, table, turn, rotation);
color = "";
cardList.addCard(table);
switch (table.getCardValue()) {
case "SKIP":
goTurn();
System.out.println("Player '" + players.get(reverseTurn()).getName() + "' is skipped");
show.show(players, table, turn, rotation );
break;
case "REVERSE":
rotation *= -1;
if (players.size() == 2)
goTurn();
else {
goTurn();
goTurn();
}
show.show(players, table, turn, rotation );
System.out.println("rotation is reversed");
break;
case "DRAW2":
System.out.print("Player '" + players.get(turn).getName() + "' is given two cards and is skipped: ");
for (int i = 0; i < 2; i++) {
Card temp = cardList.drawCard();
players.get(turn).addCard(temp);
System.out.print(temp.getCardColor() + " " + temp.getCardValue() + " " + ConsoleColors.RESET + " ");
}
System.out.println();
goTurn();
show.show(players, table, turn, rotation );
break;
}
if (table.getCardType() == CardType.WILD || table.getCardType() == CardType.WILD_DRAW4) {
if(players.get(turn).getIsAI()) {
switch (random.nextInt(4)) {
case 0:
System.out.println("Changed color to: Yellow");
color = ConsoleColors.YELLOW_BACKGROUND_BRIGHT;
break;
case 1:
System.out.println("Changed color to: Red");
color = ConsoleColors.RED_BACKGROUND_BRIGHT;
break;
case 2:
System.out.println("Changed color to: Green");
color = ConsoleColors.GREEN_BACKGROUND_BRIGHT;
break;
case 3:
System.out.println("Changed color to: Blue");
color = ConsoleColors.BLUE_BACKGROUND_BRIGHT;
break;
}
}else{
System.out.println("choose color");
do {
color = scanner.next();
}while (!color.equals("BLUE") && !color.equals("RED") && !color.equals("GREEN") && !color.equals("YELLOW"));
if(color.equals("BLUE"))
color = ConsoleColors.BLUE_BACKGROUND_BRIGHT;
if(color.equals("RED"))
color = ConsoleColors.RED_BACKGROUND_BRIGHT;
if(color.equals("GREEN"))
color = ConsoleColors.GREEN_BACKGROUND_BRIGHT;
if(color.equals("YELLOW"))
color = ConsoleColors.YELLOW_BACKGROUND_BRIGHT;
}
if (table.getCardType() == CardType.WILD_DRAW4) {
System.out.print("Player '" + players.get(turn).getName() + "' is given four cards and is skipped: ");
for (int i = 0; i < 4; i++) {
Card temp = cardList.drawCard();
players.get(turn).addCard(temp);
System.out.print(temp.getCardColor() + " " + temp.getCardValue() + " " + ConsoleColors.RESET + " ");
}
System.out.println();
goTurn();
}
}
if (canDraw(players.get(turn), table, color)) { // Player has a card to draw
if (players.get(turn).getIsAI()) // It is a bot!
table = players.get(turn).play(table, color);
else { // It is a HUMAN!!!
String user_card = null;
while (!players.get(turn).contains(user_card) || !players.get(turn).canDraw(table, players.get(turn).getEquavalentCard(user_card), color)) {
System.out.print("Hey user! enter a card: ");
user_card = scanner.nextLine();
System.out.println(players.get(turn).contains(user_card));
//System.out.println(players.get(turn).canDraw(table, players.get(turn).getEquavalentCard(user_card)));
}
table = players.get(turn).getEquavalentCard(user_card);
players.get(turn).removeCard(players.get(turn).getEquavalentCard(user_card));
}
} else { // We are out of options
players.get(turn).addCard(cardList.drawCard());
Card givenCard = players.get(turn).getCards().get(players.get(turn).getCards().size() - 1);
System.out.println("Player '" + players.get(turn).getName() + "' is given a card: " + givenCard.getCardColor() + " " + givenCard.getCardValue() + " " + ConsoleColors.RESET);
// Can the player draw the given card??!
if (canDraw(players.get(turn), table, color)) {
if (players.get(turn).getIsAI()) // It is a bot!
table = players.get(turn).play(table, color);
else { // It is a HUMAN!!!
String user_card = null;
while (!players.get(turn).contains(user_card) || !players.get(turn).canDraw(table, players.get(turn).getEquavalentCard(user_card), color)) {
System.out.print("Hey user! enter a card: ");
user_card = scanner.nextLine();
}
table = players.get(turn).getEquavalentCard(user_card);
players.get(turn).removeCard(players.get(turn).getEquavalentCard(user_card));
}
} else
System.out.println("Player '" + players.get(turn).getName() + "' is skipped, no moves");
}
// show.show(players, table, turn, rotation);
goTurn(); // Increase turn
for(Player player: players) {
if (player.getCards().size() == 0)
player.setScore(0);
else{
for(Card card: player.getCards()){
player.setScore(player.getScore() + card.getCardScore());
}
}
}
}
for (Player player: players) {
System.out.print("Player '" + player.getName() + "' score: " + player.getScore());
if (player.getCards().size() == 0)
System.out.print("\tWINNER!");
System.out.println();
}
}
/**
* changes the turn by rotation
*/
private void goTurn() {
turn += rotation;
if (turn >= players.size())
turn = 0;
if (turn < 0)
turn = players.size() - 1;
}
/**
* changes the rotation
* @return the new turns
*/
private int reverseTurn() {
int backTurn = turn - rotation;
if (backTurn >= players.size())
backTurn = 0;
if (backTurn < 0)
backTurn = players.size() - 1;
return backTurn;
}
/**
* checking if the player has a card to draw
* @param player
* @param table
* @param color
* @return true or false
*/
private boolean canDraw(Player player, Card table, String color) {
ArrayList<Card> playerCards = player.getCards();
ArrayList<String> breakDown = new ArrayList<>(); // Contains values and colors
for (Card card : playerCards) {
if (card.getCardType() != CardType.WILD && card.getCardType() != CardType.WILD_DRAW4) { // Not WILD & WILD_DRAW4
breakDown.add(card.getCardValue()); // Add card's value
breakDown.add(card.getCardColor()); // Add cards's color
}
}
// If card on the table is either WILD or DRAW4
if (!color.equals("") && breakDown.contains(color))
return true;
else if (!color.equals("") && !breakDown.contains(color))
return false;
if (breakDown.contains(table.getCardValue()) || (breakDown.contains(table.getCardColor())))
return true; // We have an ordinary card with the same value or color
// What about WILD?
for (Card card : playerCards)
if (card.getCardType() == CardType.WILD)
return true;
// WILD_DRAW4????
for (Card card : playerCards)
if (card.getCardType() == CardType.WILD_DRAW4)
return true;
return false; // We have nothing to draw ):
}
/**
* checking if anyone has won
* @param players
* @return
*/
public static boolean isGameOver(ArrayList<Player> players) {
for (Player player : players)
if (player.getCards().size() == 0)
return true;
return false;
}
}
import java.util.ArrayList;
import java.util.Random;
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("for human players please enter like cardType");
Game uno = new Game();
Show show = new Show();
//first card
Card table = null;
do {
int color = new Random().nextInt(uno.cardList.getCards().size());
table = uno.cardList.getCards().get(color);
} while (table.getCardType().name().contains("SKIP") || table.getCardType().name().contains("REVERSE") || table.getCardType().name().contains("WILD") || table.getCardType().name().contains("WILD_DRAW") || table.getCardType().name().contains("DRAW2"));
uno.play(table);
}
/**
* checking if the game is over
* if someone finishes his/her cards the game is over
* @param players
* @return true or false
*/
public static boolean isGameOver(ArrayList<Player> players) {
for (Player player : players)
if (player.getCards().size() == 0)
return true;
return false;
}
}
import java.util.ArrayList;
public class Player {
private ArrayList<Card> cards;
private String name;
private int score;
private Card lastCard;
private boolean isAI;
public Player(String name, boolean isAI) {
this.name = name;
this.score = 0;
this.lastCard = null;
cards = new ArrayList<>();
this.isAI = isAI;
}
/**
* gets the last card
* @return
*/
public Card getLastCard() {
return lastCard;
}
/**
* sets the last card
* @param lastCard
*/
public void setLastCard(Card lastCard) {
this.lastCard = lastCard;
}
/**
* gets the player's name
* @return name
*/
public String getName() {
return name;
}
/**
* gets the player's score
* @return score
*/
public int getScore() {
return score;
}
/**
* sets score
* @param score
*/
public void setScore(int score) {
this.score = score;
}
/**
* sets name
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* gets the cards
* @return cards
*/
public ArrayList<Card> getCards() {
return cards;
}
/**
* sets the cards
* @param cards
*/
public void setCards(ArrayList<Card> cards) {
this.cards = cards;
}
/**
* adds a card to the list of player's cards
* @param card
*/
public void addCard(Card card) {
cards.add(card);
}
/**
* removes a card from the list of player's cards
* @param card
*/
public void removeCard(Card card) {
cards.remove(card);
}
/**
* changes the last card
* removes the card from the list of player's cards
* @param card
*/
public void lastCardOut(Card card) {
lastCard = card;
cards.remove(card);
}
public Card play(Card table, String color) {
for (Card card : cards) {
if (color.equals("")) {
if (card.getCardColor().equals(table.getCardColor()))
return decide(card);
if (card.getCardValue().equals(table.getCardValue()))
return decide(card);
} else {
if (card.getCardColor().equals(color))
return decide(card);
}
}
for (Card card : cards)
if (card.getCardType() == CardType.WILD)
return decide(card);
for (Card card : cards)
if (card.getCardType() == CardType.WILD_DRAW4)
return decide(card);
return null;
}
/**
* removing the card
* @param cardToRemove
* @return
*/
public Card decide(Card cardToRemove) {
//changing the last card
lastCardOut(cardToRemove);
// Remove from set
removeCard(cardToRemove);
// Now return the card
return cardToRemove;
}
/**
* if the player is human or computer
* @return
*/
public boolean getIsAI() {
return isAI;
}
/**
* @param userCard
* @return
*/
public boolean contains(String userCard) {
for (Card card : cards)
if (card.getCardType().name().equals(userCard))
return true;
return false;
}
/**
* checks if the cards are the same
* @param userCard
* @return
*/
public Card getEquavalentCard(String userCard) {
for (Card card: cards)
if (card.getCardType().name().equals(userCard))
return card;
return null;
}
/**
* checking if player has a card to draw
* @param table
* @param userCard
* @return true or false
*/
public boolean canDraw(Card table, Card userCard, String color) {
if (userCard.getCardValue().equals(table.getCardValue()) || userCard.getCardColor().equals(table.getCardColor()) || userCard.getCardType() == CardType.WILD)
return true;
else {
boolean isOk = false;
for (Card card: cards) {
if (table.getCardValue().equals(card.getCardValue()) || table.getCardColor().equals(card.getCardColor())) {
isOk = true;
break;
}
}
if (!isOk && userCard.getCardType() == CardType.WILD_DRAW4)
return true;
}
if (userCard.getCardColor().equals(color) || userCard.getCardType() == CardType.WILD)
return true;
else {
boolean isOk = false;
for (Card card: cards) {
if (color.equals(card.getCardColor())) {
isOk = true;
break;
}
}
if (!isOk && userCard.getCardType() == CardType.WILD_DRAW4)
return true;
}
return false;
}
}
\ No newline at end of file
import java.util.ArrayList;
public class PlayerHuman extends Player {
public PlayerHuman(String name, boolean isAI) {
super(name, isAI);
}
@Override
public Card getLastCard() {
return super.getLastCard();
}
@Override
public String getName() {
return super.getName();
}
@Override
public void setScore(int score) {
super.setScore(score);
}
@Override
public ArrayList<Card> getCards() {
return super.getCards();
}
@Override
public void addCard(Card card) {
super.addCard(card);
}
@Override
public void removeCard(Card card) {
super.removeCard(card);
}
@Override
public void setLastCard(Card lastCard) {
super.setLastCard(lastCard);
}
@Override
public int getScore() {
return super.getScore();
}
@Override
public void setName(String name) {
super.setName(name);
}
@Override
public void setCards(ArrayList<Card> cards) {
super.setCards(cards);
}
@Override
public void lastCardOut(Card card) {
super.lastCardOut(card);
}
@Override
public Card play(Card table, String color) {
return super.play(table, color);
}
@Override
public Card decide(Card cardToRemove) {
return super.decide(cardToRemove);
}
}
import java.util.ArrayList;
public class Show {
public void cardsType(Card card){
switch (card.getCardColor()) {
case ConsoleColors.BLUE_BACKGROUND_BRIGHT:
System.out.print(ConsoleColors.BLUE_BACKGROUND_BRIGHT + " " + ConsoleColors.WHITE_BOLD_BRIGHT + card.getCardValue() + " " + ConsoleColors.RESET + " ");
break;
case ConsoleColors.RED_BACKGROUND_BRIGHT:
System.out.print(ConsoleColors.RED_BACKGROUND_BRIGHT + " " + ConsoleColors.WHITE_BOLD_BRIGHT + " " + card.getCardValue() + " " + ConsoleColors.RESET + " ");
break;
case ConsoleColors.YELLOW_BACKGROUND_BRIGHT:
System.out.print(ConsoleColors.YELLOW_BACKGROUND_BRIGHT + " " + ConsoleColors.WHITE_BOLD_BRIGHT + " " + card.getCardValue() + " " + ConsoleColors.RESET + " ");
break;
case ConsoleColors.GREEN_BACKGROUND_BRIGHT:
System.out.print(ConsoleColors.GREEN_BACKGROUND_BRIGHT + " " + ConsoleColors.WHITE_BOLD_BRIGHT + " " + card.getCardValue() + " " + ConsoleColors.RESET + " ");
break;
default:
System.out.print(" " + card.getCardValue() + " ");
break;
}
}
public void show(ArrayList<Player> players, Card table, int turn, int rotation){
if(rotation == +1)
System.out.println("rotation: right");
else if(rotation == -1)
System.out.println("rotation: left");
System.out.println("It is " + players.get(turn).getName() + "'s turn");
System.out.print("THE CARD ON THE TABLE: ");
cardsType(table);
System.out.println();
for (Player player: players){
System.out.println(player.getName() + "'s score: " + player.getScore());
System.out.print(player.getName() + "'s cards: ");
for (Card card: player.getCards()){
cardsType(card);
}
System.out.println();
}
System.out.println("\n");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment