Java로 작성한 체스 게임을 다시 개발하고 있으며 번호가 매겨진 체스 판에 체스 타일을 색칠하는 우아한 알고리즘이 있는지 궁금합니다.
현재 내 솔루션은 if else 문을 사용하여 타일이 짝수 또는 홀수 행인지 여부를 결정하고 그에 따라 밝거나 어두운 사각형이어야합니다.
Java로 작성한 체스 게임을 다시 개발하고 있으며 번호가 매겨진 체스 판에 체스 타일을 색칠하는 우아한 알고리즘이 있는지 궁금합니다.
현재 내 솔루션은 if else 문을 사용하여 타일이 짝수 또는 홀수 행인지 여부를 결정하고 그에 따라 밝거나 어두운 사각형이어야합니다.
답변:
당신이 가지고 주어진 내가 생각할 수있는 가장 우아한 방법, row
및 column
, 인덱스는 다음과 같다 :
bool isLight = (row % 2) == (column % 2);
또는 반대로 :
bool isDark = (row % 2) != (column % 2);
기본적으로 체스 판의 타일은 열과 행이 서로 홀수 또는 짝수 인 곳에서는 가볍고 그렇지 않으면 어둡습니다.
3 % 2 == 1
이고 5 % 2 == 1
.. 둘 다 고르지 않지만 "빛"으로 표시됩니다. 해결책이 잘못되었다고 말하지 않고 (패턴을 번갈아 가며 좋으므로) 주석 / 설명이 틀린 것 같습니다.
bool isLight = ((row ^ column) & 1) == 0;
행과 열 인덱스를 함께 XOR하고 가장 중요하지 않은 비트를 봅니다. 행 또는 열 인덱스를 하나씩 변경하면 결과가 반전되어 검사기 패턴이 생성됩니다.
^
괜찮지 만 +
똑같이 잘 작동합니다. :)
-
대해서도 마찬가지입니다. :)
또 다른 제안은 매우 간단합니다.
isLight = (row + column) % 2 == 0;
행과 열을 추가하면 왼쪽 상단 타일에서 수평 및 수직 단계 수가 줄어 듭니다.
단계 수조차도 밝은 색상을 제공합니다.
홀수 단계는 어두운 색을냅니다.
& 1
효율적 % 2
입니다. 그러나 일반적으로 동의합니다.
이것은 우리의 제곱이 [0..63] 범위에서 번호가 매겨 졌다고 가정합니다.
bool IsLight(int i)
{
return 0!=(i>>3^i)&1;
}
그것이 왜 작동하는지 알아내는 것은 반 재미입니다. :)
return (i>>3 ^ i) & 1 != 0
? Java에서 정수를 부울로 암시 적으로 변환 할 수 있습니까?
타일 번호를 매기십시오. row * 8 + column 또는 이와 유사한 것을 계산하여이 정보를 얻을 수 있습니다.
그리드 번호의 계수 16을 가져옵니다. (타일이 반복되기 전에 16 개의 위치가 있습니다.)
짝수 또는 홀수인지에 따라 타일의 색상을 지정하십시오. 결과가 7보다 큰 경우 타일 색상을 뒤집습니다.
0부터 시작하는 인덱스 코드 :
int cellNum = (row*8+column) % 16;
bool isSecondRow = cellNum > 7;
if(cellNum % 2 == 0 ^ isSecondRow){ //XOR operator
setColor(Color.White);
}else{
setColor(Color.Charcoal);
}
modulus 16
동작은 두 개의 행에 문제를 감소시킨다. 두 번째 행은 첫 번째 행과 다른 패턴을 따릅니다. if
중 하나가 아니라 두 번째 행의 짝수 타일 XOR 인 경우 문은 true로 평가합니다. 둘 다 참이면 거짓으로 평가됩니다. XOR 연산자를 검토하십시오. msdn.microsoft.com/en-us/library/zkacc7k1.aspx
IsSecondRow
정말 이름이 있어야합니다 IsEvenRow
. 낮은 행의 비트를 얻는 것은 다소 복잡한 방법입니다. 먼저 행 3의 비트를 오른쪽으로 이동 한 다음 행의 LSB를 제외한 모든 행을 버린 다음 4 번째 비트의 셀 번호가 설정되어 있는지 확인하십시오.
이 방법은 체스 보드처럼 단순한 것에 실제로는 필요하지 않지만 뷰와 관련된 것을 렌더링하는 우아한 방법을 생각할 때 가능한 한 렌더링 된 뷰를 변경하는 것이 가능하도록 만들고 싶습니다. 예를 들어, 각 행이 아니라 각 행에서 흑백을 교대로하기로 결정했다고 가정하십시오. 지금까지 답변에 사용 된 원 라이너는 다시 작성해야합니다.
내가 할 수있는 한 멀리 가서 체스 보드의 패턴을 가능한 한 쉽게 다시 디자인하려면 다음과 같이하십시오.
1) 체스 보드의 각 사각형이 어떤 색인지 나타내는 파일을 만들 것입니다.
예를 들어, chess_board_pattern.config
다음과 같은 파일 을 만들 수 있습니다 .
bwbwbwbw
wbwbwbwb
bwbwbwbw
wbwbwbwb
bwbwbwbw
wbwbwbwb
bwbwbwbw
wbwbwbwb
2) 나는이 파일을 읽을 수있는 클래스 / 구성 요소 / 무엇이든 쓰고 보드 패턴을 나타내는 일종의 객체를 만들 것입니다.
public class BoardPattern {
private Color[][] pattern;
public BoardPattern(File patternFile)
{
pattern = new Color[8][8];
//Parse the file and fill in the values of pattern
}
public Color[][] getPattern {
return pattern;
}
}
3) 그런 다음 실제로 보드를 그리는 함수에서 해당 클래스를 사용합니다.
File patternFile = new File("chess_board_pattern.ini");
Color[][] pattern = new BoardPattern(patternFile).getPattern();
ChessBoardDrawable chessBoard = new ChessBoardDrawable();
for(int row = 0; row < 8; row++) {
for(int column; column < 8; column++) {
chessBoard.drawSquare(row, column, Color[row][column]);
}
}
다시 말하지만 이것은 체스 보드에 필요한 것보다 훨씬 어렵습니다. 그러나 일반적으로 복잡한 프로젝트를 수행 할 때는 나중에 변경하기 어려운 코드를 작성하는 대신 이와 같은 일반화 된 솔루션을 사용하는 것이 가장 좋습니다.
The one-liners used in answers so far would have to be re-written.
뿐만 아니라, it's best to come up with generalized solutions like this instead of writing code that's difficult to change later.
하지만 당신은이 코드는 해체하고 한 줄보다 재 작성 훨씬 어렵 것을 이해해야합니다. 우아하지 않거나 그렇게하는 것이 좋지 않기 때문에 나는 당신에게 하향 투표를했습니다.