프론트엔드✏️/코드캠프

알고리즘 - 크레인 인형뽑기 게임

당근먹는하니 2022. 6. 22. 15:48
728x90
반응형

 

게임개발자인 "죠르디"는 크레인 인형뽑기 기계를 모바일 게임으로 만들려고 합니다.
"죠르디"는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.

https://programmers.co.kr/learn/courses/30/lessons/64061

function solution(board, moves) {
    var answer = 0;
  let basket = [];
  // 1번 뽑을거ㄱ야야ㅑ야야 왜이래 
  for(let j = 0; j<moves.length; ++j ){
    for(let i = 0; i<board.length; ++i) {
    if(board[i][moves[j]-1]) {
      basket.push(board[i][moves[j]-1])
      board[i][moves[j]-1]=0 // 뽑았다!
      break;} 
  	}
  }
  // 바구니에 담았다아아아!!!!! i랑 j바꿔줘야 하지만 일단 ㄱㄱ
  for(let i =0; i < basket.length; ++i ) {
    // while(basket[i]===basket[i+1]) {
      while(basket[i]===basket[i+1]) {
    	if(basket[i]===basket[i+1]) {
        basket.splice(i, 2)
      }
    	}  
  }
 //    for(let i = 0; i<moves.length; ++i) {
 // console.log(board.map((el)=> console.log(el[0]===moves[i])))    
 //  }
  console.log(board)
  console.log(basket);
    return answer;
}

solution(
  [[0,0,0,0,0],
   [0,0,1,0,3],
   [0,2,5,0,1],
   [4,2,4,4,2],
   [3,5,1,3,1]], 
  [1,5,3,5,1,2,1,4]);

바구니에 차곡차곡 담는 것까지 했는데, 

 

function solution(board, moves) {
  let basket = [];
  for(let j = 0; j<moves.length; ++j ){
    for(let i = 0; i<board.length; ++i) {
    if(board[i][moves[j]-1]) {
      basket.push(board[i][moves[j]-1])
      board[i][moves[j]-1]=0 // 뽑았다!
      break;} 
  	}
  }
  // 바구니에 담았다아아아!!!!! i랑 j바꿔줘야 하지만 일단 ㄱㄱ

  let count = 0; 
  for(let i = 0; i < basket.length; ++i) {
    if(basket[i]===basket[i+1]) {
  		  basket.splice(i,2);
        i = 0;
      count += 2;
      }
  }
    return count;
}

제거까지 했다고 생각했는데

제출하니 테스트 케이스 1, 2번 실패

 

뽑으러 갔을 때 뽑을 게 없을 때는 아무것도 push 안해야한다!!!! 아니 그렇게 한 것 같은데...

그럼 뭐지

 

1, 1, 1, 1 이렇게 쌓였을 때

1, 1이 사라지지 않는다. 왜지

 

2, 2로 넣어도 다음 1, 1은 사라지지 않는다.

0번 인덱스랑 1번 인덱스에 있는 걸 다시 검사 안하나?

내가 아무리 i=0으로 초기화해도 포문으로 다시 들어갈 때 ++i 돼서! 

그래서 i = 0 으로 초기화 안 하고 i = -1로 초기화했다.ㅎㅎ

 

function solution(board, moves) {
  let basket = [];
  // i랑 j 순서가 바뀐 건 아는데 i 먼저쓰고 j를 나중에 써서 순서가 이렇씁니다... 
  for(let j = 0; j<moves.length; ++j ){
    for(let i = 0; i<board.length; ++i) {
    if(board[i][moves[j]-1]!==0) {
      basket.push(board[i][moves[j]-1])
      board[i][moves[j]-1]=0 // 뽑았다!
      break;} 
  	}
  }

  let count = 0; 
  for(let i = 0; i < basket.length; ++i) {
    if(basket[i]===basket[i+1]) {
  		  basket.splice(i,2);
        i = -1;
      count += 2;
      }
  }
    return count;
}

 


멘토님 풀이

 

1. 크레인이 이동하는 위치값을 구하는 반복문

2. 크레인이 이동해서 뽑아올 수 있는 인형의 위치값을 구하는 반복문 

3. doll이라는 상수값에 크레인이 잡아오는 위치값들을 찍음

4. 0 0 0 하고 내려가다가 0이 아닌 수를 만나면 바구니에 넣으면 된다. 

5. 인형을 뽑은 자리는 다시 0으로 만들어준다. 

---여기서 크레인을 멈추지 않으면 아래칸까지 계속 인형을 들어올린다. 

6. 멈춰주는 로직 : break; 

7. 바구니 맨 윗칸의 인형이 지금 넣으려는 인형과 같으면 없앨 것임 

 -> if(bucket[bucket.length-1] === doll) { bucket.pop(); break; }

 

 문제를 이차원 배열 형태로 받아오고 있을 때, 격자각 형태 문제가 많다. 이때는 x,y 좌표로 접근하면 문제 풀 때 조금 더 수월하다. 

 

 

1. moves에 forEach

2. board에 forEach

3. 인형이 빈칸이 아니라면, 인형을 뽑는다. ( 바구니에 push, 인형의 위치를 0 으로 ) 

4. 인형을 뽑았으면 크레인을 멈춘다. ( forEach에서 break?! 안됨. 스위치 변수가 필요함 ) 

* stop이라는 boolean값 세팅, 반복문을 실행할 때 해당 로직을 실행하지 않게 하는 변수 

  stopr값이  true가 될 때, 조건문이 작동을 멈춘다. 

  조건식으로 감싼 후, stop이 false일때만 실행되게끔 한다. 그 조건식 안에서 멈추고 싶은 곳에서 stop을 true로 만든다. 

  ! 반복문은 계속 도는데, 실행이 안되는 것뿐!

5. bucket의 제일 윗 인형(맨 마지막칸)과 넣으려는 게 같다면 제거한다. ( pop, splice ) 

6. 맨 마지막에 인형을 push하고 있으니 break를 걸어야하는데, 이때는 else문으로 '인형 넣는 로직'을 뺀다. 

 

어렵다 

728x90
반응형