Реализация шахматной доски на Java

Я хочу создать базовый шахматный (или, если это не удастся, шашки / шашки) движок. Изучив тему, я совершенно уверен, что хочу использовать серию битовых досок. Я понимаю эту концепцию на базовом уровне, но у меня возникают проблемы с ее представлением на Java.

Я попытался представить белые фигуры на шахматной доске как 1, а все остальное как 0, используя длинное число:

long whitePieces = 0000000000000000000000000000000000000000000000001111111111111111L;

Но когда я распечатываю его, я получаю следующие 46 бит:

System.out.println(Long.toBinaryString(whitePieces));
1001001001001001001001001001001001001001001001

Что является причиной этого результата? Я уверен, что здесь есть что-то, что я в корне неправильно понимаю; Если бы кто-нибудь мог указать мне в правильном направлении, я был бы очень благодарен.


person BeepBeep    schedule 15.08.2014    source источник
comment
В шахматах есть более чем одна фигура, так что бита недостаточно? И начальные нули не будут работать. Вам нужен массив или список. Какое число 05?, Ответ: 5. Вместо этого создайте двумерный массив логических значений. Или какое-то закодированное целое число вместо нескольких таких массивов.   -  person keyser    schedule 15.08.2014
comment
Я планирую использовать серию битовых досок, я отредактирую свой пост, чтобы сделать это более понятным, спасибо.   -  person BeepBeep    schedule 15.08.2014
comment
long не хранит 0, а только 1. Почему бы не использовать массив для хранения частей? boolean[][] white = new boolean[num][num];   -  person KriszDev    schedule 15.08.2014
comment
Почему вы хотите сделать что-то подобное? простой счетчик прекрасно справится с той же задачей, не так ли?   -  person Nir Alfasi    schedule 15.08.2014
comment
Если вы ищете двоичное представление целого числа 1111111111111111, это будет не 1111111111111111... 1111111111111111 — это двоичное представление двоичного числа 1111111111111111, которое является целым числом 65535.   -  person rid    schedule 15.08.2014


Ответы (2)


Добавьте 0b перед длинным, чтобы сказать, что это двоичное число.

long whitePieces = 0b0000000000000000000000000000000000000000000000001111111111111111L;
                   ^^

(Префикс 0b был введен в Java 7. Если вы используете более старую версию, вы можете использовать Long.parseLong("000...111", 2))


Другой подход: как насчет создания перечисления:

enum ChessPiece { Pawn, Knight, ... };

и сохраните плату в файле ChessPiece[8][8]. Это должно предоставить вам гораздо более чистый интерфейс для чтения и изменения состояния, чем long дала бы вам.

Если вы беспокоитесь о производительности, просто сохраните фактическое представление должным образом инкапсулированным в классе Board (сделайте фактическую структуру данных закрытой). Если позже вы обнаружите, что ChessPiece[8][8] оказывается узким местом, вы можете поиграть и изменить его на long без особых усилий.

person aioobe    schedule 15.08.2014
comment
Это исправлено, большое спасибо. На ваш взгляд, это эффективное представление битборда? - person BeepBeep; 15.08.2014
comment
Несколько long могут быть подходящими, в зависимости от алгоритмов, которые вы реализуете. Например, должно быть быстро клонировать состояние доски. Но прежде чем выбрать long, спросите себя, представляете ли вы себе четкое представление о том, какое узкое место производительности будет в ваших алгоритмах, и стоит ли сразу же погрузиться в битовую переделку. - person aioobe; 15.08.2014
comment
Проблема в том, что я программист-любитель; Я программировал игры и раньше, но шахматный ИИ намного сложнее, чем все, что я делал раньше. Я нахожу генерацию шахматных ходов и ИИ запутанной темой, а побитовые операции с длинными - единственный способ, которым я понимаю эту тему на данный момент. Мне определенно нужно поэкспериментировать и лучше понять, прежде чем я смогу принять решение о конкретной реализации. - person BeepBeep; 15.08.2014
comment
Кроме того, что касается длинного, как мне справиться с игнорируемыми ведущими нулями? Большое спасибо - person BeepBeep; 15.08.2014
comment
Пожалуйста, СИЛЬНО рассмотрите лучшую абстракцию, чем long. Перечисление и двумерный массив — это гораздо лучшая абстракция, которая сделает код более понятным. В общем, советую СНАЧАЛА писать чистый код, а потом ОПТИМИЗИРОВАТЬ по скорости или памяти. Обратите внимание на закон Амдлы: en.wikipedia.org/wiki/Ahmdal%27s_Law - person Nick Palmer; 15.08.2014
comment
Проблема в абстракции; Я очень боюсь, что меня это запутает. Я могу понять базовую генерацию ходов, используя побитовые операции с длинными, например, позиция пешки ›› 8 и позиция пешки ›› 16 дадут вам возможные начальные ходы для пешки. Если бы я отошел от этого, я совершенно не уверен, как бы я создал представление, которое я все еще понимал. - person BeepBeep; 15.08.2014
comment
Чтобы переместить фигуру из a2 ([0][1]) в a3 ([0][2]), вы должны сделать board[0][2] = board[0][1]; board[0][1] = null. - person aioobe; 15.08.2014
comment
(также @BeepBeep :) Подсказка использовать массив ссылочных типов, таких как ChessPiece[8][8], безусловно, уместна с высокоуровневой объектно-ориентированной точки зрения. Однако для эффективного шахматного движка иногда приходится выжимать все до последней капли производительности и делать вещи, которые заставят среднестатистического Java-программиста пролить немало слез... Дополнительную информацию можно найти по адресу chessprogramming.wikispaces.com/Board+Representation - person Marco13; 15.08.2014

Вы храните не двоичное число, а десятичное. Чтобы создать число с использованием двоичной записи, вам нужно добавить к нему префикс 0b. См. документацию Oracle по двоичным литералам.

Кроме того, одна плитка или часть шахматной доски вообще не может быть представлена ​​одним битом, поэтому вы можете захотеть переосмыслить свое решение в целом.

person kviiri    schedule 15.08.2014
comment
Спасибо! Не могли бы вы объяснить, почему одна плитка не может быть представлена ​​одним битом? Почему серии таких длинных недостаточно для каждого аспекта шахматной доски (белые пешки, белые ладьи, черные пешки и т. д.)? - person BeepBeep; 15.08.2014
comment
Для запоминания текущей позиции достаточно одного длинного кадра каждого вида шахматной фигуры. Но вам также придется хранить состояние шахматной фигуры, по крайней мере, для королей, ладей и пешек. - person laune; 15.08.2014
comment
Не могли бы вы уточнить, что вы имеете в виду под состоянием? - person BeepBeep; 15.08.2014
comment
@BeepBeep, да, сработает серия лонгов. Я думал, ты собираешься собрать все части в одну, что невозможно. - person kviiri; 15.08.2014
comment
@BeepBeep, я полагаю, что laune означает такие правила, как рокировка и на проходе, которые нельзя вывести только из положения фигур. - person kviiri; 15.08.2014
comment
Рокировка и на проходе определенно сложны, но я читал, что их можно решить с помощью этой реализации. В Интернете есть значительное количество материалов по этому поводу; надеюсь доберусь! - person BeepBeep; 15.08.2014
comment
@BeepBeep, конечно, могут, но это именно то, что мы говорим. Вы должны помнить о их хранении. - person kviiri; 15.08.2014