2013-05-29 3 views
8

나는 체스 게임을 만들고 있는데, 사실 한 가지만 빼면 모든 것을 얻었습니다. 플레이어가 조각을 수표로 옮길 수 없도록해야합니다. 이 문제를 해결하는 방법에 문제가 있습니다.체스 : 모든 체스 이동 이동하기

내가 유효한 움직임을 생성하기 위해 의사에 지금있는 것은 : 이 위치가 경계에있는 경우,이 위치에 조각 : 클래스 getMoveLocations (나는 체스에서 그 사각형 중 하나가 될 위치를 정의) 적의 이동량과 시뮬레이션 된 이동으로 인해 보드가 점검되지는 않습니다. 그런 다음이 위치를 조각이 이동할 수있는 위치에 추가하십시오.

이 문제는 체스 판이 "점검 중"인지 확인하는 방법입니다. 내 코드에서 체스 판은 모든 적의 이동 위치를 수집하고 적의 이동 위치 중 하나가 왕의 위치와 겹치는지를 보면서 "점검"상태에있는 것으로 간주합니다.

불행히도 여기가 무한 루프가 시작되는 지점입니다. 모든 적의 영화 위치를 모으기 위해, 적의 가능한 이동 위치는 이동으로 인해 체크가되지 않도록해야합니다. 적의 위치가 확인되지 않도록 모든 동맹군의 잠재적 이동 위치 등을 수집해야합니다.

작동 알고리즘을 얻는 방법에 난처한 입장입니다. "이론적으로"필자의 코드는 논리적으로 의미가 있지만 구현할 수는 없습니다. 나는 A) 모든 법적 움직임을 검사하는 방법을 구현하는보다 효율적인 방법 또는 B)이 무한 루프를 해결하는 방법

+0

체크를 만드는 동작 (유효성을 확인)에 대해서만 재귀 부분을 실행할 수 있지만 다른 동작에는 사용할 수 없습니다 (유효하지 않은 경우 중요하지 않음). 그것은 무한 재귀를 방지해야합니다. – assylias

+0

getMoveLocations라는 클래스를 만들었습니까? – joshreesjones

+1

당신은 가능한 움직임을 찾고 있습니다 "상대방이 여기로 이동하면 상대방이 거기로 움직이면 상대방이 움직 인 후에 거기로 이동하면 ..... 내가 점검 할 것입니까?" 벽에 대해 튀는 공을 가지고 있고 공이 플레이어에 의해 제어 가능한 게임을 만들었다 고 가정하면 벽과의 충돌로 이어지지 않는 N 개의 경로로 그의 움직임을 제한하지 않을 것입니다 (거대한 검색), 당신은 그를 어느 한 방향으로 움직이지 않는다. 그는 벽과 충돌한다. 마찬가지로 움직일 때 수표에 넣을 수 있는지 확인하십시오. 조각으로 가능한 모든 동작을 고려하지 않습니다. (거대한 검색) – arynaq

답변

2

getMoveLocations 절차를 수정하여 이동에 대해 걱정할 필요가 있는지 여부를 나타내는 플래그를 허용합니다. 수표로. 예를 들어 조각이 고정 된 경우 상대편의 왕을 잡을 수 있습니다. 플래그가 위험 확인을 무시하도록 설정된 경우, 점검 테스트를 생략하면 재귀가 중단됩니다.

다른 방법으로 (그리고 동등하게) 검사로 이동하는 문제를 무시하는 움직임을 생성하는 별도의 방법을 작성하십시오. 그 절차를 "귀하의 이사회를 점검하게하십시오"시험의 일환으로 사용하십시오.

+0

이렇게하면 실제로 유효 할 때 이동이 무효 한 것으로 간주 될 가능성이 아직 없습니까? – Mike

+0

@ user2430625 - 그렇게 생각하지 않습니다. 상대방의 이동으로 상대방이 즉각 왕을 데려 갈 수 있다면 (상대방을 확인하는 조각을 움직여도), 그 이동을 할 수 없습니다. 달리 설명하는 예제를 제공 할 수 있습니까? –

+0

나는이 방법이 많은 고정 된 조각으로 복잡한 위치에서 작동하지 않는다고 생각합니다. 고정 된 조각 사이에 원형 관계를 가질 수 있습니다. – Zong

1

이동하면 상대방이 왕에게 공격을 할 수 있도록 이동하면 상대방을 확인합니다 (따라서 허용되지 않습니다).

자신을 체포하는 것은 상대방을 확인하는 것과는 다르다는 점에 유의하십시오. 상대방을 확인하면 응답 할 차례입니다. 자신을 점검 할 수 있다면 응답 할 기회는 0입니다. 그들은 당신의 왕을 사로 잡을 수 있었고, 상대방의 입장이 얼마나 나쁜지에 상관없이, 또는 그들이 "점검 중"이라 할지라도 항상 올바른 행동을 취할 수있었습니다. 그 이후로 아무것도 남지 않았습니다.

움직이기를 확인하는 경우, 적의 조각이 왕에게 공격을 가할 수 있는지 확인하십시오. 그게 전부 야. 당신은 재귀 적으로 미래의 수표 등을 해결하지 않습니다 - 그들이 지금 왕을 공격 할 수 있다면 무효입니다.

8

