콘텐츠로 이동

조건문 (Conditional Statements)

epScript의 조건문은 파이썬·자바스크립트와 같습니다. if, else if, else 구문과 논리 연산자 &&, ||, !를 사용해 분기합니다. &&/||는 단락 평가(Short‑circuit)를 하므로 조건의 순서에 따라 성능과 동작이 달라질 수 있습니다.

기본 형태

if (조건식) {
    // 조건식이 참일 때 실행
} else if (다른_조건식) {
    // 앞의 if가 거짓이고, 이 조건식이 참일 때 실행
} else {
    // 모든 조건이 거짓일 때 실행 (선택)
}
  • 조건식에는 비교문 또는 비교문으로 해석 가능한 표현식을 넣습니다.
  • 블록은 { ... }로 묶습니다. 한 줄이라도 가독성을 위해 {} 사용을 권장합니다.
var hp = 35;

if (hp <= 0) {
    simpleprint("Dead");
} else if (hp < 30) {
    simpleprint("Critical");
} else if (hp < 60) {
    simpleprint("Wounded");
} else {
    simpleprint("Healthy");
}

비교 연산과 진릿값

  • 비교: ==, !=, <, >, <=, >=
  • 논리: &&(그리고), ||(또는), !(부정)
var a = 10;
var b = 5;

if (a > b && a - b >= 5) {
    simpleprint("OK");
}

if (!False) {
    simpleprint("True로 평가됨");
}

Warning

=는 대입(assignment)입니다. 비교는 ==를 사용하세요.

var x = 0;
if (x = 1) { // 잘못된 예: 컴파일 에러
    ...
}

단락 평가(Short‑Circuit)

&&||는 필요할 때만 오른쪽 피연산자를 평가합니다.

  • A && B: A가 거짓이면 B는 평가하지 않음(결과는 거짓)
  • A || B: A가 참이면 B는 평가하지 않음(결과는 참)
function isExpensive() {
    simpleprint("비싼 검사 수행");
    return True;
}

var alive = False;

// alive가 거짓이므로 오른쪽은 평가하지 않음
if (alive && isExpensive()) {
    simpleprint("실행되지 않음");
}

var ready = True;

// ready가 참이므로 오른쪽은 평가하지 않음
if (ready || isExpensive()) {
    simpleprint("빠르게 통과");
}

성능을 위한 조건 순서

  • &&에서는 실패(거짓) 가능성이 높고 계산이 싼 조건을 왼쪽에 둡니다.
  • ||에서는 성공(참) 가능성이 높고 계산이 싼 조건을 왼쪽에 둡니다.
  • 이렇게 하면 불필요한 계산을 피할 수 있습니다.

예시: 조건 순서에 따른 차이

function isBossInArea(unit) {
    // 매우 비싼 판정이라고 가정
    return l2v(Bring(...));
}

function isBoss(unit) {
    // 값싼 판정: 바로 확인 가능
    return unit.ammo > 0;
}

// 비효율적인 순서: 매번 비싼 검사를 먼저 수행
if (isBossInArea(u) && isBoss(u)) {
    simpleprint("공격!");
}

// 더 나은 순서: 값싼 조건을 먼저 확인하여 단락 유도
if (isBoss(u) && isBossInArea(u)) {
    simpleprint("공격!");
}

switch

클래식 스타 트리거에서는 else 자체를 직접 구현할 수 없습니다. 반면 if(조건) 개념은 트리거의 근간이므로 epScript의 if/else if는 이해만 되면 활용이 어렵지 않습니다. 특히 ifelse if 사슬을 잘 구성하면

  • 어떤 분기에서 한 번 참을 만나면 뒤의 else if들은 평가하지 않으므로, 불필요한 비교를 피할 수 있습니다.
  • 즉, “참일 확률이 높거나 값싼 검사”를 앞쪽에 두는 것만으로도 성능 이점을 얻습니다.

이 때문에 “if/else만 알면 switch는 굳이 배울 필요가 없다”고 느낄 수 있지만, epScript의 switch는 더 강력한 형태를 제공합니다.

epScript의 switch(state, bitmask)

epScript는 switch(state, bitmask) 형태와 epd 를 읽고 비교하는 epdswitch(epd, bitmask)를 지원합니다. 스타 트리거에는 Memory, SetMemory는 있지만 일반적인 의미의 GetMemory는 없습니다. 실전에서는 “메모리 값을 읽어오는 행위” 자체가 비용이 큽니다(자료형 섹션에서 한 번 다뤘던 주제). bitmask는 다음 이점을 제공합니다.

  • 읽기 범위를 비트 단위로 제한하여 “안 읽어도 되는 부분”을 명시합니다.
  • epdswitch는 값 읽기와 비교를 한 번에 수행하므로, bread_epd/wread_epd/dwread_epd로 값을 읽고 다시 비교하는 패턴보다 빠릅니다.

사용 예시

아래는 유닛 상태가 저장된 메모리 영역 중 필요한 하위 바이트만 마스크로 제한하여 빠르게 분기하는 예시입니다.

function getUnitSkillRange(epd){
    var unit;
    var skill_range;

    // unitTpye: epd + 0x64 위치, 하위 1바이트만 필요하므로 0xFF
    epdswitch(epd + 0x64 / 4, 0xFF) {
        case 2: {
            // 예: 2 == Ghost
            unit = 2;
            skill_range = 100;
            break;
        }
        case 64: {
            // 예: 64 == 질럿
            unit = 64;
            skill_range = 15;
            break;
        }
        default: {
            unit = 0;
            skill_range = 0;
            break;
        }
    }
}
// 이후 로직에서 unit/skill_range 사용
if (unit != 0 && skill_range > 0) {
    simpleprint("선택된 unit=", unit, ", range=", skill_range);
}

동일한 분기를 if/else if 사슬로 작성하면, 매 분기마다 값을 읽고 비교하는 비용이 누적될 수 있습니다. 반면 epdswitch는 “읽기+비교”를 한 번에 처리하고, bitmask로 필요한 비트만 제한하여 불필요한 읽기를 줄입니다.

if/else vs epdswitch 선택 가이드

  • 값이 이미 지역 변수로 있고 비교만 하면 되는 경우: if/else if가 간단하고 빠릅니다.
  • 메모리/EPD에서 직접 값을 판별해야 하는 경우: epdswitch(epd, bitmask)로 “읽기+비교”를 한 번에 처리하세요.
  • bitmask는 필요한 비트만 읽도록 범위를 좁혀 성능을 챙겨줍니다.