거북이처럼 천천히

알고리즘 (6월 15일) 본문

Algorithm/알고리즘 문제 풀이

알고리즘 (6월 15일)

유로 청년 2022. 6. 15. 20:43

1. 문제 (코딩도장, tic-tac-toe game)

https://codingdojang.com/scode/464?langby=java#answer-filter-area 

 

코딩도장

프로그래밍 문제풀이를 통해서 코딩 실력을 수련

codingdojang.com


2. 생각

 

tic-tac-toe는 두 명의 플레이어가 턴을 돌아가면서 1부터 9까지 포지션을 선택하는 게임 입니다. 선택된 포지션은 X나 0로 표시가 되며, 선택된 포지션은 다시 선택할 수가 없습니다. 게임 그리드는 3*3으로 다음과 같습니다.

        *              *                
 1      *      2       *      3       
        *              *                
        *              *               
 4      *      5       *      6       
        *              *               
        *              *               
 7      *      8       *      9      
        *              *

가로 세로 대각선으로 먼저 세 줄을 연속으로 만드는 플레이어가 우승하게 되며 무승부인 경우도 생깁니다. (매 턴마다 포지션을 입력해야 하지만, 출력은 게임이 끝이 났을 때만 하셔도 됩니다)

 

  • 1 ~ 9 원소 값들을 갖는 행렬 "ticTacToe" 초기화
  • 입력을 받기 앞서 플레이어에게 현재 입력 가능한 원소 값을 알려주기 위해서 행렬 "ticTacToe"의 원소 값을 하나씩 꺼내서 String에 넣는다. 이때, 해당 원소가 "X"이거나 "O"이면 String에 추가하지 않는다.
    조건에 맞는 모든 원소가 String에 추가되면 출력한다.
  • 플레이어는 입력 가능한 원소 값들을 보고 입력한다.
  • 해당 값이 선택된 포지션인지 판단하여 이미 선택된 값이면 "잘못 입력" 했음 알려주고, 아니면  해당 위치에 행렬 "ticTacToe"의 원소 값을 플레이어 차례에 맞게 "X" or "O"을 표시한다.
  • 그 다음, 행,열, 대각선으로 나누어서 3중 for문을 이용하여 가로, 세로, 대각선으로 먼저 세 줄을 연속으로 만들었는지 확인하고, 있는 경우에는 해당 플레이어 번호를 "winner" 변수에 저장하고, 아니면 "winner" 변수 값을 0으로 유지한다.
  • "winner" 변수 값이 0이 아니면 누군가 이긴 사람이 있기때문에 "winner" 변수 값을 보고 해당 플레이어가 이겼음을 알려준다. 
  • "winner" 변수 값이 0이면 계속 플레이를 지속하고, "winner" 변수 값이 0인 동시에 9번째 차례가 넘어가면 행렬 "ticTacToe"의 원소값들이 X" or "O"으로 채워져 있기 때문에 비겼음을 알려준다. 

3. 풀이 및 코드 분석

import java.util.Scanner;

public class RealTest {	
	// 판단 
	public static int whoIsWinner(int count, String check, int winner) {	
		if(count==3&check.equals("X")) {
			winner = 1;
		}else if(count==3&check.equals("O")) {
			winner = 2;
		}
		
		return winner;
	}
	
	// 이긴 사람이 있는가?
	public static int answerResult(String[][] ticTacToe, int player) {
		int winner = 0;
		String[] checkList = {"X", "O"};
		
		// 행 판단
		for(String check : checkList) {
			for(int i=0; i<3; i++) {
				int count = 0;
				for(int j=0; j<3; j++) {
					if(ticTacToe[i][j].equals(check)){
						count++;
					}
				}
				winner = whoIsWinner(count, check, winner);
			}
		}
		
		// 열 판단
		for(String check : checkList) {
			for(int j=0; j<3; j++) {
				int count = 0;
				for(int i=0; i<3; i++) {
					if(ticTacToe[i][j].equals(check)){
						count++;
					}
				}
				winner = whoIsWinner(count, check, winner);
			}
		}
		
		// 대각선 판단
		for(String check : checkList) {
			int countLeft = 0, countRight = 0;
			for(int i=0; i<3; i++) {
				if(ticTacToe[i][i].equals(check)) {
					countLeft++;
				}
				if(ticTacToe[i][2-i].equals(check)) {
					countRight++;
				}
			}
			winner = whoIsWinner(countLeft, check, winner);
			winner = whoIsWinner(countRight, check, winner);
		}
		
		return winner;
	}
	