측면이 점검 중인지 여부를 결정하는 훨씬 더 효율적인 방법이 있습니다. 단순히 왕의 바깥 쪽을 스캔하고 공격 할 수있는 조각을 찾았는지 확인하는 것입니다. 예를 들어, 왕의 위치에서 적의 주교가 대각선을 따라 있는지 확인하십시오. 이동 목록을 생성 할 필요가 없으므로 재귀가 필요하지 않습니다. 다음은 몇 가지 의사 코드입니다 :

function leftInCheck(board, sideToCheck) { 

    // one of the four rays for bishop/queen attacks 
    d := 0 
    while (king rank + d, king file + d) is on the board 
     piece := board[king rank + d][king file + d] 
     if piece is an enemy bishop or queen 
     return true 
     if piece is not an empty square // a piece blocks any potential 
     break       // attack behind it so we can stop 
     d := d + 1 

    // do this for all the other forms of attack 
    ... 

    return false 
} 

당신은 몇 가지 코드를 반복 거기에 볼 수 있듯이,하지만 당신은 그것을 짧게 만들 수 있습니다. 나는 그것을 그대로두고 이해하기 쉽다.당신은 지금하고있는 것처럼 의사 법적 움직임을 생성하고, 각각 하나를 만들고, 위의 서브 루틴을 확인하는 것을 생략함으로써 합법적 인 움직임을 생성 할 수 있습니다. 이것은 자연적으로 passant의 추가 장점이 있습니다. 여기에 몇 가지 의사 코드가 있습니다 :

function legalMoves(board, sideToMove) { 
    moveList := empty 
    for each move in pseudoLegalMoves() 
     make(move) 
     if not leftInCheck(board, sideToMove) 
     moveList.add(move) 
     unmake(move) // you may not need this 
    return moveList 
} 

캐슬링의 경우 왕과 루크 사이의 사각형에 대한 공격이 있는지 확인해야합니다. 다행스럽게도 위의 서브 루틴을 확장하여 왕의 사각형이 아닌 다른 사각형에서도 사용할 수 있으므로 쉽습니다.

당신이 비트 보드 또는 0x88을 사용하지 않고 대신 간단한 배열 표현을 사용한다고 가정합니다. 따라서 고정 된 조각을 결정하기 위해 공격 맵을 매우 빠르게 생성해야하기 때문에 법적 이동 생성을 구현하는 것이 약간 어렵습니다 (중간의 의사 법적 이동이 없음). 당신이 야심적이라면, 이것은 가능성이 있습니다.

추가 참고 사항으로, 나는 다른 답변에 다소 실망합니다. 그리고 나는 좋은 움직임 생성기 (체스 프로그래밍에 익숙하지 않은 사람들에게만 해당됨)를 작성하려는 사람에게 내 자신의 대답을 추천하지 않습니다. 이 주제는 철저히 조사되었으며 잘 알려진 해결책을 가지고 있지만 독창적 인 아이디어를 이끌어내는 주제입니다. 물론 이것에는 아무런 문제가 없지만 왜 바퀴를 다시 만들어야합니까? well established methods of move generation을 살펴보십시오.

+0

그는 또한 캐슬링을 특별히 다루어야합니다. 왕은 공격받는 공간을 넘을 수 없으므로 포스터는 킹 쪽 캐슬링의 경우 f1 또는 f8을 확인하고 여왕면 캐스팅의 경우 d1 또는 d8을 확인해야합니다. –

+0

예, en passant입니다. 완전히 합법적 인 세대를 만드는 것은 상당히 복잡합니다. 조금 더 느리지 만 의사 - 법적 생성 후 수표를 평가하면이 모든 것이 쉽게 처리됩니다. – Zong

+0

포스터 체크 2 스퀘어 만 캐스팅해야합니다. 목적지, 그리고 중간 공간. –

0

그것은 어떤 포스터가 그렇게 주장하기 전에주의 깊게 읽고 연구하시기 바랍니다 충분히 체스 엔진을 이해하지 않는 것이 나타납니다

대신 그들은 그들이 거기에 공격 할 수 있는지 여부를 확인,이 이동할 수 있는지 확인하는

. 어쨌든 나중에 평가 함수를 사용하기를 원할 것입니다 ...

얼마나 많은 엔진이이 작업을 수행하는지는 모르겠지만 Stockfish는 src 폴더의 evaluate.cpp를 참조합니다. 그것은 좋은 엔진들 사이에서 꽤 표준입니다. 어쨌든 평가를 위해해야 ​​할 일이 있다면 운동 세대에도 사용할 수 있습니다.

+0

알고리즘이이 대답의 논리를 허용하면 모든 적의 유효한 동작보다 간단하고 잠재적으로 덜 비싼 평가입니다. 왕의 이동에 대해 매우 간단한 부울 연산이 될 수 있습니다. 공간이 ChessPiece.KING &&의 유효한 이동 인 경우 나머지 적의 공격에 의해서가 아니라 유효한 이동입니다. ChessPiece.KING이 공격 받고 && 유효한 움직임이 없다면, 게임은 손실로 끝납니다. – scottb

+0

거기서 이동할 수있는 것과 캐슬링, 패전트 및 폰 전진 외에 공격 할 수 있다는 것의 차이점은 무엇입니까? 이것은 OP가 이미하고있는 것과 거의 똑같습니다. – Zong

+0

나는 실제로 체스 엔진을 작성한 적이 없지만, 이것에 관해 상당한 연구를 해왔고, 이것이 최선의 방법이라고 생각합니다. 내 주요 관심사는 OP가 체스 엔진 용 Java를 사용하고 있다는 것입니다. 분명히 그들은 성능에 대해별로 신경 쓰지 않습니다 ... –