코딩도장

서양 중세 주사위 게임 : 킹덤 컴 딜리버런스(Kingdom come deliverance)

서양 중세를 실제 배경으로 한 게임 Kingdom come deliverance에서는 다음과 같은 규칙의 주사위 게임이 등장한다.

1부터 6까지 적힌 여섯 면의 주사위 6개가 주어지고, 이것을 무작위로 한 번에 다 던진다. 다음과 같은 규칙에 따라 점수를 획득하여 목표 점수에 먼저 도달한 사람이 게임에 이긴다.

윗면의 숫자가

(1) 1 하나 당 점수 100을 더한다. 그러나 1이 3개라면 1000을 더한다. 여기서 4개, 5개, 6개이면 각각 x2를 한다(4개 = 2000, 5개 = 4000, 6개 = 8000).

(2) 5 하나 당 점수 50을 더한다. 5가 3개이면 500을 더한다. 여기서 위와 같이 4개, 5개, 6개이면 각각 1000, 2000, 4000이 된다.

(3) 2, 3, 4, 6이 각각 3개이면 해당 숫자의 x100한 값을 더한다. 예) 3이 3개 = 300, 6이 3개 = 600. 위와 비슷하게 같은 숫자가 3개보다 많으면 하나 당 곱하기 2를 한다. 예) 3이 4개 = 600. 6이 5개 = 2400

(4) 숫자 1, 2, 3, 4, 5의 조합은 750, 그리고 2, 3, 4, 5, 6은 1250, 또 1, 2, 3, 4, 5, 6은 2000을 더한다.

(5) 한 턴에 6개 모든 주사위로 점수를 획득하면 주사위를 한 번 더 굴릴 수 있는 선택이 주어진다. 예를 들어 1) 1,2,3,4,5 + 1이면 750점 + 100점을 얻고 모든 주사위를 한 번 더 굴려서 점수를 더 얻을 수 있다. 여기서 턴을 종료하면 850점을 얻고, 주사위를 한 번 더 굴렸으나 어떠한 조합도 나오지 않는 "꽝"이 나오면 이전에 얻은 점수를 모두 날리고 0점으로 초기화 되며, 턴은 종료 된다.

이 규칙을 구현해보시오. 인풋은 Array 형태로 주어지고, 되도록이면 알고리즘 내에서 Array의 숫자 순서를 재배열해서는 안된다. 6개 숫자 생성은 Pseudo-random-number generator를 사용하여 무작위로 생성할 수 있다. 예) Python - Random library. 목표 점수는 사용자가 임의로 지정하면 된다.

입력 - 출력 예) [1, 3, 2, 6, 2, 2] -> 200(2가 3개) + 100(1이 1개) = 300점

 [3, 6, 6, 3, 4, 2] -> 0점
 [2, 6, 1, 1, 6, 3] -> 200점
 [1, 5, 2, 3, 6, 4] -> 2000점
 [3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4] -> 0점
 [5, 2, 1, 2, 5, 2] -> 400점
 [1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4] -> 800 +たす 450 +たす 900 = 2150

킹덤 컴 딜리버런스 2가 나온다길래 생각이 나서 올려보았습니다, 재미있게 풀어보세용~

(追記) (追記ここまで)
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

1개의 풀이가 있습니다.

Java 뉴비의 코드입니다

package kingdom_come_deliverance;
public class Die {
 int num; //주사위의 눈
 boolean used; //주사위가 점수 도출에 이용되었는지 여부
 public Die(int num) {
 this.num = num;
 this.used = false;
 }
}

package kingdom_come_deliverance;
import java.util.Random;
public class DieGenerator { //랜덤으로 주사위 6개의 배열 만듦
 Random random = new Random();
 public Die[] getDice() {
 Die[] dice = new Die[6];
 for (int i = 0; i < 6; i++) {
 dice[i] = new Die(random.nextInt(6) + 1);
 }
 return dice;
 }
}

package kingdom_come_deliverance;
//import java.security.PublicKey;
//주석은 테스트용 코드
public class Main {
 public static void main(String[] args) {
 // TODO Auto-generated method stub
 /*ScoreCounter sc = new ScoreCounter();
 DieGenerator dg = new DieGenerator();*/
 Player player = new Player();
 int limit = 10000; //최대 점수
 int score = 0; //누적 점수
 /*int[] seed = {1, 5, 2, 3, 6, 4};
 Die[] dice = new Die[6];
 for (int i = 0; i < 6; i++) {
 dice[i] = new Die(seed[i]);
 }
 Result result = sc.countScore(dice);
 System.out.println("score: " + result.score);*/
 while(true) {
 score += player.play(0, 0);
 System.out.println("현재 점수: " + score);
 System.out.println("");
 if(score >= limit) {
 System.out.println("성공!");
 break;
 }
 }
 }
}

