보석 같은 게임의 논리


12

제가하고있는 프로토 타입에는 보석으로 장식 한 것과 비슷한 미니 게임이 있습니다. 2D 배열 ( int[,]) 인 그리드를 사용 하면 사용자가 언제 경기를했는지 알 수 있습니까? 나는 수평과 수직에만 관심이 있습니다.

내 머리 꼭대기에서 나는 단지 각 방향을 볼 것이라고 생각했다. 다음과 같은 것 :

int item = grid[x,y];
if(grid[x-1,y]==item)
{
    int step=x;
    int matches =2;
    while(grid[step-1,y]==item)
    {
        step++;
        matches++
    }
    if(matches>2)
        //remove all matching items
}
else if(grid[x+1,y]==item
    //....
else if(grid[x,y-1==item)
    //...
else if(grid[x,y+1]==item)
    //...

더 좋은 방법이 있어야합니다. 있습니까?


나는 이것을하기 위해 지루한 for 루프를 썼다는 것을 기억했다 (connect-n을 위해)
Ming-Tang

답변:


6

동일한 항목 (x 또는 y)에서 각 항목을 반복합니다. 이전 항목과 같으면 일치하는 항목이 증가합니다. 다음 항목이 달라지면 일치 항목이 3 이상인지 확인하고 일치하는 항목을 제거하는 함수를 호출 한 다음 계속하십시오.

AS3 코드 :

var grid:Array = [[2,3,2,2,2,4],
                  [ .. ]]; //multidimensional array
var matches:uint;
var gemType:uint;
for(col = 0; col < grid.length; col++){
    matches = 0;        
    gemType = 0; //Reserve 0 for the empty state. If we make it a normal gem type, then only 2 are needed to match for the start.
    for(i = 0; i < grid[0].length; i++){
        if(grid[col][i] == gemType){
            matches++;
        }
        if(grid[col][i] != gemType || i == grid[0].length - 1){ //subtract 1 because arrays start at 0
            if(matches >= 3){
                removeMatches(blah);
            }
            gemType = grid[col][i];
            matches = 1;
        }
    }
}

이것은 x 축에만 해당됩니다. y의 경우 grid [col] [i]은 grid [i] [row] 등이됩니다. 알아낼 수 있습니다. :)


4

Match-3와 비슷한 게임을 제작 한 경험에 무게가 걸렸다 고 생각했습니다.

우리는 글자 맞추기 및 Bejeweled를 깨뜨리는 것과 비슷한 Match-3 기반 단어 게임을위한 프로토 타입을 만들었습니다. 우리는 비어있는 공간을 채우기 위해 새로운 보석 / 타일을 공급하는 엔진이 플레이어가 글자를 문자열로 묶어 단어를 만들 수있는 실제 기회를 만들기 위해 매우 내성적이어야한다는 것을 깨달았습니다 (우리는 하이브리드 휴리스틱 및 MonteCarlo 샘플링을 실행 함) 경기 3 정비공. 설명보다 더 정교하지만 종이를 써야하므로 간략히 설명하겠습니다.

OP에 답하기 위해-현재 우리는 "gladoscc"코드 스 니펫과 매우 유사한 방법을 통해 주어진 거더에 몇 개의 일치 항목이 있는지 확인하기 위해 패턴 검사를 수행하고 있습니다. 강력하게 작동하지만 트리 검색 재생 중에 재귀 적으로 실행하는 계산 비용은 상당한 부담이되므로 논리 의이 부분과 데이터 표현을 비트 보드 방법으로 다시 작성하는 중입니다 ( 체스, 체커, 오델로 등과 같은 다른 그리드에서 일반적으로 구현됩니다.) 테스트에서 우리는 ActionScript에서 20 배 이상 빠르게 실행될 수 있다는 것을 보여주었습니다. 따라서 우리에게 필요한 것은 슬램 덩크입니다. 응답 성, 사운드, 애니메이션 등을위한 필수 사이클을 해제합니다.


3
귀하의 답변은 답변이어야하며 다른 질문을 추가해서는 안됩니다. 질문이 있으시면 "질문"버튼을 사용하여 새로운 질문을 작성하십시오. 이 토론 포럼이 아닙니다.
bummzack

1
bummzack .... 감사합니다. 저의 이론적 근거는 특히 나무 검색 / 탐색이 맥락에 추가되었을 때 제안되었던 것의 성능과 관련하여 우리가 제공 할 통찰력을 가졌다는 것입니다. 그리고 여전히 "Bejeweled 게임의 논리"에 대해 이야기하고 있기 때문에 계속 관련이 있습니다. 이 형식이 계속 잘못된 경우 조언에 따라 수정 / 게시를 드리겠습니다.
Wissam

2
괜찮아. 그러나 답변에서 "질문"부분을 제거해야합니다. 질문은 새로운 질문이어야하며 답변의 일부가 아닙니다 ...
bummzack

1
편집하고 다른 곳에서 질문을 게시
Wissam

2

재귀 요 경계를 모르는 경우를위한 것입니다.

   public int getHMatchSize(int row, int column)
    {
        int returnMe = getMatchValue(row, 0, column, 1);

        if (returnMe < 3)
        {
            return 0;
        }
        else return returnMe;
    }


    public int getVMatchSize(int row, int column)
    {
        int returnMe = getMatchValue(row, 1, column, 0);

        if (returnMe < 3)
        {
            return 0;
        }
        else return returnMe;
    }

    /// <summary>
    /// I return the match size.
    /// </summary>
    /// <param name="row"></param>
    /// <param name="rowDelta">1 means look vertically.  Dont set both deltas to 1.</param>
    /// <param name="column"></param>
    /// <param name="columnDelta">1 means look horizontally.  Dont set both deltas to 1.</param>
    /// <returns>The number of contiguous matching things</returns>
    public int getMatchValue(int row, int rowDelta, int column, int columnDelta)
    {
        int[] start = getEndItem(row, -1 * rowDelta, column, -1 * columnDelta);
        int[] end = getEndItem(row, rowDelta, column, columnDelta);

        int returnMe = 0;
        returnMe += end[0] - start[0];
        returnMe += end[1] - start[1];
        return returnMe;
    }

    /// <summary>
    /// I will return the end of a sequence of matching items.
    /// </summary>
    /// <param name="row">start here</param>
    /// <param name="column">start here</param>
    private int[] getEndItem(int row, int rowDelta, int column, int columnDelta)
    {
        Gem matchGem = new Gem(-1);
        int[] returnMe = new int[2];

        if (boardSpace[row + rowDelta][column + columnDelta] == boardSpace[row][column])
        {
            return getEndItem(row + rowDelta, rowDelta, column + columnDelta, columnDelta);
        }
        else
        {
            returnMe[0] = row;
            returnMe[1] = column;
            return returnMe;
        }
    }

0

플러드 채우기 알고리즘을 사용할 수 있습니다 . 이 유형의 문제에 실제로 사용할 수 있습니다.


1
아니요, 실제로는 질문과 관련이 없습니다. OP는 3 개의 일치하는 항목을 연속으로 감지하는 방법을 묻습니다.
Cyclops

2
뒤집힌 요소로 채우기를 시작하면 알고리즘이 일치하는 요소를 통과합니다. 그러나 행 (및 교차 열 없음)에서 3 (및 더 이상) 일치하는 요소를 확인하기 만하면 과잉 일 수 있습니다. 우리는 이것을 게임과 같은 Bubble Puzzle에서 사용하며, 우리가 필요한 것을 정확하게 수행합니다.
ktornai

2
이 문제와 관련하여 잠시 혼란 스러웠 기 때문에 "홍수 채우기 사용"보다 조금 더 설명해야 할 수도 있습니다.
jhocking 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.