오셀로 비슷한데 어려운 게임 -.-

idlock의 이미지

http://game.scienceall.com/quiz_game/quiz_game_05/puzzle_game/puzzle_game_b02.asp

자바 애플릿 게임인데 5X5를 넘질 못하겟네요 -.-

어떤 법칙이나. 히든 카드가 있는지 ^^

체스맨의 이미지

저도 5x5 까지 했습니다. ^^
대충 약간의 테크닉은 알아챈 것 같은데...
좀 더 해봐야겠군요.

Orion Project : http://orionids.org

체스맨의 이미지

6x6 성공!
trial & error 의 극치 입니다. -_-
아무튼 대강의 테크닉이 보이네요.

Orion Project : http://orionids.org

체스맨의 이미지

우후후...
8x8 성공입니다. 6x6 과 동일한 원리군요.
7x7 남았습니다.!

Orion Project : http://orionids.org

체스맨의 이미지

7x7 이 제일 어렵군요. 잘 안되네요. :oops:

Orion Project : http://orionids.org

gang의 이미지

몇 시간 동안 헤맨 끝에, 답 찾는 프로그램을 만들었습니다. 8)

소스코드의 MATRIX_SIZE를 원하는 크기로 하여, 컴파일 실행하면, 3x3의 경우, X . X 라고 출력됩니다. 첫줄에서 1,3번 셀을 클릭하라는 뜻입니다. 두번째 줄부터 계속해서, 바로 윗 셀이 흰색인 아랫 셀을 클릭하여 마지막 줄까지 계속합니다. 그러면 그게 답입니다. :wink:

#include <stdio.h>
#include <string.h>

#define MATRIX_SIZE 5 // 원하는 크기로 변경하세요!
#define WHITE 1

char c[MATRIX_SIZE][MATRIX_SIZE]; // THE BOARD; white = 1, black = 0

void click(int row, int col) // 상하좌우 및 자신을 색깔 전환
{
        c[row][col] = !c[row][col];
        if(row>0) c[row-1][col] = !c[row-1][col];
        if(row<MATRIX_SIZE-1) c[row+1][col] = !c[row+1][col];
        if(col>0) c[row][col-1] = !c[row][col-1];
        if(col<MATRIX_SIZE-1) c[row][col+1] = !c[row][col+1];
}

void expand_matrix() // 한 줄씩 아래로, 바로 윗칸이 흰색이면 클릭한다.
{
        int row, col;
        for(row=1; row<MATRIX_SIZE; row++)
        {
                for(col=0; col<MATRIX_SIZE; col++)
                {
                        if(c[row-1][col]==WHITE) click(row,col);
                }
        }
}

int is_solution() // 맨 마지막줄이 모두 검정이면 성공
{
        int col;

        for(col=0; col<MATRIX_SIZE; col++)
        {
                if(c[MATRIX_SIZE-1][col] == WHITE) return 0;
        }

        return 1; // 해답
}

void make_first_row(unsigned bits) // 첫줄을 배열한다.
{
        int col;
        unsigned b;

        for(col=0; col<MATRIX_SIZE; col++)
        {
                if( ( 1 << col ) & bits )
                {
                        click(0,col);
                }
        }
}

void print_bits(unsigned long long bits) // 첫줄에서 클릭한 위치 표시
{
        int col;

        for(col=0; col<MATRIX_SIZE; col++)
        {
                if( ( 1 << col ) & bits ) printf("X ");
                else printf(". ");
        }
        printf("\n");
}

void reset() // 모두 흰색으로 리셋
{
        int row, col;
        for(row=0; row<MATRIX_SIZE; row++)
        for(col=0; col<MATRIX_SIZE; col++)
                c[row][col] = WHITE;
}

