Skip to content

Instantly share code, notes, and snippets.

@VirtuosiMedia
Created September 10, 2012 03:42
Show Gist options
  • Save VirtuosiMedia/3688742 to your computer and use it in GitHub Desktop.
Save VirtuosiMedia/3688742 to your computer and use it in GitHub Desktop.
Demo classes for moving chess pieces
<?php
/**
* @description An abstract class for all chess pieces
* @author Benjamin Kuker
*/
abstract class ChessPiece {
protected $color = null;
protected $constraints = array();
protected $currentPosition = null;
protected $history = array();
protected $name = null;
/**
* @param string $name - The name of the chess piece: B=Bishop, R=Rook, Q=Queen, K=King, N=Knight, and an empty
* string should be used for Pawns
* @param string $startingPosition - The starting position of the chess piece, in algebraic notation
* @param string $color - Either 'black' or 'white'
*/
function __construct($name, $startingPosition, $color){
$this->name = "$color $name";
$this->currentPosition = $startingPosition;
$this->color = $color;
}
/**
* @description Gets the shorthand name of the chess piece
* @return - The shorthand name of the chess piece
*/
public function getName(){
return $this->name;
}
/**
* @description Gets the color of the chess piece.
* @return - The color of the chess piece, either 'black' or 'white'
*/
public function getColor(){
return $this->color;
}
/**
* @description Gets the valid moves for the piece
* @param array $boardState - A multi-dimensional array of type $boardState[row][column], with 8 rows and 8 lettered
* columns (a-h) in each row. The value of each column should reflect the status of that square. If it is empty,
* the value should be null, if it is occupied by a piece, it should contain an object representing that piece.
* @return array An array of valid moves for the piece, given the current board and the piece's current position
*/
abstract public function getValidMoves(array $boardState);
/**
* @description Checks possible moves for conflicts with pieces on the same team
* @param array $possibleMoves - An array of possible moves to check for conflicts
* @param array $boardState - A multi-dimensional array of type $boardState[row][column], with 8 rows and 8 lettered
* columns (a-h) in each row. The value of each column should reflect the status of that square. If it is empty,
* the value should be null, if it is occupied by a piece, it should contain an object representing that piece.
* @return array An array of valid moves for the piece, given the current board and the piece's current position
*/
abstract protected function checkTeamConflicts(array $possibleMoves, array $boardState);
/**
* @description Checks a move to see if it is valid
* @param string $move The proposed position of the chess piece, in algebraic notation
* @param array $boardState - A multi-dimensional array of type $boardState[row][column], with 8 rows and 8 lettered
* columns (a-h) in each row. The value of each column should reflect the status of that square. If it is empty,
* the value should be null, if it is occupied by a piece, it should contain an object representing that piece.
* @return boolean
*/
public function isValidMove($move, array $boardState){
return (in_array($move, $this->getValidMoves($boardState)));
}
/**
* @description Moves a piece, if the move is valid, and records the move to the piece's history
* @param string $move The proposed position of the chess piece, in algebraic notation
* @param array $boardState - A multi-dimensional array of type $boardState[row][column], with 8 rows and 8 lettered
* columns (a-h) in each row. The value of each column should reflect the status of that square. If it is empty,
* the value should be null, if it is occupied by a piece, it should contain an object representing that piece.
* @param boolean $captures - Whether or not the move will result in capturing an opposing piece
* @return boolean - TRUE if the move was successful, FALSE otherwise
*/
public function movePiece($move, array $boardState, $captures = false){
if (isValidMove($move, $boardState)){
if ($captures){
if ($this->name === ''){ //Pawn captures
$previousPosition = explode('', $this->currentPosition);
$this->history[] = $name.$previousPosition[0].'x'.$move;
} else {
$this->history[] = $name.'x'.$move;
}
} else {
$this->history[] = $name.$move;
}
$this->currentPosition = $move;
return true;
}
return false;
}
/**
* @description Gets the history of the piece
* @return array The history of the piece, with each move as an array item
*/
public function getHistory(){
return $this->history;
}
/**
* @description Gets the last move of the piece
* @return string The last move of the piece, in algebraic notation
*/
public function getLastMove(){
return end($this->history);
}
/**
* @description Gets the current position of the piece
* @return string The current position of the piece, in algebraic notation
*/
public function getCurrentPosition(){
return $this->currentPosition;
}
}
/**
* @description A class for controlling a knight
* @author Benjamin Kuker
*/
class Knight extends ChessPiece {
/**
* @param string $startingPosition - The starting position of the chess piece, in algebraic notation
* @param string $color - Either 'black' or 'white'
*/
function __construct($startingPosition, $color){
parent::__construct('N', $startingPosition, $color);
}
/**
* (non-PHPdoc)
* @see ChessPiece::getValidMoves()
*/
public function getValidMoves(array $boardState){
$allColumns = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h');
$position = str_split($this->currentPosition);
$column = array_search($position[0], $allColumns);
$row = $position[1] - 1;
$possibleMoves = array();
if ($column > 0){ //Near left side is available
$newColumn = $column - 1;
if (($row + 2) < 7){
$possibleMoves[] = $allColumns[$newColumn].($row + 3);
}
if (($row - 2) >= 0){
$possibleMoves[] = $allColumns[$newColumn].($row - 1);
}
}
if ($column > 1){ //Far left side is available
$newColumn = $column - 2;
if (($row + 1) < 7){
$possibleMoves[] = $allColumns[$newColumn].($row + 2);
}
if (($row - 1) > 0){
$possibleMoves[] = $allColumns[$newColumn].$row;
}
}
if ($column < 7){ //Near right side is available
$newColumn = $column + 1;
if (($row + 2) < 7){
$possibleMoves[] = $allColumns[$newColumn].($row + 3);
}
if (($row - 2) >= 0){
$possibleMoves[] = $allColumns[$newColumn].($row - 1);
}
}
if ($column < 6){ //Far right side is available
$newColumn = $column + 2;
if (($row + 1) < 7){
$possibleMoves[] = $allColumns[$newColumn].($row + 2);
}
if (($row - 1) > 0){
$possibleMoves[] = $allColumns[$newColumn].$row;
}
}
return $this->checkTeamConflicts($possibleMoves, $boardState);
}
/**
* (non-PHPdoc)
* @see ChessPiece::checkTeamConflicts()
*/
protected function checkTeamConflicts($possibleMoves, array $boardState){
$validMoves = array();
foreach($possibleMoves as $move){
list($column, $row) = str_split($move);
$row -= 1;
$square = $boardState[$row][$column];
if ((!$square) || ($square->getColor() !== $this->color)){
$validMoves[] = $move;
}
}
return $validMoves;
}
}
/**
* @description A generic chess piece class used only for demonstration purposes
* @author Benjamin Kuker
*/
class GenericPiece extends ChessPiece {
/**
* @param string $startingPosition - The starting position of the chess piece, in algebraic notation
* @param string $color - Either 'black' or 'white'
*/
function __construct($startingPosition, $color){
parent::__construct('GP', $startingPosition, $color);
}
/**
* (non-PHPdoc)
* @see ChessPiece::getValidMoves()
*/
public function getValidMoves(array $boardState){}
/**
* (non-PHPdoc)
* @see ChessPiece::checkTeamConflicts()
*/
protected function checkTeamConflicts($possibleMoves, array $boardState){}
}
/**
* Demonstration - Uncomment the following examples to see how the class would be used
*/
/**
* Get moves on an empty board
*/
/* (Just add a / to the beginning of the line to uncomment the code)
$emptyBoard = array(
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null)
);
$knight = new Knight('e4', 'white');
var_dump($knight->getValidMoves($emptyBoard));
//*/
/**
* Get moves on a board with pieces from same team
*/
/* (Just add a / to the beginning of the line to uncomment the code)
$whitePiece1 = new GenericPiece('f6', 'white');
$whitePiece2 = new GenericPiece('f2', 'white');
$board = array(
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>$whitePiece2, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>$whitePiece1, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null)
);
$knight = new Knight('e4', 'white');
var_dump($knight->getValidMoves($board));
//*/
/**
* Get moves on a board with pieces from opposite team
*/
/* (Just add a / to the beginning of the line to uncomment the code)
$blackPiece1 = new GenericPiece('d6', 'black');
$blackPiece2 = new GenericPiece('d2', 'black');
$board = array(
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>$blackPiece2, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>$blackPiece1, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null)
);
$knight = new Knight('e4', 'white');
var_dump($knight->getValidMoves($board));
//*/
/**
* Get moves on a board with pieces from both teams
*/
/* (Just add a / to the beginning of the line to uncomment the code)
$blackPiece1 = new GenericPiece('d6', 'black');
$blackPiece2 = new GenericPiece('d2', 'black');
$whitePiece1 = new GenericPiece('f6', 'white');
$whitePiece2 = new GenericPiece('f2', 'white');
$board = array(
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>$blackPiece2, 'e'=>null, 'f'=>$whitePiece2, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>$blackPiece1, 'e'=>null, 'f'=>$whitePiece1, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null),
array('a'=>null, 'b'=>null, 'c'=>null, 'd'=>null, 'e'=>null, 'f'=>null, 'g'=>null, 'h'=>null)
);
$knight = new Knight('e4', 'white');
var_dump($knight->getValidMoves($board));
//*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment