[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Алгоритм в игре "Шашки"
p.pavluxa
Здравствуйте, уважаемые программисты! Пишу игру "Шашки" на PHP, для хранение игровой доски использую одномерный массив размером 64. В нём: 0 - пустое место, 1 - пешка первого игрока, 2 - пешка второго игрока, 3 - дамка первого игрока, 4 - дамка второго игрока. Данные в массиве расположены таким образом, что если разбить этот одномерный массив на двумерный через каждые 9 элементов то получиться игровая доска повернутая таким образом: слева первый игрок, справа второй игрок.

У меня имеется метод, который принимает № игрока, позицию элемента который берём (от 0 до 63) и позицию ячейки куда его поставить (от 0 до 63). Нужно проверить, можно ли данному игроку данной пешкой (дамкой) поставить в то положение?

Как реализовать эту проверку?



Спустя 28 минут, 27 секунд (17.07.2012 - 17:32) Игорь_Vasinsky написал(а):
глянуть куда в массив должно (может) записаться это значение, и если оно не 0 - то разрешено.

Спустя 1 час, 7 минут, 49 секунд (17.07.2012 - 18:40) kamanch написал(а):
Я бы сделал так:
Как ходим шашками?
1. Если обычная клетка, то на соседние клетки по диоганали. -> пишем функцию, которая возвращает всех этих соседей. Если свободная клетка, то можно ходить.

И т.д. по данному принципу.

Вот нашел, на мой взгляд, неплохое описание алгоритма: Алгоритм проверки правильности хода в шашках

Спустя 10 минут, 38 секунд (17.07.2012 - 18:50) p.pavluxa написал(а):
А готовой реализации никого нет?

Спустя 1 час, 11 минут, 18 секунд (17.07.2012 - 20:02) kamanch написал(а):
Есть и много.
Я за 3 минуты нашел алгоритм и запостил тебе сюда.
Завтра выделю еще 3 минуты на поиск в гуугле и запостю готовый алгоритм.
Ссори, просто у меня лимит суточный - 3 минуты на поиски того, что другие и сами могли бы поискать wink.gif

// когда искал алгоритм, нашел реализацию на Паскакале.

Спустя 38 минут, 16 секунд (17.07.2012 - 20:40) p.pavluxa написал(а):
Пожалуйста, я уже пол интернета облазил ничего нормального не нашел

Спустя 11 часов, 52 минуты, 26 секунд (18.07.2012 - 08:32) T1grOK написал(а):
Принцип работы ерунда, пишется на ура. Другое дело грамотный ход AI - это к сожалению я так и не осилил.

Спустя 1 час, 24 минуты, 56 секунд (18.07.2012 - 09:57) sergeiss написал(а):
p.pavluxa - вот честно скажу. Когда человек задает такие вопросы, то у меня сразу мысль появляется: а надо ли этому человеку быть программистом? Ведь есть еще много других, не менее интересных и не менее важных профессий.

Спустя 4 часа, 28 минут, 20 секунд (18.07.2012 - 14:26) p.pavluxa написал(а):
Скажу по секрету: я об существовании этой игры узнал ток вчера, никогда не сталкивался и правил не знаю и о чём идёт речь не понимаю

Спустя 1 час, 20 секунд (18.07.2012 - 15:26) Каролина написал(а):
p.pavluxa
древняя игра и узнал ток сейчас ее даже в школе преподают 1 раз в неделю с 1 по 4 классы

Спустя 20 минут, 50 секунд (18.07.2012 - 15:47) kamanch написал(а):
Каролина
Шашки в украинских школах? Серьезно?

Спустя 11 минут, 35 секунд (18.07.2012 - 15:58) waldicom написал(а):
Цитата (T1grOK @ 18.07.2012 - 06:32)
Принцип работы ерунда, пишется на ура. Другое дело грамотный ход AI - это к сожалению я так и не осилил.

Это прикольное дело! Я как-то программу учил в крестики-нолики выигрывать - получилось. Хотя там конечно ваще не сравнить с шашками (а тем более с шахматами).

Спустя 2 минуты, 39 секунд (18.07.2012 - 16:01) Каролина написал(а):
я в русской школе но в украине

Спустя 2 часа, 28 минут, 45 секунд (18.07.2012 - 18:30) p.pavluxa написал(а):
так вы поможете? Как определить после хода дамки, может ли она ещё побить или нет?

Спустя 17 минут, 34 секунды (18.07.2012 - 18:47) kamanch написал(а):
Цитата
Как определить после хода дамки, может ли она ещё побить или нет?

Так уже лучше.
Давай думать:
Поле у нас массив, делаем из него матрицу, визуализируем на листе бумаги, отмечаем в клетках индексы.
Создаем сначала обычные текствоые правила, которые пишем на бумаге:
1. Дамка может ходить по диоганали или ее части, если диоганаль или ее часть пуста.
2. Дамка может "бить" шашки соперника, если на траектории ее хода нет 2х рядом стоящих шашек (любых)
3. Если дамка сделала ход и не била, то ход закончен.
4. Если дамка сделал ход и била, то смотрим все новые диогонали, относительно ее нового места и возвращаемся к п.п. 2

Теперь переводим в код, создав несколько функций типа:
function может_ли_шашка ходить();
function является_ли_шашка_дамкой();
function есть_ли_на_диогонали_другие_шашки();
и т.д.

Спустя 13 минут, 10 секунд (18.07.2012 - 19:01) p.pavluxa написал(а):
Помогите пожалуйста составить 4 цикла, либо как-то их объединить, что бы я мог пройтись по диагоналям на которых расположена моя дамка.

То есть, у меня есть дамка, о ней я знаю её X и Y координаты. Так же я знаю размер поля. Моя задача первым циклом пройтись по вертикали которая отходит от точки сверху влево, далее сверху справа, далее снизу слева и далее снизу справа.

Как подобный цикл можно реализовать? Помогите пожалуйста, уже все мозги себе вынес.

Спустя 1 час, 37 минут, 5 секунд (18.07.2012 - 20:38) kamanch написал(а):
У тебя есть доска:
$desk = array();

В ней 64 элемента с индексами 0..63

Пишем функцию border (проверка, не уперлась ли шашка в бордюр, она возвращает нам 1 - верхний бордюр, 2 - правый бордюр, 3 - нижний бордюр, 4 - левый бордюр.

Пишем функцию diogonal($x, $course) // $x - координата шашки в массиве, $course - 1, 2, 3 или 4 - направление диогонали. Возвращает нам массив координат данной диогонали;

Если 1 (вправо-вниз):
while(border($x) != 2 and border($x) != 3){
$x = $x + 9;
$diogonal[] = $x;
}


Если 2 (вправо-вверх):
while(border($x) != 1 and border($x) != 2){
$x = $x -7;
$diogonal[] = $x;
}


И т.д.

Я же говорил - напиши, нарисуй доску, расставь индексы в ней, посмотри, что происходит, когда шашки ходят.



Спустя 12 минут, 59 секунд (18.07.2012 - 20:51) p.pavluxa написал(а):
Не совсем понятно как организована функция border, как её реализовать? Не догоняю идею

Спустя 6 минут, 5 секунд (18.07.2012 - 20:57) kamanch написал(а):
НУ ТЫ ЧЕГО??? user posted image
Верхний бордюр - множество 0..7
Правый бордюр - множество 7, 15, 23, 31, 39, 47, 55, 63
Нижний бордюр - множество 56..63
Левый бордюр - множество 0, 8, 16, 24, 32, 40, 56

Если координата шашка состоит в одном из этих множеств, зачит шашка стоит на бордюре.

Доску нарисуй и пронумеруй клетки от 0 до 63 сверху-вниз, слева-направо


Спустя 40 минут, 40 секунд (18.07.2012 - 21:37) kamanch написал(а):
1 - верхний бордюр, 2 - правый бордюр, 3 - нижний бордюр, 4 - левый бордюр.
0 - шашка не на бордюре.
 function border($x){
$border = array();
$border[1] = array(0, 1, 2, 3, 4, 5, 6 ,7);
$border[2] = array(7, 15, 23, 31, 39, 47, 55, 63);
$border[3] = array(56, 57, 58, 59, 60, 61, 62, 63);
$border[4] = array(0, 8, 16, 24, 32, 40, 56);
foreach ($border as $key => $value) {
if(!(array_search($x, $value) === false)){
return $key;
}
}

return 0;
}


Спустя 14 минут, 53 секунды (18.07.2012 - 21:52) p.pavluxa написал(а):
Я вот немного по другому почти сделал, токо не могу дотуплить как правильно получить 3 остальные диагонали.
function diagonalsValues( &$aMyArray, $iX, $iY ) {
echo 'Вы хотите получить диагонали элемента номер '.$aMyArray[$iY][$iX].'.<br />';
$aResult = array( array(), array(), array(), array() );

# Получение значений верхней левой диагонали :
for( $i = 1; $i < min( $iX, $iY ) + 1; $i++ )
$aResult[0][] = $aMyArray[$iY - $i][$iX - $i];

# Получение значений верхней правой диагонали :
for( $i = 1; $i < min( 8 - $iX, $iY ) + 1; $i++ )
$aResult[1][] = $aMyArray[$iY - $i][$iX + $i];

# Получение значений нижней левой диагонали :
for( $i = 1; $i < min( $iX, 7 - $iY ); $i++ )
$aResult[2][] = $aMyArray[$iY + $i][$iX - $i];

return $aResult;
}

Спустя 38 секунд (18.07.2012 - 21:53) p.pavluxa написал(а):
Правильно работает токо на верхней левой диагонали, а на остальных не хватает внимания что бы понять что за фигня и почему неверно работает

Спустя 3 минуты, 2 секунды (18.07.2012 - 21:56) sergeiss написал(а):
"В своё время" smile.gif развлекался, сделал Тетрис. На Си. Куда как проще: стакан Тетриса был представлен 2-мерным массивом. При попытке сдвинуть (повернуть) фигуру шла проверка: не занята ли хотя бы одна позиция, куда идет попытка сдвижки (поворота). В шашках принципиально то же самое, тоже 2-мерный массив нужен. Тогда с границами всё очень просто будет определяться.

Спустя 4 минуты, 44 секунды (18.07.2012 - 22:01) kamanch написал(а):
Если ты хочешь всеж в декартовых координатах (1..8 x 1..8), то проще так:

если x = 1 -> левый бордюр
если x = 8 -> правый бордюр
если y = 1 -> верхний бордюр
если y = 8 -> нижний бордюр

Спустя 16 минут, 35 секунд (18.07.2012 - 22:17) p.pavluxa написал(а):
сделал функцию которая получает все диагонали из указанного положения!

function diagonalsValues( &$aMyArray, $iX, $iY ) {

echo 'Вы хотите получить диагонали элемента номер '.$aMyArray[$iY][$iX].'.<br />';

# Определяем размер поля :
$iArraySize = count( $aMyArray );

# Проверка внешних данных :
if( $iX >= $iArraySize || $iY >= $iArraySize )
throw new Exception( 'wrong coordinate' );

$aResult = array( 'top_left' => array(), 'top_right' => array(), 'bottom_left' => array(), 'bottom_right' => array() );

# Получение значений верхней левой диагонали :
for( $i = 1; $i <= min( $iX, $iY ); $i++ )
$aResult['top_left'][] = $aMyArray[$iY - $i][$iX - $i];

# Получение значений верхней правой диагонали :
for( $i = 1; $i <= min( 7 - $iX, $iY ); $i++ )
$aResult['top_right'][] = $aMyArray[$iY - $i][$iX + $i];

# Получение значений нижней левой диагонали :
for( $i = 1; $i <= min( $iX, 7 - $iY ); $i++ )
$aResult['bottom_left'][] = $aMyArray[$iY + $i][$iX - $i];

# Получение значений нижней правой диагонали :
for( $i = 1; $i <= min( 7 - $iX, 7 - $iY ); $i++ )
$aResult['bottom_right'][] = $aMyArray[$iY + $i][$iX + $i];

return $aResult;
}

Спустя 11 минут, 3 секунды (18.07.2012 - 22:28) kamanch написал(а):
на угловых клеткай потестируй

Спустя 9 минут, 39 секунд (18.07.2012 - 22:38) p.pavluxa написал(а):
Протестил, всё отлично

Спустя 54 секунды (18.07.2012 - 22:39) kamanch написал(а):
у тебя координаты какие? 0-7 или 1-8 ?

Спустя 33 секунды (18.07.2012 - 22:39) p.pavluxa написал(а):
Координаты начинаются с 0.Теперь возникает вопрос, а как же полученные массивы обрабатывать? Как понять, может ли в них ударить дамка или нет?

Спустя 24 минуты, 15 секунд (18.07.2012 - 23:04) kamanch написал(а):
я же выше описывал: Может ли дамка ходить / бить

Вообще, то, чем ты сейчас занимаешься - это есть в чистом виде Математическое моделирование.
Ты создаешь мат. модель реального объекта из нашего мира.
Абстрагируйся от программирования, сделай проекцию на реальную ситуацию. Как себя ведет ситуация в том или ином случае, какие ветвления получаются.

Вот у тебя вопрос:
Цитата
может ли в них ударить дамка или нет?

Значит тебе необходима функция is_move($iX, $iY, $new_iX, $new_iY )
Сначала разбей весь предпологаемый код на мелкие части. Пусть у тебя будет 150 функций, каждая из которых будет выполнять свою маленькую конечную задачу.
Так будет очень легко прослеживать логику кода
На любой вопрос, типа "а может ли...?" возникший у тебя в голове, пишешь функцию типа is_что_то_можно(этой_шашке), которая вернет булево значение.

Спустя 11 часов, 24 минуты, 49 секунд (19.07.2012 - 10:28) p.pavluxa написал(а):
В принципе всё готово, за исключением того что нужно после каждого хода проверять, нет ли победителя. Как это организовать? Та легко, если у одного из игроков нет шашек, то другой посетитель. Либо у одного из игроков нет ходов, то другой победитель.

Спустя 2 минуты, 18 секунд (19.07.2012 - 10:31) kamanch написал(а):
Ну выкладывай, будем обмывать smile.gif

Спустя 2 минуты (19.07.2012 - 10:33) p.pavluxa написал(а):

class XCheckers {
private $iGameID;
public $aPlayGround;
public $iGroundSize;
public $iWhoseMove;

# Конструктор: принимает ID игры.
public function __construct( $iGameID ) {

# Получение информации об игре с базы данных :
if( ($aGame = DB()->query( 'SELECT * FROM `Checkers` WHERE `ID` = '.$iGameID )->fetch( PDO::FETCH_ASSOC )) === false )
throw new Exception( 'game not found' );

# Полученные данные записываем в класс :
$this->iGameID = $iGameID;
$this->aPlayGround = json_decode( $aGame['playGround'] );
$this->iGroundSize = count( $this->aPlayGround );
$this->iWhoseMove = intval( $aGame['whoseMove'] );
}

# Деконструктор: обновляет данные об игре.
public function __destruct() {

# Обновляем информацию в базе данных :
DB()->prepare( "UPDATE `Checkers` SET `playGround` = ?, `whoseMove` = '".$this->iWhoseMove."' WHERE `ID` = ".$this->iGameID )->execute( array( json_encode( $this->aPlayGround ) ) );
}

# Метод: перемещение шашки игроком.
public function Move( $iFrom, $iTo ) {

# Проверка внешних данных :
if( $iFrom < 0 || $iFrom >= $this->iGroundSize * $this->iGroundSize )
return -1;
if( $iTo < 0 || $iTo >= $this->iGroundSize * $this->iGroundSize )
return -2;

# Преобразование в координаты :
$iFromX = $iFrom % $this->iGroundSize;
$iFromY = intval( $iFrom / $this->iGroundSize );
$iToX = $iTo % $this->iGroundSize;
$iToY = intval( $iTo / $this->iGroundSize );

# Если координаты от куда и куда равны :
if( $iFromX == $iToX && $iFromY == $iToY )
return -4;

# Пренадлежит ли перемещаемая шашка текущему игроку ?
if( $this->aPlayGround[$iFromY][$iFromX] != $this->iWhoseMove && $this->aPlayGround[$iFromY][$iFromX] != $this->iWhoseMove + 2 )
return -5;

# Находится ли место перемещения на диалогонале с перемещаемой шашкой?
if( abs( $iFromX - $iToX ) != abs( $iFromY - $iToY ) )
return -6;

# Место куда хотим поставить должно быть свободным :
if( $this->aPlayGround[$iToY][$iToX] != 0 )
return -7;

# Если передвигаемая шашка - пешка :
if( $this->aPlayGround[$iFromY][$iFromX] < 3 ) {

# Если шашка перемещается на одну клетку, то она делает ход :
if( abs( $iFromX - $iToX ) == 1 ) {

# Пешка может делать ход, только в одном направлении :
if( ($this->iWhoseMove == 1 && $iFromY >= $iToY) || ($this->iWhoseMove == 2 && $iFromY <= $iToY) )
return -9;

# Проверяем, нет ли обязательного хода пешкой либо дамкой :
if( $this->isHaveRequestAttack() )
return -13;

# Перемещаем шашку на новую позицию :
$this->aPlayGround[$iToY][$iToX] = $this->aPlayGround[$iFromY][$iFromX];
$this->aPlayGround[$iFromY][$iFromX] = 0;

# Если она дошла до конца доски, то она превращается в дамку :
if( ($this->iWhoseMove == 1 && $iToY == $this->iGroundSize - 1) || ($this->iWhoseMove == 2 && $iToY == 0) )
$this->aPlayGround[$iToY][$iToX] += 2;

# Передаем ход противнику :
$this->iWhoseMove = $this->iWhoseMove == 1 ? 2 : 1;

return true;
}
# Иначе, если шашка перемещается на две клетки, то она бьёт :
else if( abs( $iFromX - $iToX ) == 2 ) {

# Между шашкой и местом перемещения должна находится шашка противника :
if( $this->aPlayGround[($iFromY+$iToY)/2][($iFromX+$iToX)/2] != ($this->iWhoseMove == 1 ? 2 : 1) && $this->aPlayGround[($iFromY+$iToY)/2][($iFromX+$iToX)/2] != ($this->iWhoseMove == 1 ? 4 : 3) )
return -10;

# Убераем убитую шашку :
$this->aPlayGround[($iFromY+$iToY)/2][($iFromX+$iToX)/2] = 0;

# Перемещаем шашку на новую позицию :
$this->aPlayGround[$iToY][$iToX] = $this->aPlayGround[$iFromY][$iFromX];
$this->aPlayGround[$iFromY][$iFromX] = 0;

# Если она дошла до конца доски, то она превращается в дамку :
if( ($this->iWhoseMove == 1 && $iToY == $this->iGroundSize - 1) || ($this->iWhoseMove == 2 && $iToY == 0) )
$this->aPlayGround[$iToY][$iToX] += 2;

# Если нельзя ударить ещё раз, то передаём ход противнику :
if( !(isset( $this->aPlayGround[$iToY-2] ) && isset( $this->aPlayGround[$iToY-2][$iToX-2] ) && $this->aPlayGround[$iToY-1][$iToX-1] == ($this->iWhoseMove == 1 ? 2 : 1) && $this->aPlayGround[$iToY-2][$iToX-2] == 0) && !(isset( $this->aPlayGround[$iToY-2] ) && isset( $this->aPlayGround[$iToY-2][$iToX+2] ) && $this->aPlayGround[$iToY-1][$iToX+1] == ($this->iWhoseMove == 1 ? 2 : 1) && $this->aPlayGround[$iToY-2][$iToX+2] == 0) && !(isset( $this->aPlayGround[$iToY+2] ) && isset( $this->aPlayGround[$iToY+2][$iToX-2] ) && $this->aPlayGround[$iToY+1][$iToX-1] == ($this->iWhoseMove == 1 ? 2 : 1) && $this->aPlayGround[$iToY+2][$iToX-2] == 0) && !(isset( $this->aPlayGround[$iToY+2] ) && isset( $this->aPlayGround[$iToY+2][$iToX+2] ) && $this->aPlayGround[$iToY+1][$iToX+1] == ($this->iWhoseMove == 1 ? 2 : 1) && $this->aPlayGround[$iToY+2][$iToX+2] == 0) )
$this->iWhoseMove = $this->iWhoseMove == 1 ? 2 : 1;

return true;
}
# Иначе пешкой сделать ход более чем на 1 ячейку :
return -8;
}
# Если передвигаемая шашка - дамка :
else {

# На пути перемещения может быть только шашка противника в кол-ве - 1 :
for( $i = 1, $iCounter = 0; $i <= abs( $iFromX - $iToX ); $i++ ) {

# Получение значения ячейки :
$iCell = $this->aPlayGround[$iFromY + $i * ($iToY > $iFromY ? 1 : (-1))][$iFromX + $i * ($iToX > $iFromX ? 1 : (-1))];

# Если встретилась своя шашка :
if( $iCell == $this->aPlayGround[$iFromY][$iFromX] || $iCell == $this->aPlayGround[$iFromY][$iFromX] - 2 )
return -12;
# Иначе, если встретилась шашка противника :
else if( $iCell != 0 )
$iCounter++;

# Проверка количества шашек противника :
if( $iCounter > 1 )
return -13;
}

# Если дамка выполняет удар:
if( $iCounter > 0 ) {

# Забираем с пути шашку противника :
for( $i = 1; $i <= abs( $iFromX - $iToX ); $i++ )
$this->aPlayGround[$iFromY + $i * ($iToY > $iFromY ? 1 : (-1))][$iFromX + $i * ($iToX > $iFromX ? 1 : (-1))] = 0;

# Переносим дамку :
$this->aPlayGround[$iToY][$iToX] = $this->aPlayGround[$iFromY][$iFromX];
$this->aPlayGround[$iFromY][$iFromX] = 0;

# Если дамкой хода сделать нельзя, то передаём ход сопернику :
$bHaveAttack = false;
foreach( $this->diagonalsValues( $iToX, $iToY ) as $aDiagonal ) {
for( $i = 0; $i < count( $aDiagonal ); $i++ ) {

# Если это шашка текущего игрока :
if( $aDiagonal[$i] == $this->aPlayGround[$iFromY][$iFromX] || $aDiagonal[$i] == $this->aPlayGround[$iFromY][$iFromX] - 2 )
break;
# Иначе, если это шашка противника :
else if( $aDiagonal[$i] != 0 ) {
if( isset( $aDiagonal[$i+1] ) && $aDiagonal[$i+1] == 0 ) {
$bHaveAttack = true;
break 2;
}
break;
}
}
}

if( !$bHaveAttack )
$this->iWhoseMove = $this->iWhoseMove == 1 ? 2 : 1;
}
# Иначе, дамка выполняет ход :
else {

# Проверяем, нет ли обязательного хода пешкой либо дамкой :
if( $this->isHaveRequestAttack() )
return -13;

# Передаем ход сопернику :
$this->iWhoseMove = $this->iWhoseMove == 1 ? 2 : 1;

# Переносим дамку :
$this->aPlayGround[$iToY][$iToX] = $this->aPlayGround[$iFromY][$iFromX];
$this->aPlayGround[$iFromY][$iFromX] = 0;
}

return true;
}

return 0;
}
private function isHaveRequestAttack() {
for( $iY = 0; $iY < $this->iGroundSize; $iY++ ) {
for( $iX = 0; $iX < $this->iGroundSize; $iX++ ) {
if( ($this->aPlayGround[$iY][$iX] == $this->iWhoseMove || $this->aPlayGround[$iY][$iX] == $this->iWhoseMove + 2) && ((isset( $this->aPlayGround[$iY-2] ) && isset( $this->aPlayGround[$iY-2][$iX-2] ) && ($this->aPlayGround[$iY-1][$iX-1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY-1][$iX-1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY-2][$iX-2] == 0) || (isset( $this->aPlayGround[$iY-2] ) && isset( $this->aPlayGround[$iY-2][$iX+2] ) && ($this->aPlayGround[$iY-1][$iX+1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY-1][$iX+1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY-2][$iX+2] == 0) || (isset( $this->aPlayGround[$iY+2] ) && isset( $this->aPlayGround[$iY+2][$iX-2] ) && ($this->aPlayGround[$iY+1][$iX-1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY+1][$iX-1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY+2][$iX-2] == 0) || (isset( $this->aPlayGround[$iY+2] ) && isset( $this->aPlayGround[$iY+2][$iX+2] ) && ($this->aPlayGround[$iY+1][$iX+1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY+1][$iX+1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY+2][$iX+2] == 0)) )
return true;
else if( $this->aPlayGround[$iY][$iX] == $this->iWhoseMove + 2 ) {
foreach( $this->diagonalsValues( $iX, $iY ) as $aDiagonal ) {
for( $i = 0; $i < count( $aDiagonal ); $i++ ) {

# Если это шашка текущего игрока :
if( $aDiagonal[$i] == $this->iWhoseMove || $aDiagonal[$i] == $this->iWhoseMove + 2 )
break;
# Иначе, если это шашка противника :
else if( $aDiagonal[$i] != 0 ) {
print_r( $aDiagonal );
if( isset( $aDiagonal[$i+1] ) && $aDiagonal[$i+1] == 0 )
return true;
break;
}
}
}
}
}
}

return false;
}
private function diagonalsValues( $iX, $iY ) {

# Проверка внешних данных :
if( $iX >= $this->iGroundSize || $iY >= $this->iGroundSize )
throw new Exception( 'wrong coordinate' );

$aResult = array( 'top_left' => array(), 'top_right' => array(), 'bottom_left' => array(), 'bottom_right' => array() );

# Получение значений верхней левой диагонали :
for( $i = 1; $i <= min( $iX, $iY ); $i++ )
$aResult['top_left'][] = $this->aPlayGround[$iY - $i][$iX - $i];

# Получение значений верхней правой диагонали :
for( $i = 1; $i <= min( 7 - $iX, $iY ); $i++ )
$aResult['top_right'][] = $this->aPlayGround[$iY - $i][$iX + $i];

# Получение значений нижней левой диагонали :
for( $i = 1; $i <= min( $iX, 7 - $iY ); $i++ )
$aResult['bottom_left'][] = $this->aPlayGround[$iY + $i][$iX - $i];

# Получение значений нижней правой диагонали :
for( $i = 1; $i <= min( 7 - $iX, 7 - $iY ); $i++ )
$aResult['bottom_right'][] = $this->aPlayGround[$iY + $i][$iX + $i];

return $aResult;
}
private function WinnerSearch() {

}
}


Спустя 1 минута, 7 секунд (19.07.2012 - 10:34) p.pavluxa написал(а):
Ну как-то так :-)

Спустя 3 минуты, 2 секунды (19.07.2012 - 10:37) p.pavluxa написал(а):
В принципе вариант что нет шашек и нет ходов можно объеденить одним - нет ходов. Так как если нет шашек то не будет и ходов.

Спустя 2 часа, 24 минуты, 44 секунды (19.07.2012 - 13:02) p.pavluxa написал(а):
Дописал функцию поиска победителя, но не могу понять почему она не правильно работает. Помогите пожалуйста разобраться:
# !Метод: поиск победителя в игре.
# Возвращает:
# 0 - не найдено,
# 1 - первый игрок,
# 2 - второй игрок.

public function WinnerSearch() {

# Поиск игрока, у которого нет ходов :
$bHaveAttacks = array( false, false );
for( $iX = 0; $iX < $this->iGroundSize; $iX++ ) {
for( $iY = 0; $iY < $this->iGroundSize; $iY++ ) {

# Получение содержимого ячейки :
$iValue = $this->aPlayGround[$iY][$iX];

# Если это не шашка, то пропускаем :
if( $iValue == 0 )
continue;

# Если эта шашка пренадлежит игроку, у которого уже есть ходы, то пропускаем :
if( $bHaveAttacks[($iValue > 2 ? $iValue - 2 : $iValue) - 1] )
continue;

# Если это шашка :
if( $iValue < 3 ) {
if( (isset( $this->aPlayGround[$iY-2] ) && isset( $this->aPlayGround[$iY-2][$iX-2] ) && ($this->aPlayGround[$iY-1][$iX-1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY-1][$iX-1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY-2][$iX-2] == 0) || (isset( $this->aPlayGround[$iY-2] ) && isset( $this->aPlayGround[$iY-2][$iX+2] ) && ($this->aPlayGround[$iY-1][$iX+1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY-1][$iX+1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY-2][$iX+2] == 0) || (isset( $this->aPlayGround[$iY+2] ) && isset( $this->aPlayGround[$iY+2][$iX-2] ) && ($this->aPlayGround[$iY+1][$iX-1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY+1][$iX-1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY+2][$iX-2] == 0) || (isset( $this->aPlayGround[$iY+2] ) && isset( $this->aPlayGround[$iY+2][$iX+2] ) && ($this->aPlayGround[$iY+1][$iX+1] == ($this->iWhoseMove == 1 ? 2 : 1) || $this->aPlayGround[$iY+1][$iX+1] == ($this->iWhoseMove == 1 ? 4 : 3)) && $this->aPlayGround[$iY+2][$iX+2] == 0) )
$bHaveAttacks[$iValue - 1] = true;
}
# Иначе, это дамка :
else {
foreach( $this->diagonalsValues( $iX, $iY ) as $aDiagonal ) {
for( $k = 0; $k < count( $aDiagonal ); $k++ ) {

# Если это шашка текущего игрока :
if( $aDiagonal[$k] == ($iValue > 2 ? $iValue - 2 : $iValue) || $aDiagonal[$k] == ($iValue > 2 ? $iValue - 2 : $iValue) + 2 )
break;
# Иначе, если это шашка противника :
else if( $aDiagonal[$k] != 0 ) {
if( isset( $aDiagonal[$k+1] ) && $aDiagonal[$k+1] == 0 )
$bHaveAttacks[$iValue - 1] = true;
break;
}
}
}
}


# Если у обоих игроков есть ходы, то завершаем цикл :
if( $bHaveAttacks[0] && $bHaveAttacks[1] )
break 2;
}
}

if( !$bHaveAttacks[0] )
return 2;
else if( !$bHaveAttacks[1] )
return 1;

return 0;
}

Спустя 6 часов, 13 минут, 28 секунд (19.07.2012 - 19:15) p.pavluxa написал(а):
Не могу дать дупля, почему то шашка не видит дамки а дамка не видит шашки.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.