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;
}
}
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.
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);
}
}
}
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.
| Data Type | Description | Range | size |
|---|---|---|---|
| int | To store integers | -2,147,483,648 to 2,147,483,647 | 4 bytes |
| double | to store large floating point numbers with decimals | can store 15 decimal digits | 8 bytes |
| float | to store floating point numbers with decimals | can store upto 7 decimal digits | 4 bytes |
| char | to store single characters | - | 2 bytes |
| string | to stores text | - | 2 bytes per character |
| bool | to stores either true or false | - | 1 bit |
datatype variable-name = value;
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.
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;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement) {
// code
}
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
}
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);
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.
data-type[] array-name;
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.
static void method-name()
{
// code to be executed
}