	// 해당 원소가 들어있는가? & 있으면 표시
	public static boolean checkContain(String[][] ticTacToe, String selectedElement, int player) {
		boolean result = false;
		
		for(int i=0; i<3; i++) {
			for(int j=0; j<3; j++) {
				if(ticTacToe[i][j].equals(selectedElement)) {
					result = true;
					
					if(player==1) {
						ticTacToe[i][j] = "X";
					}else {
						ticTacToe[i][j] = "O";
					}
				}
			}
		}
		
		return result;
	}
	
	// 남은 원소 출력
	public static void printRemaining (String[][] ticTacToe, int player) {
		String remaining = "";
		
		for(int i=0; i<3; i++) {
			for(int j=0; j<3; j++) {
				if((ticTacToe[i][j].equals("X")==false)&(ticTacToe[i][j].equals("O")==false)) {
					remaining += " "+ticTacToe[i][j]+",";
				}
			}
		}
		remaining = remaining.substring(0, remaining.length()-1);
		
		System.out.printf("Player %d's turn\n", player);
		System.out.printf("please type a position (available position(s) are %s):", remaining);
	}
	
	// 결과 출력
	public static void painting(String[][] ticTacToe) {
		for(int i=0; i<3; i++) {
			for(int j=0; j<3; j++) {
				if(j!=2) {
					System.out.print("         *");
				}else {
					System.out.print("         ");
				}
			}
			System.out.println();
			for(int j=0; j<3; j++) {
				if(j!=2) {
					System.out.printf("    %s    *",ticTacToe[i][j]);
				}else {
					System.out.printf("    %s    ",ticTacToe[i][j]);
				}	
			}
			System.out.println();
			for(int j=0; j<3; j++) {
				if(j!=2) {
					System.out.print("         *");
				}else {
					System.out.print("         ");
				}
			}
			System.out.println();
		}
		System.out.println();
	}
	
	// 메인 
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		// 게임 시작 전 세팅
		String[][] ticTacToe = {{"1", "2", "3"}, {"4", "5", "6"}, {"7" ,"8" ,"9"}};
		System.out.println("Game Start!");
		painting(ticTacToe);

		// 시작	
		int player = 1;
		for(int i=1; i<=9; i++) {
			while(true) {
				printRemaining(ticTacToe, player);
				String selectedElement = scan.next();
				
				boolean isContain = checkContain(ticTacToe, selectedElement, player);
				
				if(isContain==false) {
					System.out.println("The element does not exist. Please re-enter.\n");
					continue;
				}else {
					break;
				}
			}
			System.out.println();
			painting(ticTacToe);
			
			int winner = answerResult(ticTacToe, player);
			
			if(winner!=0) {
				System.out.printf("Game over! Winner is player %d\n", winner);
				break;
			}else if(i==9&&winner==0) {
				System.out.println("Game over! draw! \n");
			}
			
			
			// 플레이어 차례 선정
			if(player==1) {
				player=2;
			}else {
				player=1;
			}
		}
	}
}

4. 메모

  • 이번 문제는 생각보다 코드 줄이 많아서 당황했다.....;; 하지만, 풀어서 나름 기분이 좋고, 재미있는 게임이였다.^^

'Algorithm > 알고리즘 문제 풀이' 카테고리의 다른 글

알고리즘 (6월 19일)  (0) 2022.06.19
알고리즘 (6월 16일)  (0) 2022.06.16
알고리즘 (6월 13일) - (3)  (0) 2022.06.13
알고리즘 (6월 13일) - (2)  (0) 2022.06.13
알고리즘 (6월 13일)  (0) 2022.06.13