int main()
{
        unsigned bits;
        unsigned num;

        num = 1 << MATRIX_SIZE;

        for(bits=0; bits<num; bits++) // 첫 줄에서 가능한 모든 경우의 수
        {
                reset();
                make_first_row(bits);
                expand_matrix();
                if(is_solution())
                {
                        printf("Clicks of the first row of a solution: ");
                        print_bits(bits);
                }
        }

        return 0;
}
체스맨의 이미지

대단하군요.
그러니까 첫줄만 잘 하면, 나머지 줄은 원리가 있는 것이군요.
그 원리는 어찌 파악하셨는지 대단하네요.

아무튼 저는 다른 방법으로 풀고 있었습니다.

예를 들어, 8x8 풀이가 다음과 같았죠.

4,4 5,4 5,5 4,5 3,3 6,3 6,6 3,6
4,2 5,2 5,3 4,3 6,4 7,4 7,5 6,5
4,6 5,6 5,7 4,7 2,4 3,4 3,5 2,5
1,1 2,1 2,2 1,2 7,1 8,1 8,2 7,2
1,7 2,7 2,8 1,8 7,7 8,7 8,8 7,8

몇가지 패턴을 파악해서 응용하고 있었죠.
원리 파악을 못했군요. :oops:

Orion Project : http://orionids.org

체스맨의 이미지

int clicked; //전역 변수로 하나 두고,

void click(int row, int col) // 상하좌우 및 자신을 색깔 전환 
{ 
        clicked++; // 클릭 될 때마다 증가시키고,

...

void reset() // 모두 흰색으로 리셋 
{ 
        int row, col; 
        clicked = 0; // reset 에서 0으로 만들고

...

//main 에서 클릭회수를 표시하면...
          printf("Clicks of the first row of a solution (%d clicks): ", clicked); 


최적 솔루션을 볼 수 있겠네요.

Orion Project : http://orionids.org

ihavnoid의 이미지

뭔가 다른 방법이 있지 않을까 해서 열씨미 분석중입니다....-_-
쉽지 않네요....-_-;

Consider the ravens: for they neither sow nor reap; which neither have storehouse nor barn; and God feedeth them: how much more are ye better than the fowls?
Luke 12:24

체스맨의 이미지

컴으로 구현하기 위한 가장 쉬운 알고리즘으로는 gang 님께서 찾으신게 정답이 아닌가 합니다.

재밌는 건 이 문제는 순서에 무관하다는 것입니다. 즉 click 해야할 위치가 중요하지, 그것을 어떠한 순서로 클릭했는가는 전혀 무관하기 때문에, 제가 한 것처럼 다른 솔루션이 나올 수 있었던 거죠. 결과적으로 누른 위치들은 같을 겁니다.

Orion Project : http://orionids.org

idlock의 이미지

최적 해가 있는것으로 보이네요.. 단지 모를뿐이지.. -.-;;;
혹시 쉽게 설명해주실분 없으시나요 ^^;;;;;

gang 님 ( -.-)=b

ihavnoid의 이미지

체스맨 wrote:
컴으로 구현하기 위한 가장 쉬운 알고리즘으로는 gang 님께서 찾으신게 정답이 아닌가 합니다.

재밌는 건 이 문제는 순서에 무관하다는 것입니다. 즉 click 해야할 위치가 중요하지, 그것을 어떠한 순서로 클릭했는가는 전혀 무관하기 때문에, 제가 한 것처럼 다른 솔루션이 나올 수 있었던 거죠. 결과적으로 누른 위치들은 같을 겁니다.

잘 살펴보면 아시겠지만, O(n^2 * 2^n) 알고리즘-_-입니다...
넓이가 증가하면 증가할수록 필요한 시간은 기하급수적으로 증가한다는 얘기죠.

뭔가 더 좋은 방법이 없을까 생각을 해보려고 했지만.....
힘드네요-_-

Consider the ravens: for they neither sow nor reap; which neither have storehouse nor barn; and God feedeth them: how much more are ye better than the fowls?
Luke 12:24