2024. 1. 3. 18:25ㆍSKKU DT
이전 글에 이어서...
패널 프리팹을 보면 Image가 비어있는 것을 볼 수 있다.
Panel 프리팹을 Image에 드래그앤 드랍 한다.
PanelManager에서 panelCount를 선언하고 하나씩 증가하도록 수정
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PanelManager : MonoBehaviour
{
[SerializeField] GameObject panelPrefab;
[SerializeField] Transform parent;
int panelCount = 0;
//흰색 뺀 색상을 배열에 정의
Color[] colors = new Color[4] { Color.black, Color.blue, Color.yellow, Color.green };
public void Open()
{
GameObject panelObject = Instantiate(panelPrefab, parent);
Panel panel = panelObject.GetComponent<Panel>();
panel.IndexText = panelCount++;
panel.manager = this;
panel.ChangeColor(colors[Random.Range(0,3)]);
}
public void Close()
{
}
}
이미지도 넣었고 패널도 증가하도록 설정하여 적용된 것을 볼 수 있다.
Previous 버튼을 누를 때 패널이 닫히게 하기
Panel 스크립트 수정. 굳이 Close를 PanelManager 스크립트에게 위임하지 않고 Destroy(gameObject);로 스스로 지울 수 있다.
하지만 우리는 PanelManager 스크립트를 이용해서 Close를 실행할 것이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class Panel : MonoBehaviour
{
//패널 가운데 텍스트 접근
[SerializeField] private TMP_Text indexText;
//패널 색상 변경 위해 색상 접근
[SerializeField] private Image image;
//PanelManager 선언
public PanelManager manager; //프리팹이라 SerializeField를 사용할 수 없다.
/*
public int IndexText { get; set; } //프로퍼티의 축약형. 변수처럼 쓸수있고 함수도 사용할 수 있다.
public int IndexText2; //변수. 유효한 값을 판단할 수 없다. 프로퍼티에서는 set 중괄호 안에 if, else문을 넣을 수 있다.
*/
//프로퍼티를 사용하면 아래와 같다.
public int index; //저장을 위한 변수. 아예 지우고 아래의 index를 Index로 대문자로 쓰기도 한다.
public int IndexText //값을 저장하기 위해서 접근할 수 있는 속성을 가진 프로퍼티
{
get
{
return index;
}
set
{
index = value;
indexText.text = index.ToString();
}
}
/*
프로퍼티를 쓰기 때문에 SetPanelIndex는 쓰지 않는다.
public void SetPanelIndex(int index) //세터 메서드: 값을 외부에서 받아서 전달하기 위한 메서드
{
indexText.text = index.ToString(); //매개변수 index를 문자열로 변환
}
*/
// Open 버튼 클릭시 호출되는 메서드
public void Open()
{
manager.Open(); //manager 스크립트에게 위임
}
//Previous 버튼 클릭시 호출되는 메서드
public void Close()
{
manager.Close(); //manager 스크립트에게 위임
}
/// <summary>
/// 패널의 색상 변경 메서드
/// </summary>
/// <param name="color">변경할 색상</param>
public void ChangeColor(Color color) //컬러 변경 메서드 생성
{
image.color = color;
}
}
PanelManager 수정. Stack을 사용한다. 마지막에 들어간 것이 가장 먼저 나오는 First In Last Out 형태이다.
//스택 생성
Stack<GameObject> panelStack = new Stack<GameObject>();
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PanelManager : MonoBehaviour
{
[SerializeField] GameObject panelPrefab;
[SerializeField] Transform parent;
//스택 생성
Stack<GameObject> panelStack = new Stack<GameObject>();
//int panelCount = 0; //panelStack.Count;를 씀으로써 지워진다.
//흰색 뺀 색상을 배열에 정의
Color[] colors = new Color[4] { Color.black, Color.blue, Color.yellow, Color.green };
public void Open()
{
GameObject panelObject = Instantiate(panelPrefab, parent);
//Push로 게임오브젝트인 panelObject를 넣는다.
panelStack.Push(panelObject);
Panel panel = panelObject.GetComponent<Panel>();
panel.IndexText = panelStack.Count; //panelCount 변수를 사용하지 않고 Count 함수를 가져다 쓸 수 있다. get만 가능한 읽기 전용.
panel.manager = this;
panel.ChangeColor(colors[Random.Range(0,3)]);
}
public void Close()
{
GameObject lastPanelObject = panelStack.Pop(); //마지막 패널을 Pop 시키면 뽑아져 나오면서 Stack에서 삭제 된다.
Destroy(lastPanelObject); //마지막 패널을 삭제한다.
}
}
이제 숫자가 이상하게 변하지 않고 차례대로 커지고 작아진다.
패널이 켜지고 꺼질 때의 효과를 주기 위해서 에셋스토어에서 DOTween을 받는다.
Setup을 하고 Apply 한다.
PanelManager 스크립트 수정
네임스페이스 추가
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class PanelManager : MonoBehaviour
{
[SerializeField] GameObject panelPrefab;
[SerializeField] Transform parent;
//스택 생성
Stack<GameObject> panelStack = new Stack<GameObject>();
//int panelCount = 0; //panelStack.Count;를 씀으로써 지워진다.
//흰색 뺀 색상을 배열에 정의
Color[] colors = new Color[4] { Color.black, Color.blue, Color.yellow, Color.green };
public void Open()
{
GameObject panelObject = Instantiate(panelPrefab, parent);
//Push로 게임오브젝트인 panelObject를 넣는다.
panelStack.Push(panelObject);
panelObject.transform.localScale = Vector3.zero; //처음엔 스케일을 0으로 설정
panelObject.transform.DOScale(1, 0.2f); //(스케일의 결과 값, 도달하는 데에 걸리는 시간)
Panel panel = panelObject.GetComponent<Panel>();
panel.IndexText = panelStack.Count; //panelCount 변수를 사용하지 않고 Count 함수를 가져다 쓸 수 있다. get만 가능한 읽기 전용.
panel.manager = this;
panel.ChangeColor(colors[Random.Range(0,3)]);
}
public void Close()
{
GameObject lastPanelObject = panelStack.Pop(); //마지막 패널을 Pop 시키면 뽑아져 나오면서 Stack에서 삭제 된다.
Destroy(lastPanelObject); //마지막 패널을 삭제한다.
}
}
끌 때도 애니메이션을 적용한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class PanelManager : MonoBehaviour
{
[SerializeField] GameObject panelPrefab;
[SerializeField] Transform parent;
//스택 생성
Stack<GameObject> panelStack = new Stack<GameObject>();
//int panelCount = 0; //panelStack.Count;를 씀으로써 지워진다.
//흰색 뺀 색상을 배열에 정의
Color[] colors = new Color[4] { Color.black, Color.blue, Color.yellow, Color.green };
public void Open()
{
GameObject panelObject = Instantiate(panelPrefab, parent);
//Push로 게임오브젝트인 panelObject를 넣는다.
panelStack.Push(panelObject);
panelObject.transform.localScale = Vector3.zero; //처음엔 스케일을 0으로 설정
panelObject.transform.DOScale(1, 0.2f); //(스케일의 결과 값, 도달하는 데에 걸리는 시간)
Panel panel = panelObject.GetComponent<Panel>();
panel.IndexText = panelStack.Count; //panelCount 변수를 사용하지 않고 Count 함수를 가져다 쓸 수 있다. get만 가능한 읽기 전용.
panel.manager = this;
panel.ChangeColor(colors[Random.Range(0,3)]);
}
public void Close()
{
GameObject lastPanelObject = panelStack.Pop(); //마지막 패널을 Pop 시키면 뽑아져 나오면서 Stack에서 삭제 된다.
lastPanelObject.transform.DOScale(0, 0.2f).OnComplete(() =>
{
Destroy(lastPanelObject);
}); //스케일 0으로, 0.2초 동안. OnComplete으로 애니메이션이 다 작동될 때까지 Destroy하지 않는다.
}
}
켜질 때와 꺼질 때 애니메이션 적용 굿~
나만의 Stack 만들기?
**프로퍼티는 필드 값을 가져오거나 설정하는데 사용되며, 외부에서 프로퍼티에 접근하는 것은 변수에 직접 접근하는 것과 유사하게 보입니다. 그러나 프로퍼티는 내부적으로 메서드로 구현되어 있어 더 많은 제어를 제공하고, 간단한 계산이나 로직을 추가할 수 있습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyStack : MonoBehaviour
{
List<int> values = new List<int>();
//스택 생성
Stack<int> myStack = new Stack<int>();
//Stack에 저장된 요소의 수
public int Count
{
get { return myStack.Count;}
}
public void Push(int value)
{
//Push로 value를 넣는다.
myStack.Push(value);
}
public int Pop()
{
if (myStack.Count > 0)
{
return myStack.Pop();
}
else
{
Debug.Log("스택이 비어있습니다.");
return -1;
}
}
private void Start()
{
Push(10);
Push(20);
Push(30);
Debug.Log("Pop: " + Pop()); //30
Debug.Log("Pop: " + Pop()); //20
Debug.Log("Pop: " + Pop()); //10
Debug.Log("현재 스택의 요소 수: " + Count);
}
}
GPT 친구의 도움을 받아 Stack의 예시를 하나 작성하였다.
Push로 입력한 순서는 10, 20, 30 순서지만 출력되는 값의 순서는 30, 20, 10으로 나오는 것을 볼 수 있다.
Stack 예시
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyStack : MonoBehaviour
{
List<int> values = new List<int>();
//Stack에 저장된 요소의 수
public int Count
{
get { return values.Count; } //get으로 읽기만 가능하도록.
}
public void Push(int value)
{
values.Add(value);
}
public int Pop()
{
int idx = values.Count - 1; //인덱스는 카운트의 -1
int result = values[idx]; //result는 리스트에서 인덱스의 값
values.RemoveAt(idx); //인덱스 값을 지우고
return result; //결과를 반환한다.
}
}
Queue 예시
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyQueue : MonoBehaviour
{
List<int> values = new List<int>();
public int Count { get { return values.Count; } }
public void Enqueue(int value)
{
values.Add(value);
}
public int Dequeue()
{
int idx = 0;
int result = values[idx]; //첫 번째 값이 불러와진다.
values.RemoveAt(idx);
return result;
}
}
일반화 프로그래밍
바로 직전의 Stack과 Queue코드를 일반화 프로그래밍으로 바꾸면, 값 형식 자리에 T를 넣을 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyStack<T> : MonoBehaviour
{
List<T> values = new List<T>();
//Stack에 저장된 요소의 수
public int Count
{
get { return values.Count; } //get으로 읽기만 가능하도록.
}
public void Push(T value)
{
values.Add(value);
}
public T Pop()
{
int idx = values.Count - 1; //인덱스는 카운트의 -1
T result = values[idx]; //result는 리스트에서 인덱스의 값
values.RemoveAt(idx); //인덱스 값을 지우고
return result; //결과를 반환한다.
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyQueue<T> : MonoBehaviour
{
List<T> values = new List<T>();
public int Count { get { return values.Count; } }
public void Enqueue(T value)
{
values.Add(value);
}
public T Dequeue()
{
int idx = 0;
T result = values[idx]; //첫 번째 값이 불러와진다.
values.RemoveAt(idx);
return result;
}
}
바로 위에서 MyStack과 MyQueue를 T 제네릭으로 선언했기 때문에 새로운 스크립트에서도 가져와서 int 형을 대입해도 문제가 없다. 물론 string도 문제 없다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StackQueueExample : MonoBehaviour
{
void Start()
{
MyStack<int> stack = new MyStack<int>(); //MyStack에서 정의했던 모든 T가 int 형으로 자동으로 바뀐다.
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
stack.Push(5);
stack.Push(6);
while(stack.Count > 0)
{
int result = stack.Pop();
Debug.Log(result);
}
MyQueue<int> queue = new MyQueue<int>();
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
queue.Enqueue(4);
queue.Enqueue(5);
queue.Enqueue(6);
while(queue.Count > 0)
{
int result = queue.Dequeue();
Debug.Log(result);
}
}
}
**Pop을 할 때 아무것도 없는데 pop하면 크래시가 날 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyStack : MonoBehaviour
{
List<int> values = new List<int>();
//Stack에 저장된 요소의 수
public int Count
{
get { return values.Count; } //get으로 읽기만 가능하도록.
}
public void Push(int value)
{
values.Add(value);
}
public int Pop()
{
if(values.Count > 0)
{
int idx = values.Count - 1; //인덱스는 카운트의 -1
int result = values[idx]; //result는 리스트에서 인덱스의 값
values.RemoveAt(idx); //인덱스 값을 지우고
return result; //결과를 반환한다.
}
else
{
return 0;
}
}
}
크래시가 나지 않는 안전장치로는, values.Count가 0보다 크면 Pop을 실행하고 아니면 0만 반환하게 할 수 있다. 이건 int형일 때만 가능.
제네릭에서는 return에 int형을 쓸 수 없다. 왜냐하면 아직 형이 정해지지 않은 T에 int를 확정지을 수 없기 때문.
다음과 같이 크래시를 예방할 수 있다. throw~ 부분을 추가하였다.
public T Pop()
{
if(values.Count > 0)
{
int idx = values.Count - 1; //인덱스는 카운트의 -1
T result = values[idx]; //result는 리스트에서 인덱스의 값
values.RemoveAt(idx); //인덱스 값을 지우고
return result; //결과를 반환한다.
}
else
{
throw new InvalidOperationException("MyStack Enpty");
}
}
try ~ catch 문으로 묶으면, MyStack 스크립트에서 throw 된 exception이 try catch문으로 들어가면서 메시지가 출력된다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class StackQueueExample : MonoBehaviour
{
void Start()
{
MyStack<int> stack = new MyStack<int>(); //MyStack에서 정의했던 모든 T가 int 형으로 자동으로 바뀐다.
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
stack.Push(5);
stack.Push(6);
while(stack.Count > 0)
{
int result = stack.Pop();
Debug.Log(result);
}
try
{
stack.Pop();
}
catch(Exception e)
{
Debug.Log(e.Message);
}
MyQueue<int> queue = new MyQueue<int>();
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
queue.Enqueue(4);
queue.Enqueue(5);
queue.Enqueue(6);
while(queue.Count > 0)
{
int result = queue.Dequeue();
Debug.Log(result);
}
}
}
MyQueue 스크립트에서도 마찬가지로 if, else 문으로 else에 throw~를 넣는다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class MyQueue<T> : MonoBehaviour
{
List<T> values = new List<T>();
public int Count { get { return values.Count; } }
public void Enqueue(T value)
{
values.Add(value);
}
public T Dequeue()
{
if(values.Count > 0)
{
int idx = 0;
T result = values[idx]; //첫 번째 값이 불러와진다.
values.RemoveAt(idx);
return result;
}
else
{
throw new InvalidOperationException("MyQueue Empty");
}
}
}
배열
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoreOnArray : MonoBehaviour
{
// 점수가 60 이상인지 확인하는 함수
bool CheckPassed(int score)
{
return score >= 60;
}
// 값을 출력하는 함수
void Print(int value)
{
Debug.Log($"{value}");
}
void Start()
{
// 정수형 배열 생성 및 초기화
int[] scores = new int[] { 80, 74, 81, 90, 34 };
// 배열의 각 요소를 출력
foreach (int score in scores)
{
Debug.Log($"Original Scores: {score}");
}
Debug.Log("- - -");
// 배열을 정렬하고 정렬된 배열 출력
Array.Sort(scores);
Array.ForEach<int>(scores, new Action<int>(Print));
// Sorted Scores: 34 74 80 81 90
Debug.Log("- - -");
// 배열의 차원 수 출력
Debug.Log($"Number of dimensions: {scores.Rank}");
// Number of dimensions: 1
// 이진 검색을 통해 값 81이 배열에서 위치를 출력
Debug.Log($"Binary search : 81 is at " + $"{Array.BinarySearch<int>(scores, 81)}");
// Binary search : 81 is at 3
// 선형 검색을 통해 값 81이 배열에서 위치를 출력
Debug.Log($"Linear search : 81 is at " + $"{Array.IndexOf(scores, 81)}");
// Linear search : 81 is at 2
// 모든 요소가 특정 조건을 만족하는지 확인
Debug.Log($"Everyone passed ? : " + $"{Array.TrueForAll<int>(scores, CheckPassed)}");
// Everyone passed ? : False
// 특정 조건을 만족하는 첫 번째 요소의 인덱스 찾기
int index = Array.FindIndex<int>(scores, (score) => score < 60);
// 해당 인덱스의 값을 변경하여 모든 요소가 특정 조건을 만족하는지 확인
scores[index] = 61;
Debug.Log($"Everyone passed ? : " + $"{Array.TrueForAll<int>(scores, CheckPassed)}");
// Everyone passed ? : True
// 배열의 길이 출력
Debug.Log($"Old length of scores : " + $"{scores.GetLength(0)}");
// Old length of scores : 5
// 배열 크기 조정 및 조정된 크기 출력
Array.Resize<int>(ref scores, 10);
Debug.Log($"New length of scores : {scores.Length}");
// New length of scores : 10
// 배열의 모든 요소 출력
Array.ForEach<int>(scores, new Action<int>(Print));
// Resized Scores: 61 0 0 0 0 0 0 0 0 0
// 배열의 일부 요소를 지우고 나머지 요소 출력
Array.Clear(scores, 3, 7);
Array.ForEach(scores, new Action<int>(Print));
// Cleared Scores: 61 0 0 0 0 0 0 0 0 0
// 배열의 일부를 새로운 배열로 복사하고 복사된 배열 출력
int[] sliced = new int[3];
Array.Copy(scores, 0, sliced, 0, 3);
Array.ForEach<int>(sliced, new Action<int>(Print));
// Sliced Scores: 61 0 0
}
}
배열 정렬하기 -버블 정렬
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class ArraySort : MonoBehaviour
{
void Print(int value)
{
Debug.Log($"{value}");
}
void Start()
{
int[] scores = { 10, 30, 60, 20, 80, 50, 90, 70, 40, 35 };
int[] newScore = MySort(scores);
}
int[] MySort(int[] scores)
{
int temp;
for(int i = 0; i < scores.Length; i++)
{
for (int j = 0; j < scores.Length - 1; j++)
{
if (scores[j] < scores[j+1])
{
temp = scores[j];
scores[j] = scores[j+1];
scores[j+1] = temp;
}
}
}
return scores;
}
}
배열 정렬하기 -이진 탐색(Binary Search)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class ArraySort : MonoBehaviour
{
void Print(int value)
{
Debug.Log($"{value}");
}
void Start()
{
int[] scores = { 10, 30, 60, 20, 80, 50, 90, 70, 40, 35 };
int[] newScore = MySort(scores);
Array.ForEach<int>(scores, new Action<int>(Print));
int result = MyBinarySearch(newScore, 70);
Debug.Log($"70은 {result + 1}번째에 위치");
}
int MyBinarySearch(int[] scores, int findValue)
{
int low = 0;
int high = scores.Length - 1;
while (low <= high)
{
int middle = (low + high) / 2;
// 중간 값이 찾는 값과 같으면 인덱스 반환
if (scores[middle] == findValue)
return middle;
// 중간 값이 찾는 값보다 작으면 오른쪽 부분 검색
if (scores[middle] < findValue)
low = middle + 1;
// 중간 값이 찾는 값보다 크면 왼쪽 부분 검색
else
high = middle - 1;
}
// 찾는 값이 배열에 없을 경우 0 반환
return 0;
}
int[] MySort(int[] scores)
{
int temp;
for (int i = 0; i < scores.Length; i++)
{
for (int j = 0; j < scores.Length - 1; j++)
{
if (scores[j] > scores[j + 1])
{
temp = scores[j];
scores[j] = scores[j + 1];
scores[j + 1] = temp;
}
}
}
return scores;
}
}
이진 탐색 예제2
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
class Person
{
public string Name { get; private set; }
public int Age { get; private set; }
public string Id { get; private set; }
public Person(string name, int age, string id)
{
this.Name = name;
this.Age = age;
this.Id = id;
}
}
public class ArraySort : MonoBehaviour
{
void Start()
{
Person p1 = new Person("홍길동", 23, "001");
Person p2 = new Person("김길동", 33, "002");
Person p3 = new Person("최길동", 31, "003");
Person p4 = new Person("고길동", 28, "004");
Person p5 = new Person("마길동", 27, "005");
Person p6 = new Person("박길동", 36, "006");
Person p7 = new Person("우길동", 42, "007");
List<Person> list = new List<Person> { p1, p2, p3, p4, p5, p6, p7 };
}
int binaryAgeSearch(Person[] persons, int age)
{
int low = 0, high = persons.Length - 1;
int mid;
while(low <= high)
{
mid = (low + high) / 2;
if (persons[mid].Age == age)
{
return mid;
}
else if (persons[mid].Age > age)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
}
이진 탐색 예제3 -나이로 검색하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
class Person : IComparable<Person> //인터페이스 추가
{
public string Name { get; private set; }
public int Age { get; private set; }
public string Id { get; private set; }
public Person(string name, int age, string id)
{
this.Name = name;
this.Age = age;
this.Id = id;
}
public int CompareTo(Person other) //"Ctrl + ."으로 자동 완성
{
if(other == null) return 1;
else return this.Age.CompareTo(other.Age);
}
}
public class ArraySort : MonoBehaviour
{
void Start()
{
Person p1 = new Person("홍길동", 23, "001");
Person p2 = new Person("김길동", 33, "002");
Person p3 = new Person("최길동", 31, "003");
Person p4 = new Person("고길동", 28, "004");
Person p5 = new Person("마길동", 27, "005");
Person p6 = new Person("박길동", 36, "006");
Person p7 = new Person("우길동", 42, "007");
List<Person> list = new List<Person> { p1, p2, p3, p4, p5, p6, p7 };
list.Sort();
int result = binaryAgeSearch(list.ToArray(), 36); //괄호 안에 찾고자 하는 정보
Debug.Log(result);
}
int binaryAgeSearch(Person[] persons, int age)
{
int low = 0, high = persons.Length - 1;
int mid;
while(low <= high)
{
mid = (low + high) / 2;
if (persons[mid].Age == age)
{
return mid;
}
else if (persons[mid].Age > age)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
}
이진 탐색 예제3 -이름으로 검색하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
class Person : IComparable<Person> //인터페이스 추가
{
public string Name { get; private set; }
public int Age { get; private set; }
public string Id { get; private set; }
public Person(string name, int age, string id)
{
this.Name = name;
this.Age = age;
this.Id = id;
}
public int CompareTo(Person other) //"Ctrl + ."으로 자동 완성
{
if(other == null) return 1;
else return this.Age.CompareTo(other.Age);
}
}
public class ArraySort : MonoBehaviour
{
void Start()
{
Person p1 = new Person("홍길동", 23, "001");
Person p2 = new Person("김길동", 33, "002");
Person p3 = new Person("최길동", 31, "003");
Person p4 = new Person("고길동", 28, "004");
Person p5 = new Person("마길동", 27, "005");
Person p6 = new Person("박길동", 36, "006");
Person p7 = new Person("우길동", 42, "007");
List<Person> list = new List<Person> { p1, p2, p3, p4, p5, p6, p7 };
list.Sort(); //정렬
int result = binaryAgeSearch(list.ToArray(), 36); //괄호 안에 찾고자 하는 정보 검색
list.Sort(new Comparison<Person>((n1, n2) => n1.Name.CompareTo(n2.Name))); //정렬. n1의 이름과 n2의 이름 비교
int result2 = binaryNameSeach(list.ToArray(), "우길동", 0, list.ToArray().Length - 1);
Person p8 = new Person("윤길동", 34, "008"); //새로운 값 생성
if (p6.Equals(p7))
{
Debug.Log("");
}
}
int binaryAgeSearch(Person[] persons, int age) //나이로 정렬
{
int low = 0, high = persons.Length - 1;
int mid;
while(low <= high)
{
mid = (low + high) / 2;
if (persons[mid].Age == age)
{
return mid;
}
else if (persons[mid].Age > age)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
int binaryNameSeach(Person[] persons, string name, int myLow, int myHigh) //이름으로 정렬
{
if (myLow > myHigh) return -1;
if (name == null) return -1;
int mid = myLow + (myHigh - myLow) / 2;
if (persons[mid].Name.CompareTo(name) == 0)
{
return mid;
}
else if (persons[mid].Name.CompareTo(name) > 0)
{
myHigh = mid - 1;
return binaryNameSeach(persons, name, myLow, myHigh); //재귀 함수
}
else
{
myLow = mid + 1;
return binaryNameSeach(persons, name, myLow, myHigh); //재귀 함수
}
}
}
int binaryNameSearch를 추가 하여 이름으로 정렬하고 검색하는 기능이 추가되었다.