[JS] 로그라이크 게임과제 - 1일차

GDORI·2024년 8월 21일
0

JavaScript

목록 보기
24/28

구현 목록

  1. attack 클래스 메서드 구현
    1.1 attack 클래스 메서드는 최종 공격값을 반환한다.
    1.2 최소 공격력과 최대공격력 사이 랜덤한 값이 최종 공격력이다.
attack() {
    return Math.floor(Math.random() * (this.maxAtt-this.minAtt+1)) + this.minAtt;
  }
  1. Player stageAbility 클래스 메서드 구현
    2.1 체력은 스테이지 성공시마다 0~100 랜덤숫자에서 스테이지를 나눈 값을 얻는다.
    2.2 플레이어 최소 공격력, 최대 공격력이 현재 체력대비 0.1~0.2배(랜덤)/최종값 정수로 오른다.
    2.3 스테이지 성공보상을 출력하고 반영한다.
async stageAbility(stage){
    //체력은 스테이지에 비례하여 증가함. 랜덤(0 ~ 100) / 스테이지
    const addHp = Math.floor( (Math.random()*101) / stage );
    this.hp += addHp;
    // 공격력은 현재 체력대비 * 0.1~0.2 배 상승 
    const addAtt = Math.floor(this.hp * (Math.floor(Math.random()*11+10) /100));
  	// 성공보상 출력 및 보상 반영
    console.log(`스테이지 성공보상으로 체력이 ${addHp}만큼 증가, 공격력이 ${addAtt} 만큼 증가하였습니다!! `)
    this.minAtt += addAtt;  
    this.maxAtt += addAtt;
  }
  1. Monster stageAbiliy 클래스 메서드 구현
    3.1 체력은 매 스테이지마다 기본 체력(50) + (stage-1) 60 으로 설정된다.
    3.2 공격력은 매 스테이지마다 기본공격력(1~5) + (stage-1)
    3 으로 설정된다.
stageAbility(stage){
  // 기본 체력 및 공격력에서 스테이지 비례한 값을 증감 후 대입
    this.hp += (stage-1)*60;
    this.minAtt += (stage-1)*3;
    this.maxAtt += (stage-1)*3
  }
  1. displayStatus 정보 추가
    4.1 호출될 당시 스테이지 정보, 플레이어의 체력, 공격력, 몬스터의 체력, 공격력이 출력된다.
function displayStatus(stage, player, monster) {
  console.log(chalk.magentaBright(`\n=== Current Status ===`));
  console.log(
    chalk.cyanBright(`| Stage: ${stage} `) +
    chalk.blueBright(
      `| 플레이어 정보 : 체력 - ${player.hp}`,
      `| 공격력 - ${player.minAtt}~${player.maxAtt}`
    ) +
    chalk.redBright(
      `| 몬스터 정보 : hp - ${monster.hp}|`,
      `| 공격력 - ${monster.minAtt}~${monster.maxAtt}`
    ),
  );
  console.log(chalk.magentaBright(`=====================\n`));
}
  1. 전투기능 구현(battle 함수)
    5.1 공격시 attack 메서드를 호출하여 반환된 값을 변수에 담고 상대 객체에 반영 후 결과를 출력한다.
    5.2 더블공격시 10%확률로 공격메서드를 2번 호출한다. 90% 확률로 공격 못하고 뚜까 맞는다.
    5.3 기도메타시 5% 확률로 몬스터 체력을 0으로 만들어 다음 스테이지로 진행한다.
    5.4 플레이어의 체력을 확인하여 0 아래일 경우 게임을 종료한다.
