-
열아홉번째 포켓몬, 마기라스 구현 (모래바람)포켓몬 배틀 구현 2022. 3. 25. 22:05
열아홉번째 포켓몬 마기라스,
모래바람 파티로 쓰이나 했더니
그냥 깡스탯에 악(흑마렉스) 바위(썬더 랜드로스) 타입 타점으로
"딜"쪽에 치중된 딜탱느낌이다.
https://pikalytics.com/pokedex/homebss/tyranitar
Tyranitar Series 12 Battle Stadium Singles Stats Pokédex | Pokémon | Pikalytics
Assault Vest 49.700% Leftovers 16.400% Weakness Policy 9.400% Sitrus Berry 4.400% Choice Band 2.600% Eject Pack 2.500% Focus Sash 2.500% Chesto Berry 2.500% Lum Berry 2.300% Figy Berry 1.700%
pikalytics.com
스킬은 깨물어부수기, 스톤에지, 지진에
채용율 4위는 락블레스트인데
바위타입은 스톤에지가 존재하므로 얼음타입의 냉동펀치를 채용했다.
{"지진", "땅", "100", "100", "10", "물리", "null", "null", "null", "null", "null", "n", "y", "y", "부가효과 없음"}, {"스톤에지", "바위", "100", "80", "5", "물리", "null", "null", "null","null","null", "n", "n","y","급소에 맞을 확률이 높다."}, {"냉동펀치", "얼음", "75", "100", "15", "물리", "얼음", "10", "null", "null", "null", "y", "n", "y","10% 확률로 상대방을 얼린다." }, {"깨물어부수기", "악", "80", "100", "15", "물리", "랭크", "20", "방어", "-1", "상대", "y", "n", "y", "20% 확률로 상대방의 방어를 1랭크 떨어뜨린다."},
급소, 얼음, 랭크변화
전부 구현해놓은 부가효과들이므로 스킬 정보만 배열에 쓰면 기술 구현은 끝!
마기라스가 채용하는 아이템은 보통 돌격조끼
변화기를 사용하지 못하게 되지만 특방이 1.5배 오른다.
4 공격기를 채용하면 사실상 디메리트 없는 아이템이다.
void 스카프(string p[][one][two], string s[][one][two]) { for (int i = 1; i < 4; i++) { if (p[i][0][13] == "스카프") { int scarf = stoi(p[i][11][14]); scarf = scarf * 3 / 2; p[i][11][14] = to_string(scarf); p[i][0][8] = to_string(scarf); } if (s[i][0][13] == "스카프") { int scarf = stoi(s[i][11][14]); scarf = scarf * 3 / 2; s[i][11][14] = to_string(scarf); s[i][0][8] = to_string(scarf); } } } //지닌 도구가 스카프인 포켓몬의 고유 스피드 값을 1.5배로 올리는 함수. void 돌격조끼(string p[][one][two], string s[][one][two]) { for (int i = 1; i < 4; i++) { if (p[i][0][13] == "돌조") { int scarf = stoi(p[i][11][13]); scarf = scarf * 3 / 2; p[i][11][13] = to_string(scarf); p[i][0][7] = to_string(scarf); } if (s[i][0][13] == "돌조") { int scarf = stoi(s[i][11][13]); scarf = scarf * 3 / 2; s[i][11][13] = to_string(scarf); s[i][0][7] = to_string(scarf); } } } //지닌 도구가 돌격조끼인 포켓몬의 고유 특방 값을 1.5배로 올리는 함수.
이와 비슷하게 스피드를 올려주는 "스카프" 아이템이 존재하는데,
해당 함수를 복사하여 값만 살짝 수정해주면 구현 완료
스카프와 다르게 디메리트가 사실상 없으므로 돌격조끼 구현은 끝!
스카프(p, s); //지닌 물건이 스카프인 포켓몬의 스피드 1.5배 증가 돌격조끼(p, s); //지닌 물건이 돌격조끼인 포켓몬의 특방 1.5배 증가 printf("\n\n"); cout << "상대는 " << s[1][0][11] << t1(p, ps[0]) << "내보냈다!\n"; cout << "가랏! " << p[1][0][11] << "!\n\n"; int startspeed = 스피드비교(p, s, 1,1); if (startspeed == 1) {//플레이어 포켓몬이 더 빠른 경우 즉발특성(p, ps[0], 1, s, ps[1], ps);//플레이어 포켓몬의 특성 먼저 발동 즉발특성(s, ps[1], 0, p, ps[0], ps);//이후 상대 포켓몬의 특성 발동 } else if (startspeed == 0) {//상대방 포켓몬이 더 빠른 경우 즉발특성(s, ps[1], 0, p, ps[0], ps);//상대 먼저 특성 발동 즉발특성(p, ps[0], 1, s, ps[1], ps);//후 플레이어 특성 발동 } else printf("startspeed 오류, main파일, id 3483589\n");
이제 메인함수에서 배틀을 시작하기 전에 한번씩 호출해주면 완료.
마기라스 구현은 이렇게 날먹으로 끝나나싶지만
마기라스의 특성 "모래날림"은
필드의 날씨를 5턴동안 "모래바람" 상태로 만든다.
옛날에 가이오가를 구현할때 "비" 날씨를 구현한 이후로 오랜만에 돌아온 날씨 구현 차례이다.
해당 날씨의 효과는 여러가지 있지만
실전에 필요한 효과들만 추려보자면...
1.바위, 땅, 강철 타입이 아닌 포켓몬들은 매 턴 최대 체력의 1/16의 데미지를 입는다.
2.바위타입 포켓몬의 특방이 50% 상승한다.
3.아침햇살 (날씨에 영향을 받는 회복기)의 회복량이 절반이 왼다.
이렇게 3가지.
여기에 추가로
1.필드를 모래바람 상태로 만드는 파트
2.이후 5턴이 지나면 모래바람 날씨가 종료되는 파트
3.도중에 다른 날씨가 발생하면 모래바람이 사라지는 파트
이렇게 3가지를 더 구현하면 날씨 모래바람은 구현이 끝난다.
int ps[13] = { 1,1,0,0,0,0,0,0,0,0,0,0,0 }; //ps[0] = 플레이어의 필드 위 포켓몬 번호. //ps[1] = cpu의 필드 위 포켓몬 번호. //ps[2] = 필드의 날씨가 비면 1, 아니면 0 //ps[3] = 비 카운트. 날씨가 비로 바뀌면 5가 지정되고 매 턴 1씩 까여 0이 되면 비가 끝난다. //ps[4],[6] 다른 날씨 //ps[5],[7] 다른 날씨 카운트 //ps[8] = 필드의 날씨가 모래바람이면 1, 아니면 0 //ps[9] = 모래바람 카운트 //ps[10] = 교체 전 플레이어 포켓몬 번호 //ps[11] = 교체 전 cpu 포켓몬 번호 *기술 속임수 구현에 필요 //ps[12] = 플레이어 진영의 스텔스록 여부 //ps[13] = CPU 진영의 스텔스록 여부
필드의 모래바람 여부는 필드위 상태 변수를 저장해둔 배열 ps배열의
[9]번칸과 [10]번 칸을 사용한다.
ps[9]가 1이면 필드 상태가 모래바람인것이고
ps[10]엔 남은 모래바람 턴 수가 저장된다.
자 그럼 일단 모래바람이 발동되는 파트부터
if (p[pp][0][12] == "잔비") { //가이오가의 잔비, 날씨를 비 상태로 만듬 if (ps[2] != 1) { //현재 날씨가 비 상태가 아닐때만 발동 cout << "[특성 잔비]\n"; cout << "비가 내리기 시작했다!\n"; ps[2] = 1;//필드를 비 상태로 만듬 ps[3] = 5;//비 상태 카운트. 0이 되면 비가 끝남 for (int i = 4; i < 10; i++) ps[i] = 0; //기존의 날씨는 없어지므로 0으로 바꿈. } } if (p[pp][0][12] == "모래날림") { //마기라스의 모래날림. 날씨를 모래바람 상태로 만듬 if (ps[8] != 1) { //현재 날씨가 모래바람 상태가 아닐때만 발동 cout << "[특성 모래날림]\n"; cout << "모래바람이 불기 시작했다!\n"; ps[8] = 1;//필드를 모래바람 상태로 만듬 ps[9] = 5;//지속시간 카운트. 0이 되면 비가 끝남
마기라스의 "모래날림"처럼
등장하면 날씨가 변화하는 가이오가의 "잔비" 특성
코드를 배껴 값만 바꿔준다.
그 다음 바위타입의 특방이 1.5배 오르는 파트.
for(int i = 1; i < 4; i++) { if (p[i][0][1] == "바위" || p[i][0][2] == "바위") { p[i][11][13] = to_string(stoi(p[i][11][13]) * 3 / 2); p[i][0][7] = to_string(stoi(p[i][0][7]) * 3 / 2); } if (k[i][0][1] == "바위" || k[i][0][2] == "바위") { k[i][11][13] = to_string(stoi(k[i][11][13]) * 3 / 2); k[i][0][7] = to_string(stoi(k[i][0][7]) * 3 / 2); } }
필드 위 두 포켓몬의 타입중 하나라도 바위라면
현재 특방과 고유 특방을 1.5배로 한다.
고유값은 랭크 변화가 적용 안된 값,
현재값은 랭크 변화가 적용된 값인데
어차피 1.5배 되는건 똑같으므로 둘다 1.5를 곱해준다.
사실 처음엔 이걸 어떻게 구현할까 고민을 많이했다.
랭크 변화 외에 능력치가 증가하는 경우는
위의 스카프, 돌격조끼처럼 아이템으로 오르는 경우와 모래바람 2가지 뿐이다.
이때 아이템으로 인한 능력치 증가는 "처음부터" 능력치가 올라가 있으므로
그냥 코드 시작할때 "고유" 능력치를 한번 올려주면 끝난다.
근데 모래바람으로 인한 특방 증가는, 게임 "도중에" 능력치가 상승한다.
게임 도중에 "고유" 능력치만 올리면,
현재 능력치엔 이게 적용되지 않는다.
for(int i = 1; i < 4; i++) { if (p[i][0][1] == "바위" || p[i][0][2] == "바위") { p[i][11][13] = to_string(stoi(p[i][11][13]) * 3 / 2); 랭크(p, i, "특방", 0, 1); } if (k[i][0][1] == "바위" || k[i][0][2] == "바위") { k[i][11][13] = to_string(stoi(k[i][11][13]) * 3 / 2); 랭크(k, i, "특방", 0, 0); } }
그렇기에, 처음에는 고유 능력치를 1.5배로 올리고
랭크 변화값을 0으로 랭크 변화 함수만 호출해서
기존의 랭크 변화 수치를 적용하는 방식으로 했는데...
생각해보니 랭크변화나 모래바람 특방 증가나 어차피 곱적용이라
최종적으로 1.5배 되는건 똑같으므로 그냥 1.5배 곱해주면 됐었다.
이걸 지금 글 쓰면서 깨달아서 수정했다
바보같았네.
그리고 필드 위 바위 타입의 특방을 1.5배 올리고,
필드가 모래바람일떄 교체해서 나온 바위 타입의 특방을 1.5배 올리는 코드를
교체함수에 따로 작성하려 했는데
그냥 모래바람을 퍼뜨릴때 모든 바위타입 포켓몬의 특방을 1.5배로 해버리면
더 간단하게 되더라.
충분히 생각하고 코드를 짰어야했는데.
오늘은 어쩐지 아쉽다.
void 모래바람캔슬(string p[][one][two], string k[][one][two]) { for (int i = 1; i < 4; i++) { if (p[i][0][1] == "바위" || p[i][0][2] == "바위") { p[i][11][13] = to_string(stoi(p[i][11][13]) * 2 / 3); 랭크(p, i, "특방", 0, 1); } if (k[i][0][1] == "바위" || k[i][0][2] == "바위") { k[i][11][13] = to_string(stoi(k[i][11][13]) * 2 / 3); 랭크(k, i, "특방", 0, 0); } } }
그리고 모래바람이 끝날때
모든 바위 타입의 특방을 다시 1.5로 나눠 원래대로 되돌린다.
모래바람이 없어지는 경우는
지속시간이 다 지날때, 다른 날씨로 바뀔때인데
날씨가 4개에 모래바람 빼면 3개이므로 총 4가지 경우이다.
4번 복붙하기는 싫으므로 함수로 따로 써서 필요할때마다 호출해주자.
if (ps[2] == 1) { ps[3] -= 1; if (ps[3] == 0) { printf("비가 그쳤다!\n"); ps[2] = 0; } } //날씨가 비 상태이면 //남은 비 턴을 1 깎음 //해당 값이 0이 되면 비 날씨를 없앰 if (ps[8] == 1) { ps[9] -= 1; if (ps[9] == 0) { printf("모래바람이 멎었다!\n"); ps[8] = 0; 모래바람캔슬(p, s); } } //모래바람.
지속시간이 다되서 끝나는 경우는
메인함수의 "비" 날씨가 끝날때 날씨가 없어지는 파트를 복붙하여
방금 만든 함수 하나 추가로 호출하면 되고
if (p[pp][0][12] == "잔비") { //가이오가의 잔비, 날씨를 비 상태로 만듬 if (ps[2] != 1) { //현재 날씨가 비 상태가 아닐때만 발동 cout << "[특성 잔비]\n"; cout << "비가 내리기 시작했다!\n"; ps[2] = 1;//필드를 비 상태로 만듬 ps[3] = 5;//비 상태 카운트. 0이 되면 비가 끝남 if(ps[8]==1){ 모래바람캔슬(p, k); } for (int i = 4; i < 10; i++) ps[i] = 0; //기존의 날씨는 없어지므로 0으로 바꿈. } }
"즉발특성" 함수의 다른 날씨로 바꾸는 특성에도 해당 함수를 추가해준다.
이제 남은건 매턴 주는 데미지와 아침햇살 힐량 감소
if (skillname == "날개쉬기" || skillname =="HP회복" || skillname == "아침햇살") { //날개쉬기 : 체력을 절반 회복한다. if (plife[pn] == stoi(p[pn][0][3])) { printf("더이상 회복할 수 없다!\n"); }//이미 풀피면 회복할 수 없다. else { if (k == 0)cout << "상대 "; cout << p[pn][0][11] << "의 체력이 회복되었다! ("; cout << plife[pn]; int hill = stoi(p[pn][0][3]) / 2; //회복량은 최대 체력의 절반 if (skillname == "아침햇살" && (ps[2] == 1 || ps[8] == 1)) hill /= 2; //날씨가 비나 모래바람이면 아침햇살의 회복량은 절반이됨
"변화스킬" 함수의 아침햇살은 체력회복기이지만 날씨에 따라 힐량이 감소하는데
날씨가 "비"나 "모래바람"이면 힐량이 절반이된다
즉 "비"를 구현할떄 구현해놨으므로 조건문에 추가만 해주면 된다.
if (plife[pp] > 0 && ps[8]==1 && (p[pp][0][1]!="바위" && p[pp][0][2] != "바위" && p[pp][0][1] != "강철" && p[pp][0][2] != "강철" && p[pp][0][1] != "땅" && p[pp][0][1] != "땅")) { printf("모래바람이 "); if (k == 0) cout << "상대 "; cout << p[pp][0][11] << t1(p, pp) << "덮쳤다! ("; ccd = stoi(p[pp][0][3]) / 16; if (ccd > plife[pp]) { ccd = plife[pp]; } cout << plife[pp] << "-" << ccd << "="; plife[pp] -= ccd; // 독 데미지는 최대 체력의 1/8 cout << plife[pp] << ")\n"; 자뭉열매(p, pp, s, ss, plife); if (plife[pp] <= 0) { cout << p[pp][0][11] << s1(p, pp) << "쓰러졌다!\n"; } }
마지막 매 턴 최대체력 1/16의 데미지를 입는 함수.
역시나 배틀이 끝난 다음 발생하는 이벤트이므로 '후처리" 함수에서 처리해준다.
조건문으로 포켓몬의 타입이 바위, 강철, 땅인지 확인하고
아니면 데미지를 준다.
모래바람 하나만 구현하면 되서 금방 끝날줄 알았는데,
생각보다 신경쓸게 많아서 좀 오래걸렸다.
무엇보다 그냥 1.5배 곱해버리면 끝나는걸 괜히 복잡하게 생각했다가 시간만 버렸는데
오늘은 좀 아쉽다.
'포켓몬 배틀 구현' 카테고리의 다른 글
스무번째 포켓몬, 파이어로 구현 (질풍날개) (0) 2022.03.26 열여덟번째 포켓몬, 대짱이 구현 (스텔스록, 자뭉열매) (0) 2022.03.25 열일곱번째 포켓몬, 트리토돈 구현 (하품, 잠듦) (0) 2022.03.25 열여섯번째 포켓몬, 무한다이노 구현 (프레셔) (0) 2022.03.25 열다섯번째 포켓몬, 맘모꾸리 구현 (연속기) (0) 2022.03.25