KDT Unity 2주차~4주차 - 팀과제 4
2023-11-22 TIL
알고리즘 문제
오늘의 알고리즘 문제 : 핸드폰 번호 가리기
프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다. 전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.
1
2
3
4
5
6
public class Solution {
public string solution(string phone_number) {
string answer = "";
return answer;
}
}
해결
1
2
3
4
5
6
7
8
9
10
11
public class Solution {
public string solution(string phone_number) {
string answer = "";
for (int i = 0; i < phone_number.Length - 4; i++)
{
answer += "*";
}
answer += phone_number.Substring(phone_number.Length - 4);
return answer;
}
}
한줄씩 해석해보겠습니다.
for (int i = 0; i < phone_number.Length - 4; i++)을 이용하여 문자열 길이 -4만큼 반복합니다.
answer += "*";그만큼 answer변수에 *을 추가합니다.
answer += phone_number.Substring(phone_number.Length - 4); 마지막으로 해당 문자열에 매개변수로 받은 문자열을 뒤에서 4자리를 끊는 함수를 사용하여 뒷 4자리를 잘라 answer에 추가합니다.
return answer;마지막으로 answer을 리턴해주면 됩니다.
C# 팀프로젝트
오늘은 배틀씬을 구현해보려고 합니다. 배틀은 2가지로 5의 배수가 되는 스테이지 마다 보스가 생성됩니다.
Source Code
배틀을 만들어보자!
배틀을 만들 때 감안해야하는 점이 좀 많았습니다.
하지만 한가지의 문제를 제외하고는 크게 오류가 나거나 문제가 되는 부분은 없었습니다.
여기서 문제가 되는 부분은 각 객체의 스피드에 따라 공격순서를 정하는 것에 있었습니다.
공격을 하는 객체가 몬스터와 플레이어가 섞여있다는게 문제였다.
그래서 해당 객체들의 Speed값을 뽑아서 배열로 만들어 오름차순으로 정렬하자라는 생각을 했다. BattleNew.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
...
//랜덤으로 나오는 몬스터 수 + 플레이어
int[] speedCompare = new int[monster.Count + 1];
for (int i = 0; i <= monster.Count; i++)
{
if (i == 0)
{
speedCompare[i] = PlayerInfo.Player.Speed;
}
else
{
speedCompare[i] = monster[i - 1].Speed;
}
}
for (int i = 0; i < speedCompare.Length - 1; i++)
{
for (int j = 0; j < speedCompare.Length - i - 1; j++)
{
// 현재 원소와 다음 원소를 비교하여 순서가 바뀌어 있으면 교환
if (speedCompare[j] < speedCompare[j + 1])
{
// Swap arr[j] and arr[j+1]
int temp = speedCompare[j];
speedCompare[j] = speedCompare[j + 1];
speedCompare[j + 1] = temp;
}
}
}
...
그래서 하나의 배열을 더 추가했습니다. 랜덤으로 나오는 몬스터의 배열 하지만 이렇게 하면 오름차순으로는 정리할수 있겠지만 그 Speed가 누구인지를 알수 없었습니다.
그래서 하나의 방법을 더 생각해보았습니다. 배열을 하나 더 만들자 라고 말입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int[] attackSequence = new int[monster.Count + 1];
...
for (int i = 0; i <= monster.Count; i++)
{
if (i == 0)
{
speedCompare[i] = PlayerInfo.Player.Speed;
}
else
{
speedCompare[i] = monster[i - 1].Speed;
}
attackSequence[i] = i;
}
...
...
for (int j = 0; j < speedCompare.Length - i - 1; j++)
{
// 현재 원소와 다음 원소를 비교하여 순서가 바뀌어 있으면 교환
if (speedCompare[j] < speedCompare[j + 1])
{
// Swap arr[j] and arr[j+1]
int temp = speedCompare[j];
speedCompare[j] = speedCompare[j + 1];
speedCompare[j + 1] = temp;
int temp1 = attackSequence[j];
attackSequence[j] = attackSequence[j + 1];
attackSequence[j + 1] = temp1;
}
}
...
attackSequence 배열은 플레이어를 0번으로 그리고 몬스터를 배열 인덱스 순으로 넣어줍니다.
그래서 0번이 플레이어 1부터 monster배열의 인덱스 0번이 됩니다.
BattleNew.cs BattleStart메서드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
...
private bool BattleStart()
{
BattleAttackSequence();
//전투
while (!PlayerInfo.Player.IsDead && monster.Count != 0)
{
Date.Line();
Console.Write($"{PlayerInfo.Player.Name} ");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write($"HP : {PlayerInfo.Player.HP} / {PlayerInfo.Player.MaxHP} ");
Console.ResetColor();
Console.ForegroundColor= ConsoleColor.Blue;
Console.WriteLine($"MP : {PlayerInfo.Player.MP} / { PlayerInfo.Player.MaxMP}");
Console.ResetColor();
(int, int) playerSelete = PlayerSelete();
for(int i = 0; i < attackSequence.Length; i++)
{
int fatalDamage = new Random().Next(0,100);
if (attackSequence[i]==0)
{
Console.WriteLine($"{PlayerInfo.Player.Name}의 턴");
if(fatalDamage < 3)
{
monster[playerSelete.Item1-1].FatalDamage(playerSelete.Item2);
}
else if(fatalDamage < 97) monster[playerSelete.Item1-1].Damage(playerSelete.Item2);
else Console.WriteLine($"\n{monster[playerSelete.Item1 - 1].Name}가 공격을 피했습니다!");
if (monster[playerSelete.Item1 - 1].IsDead) Console.WriteLine($"\n{monster[playerSelete.Item1 - 1].Name} (은)는 죽었습니다.");
}
else
{
if (!monster[attackSequence[i] - 1].IsDead)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write($"{monster[attackSequence[i] - 1].Name}");
Console.ResetColor();
Console.WriteLine("의 턴");
if (fatalDamage < 3)
{
PlayerInfo.Player.BeFatalDamaged(monster[attackSequence[i] - 1].AD);
}
else if (fatalDamage < 97) PlayerInfo.Player.BeDamaged(monster[attackSequence[i] - 1].AD);
else Console.WriteLine($"\n{PlayerInfo.Player.Name}가 공격을 피했습니다!");
}
if(PlayerInfo.Player.IsDead)
{
return false;
}
}
Console.WriteLine();
Thread.Sleep(1000);
}
if (monster[playerSelete.Item1 - 1].IsDead)
{
getGold += monster[playerSelete.Item1 - 1].Gold;
getExp += monster[playerSelete.Item1 - 1].EXP;
monster.RemoveAt(playerSelete.Item1 - 1);
BattleAttackSequence();
}
}
return true;
}
...
정리를 한후 attackSequence배열을 받아와 for문을 이용하여 attackSequence[i]째의 숫자를 가지고 배틀 씬을 구현하였습니다.
거기에 랜덤수(fatalDamage)를 사용하여 각 3% 확률로 회피와 치명타를 구현했습니다.
오늘의 정리
서로 다른 객체를 가지고 같은 값을 비교하는 방법은 많을 것이다.
하지만 나는 그런 방법을 잘 사용하지 못하고 너무 직관적으로 사용한게 아쉬운 분이다.
앞으로 라이브러리를 조금더 깊고 많이 공부를 해야할 것 같다.
