Как изменить значение объекта в многомерном массиве с ООП в Stack Overflow

Я строю игру в шахматы, которая случайным образом помещает 7 ферзей на доску, не задевая друг друга. Доска построена из 7 рядов и 7 столбцов. Пока я сделал следующие шаги

  1. Сделано 5 классов: Игра, Доска, Коробка, Кусок и Королева.
  2. Создан и экземпляр игры.
  3. Создан новый объект Board с методом createBoard.
  4. Создан метод showBoard для отображения доски.

Теперь я хочу поместить первую ферзь в случайное поле на доске, но я не знаю, как получить доступ к объекту многомерного массива. Метод set_piece должен получить доступ к объекту доски и поместить Q в случайное поле, а затем пометить поле как занятое = true. Кто-нибудь знает, как должен быть построен метод set_piece в классе Game?

Класс игры:

class Game {
var $board;
var $length;

public function createBoard($length) {
$this->board = new Board($length);
$this->length = $length;
}

public function showBoard() {
// Create table
$table_str = '<table border="1px">';
for($row=1; $row <= $this->length; $row++) {
$table_str .= "<tr>";
for($col=1; $col <= $this->length; $col++) {
$total = $row + $col;
if($total%2==0) {
$table_str .= "<td height=100px width=100px bgcolor=#FFFFFF></td>";
} else {
$table_str .= "<td height=60px width=60px bgcolor=#000000></td>";
}
}
$table_str .= "</tr>";
}
return $table_str;
}
public function set_piece() {

}
}

Класс платы:

class Board {
public $box;
public function __construct($length) {
for($i=0; $i < $length; $i++){
for($j=0; $j< $length; $j++){
$this->box[$i+1][$j+1] = new Box($i+1, $j+1);
}
}
}
}

Класс коробки:

class Box {
public $piece;
public $occupied = false;
}

Штучный класс:

class Piece {

}

Королева класс:

class Queen extends Piece {

}

Индекс:

$game = new Game();

$game->createBoard(7);
$game->set_piece();

echo $game->showBoard();

echo "<pre>";
print_r($game->board);
echo "</pre>";

Массив, к которому я пытаюсь получить доступ, выглядит так:

Board Object
(
[box] => Array
(
[1] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

[2] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

[3] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

[4] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

[5] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

[6] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

[7] => Array
(
[1] => Box Object
(
[piece] =>
[occupied] =>
)

[2] => Box Object
(
[piece] =>
[occupied] =>
)

[3] => Box Object
(
[piece] =>
[occupied] =>
)

[4] => Box Object
(
[piece] =>
[occupied] =>
)

[5] => Box Object
(
[piece] =>
[occupied] =>
)

[6] => Box Object
(
[piece] =>
[occupied] =>
)

[7] => Box Object
(
[piece] =>
[occupied] =>
)

)

)

)

0

Решение

Поскольку у вас уже есть почти идеальный OO-макет, попробуйте уменьшить проблему: вместо доступа к многомерному массиву попробуйте добавить методы получения и установки для явного обращения к определенному уровню.

Один подход:

$Game->getBoard()->getBox($row, $col)->getPiece()->set($queen);

Где более сложной функцией будет getBox($row, $col):

class Board {
public $box;
public function __construct($length) {
for($i=0; $i < $length; $i++){
for($j=0; $j< $length; $j++){
$this->box[$i+1][$j+1] = new Box($i+1, $j+1);
}
}
}

public function getBox($row, $col) {
return $this->box[$row][$col];  // should ave some eception handling here!
}
}
0

Другие решения

Я бы сказал, что это метод, который вы ищете:

public function set_piece(Piece $piece, $x, $y) {
$this->board->box[$x][$y]->piece = $piece;
$this->board->box[$x][$y]->occupied = true;
}

Однако вы должны подумать о рефакторинге вашего кода. Приведенный выше код использует тот факт, что вы создали свойства плат как public, Поначалу это может показаться удобным, так как вы можете просто получить доступ и изменить внутренние объекты. Но это противоречит идее ООП, заключающейся в том, что это именно то, что вы не должны делать или не должны делать. Вместо этого вы должны скрыть внутренние объекты, объявив их private или же protected, Доступ должен быть возможен только через методы получения и установки для свойств.

0

Вы должны использовать setPiece вместо того, чтобы смешивать camelCase и snake_case. Вот одна из реализаций. Вы также можете рассмотреть возможность использования частных переменных экземпляра вместо общих переменных. После того, как вы сделаете общедоступным, вы не сможете вернуться назад, но вы всегда можете сделать частные переменные общедоступными позже. Вот что будет, если occupied стал ложным, но piece содержал Piece, Тогда у вас будет противоречивое состояние. На самом деле, я бы посоветовал вам бросить occupied собственность в целом, и просто есть свойство части.

class Game {
private $board; // use private vars since you're already doing accessors
...
public function setPiece ($row, $col, Piece $piece) {
$this->board->setPiece($row, $col, $piece);
}
}

class Board {
...
public function setPiece ($row, $col, Piece $piece) {
// since box is an array, make it plural
$this->boxes[$row][$col]->setPiece($piece);
}
}

class Box {
...
public function setPiece (Piece $piece) {
$this->piece = $piece;
}
public function isOccupied () {
return !empty($this->piece);
}
}
0

И незначительная вещь: вам действительно нужно public $occupied в Box учебный класс? Если $piece является NULL чем он не занят?

0
По вопросам рекламы [email protected]