using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Deck : MonoBehaviour
{
  [Header("Set in Inspector")]
  public bool startFaceUp = false;
  // Масти
  public Sprite suitClub; // Трефы
  public Sprite suitDiamond; // Бубны
  public Sprite suitHeart; // Черви
  public Sprite suitSpade; // Пики
  
  public Sprite[] faceSprites;
  public Sprite[] rankSprites;
  
  public Sprite cardBack;
  public Sprite cardBackGold;
  public Sprite cardFront;
  public Sprite cardFrontGold;
  // Шаблоны
  public GameObject prefabCard;
  public GameObject prefabSprite;
  
  [Header("Set Dynamically")]
  public PT_XMLReader xmlr;
  public List<string> cardNames;
  public List<Card> cards;
  public List<Decorator> decorators;
  public List<CardDefinition> cardDefs;
  public Transform deckAnchor;
  public Dictionary<string,Sprite> dictSuits;
  
  // InitDeck вызывается экземпляром Prospector, когда будет готов
  public void InitDeck(string deckXMLText)
  {
    // Создать точку привязки для всех игровых объектов Card в иерархии
    if (GameObject.Find("_Deck") == null)
    {
      GameObject anchorGO = new GameObject("_Deck");
      deckAnchor = anchorGO.transform;
    }
    
    // Инициализировать словарь со спрайтами значков мастей
    dictSuits = new Dictionary<string, Sprite>()
    {
      { "C", suitClub     },
      { "D", suitDiamond  },
      { "H", suitHeart    },
      { "S", suitSpade    }
    };
    ReadDeck(deckXMLText);
    MakeCards();
  }
  
  /* метод ReadDeck() читает содержимое XML-файла и преобразует
  в списки экземпляров Decorator (масть и достоинство в углах карты)
  и экземпляров CardDefinition (с информацией о достоинстве каждой карты (от туза до короля)*/
  
  // ReadDeck читает указанный XML-файл и создает массив экземпляров CardDefinition
  public void ReadDeck(string deckXMLText)
  {
    xmlr = new PT_XMLReader(); // создать новый экземпляр PT_XMLReader
    xmlr.Parse(deckXMLText); // использвать его для чтения DeckXML
    
    // Вывод проверочной строки
    string s = "xml[0] decorator[0]";
    s += "type="+xmlr.xml   ["xml"][0]["decorator"][0].att("type");
    s += "x="+xmlr.xml      ["xml"][0]["decorator"][0].att("x");
    s += "y="+xmlr.xml      ["xml"][0]["decorator"][0].att("y");
    s += "scale="+xmlr.xml  ["xml"][0]["decorator"][0].att("scale");
    //print(s);
    
    // Прочитать элементы <decorator> для всех карт
    decorators = new List<Decorator>();
    // Извлечь список PT_XMLHashListвсех элементов ,decorator> из XML-файла
    PT_XMLHashList xDecos = xmlr.xml["xml"][0]["decorator"];
    Decorator deco;
    for (int i=0; i<xDecos.Count; i++)
    {
      // Для каждого элемента <decorator> в XML
      deco = new Decorator(); // Создать экземпляр Decorator
      // Скопировать атрибуты из <decorator> в Decorator
      deco.type = xDecos[i].att("type");
      // deco.flip получит значение true, если атрибут flip содержит текст "1" 
      deco.flip = ( xDecos[i].att ("flip") == "1" );
      // Получить значение float из строковых атрибутов
      deco.scale = float.Parse( xDecos[i].att ("scale") );
      // Vector3 loc инициализируется как [0, 0, 0], изменяем его
      deco.loc.x = float.Parse( xDecos[i].att ("x") );
      deco.loc.y = float.Parse( xDecos[i].att ("y") );
      deco.loc.z = float.Parse( xDecos[i].att ("z") );
      // Добавить deco  в список decorators
      decorators.Add (deco);
    }
    
    // Прочитать координаты для значков, определяющих достоинство карты
    cardDefs =  new List<CardDefinition>(); // Инициализировать список карт
    // Извлечь список PT_XMLHashList всех элементов <card> из XML файла
    PT_XMLHashList xCardDefs = xmlr.xml["xml"][0]["card"];
    for (int i=0; i<xCardDefs.Count; i++)
    {
      // Для каждого элемента <card> Создать экземпляр CardDefinition
      CardDefinition cDef = new CardDefinition();
      // Получить значения атрибута и добавить их в cDef
      cDef.rank = int.Parse( xCardDefs[i].att ("rank") );
      // Извлечь список PT_XMLHashList из всех элементов <pip> внутри второго элемента  <card>
      PT_XMLHashList xPips = xCardDefs[i]["pip"];
      if (xPips != null)
      {
        for (int j=0; j<xPips.Count; j++)
        {
          deco = new Decorator();
          // Элементы <pip> в <card> обрабатываются классом Decorator
          deco.type = "pip";
          deco.flip = ( xPips[j].att ("flip") == "1" );
          deco.loc.x = float.Parse( xPips[j].att ("x") );
          deco.loc.y = float.Parse( xPips[j].att ("y") );
          deco.loc.z = float.Parse( xPips[j].att ("z") );
          if ( xPips[j].HasAtt("scale") )
          {
            deco.scale = float.Parse( xPips[j].att ("scale") );
          }
          cDef.pips.Add(deco);
        }
      }
      // считать масть
      if (xCardDefs[i].HasAtt("face"))
      {
        cDef.face = xCardDefs[i].att ("face");
      }
      cardDefs.Add(cDef);
    }
  }
  
  // Получает  CardDefinition на основе значения достоинства
  public  CardDefinition GetCardDefinitionByRank(int rnk)
  {
    // Поиск во всех опредлениях CardDefinition
    foreach (CardDefinition cd in cardDefs)
    {
      // Если достоинство совпадает, вернуть определение
      if (cd.rank == rnk)
      {
        return (cd);
      }
    }
    return( null );
  }
  
  // Создает игровые объекты карт
  public void MakeCards()
  {
    //  cardNames будет содержать имена сконструированных карт
    // Каждая масть имеет 14 значений достоинства
    cardNames = new List<string>();
    string[] letters = new string[] {"C","D","H","S"};
    foreach (string s in letters)
    {
      for (int i=0; i<13; i++)
      {
        cardNames.Add(s+(i+1));
      }
    }
    
    // Создать список со всеми картами
    cards = new List<Card>();
    
    // Обойти все только что созданные имена карт
    for (int i=0; i<cardNames.Count; i++)
    {
      cards.Add ( MakeCard(i) ); // Создать карту и добавить ее в колоду
    }
  }
  
  private Card MakeCard(int cNum)
  {
    // Создать игровой объект с картой
    GameObject cgo = Instantiate(prefabCard) as GameObject;
    // Настроить transform.parent новой карты в соответствии с точкой привязки
    cgo.transform.parent = deckAnchor;
    Card card = cgo.GetComponent<Card>(); // получить компонент Card
    
    // Выкладываем в аккуратный ряд
    cgo.transform.localPosition = new Vector3( (cNum%13)*3, cNum/13*4, 0 );
    
    // Настроить основные параметры карты
    card.name = cardNames[cNum];
    card.suit = card.name[0].ToString();
    card.rank = int.Parse( card.name.Substring(1) );
    if (card.suit == "D" || card.suit == "H") // при необходимости красим в карсный
    {
      card.colS = "Red";
      card.color = Color.red;
    }
    // Получить CardDefinition для этой карты
    card.def = GetCardDefinitionByRank(card.rank);
    
    AddDecorators(card);
    AddPips(card);
    AddFace(card);
    AddBack(card);
    
    return card;
  }
  
  // Эти скрытые переменные используются вспомогательными методами
  private Sprite _tSp = null;
  private GameObject _tGO = null;
  private SpriteRenderer _tSR = null;
  
  private void AddDecorators(Card card)
  {
    // Добавить оформление
    foreach( Decorator deco in decorators )
    {
      if (deco.type == "suit")
      {
        tGO = Instantiate( prefabSprite ) as GameObject; // Создать эземпляр игрового объекта спрайта
        tSR = _tGO.GetComponent<SpriteRenderer>(); // Получить ссылку на компонент SpriteRenderer
        tSR.sprite = dictSuits[card.suit]; // Установить спрайт масти
      } else {
        tGO = Instantiate( prefabSprite ) as GameObject;
        tSR = _tGO.GetComponent<SpriteRenderer>();
        tSp = rankSprites[ card.rank ]; // Получить спрайт для отображения достоинства
        tSR.sprite = _tSp; // Установить спрайт достоинства в SpriteRenderer
        tSR.color = card.color; // Установить цвет соответствующей масти
      }
      tSR.sortingOrder = 1; // Поместить спрайты над картой
      tGO.transform.SetParent( card.transform ); // Сделать спрайт дочерним по отношению к карте
      tGO.transform.localPosition = deco.loc; // Location как в DeckXML
      if (deco.flip) // Перевернуть значок
      {
        tGO.transform.rotation = Quaternion.Euler(0,0,180);
      }
      if (deco.scale != 1) // Установить масштаб, чтобы уменьшить размер спрайта
      {
        tGO.transform.localScale = Vector3.one * deco.scale;
      }
      tGO.name = deco.type; // Дать имя
      card.decoGOs.Add(_tGO); // Добавить этот игровой объект в список card.decoGOs
    }
  }
  
  private void AddPips(Card card)
  {
    foreach( Decorator pip in card.def.pips ) // Для каждого значка в определении
    {
      _tGO = Instantiate( prefabSprite ) as GameObject; // Создать игровой объект спрайта
      _tGO.transform.SetParent( card.transform ); // Назначить родителем игровой объект карты
      _tGO.transform.localPosition = pip.loc; // Установить localPosition как в XML файле
      if (pip.flip) // Перевернуть если необходимо
      {
        _tGO.transform.rotation = Quaternion.Euler(0,0,180);
      }
      if (pip.scale != 1) // Масштабировать (только для туза)
      {
        _tGO.transform.localScale = Vector3.one * pip.scale;
      }
      _tGO.name = "pip"; // Дать имя игровому объекту
      _tSR = _tGO.GetComponent<SpriteRenderer>(); // Получить ссылку на компонент SpriteRenderer
      _tSR.sprite = dictSuits[card.suit]; // Установить спрайт масти
      _tSR.sortingOrder = 1; // Установить sortingOrder, чтобы значок отображался над Card_Front
      card.pipGOs.Add(_tGO); // Добавить этот игровой объект в список значков
    }
  }
  
  private void AddFace(Card card)
  {
    if (card.def.face == "") // Выйти, если это не карта с картинкой
    {
      return;
    }
    _tGO = Instantiate( prefabSprite ) as GameObject;
    _tSR = _tGO.GetComponent<SpriteRenderer>();
    _tSp = GetFace( card.def.face+card.suit ); // Сгенерировать имя и передать его в GetFace()
    _tSR.sprite = _tSp; // Установить этот спрайт в _tSR
    _tSR.sortingOrder = 1; // Установить sortingOrder
    _tGO.transform.SetParent( card.transform );
    _tGO.transform.localPosition = Vector3.zero;
    _tGO.name = "face";
  }
  
  // Находит спрайт с картинкой для карты
  private Sprite GetFace(string faceS)
  {
    foreach (Sprite _tSP in faceSprites)
    {
      if (_tSP.name == faceS) // Если найден спрайт с требуемым именем
      {
        return( _tSP ); // вернуть его
      }
    }
    return( null ); // Если не найден
  }
  
  // Добавить рубашку
  private void AddBack(Card card)
  {
    tGO = Instantiate( prefabSprite ) as GameObject;
    _tSR = _tGO.GetComponent<SpriteRenderer>();
    _tSR.sprite = cardBack;
    _tGO.transform.SetParent( card.transform );
    _tGO.transform.localPosition = Vector3.zero;
    // Большее значение sortingOrder, чем у других спрайтов
    _tSR.sortingOrder = 2;
    _tGO.name = "back";
    card.back = _tGO;
    
    //  По умолчанию рубашкой вверх
    card.faceUp = startFaceUp;
  }
  // Перемешивание карт
   static public void Shuffle (ref List<Card> oCards) // ref - ссылка
   {
     // Создать временный список для хранения карт
     List<Card> tCards = new List<Card>();
     int ndx; // индекс перемешиваемой карты
     tCards = new List<Card>();
     while (oCards.Count > 0) // перемешиваем
     {
       ndx = Random.Range(0,oCards.Count);
       tCards.Add (oCards[ndx]);
       oCards.RemoveAt(ndx);
     }
     // Заменить исходный список временным
     oCards = tCards;
   }
}









 
by

