강께르의 개발일지
[문제 풀기] Bit Flags, Generics, Delegate에 대하여 본문
1. 비트맵 색상 합치기와 추출을 비트 플래그로 구현
using System;
public class Test
{
public static uint MergeARGB(uint a, uint r, uint g, uint b)
{
uint result = 0;
result |= b;
result |= (g << 8);
result |= (r << 16);
result |= (a << 24);
Console.WriteLine(Convert.ToString(a, 16));
return result;
}
public static void ExtractARGB(uint argb, out uint a, out uint r, out uint g, out uint b)
{
a = (argb & 0xFF000000) >> 24;
r = (argb & 0x00FF0000) >> 16;
g = (argb & 0x0000FF00) >> 8;
b = (argb & 0x000000FF);
// 위 방법보단 아래 방법을 더 추천
//a = (argb >> 24) & 0xFF;
//r = (argb >> 16) & 0xFF;
//g = (argb >> 8) & 0xFF;
//b = argb & 0xFF;
}
public static void Main()
{
uint colorA = MergeARGB(255, 192, 255, 192);
ExtractARGB(colorA, out uint a, out uint r, out uint g, out uint b);
Console.WriteLine(a); // 255
Console.WriteLine(r); // 192
Console.WriteLine(g); // 255
Console.WriteLine(b); // 192
}
}
2. 몬스터 상태에 대한 기능 구현
using System;
var monster = new Monster();
monster.SetStatus(Monster.Status.A | Monster.Status.B);
Console.WriteLine(monster.CurrentStatus);
monster.RemoveStatus(Monster.Status.B);
Console.WriteLine(monster.CurrentStatus);
monster.RemoveStatus(Monster.Status.C);
Console.WriteLine(monster.CurrentStatus);
monster.RemoveStatus(Monster.Status.A);
Console.WriteLine(monster.CurrentStatus);
monster.ToggleStatus(Monster.Status.All);
Console.WriteLine(monster.CurrentStatus);
monster.RemoveStatus(Monster.Status.A | Monster.Status.B);
Console.WriteLine(monster.CurrentStatus);
monster.AddStatus(Monster.Status.C);
Console.WriteLine(monster.CurrentStatus);
Console.WriteLine(monster.CheckStatus(Monster.Status.A));
Console.WriteLine(monster.CheckStatus(Monster.Status.B));
Console.WriteLine(monster.CheckStatus(Monster.Status.C));
monster.ToggleStatus(Monster.Status.B);
Console.WriteLine(monster.CurrentStatus);
monster.RemoveStatus(Monster.Status.C);
Console.WriteLine(Enum.IsDefined(typeof(Monster.Status), monster.CurrentStatus)); // test 원래는 플래그 enum엔 사용하면 안됨
class Monster
{
[Flags]
public enum Status
{
None = 0,
A = 1 << 0,
B = 1 << 1,
C = 1 << 2,
All = A | B | C
}
private Status currentStatus;
public Status CurrentStatus
{
get { return currentStatus; }
}
public void SetStatus(Status status)
{
currentStatus &= 0b000;
currentStatus |= status;
}
public bool CheckStatus(Status status)
{
return (currentStatus & status) == status;
}
public void AddStatus(Status status)
{
currentStatus |= status;
}
public void ToggleStatus(Status status)
{
currentStatus ^= status;
}
public void RemoveStatus(Status status)
{
currentStatus = currentStatus ^ status & currentStatus;
// 다른 방법
//currentStatus &= ~status;
}
}
3. MyArray 메소드 추가 / 델리게이트와 일반화를 이용
- Find 씨리즈
- FindAll 씨리즈
- Exists
- Clear
- Fill
- Sort<T>(T[], Comparison<T>)
- ForEach<T> (T[] array, Action<T> action);
class MyArray<T> where T : IComparable<T>, IEquatable<T>
{
public static void Copy(T[] sour, T[] dest, int length)
{
for (int i = 0; i < length; i++)
{
dest[i] = sour[i];
}
}
public static void Copy(T[] sour, int sourStart, T[] dest, int destStart, int length)
{
for (int i = 0; i < length; i++)
{
dest[destStart + i] = sour[sourStart + i];
}
}
public static int IndexOf(T[] array, T number)
{
for (int idx = 0; idx < array.Length; idx++)
{
if (array[idx].Equals(number))
{
return idx;
}
}
return -1;
}
public static void Sort(T[] array)
{
for (int idx = 0; idx < array.Length - 1; idx++)
{
for (int innerIdx = 0; innerIdx < array.Length - 1 - idx; innerIdx++)
{
if (array[innerIdx].CompareTo(array[innerIdx + 1]) > 0)
{
T temp = array[innerIdx];
array[innerIdx] = array[innerIdx + 1];
array[innerIdx + 1] = temp;
}
}
}
}
public static void Sort(T[] array, Comparison<T> comparison, bool order = true)
{
for (int idx = 0; idx < array.Length - 1; idx++)
{
for (int innerIdx = 0; innerIdx < array.Length - 1 - idx; innerIdx++)
{
if (comparison(array[innerIdx], array[innerIdx + 1]) > 0)
{
T temp = array[innerIdx];
array[innerIdx] = array[innerIdx + 1];
array[innerIdx + 1] = temp;
}
}
}
}
public static int BinarySearch(T[] array, T number)
{
int mid = array.Length / 2;
int min = 0;
int max = array.Length - 1;
while (true)
{
if (array[mid].Equals(number))
return mid;
if (min > max)
return -1;
if (array[mid].CompareTo(number) > 0) // 왼쪽
{
max = mid - 1;
mid = (min + max) / 2;
}
else if (array[mid].CompareTo(number) < 0) // 오른쪽
{
min = mid + 1;
mid = (min + max) / 2;
}
}
}
public static void Clear(T[] array, int index, int length)
{
for (int idx = index; idx < length; idx++)
{
array[idx] = default(T);
}
}
public static void Fill(T[] array, T value)
{
for (int idx = 0; idx < array.Length; idx++)
{
array[idx] = value;
}
}
public static T Find(T[] array, Predicate<T> match)
{
foreach (var elem in array)
{
if (match(elem))
return elem;
}
return default(T);
}
public static T[] FindAll(T[] array, Predicate<T> match)
{
List<T> temp = new List<T>();
foreach (var elem in array)
{
if (match(elem))
{
temp.Add(elem);
}
}
return temp.ToArray();
}
public static int FindIndex(T[] array, Predicate<T> match)
{
for (int idx = 0; idx < array.Length; idx++)
{
if (match(array[idx]))
return idx;
}
return -1;
}
public static T FindLast(T[] array, Predicate<T> match)
{
T result = default(T);
foreach (var elem in array)
{
if (match(elem))
result = elem;
}
return result;
}
public static int FindLastIndex(T[] array, Predicate<T> match)
{
int result = -1;
for (int idx = 0; idx < array.Length; idx++)
{
if (match(array[idx]))
result = idx;
}
return result;
}
public static void ForEach(T[] array, Action<T> action)
{
foreach (var elem in array)
{
action(elem);
}
}
public static bool Exists(T[] array, Predicate<T> match)
{
foreach (var elem in array)
{
if (match(elem))
return true;
}
return false;
}
}
'프로그래밍 > C#' 카테고리의 다른 글
[수업] 20210923_6일차 (0) | 2021.09.24 |
---|---|
[수업] 20210917_5일차 (0) | 2021.09.18 |
[문제 풀기] boxing, unboxing과 인터페이스에 대하여 (0) | 2021.09.17 |
[수업] 20210916_4일차 (0) | 2021.09.17 |
[문제 풀기] 클래스에 관하여 (0) | 2021.09.16 |