const battle = async (stage, player, monster) => {
  let logs = [];
  // 기도메타 잔여 횟수 저장
  let prey = 1;
  // 플레이어나 몬스터 둘중 하나 죽을때까지 반복
  while(player.hp > 0 && monster.hp > 0) {
    console.clear();
    
    displayStatus(stage, player, monster);
    console.log("두둥탁. 몬스터가 등장했어요!");
    logs.forEach((log) => console.log(log));

    console.log(
      chalk.green(
        `\n1. 공격한다 2. 연속공격(10% 확률) 3.기도메타(5% 확률 / 잔여:${prey}회)`,
      ),
    );
    
    // switch 구문을 통해 선택한 행동 처리
    function battleInput() {
      const choice = readlineSync.question('당신의 선택은?');

      switch (choice) {
        // 일반공격
          case '1':
              const attP = player.attack(); 
              const attM = monster.attack();
              monster.hp -= attP;
              logs.push(chalk.green(`[${hour}:${new Date().getMinutes()}:${new Date().getSeconds()}] 몬스터에게 ${attP} 만큼 피해를 입혔습니다.`));
              player.hp -= attM;
              logs.push(chalk.red(`[${hour}:${new Date().getMinutes()}:${new Date().getSeconds()}] 몬스터로부터 ${attM} 만큼 피해를 받았습니다.`));
              break;
          // 10% 확률로 공격 2번 진행, 실패 시 플레이어만 뚜까 맞음.
          case '2':
              const ddRand = Math.floor(Math.random()*101);
              if(ddRand <= 10){
                logs.push(chalk.blue(`-------------------------------------------`));
                logs.push(chalk.blue(`더블공격 성공!`));
                let attP = player.attack();
                monster.hp -= attP;
                logs.push(chalk.blue(`[${hour}:${new Date().getMinutes()}:${new Date().getSeconds()}] 몬스터에게 ${attP} 만큼 피해를 입혔습니다.`));
                attP = player.attack();
                monster.hp -= attP;
                logs.push(chalk.blue(`[${hour}:${new Date().getMinutes()}:${new Date().getSeconds()}] 몬스터에게 ${attP} 만큼 피해를 입혔습니다.`));
                logs.push(chalk.blue(`-------------------------------------------`));
              }else{
                const attM = monster.attack();
                player.hp -= attM;
                logs.push(chalk.red(`-------------------------------------------`));
                logs.push(chalk.red(`더블공격 실패....`));
                logs.push(chalk.red(`[${hour}:${new Date().getMinutes()}:${new Date().getSeconds()}] 몬스터로부터 ${attM} 만큼 피해를 받았습니다.`));
                logs.push(chalk.red(`-------------------------------------------`));
              }
              break;
          // 기도메타. 5% 확률로 몬스터의 피를 0으로 만들고 다음 스테이지로 진행
          case '3':
              const rand = Math.floor(Math.random()*101);
              if(prey===1 && rand<=5){
                monster.hp=0;
                console.log("오 신께서 대신 몬스터를 물리치셨습니다. 다음 스테이지로 이동합니다.");
              }
              
              else if(prey !== 1){
                logs.push(chalk.red(`헤이, 헤이! 기도메타는 한번 뿐이라고.`));
              }
              
              else{
                logs.push(chalk.red(`기도메타가 실패하였습니다.. 이어서 싸우십시요.`));
                prey --;
              }
              break;
              
          default:
              console.log(chalk.red('올바른 선택을 하세요.'));
              battleInput(); // 유효하지 않은 입력일 경우 다시 입력 받음
              break;
      }
  }
  battleInput();


  }
  // 위 반복문이 끝났다는 것은 플레이어나 몬스터가 죽었다는 뜻.
  // 누가 죽었는지 판별해서 조건 
  if(player.hp < 0){
    console.log(chalk.red("플레이어가 죽었습니다. 게임을 종료합니다."),);
    process.exit();
  }else{
    console.log(chalk.blue("몬스터를 물리쳤습니다! 잠시 후 다음 스테이지로 이동합니다."),);
  }
  
};
  1. startGame 함수 구현
    6.1 반복문 초반 몬스터 객체 생성 후 stageAbility 메서드를 호출하여 초기화 시킨다.
    6.2 스테이지를 깼을 경우 플레이어의 stageAbility 메서드를 호출하여 게임에 반영한다.
    6.3 stageAbility 내 반영결과 출력문을 확인하기 위해 3초간 wait한다.
export async function startGame() {
  console.clear();
  const player = new Player(); // 플레이어 객체 생성
  let stage = 1;
  
  while (stage <= 10) {
  // 스테이지 시작할 때마다 Monster 객체 생성
    const monster = new Monster(stage);
    monster.stageAbility(stage);
    await battle(stage, player, monster);
    // battle 함수 내에서 플레이어의 체력이 0이 되었을경우 바로 종료하기 때문에, 승리했을 경우를 실행.
    stage++;
    await player.stageAbility(stage);

    // setTimeout은 promise를 반환하지 않기 때문에 await이 작동하지 않음. 따라서 wait 함수를 작성하여 사용.
    // wait 함수는 전역에 위치
    await wait(3000);
  }

  console.log("모든 스테이지를 무찌르셨습니다! 축하드립니다.")

}

오늘 작업물 결과

profile
하루 최소 1시간이라도 공부하자..

0개의 댓글