C Sharp Online Compiler

Write, Run & Share C# code online using OneCompiler's C# online compiler for free. It's one of the robust, feature-rich online compilers for C# language, running on the latest version 8.0. Getting started with the OneCompiler's C# compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C# and start coding.

Read inputs from stdin

OneCompiler's C# online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.

using System;
 
namespace Sample
{
  class Test
    {
      public static void Main(string[] args)
       {
         string name;
         name = Console.ReadLine();
         Console.WriteLine("Hello {0} ", name);
	}
     }
}

About C Sharp

C# is a general purpose object-oriented programming language by Microsoft. Though initially it was developed as part of .net but later it was approved by ECMA and ISO standards.

You can use C# to create variety of applications, like web, windows, mobile, console applications and much more using Visual studio.

Syntax help

Data types

Data TypeDescriptionRangesize
intTo store integers-2,147,483,648 to 2,147,483,6474 bytes
doubleto store large floating point numbers with decimalscan store 15 decimal digits8 bytes
floatto store floating point numbers with decimalscan store upto 7 decimal digits4 bytes
charto store single characters-2 bytes
stringto stores text-2 bytes per character
boolto stores either true or false-1 bit

Variables

Syntax

datatype variable-name = value;

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition or set of few conditions IF-ELSE is used.

if(conditional-expression) {
   // code
} 
else {
   // code
}

You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.

2. Switch:

Switch is an alternative to If-Else-If ladder.

switch(conditional-expression) {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 // code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement) {
  // code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition) {
 // code 
}

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {
  // code 
} while (condition);

Arrays

Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.

Syntax

data-type[] array-name;

Methods

Method is a set of statements which gets executed only when they are called. Call the method name in the main function to execute the method.

Syntax

static void method-name() 
{
  // code to be executed
}