package kingdom_come_deliverance;
import java.util.Scanner;
public class Player {
 ScoreCounter sc = new ScoreCounter();
 DieGenerator dg = new DieGenerator();
 Scanner scanner = new Scanner(System.in);
 int play(int streak, int acc) { //streak: 연속 플레이 횟수, acc: 누적 점수
 Die[] dice = dg.getDice();
 for (Die die : dice) {
 System.out.print(die.num); //주사위 배열 표시
 }
 System.out.println("");
 System.out.println("현재 연속: " + streak);
 Result result = sc.countScore(dice); //점수 계산 결과 추출
 if(streak != 0 && !result.combo) { //5번 조건에서 조합 실패 시
 System.out.println("실패!");
 return 0; //연속 플레이의 점수가 모두 0으로 처리됨
 }
 if(result.again) { //모든 주사위가 점수 도출에 쓰인 경우
 System.out.println("계속 하시겠습니까?(O: 0, X: 1)"); //연속 여부 입력
 if(scanner.nextInt() == 0) {
 return play(streak + 1, acc + result.score);
 //재귀함수를 이용해서 연속 플레이를 구현했습니다.
 }
 }
 return result.score;
 }
}

package kingdom_come_deliverance;
public class Result { //점수, 연속 플레이 여부, 조합 여부를 묶어서 전달
 int score; //조합 점수
 boolean again; //연속 플레이가 가능한지 여부
 boolean combo; //조합이 나왔는지 여부
 public Result(int score, boolean again) {
 this(score, again, true);
 }
 public Result(int score, boolean again, boolean combo) {
 this.score = score;
 this.again = again;
 this.combo = true;
 }
}

package kingdom_come_deliverance;
import java.util.ArrayList;
import java.util.List;
public class ScoreCounter {
 static final int[] scoreModel1 = {0, 100, 200, 300, 1000, 2000, 4000};
 //1의 눈에 대한 점수 배율
 static final int[] scoreModel2 = {0, 10, 20, 30, 100, 200, 400};
 //5의 눈에 대한 점수 배율
 static final int[] scoreModel3 = {0, 0, 0, 100, 200, 400, 800};
 //2, 3, 4, 6의 눈에 대한 점수 배율
 public Result countScore(Die[] dice) {
 int score = 0;
 List<List<Die>> count = new ArrayList<List<Die>>();
 //1~6까지 각각의 눈이 나온 주사위의 리스트
 for (int i = 0; i < 6; i++) {
 count.add(new ArrayList<Die>());
 }
 for (Die die : dice) {
 count.get(die.num - 1).add(die);
 }
 //4번 조건 검사
 boolean cond1 = true; //1, 2, 3, 4, 5
 boolean cond2 = true; //2, 3, 4, 5, 6
 boolean cond3 = true; //1, 2, 3, 4, 5, 6
 int twice = -1; //cond1, cond2일 때 두 번 나온 눈이 무엇인지 확인
 for (int i = 0; i < 6; i++) {
 List<Die> list = count.get(i);
 if(list.size() == 0) { //하나라도 없는 눈이 있으면 cond3 위배
 cond3 = false;
 if(i != 0) { //1 제외 없는 눈이 있으면 cond2 위배
 cond2 = false;
 }
 if(i != 5) { //6 제외 없는 눈이 있으면 cond1 위배
 cond1 = false;
 }
 }
 else if(list.size() == 2) {
 twice = i;
 }
 }
 if(cond3) {
 score += 2000;
 return new Result(score, true);
 }
 else if(cond2) {
 score += 1250;
 if(twice == 4) {
 score += 50;
 return new Result(score, true); //두 번 나온 값이 5이면 모두 사용
 }
 else {
 return new Result(score, false);
 }
 }
 else if (cond1) {
 score += 750;
 if(twice == 0) {
 score += 100;
 return new Result(score, true);
 }
 else if(twice == 4) {
 score += 50;
 return new Result(score, true);
 }
 else {
 return new Result(score, false);
 }
 //두 번 나온 값이 1 또는 5이면 모두 사용
 }
 //1, 2, 3번 조건 검사
 boolean combo = false;
 for (int j = 0; j < 6; j++) {
 boolean used = false; //해당 눈의 주사위들이 사용되었는지 여부
 int size = count.get(j).size();
 int[] scoreModel = new int[6];
 switch (j) {
 case 0: //1의 눈의 개수
 if(size > 0) {
 used = true;
 scoreModel = scoreModel1;
 }
 break;
 case 4: //5의 눈의 개수
 if(size > 0) {
 used = true;
 scoreModel = scoreModel2;
 }
 break;
 default: //2, 3, 4, 6의 경우
 if(size > 2) {
 used = true;
 scoreModel = scoreModel3;
 }
 break;
 }
 score += scoreModel[size]*(j+1);
 for (Die die : count.get(j)) {
 if(used) {
 die.used = true;
 combo = true;
 }
 }
 }
 for (Die die : dice) {
 if(!die.used) { //하나라도 사용되지 않은 주사위가 있으면 다시 하지 않음
 return new Result(score, false, combo);
 }
 }
 return new Result(score, true, combo);
 }
}
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

(注記) 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
풀이 작성은 로그인이 필요합니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 5
python x 3
java x 1
ruby x 1
코딩도장 © 2014 · 문의 [email protected]
피드백 · 개인정보취급방침 · RSS

AltStyle によって変換されたページ (->オリジナル) /