2-Player Pokémon Chess [Work in progress]
Because it's more fun this way. Coming up some day: AI, isometric grid, and shadows!
http://minite.ch/chess/?i=1http://minite.ch/chess/?i=2http://minite.ch/chess/?i=3http://minite.ch/chess/?i=4http://minite.ch/chess/?i=5http://minite.ch/chess/?i=6http://minite.ch/chess/?i=7http://minite.ch/chess/?i=8
http://minite.ch/chess/?i=9http://minite.ch/chess/?i=10http://minite.ch/chess/?i=11http://minite.ch/chess/?i=12http://minite.ch/chess/?i=13http://minite.ch/chess/?i=14http://minite.ch/chess/?i=15http://minite.ch/chess/?i=16
http://minite.ch/chess/?i=17http://minite.ch/chess/?i=18http://minite.ch/chess/?i=19http://minite.ch/chess/?i=20http://minite.ch/chess/?i=21http://minite.ch/chess/?i=22http://minite.ch/chess/?i=23http://minite.ch/chess/?i=24
http://minite.ch/chess/?i=25http://minite.ch/chess/?i=26http://minite.ch/chess/?i=27http://minite.ch/chess/?i=28http://minite.ch/chess/?i=29http://minite.ch/chess/?i=30http://minite.ch/chess/?i=31http://minite.ch/chess/?i=32
http://minite.ch/chess/?i=33http://minite.ch/chess/?i=34http://minite.ch/chess/?i=35http://minite.ch/chess/?i=36http://minite.ch/chess/?i=37http://minite.ch/chess/?i=38http://minite.ch/chess/?i=39http://minite.ch/chess/?i=40
http://minite.ch/chess/?i=41http://minite.ch/chess/?i=42http://minite.ch/chess/?i=43http://minite.ch/chess/?i=44http://minite.ch/chess/?i=45http://minite.ch/chess/?i=46http://minite.ch/chess/?i=47http://minite.ch/chess/?i=48
http://minite.ch/chess/?i=49http://minite.ch/chess/?i=50http://minite.ch/chess/?i=51http://minite.ch/chess/?i=52http://minite.ch/chess/?i=53http://minite.ch/chess/?i=54http://minite.ch/chess/?i=55http://minite.ch/chess/?i=56
http://minite.ch/chess/?i=57http://minite.ch/chess/?i=58http://minite.ch/chess/?i=59http://minite.ch/chess/?i=60http://minite.ch/chess/?i=61http://minite.ch/chess/?i=62http://minite.ch/chess/?i=63http://minite.ch/chess/?i=64
No en passant or castling, sorry. Checkmate/check/stalemate detection to be implemented. Sprites from here: http://floatzel.net/pokemon/black-white/sprites/
Here's the source:
<?php
session_start();
function kick() {
header("Status: Forbidden\r\n", true, 403);
header("Content-Type: text/plain\r\n");
die('Go away.');
}
function isEnemy($item) {
return $item !== -1 && $item & 8;
}
function iValidMoves($board, $type, $x, $y) {
$results = array();
switch($type) {
case 0:
# Pawn
if($board[$y - 1][$x] === -1) {
$results[] = array($x, $y - 1);
if($y == 6 && $board[$y - 2][$x] === -1) $results[] = array($x, $y - 2);
}
if($x > 0 && isEnemy($board[$y - 1][$x - 1])) $results[] = array($x - 1, $y - 1);
if($x < 7 && isEnemy($board[$y - 1][$x + 1])) $results[] = array($x + 1, $y - 1);
break;
case 1:
# King
if($x > 0 && $board[$y][$x - 1] & 8) $results[] = array($x - 1, $y);
if($x > 0 && $y > 0 && $board[$y - 1][$x - 1] & 8) $results[] = array($x - 1, $y - 1);
if($x > 0 && $y < 7 && $board[$y + 1][$x - 1] & 8) $results[] = array($x - 1, $y + 1);
if($x < 7 && $board[$y][$x + 1] & 8) $results[] = array($x + 1, $y);
if($x < 7 && $y > 0 && $board[$y - 1][$x + 1] & 8) $results[] = array($x + 1, $y - 1);
if($x < 7 && $y < 7 && $board[$y + 1][$x + 1] & 8) $results[] = array($x + 1, $y + 1);
if($y > 0 && $board[$y - 1][$x] & 8) $results[] = array($x, $y - 1);
if($y < 7 && $board[$y + 1][$x] & 8) $results[] = array($x, $y + 1);
break;
case 2:
# Queen
# Downwards diagonal
for($d = 1; $x + $d < 8 && $y + $d < 8; $d++) {
if($board[$y + $d][$x + $d] & 8) {
$results[] = array($x + $d, $y + $d);
if($board[$y + $d][$x + $d] !== -1) break;
} else {
break;
}
}
for($d = -1; $x + $d >= 0 && $y + $d >= 0; $d--) {
if($board[$y + $d][$x + $d] & 8) {
$results[] = array($x + $d, $y + $d);
if($board[$y + $d][$x + $d] !== -1) break;
} else {
break;
}
}
# Upwards diagonal
for($d = 1; $x + $d < 8 && $y - $d >= 0; $d++) {
if($board[$y - $d][$x + $d] & 8) {
$results[] = array($x + $d, $y - $d);
if($board[$y - $d][$x + $d] !== -1) break;
} else {
break;
}
}
for($d = -1; $x + $d >= 0 && $y - $d < 8; $d--) {
if($board[$y - $d][$x + $d] & 8) {
$results[] = array($x + $d, $y - $d);
if($board[$y - $d][$x + $d] !== -1) break;
} else {
break;
}
}
# Horizontal
for($d = 1; $x + $d < 8; $d++) {
if($board[$y][$x + $d] & 8) {
$results[] = array($x + $d, $y);
if($board[$y][$x + $d] !== -1) break;
} else {
break;
}
}
for($d = -1; $x + $d >= 0; $d--) {
if($board[$y][$x + $d] & 8) {
$results[] = array($x + $d, $y);
if($board[$y][$x + $d] !== -1) break;
} else {
break;
}
}
# Vertical
for($d = 1; $y + $d < 8; $d++) {
if($board[$y + $d][$x] & 8) {
$results[] = array($x, $y + $d);
if($board[$y + $d][$x] !== -1) break;
} else {
break;
}
}
for($d = -1; $y + $d >= 0; $d--) {
if($board[$y + $d][$x] & 8) {
$results[] = array($x, $y + $d);
if($board[$y + $d][$x] !== -1) break;
} else {
break;
}
}
break;
case 3:
# Bishop
# Downwards diagonal
for($d = 1; $x + $d < 8 && $y + $d < 8; $d++) {
if($board[$y + $d][$x + $d] & 8) {
$results[] = array($x + $d, $y + $d);
if($board[$y + $d][$x + $d] !== -1) break;
} else {
break;
}
}
for($d = -1; $x + $d >= 0 && $y + $d >= 0; $d--) {
if($board[$y + $d][$x + $d] & 8) {
$results[] = array($x + $d, $y + $d);
if($board[$y + $d][$x + $d] !== -1) break;
} else {
break;
}
}
# Upwards diagonal
for($d = 1; $x + $d < 8 && $y - $d >= 0; $d++) {
if($board[$y - $d][$x + $d] & 8) {
$results[] = array($x + $d, $y - $d);
if($board[$y - $d][$x + $d] !== -1) break;
} else {
break;
}
}
for($d = -1; $x + $d >= 0 && $y - $d < 8; $d--) {
if($board[$y - $d][$x + $d] & 8) {
$results[] = array($x + $d, $y - $d);
if($board[$y - $d][$x + $d] !== -1) break;
} else {
break;
}
}
break;
case 4:
# Knight
if($x > 1 && $y > 0 && $board[$y - 1][$x - 2] & 8) $results[] = array($x - 2, $y - 1);
if($x > 0 && $y > 1 && $board[$y - 2][$x - 1] & 8) $results[] = array($x - 1, $y - 2);
if($x < 7 && $y > 1 && $board[$y - 2][$x + 1] & 8) $results[] = array($x + 1, $y - 2);
if($x < 6 && $y > 0 && $board[$y - 1][$x + 2] & 8) $results[] = array($x + 2, $y - 1);
if($x < 6 && $y < 7 && $board[$y + 1][$x + 2] & 8) $results[] = array($x + 2, $y + 1);
if($x < 7 && $y < 6 && $board[$y + 2][$x + 1] & 8) $results[] = array($x + 1, $y + 2);
if($x > 0 && $y < 6 && $board[$y + 2][$x - 1] & 8) $results[] = array($x - 1, $y + 2);
if($x > 1 && $y < 7 && $board[$y + 1][$x - 2] & 8) $results[] = array($x - 2, $y + 1);
break;
case 5:
# Rook
# Horizontal
for($d = 1; $x + $d < 8; $d++) {
if($board[$y][$x + $d] & 8) {
$results[] = array($x + $d, $y);
if($board[$y][$x + $d] !== -1) break;
} else {
break;
}
}
for($d = -1; $x + $d >= 0; $d--) {
if($board[$y][$x + $d] & 8) {
$results[] = array($x + $d, $y);
if($board[$y][$x + $d] !== -1) break;
} else {
break;
}
}
# Vertical
for($d = 1; $y + $d < 8; $d++) {
if($board[$y + $d][$x] & 8) {
$results[] = array($x, $y + $d);
if($board[$y + $d][$x] !== -1) break;
} else {
break;
}
}
for($d = -1; $y + $d >= 0; $d--) {
if($board[$y + $d][$x] & 8) {
$results[] = array($x, $y + $d);
if($board[$y + $d][$x] !== -1) break;
} else {
break;
}
}
break;
}
return $results;
}
function invertRelationship($piece) {
return $piece === -1 ? -1 : $piece ^ 8;
}
function invertPosition($position) {
return array($position[0], 7 - $position[1]);
}
function invertBoard($board) {
$invertedBoard = array();
for($i = 7; $i > -1; $i--) {
$invertedBoard[] = array_map('invertRelationship', $board[$i]);
}
return $invertedBoard;
}
function validMoves($x, $y) {
global $board;
$type = $board[$y][$x];
if($type & 8) {
return array_map('invertPosition', iValidMoves(invertBoard($board), $type & ~8, $x, 7 - $y));
} else {
return iValidMoves($board, $type, $x, $y);
}
}
function shouldHighlight($x, $y) {
global $highlight;
foreach($highlight as $position) {
if($position[0] == $x && $position[1] == $y) {
return true;
}
}
return false;
}
if(isset($_SESSION['board'])) {
$board = $_SESSION['board'];
} else {
$board = array(
array(5 | 8, 4 | 8, 3 | 8, 1 | 8, 2 | 8, 3 | 8, 4 | 8, 5 | 8),
array(0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8),
array(-1, -1, -1, -1, -1, -1, -1, -1),
array(-1, -1, -1, -1, -1, -1, -1, -1),
array(-1, -1, -1, -1, -1, -1, -1, -1),
array(-1, -1, -1, -1, -1, -1, -1, -1),
array(0, 0, 0, 0, 0, 0, 0, 0),
array(5, 4, 3, 1, 2, 3, 4, 5)
);
}
$back = array(
imagecreatefrompng('back/16.png'), # pawn
imagecreatefrompng('back/6.png'), # king
imagecreatefrompng('back/149.png'), # queen
imagecreatefrompng('back/37.png'), # bishop
imagecreatefrompng('back/25.png'), # knight
imagecreatefrompng('back/75.png') # rook
);
$front = array(
imagecreatefrompng('front/16.png'), # pawn
imagecreatefrompng('front/6.png'), # king
imagecreatefrompng('front/149.png'), # queen
imagecreatefrompng('front/37.png'), # bishop
imagecreatefrompng('front/25.png'), # knight
imagecreatefrompng('front/75.png') # rook
);
$image = $_GET['i'];
if(ctype_digit($image)) {
$image = (int)$image;
} else {
kick();
}
if($image < 1 || $image > 64) {
kick();
}
$highlight = array();
$referrer = $_SERVER['HTTP_REFERER'];
$action = null;
if(strpos($referrer, '?a=') > -1) {
$action = substr($referrer, strpos($referrer, '?a=') + 3);
}
if($action !== null && $image === 1) { # Only do this once!
if(!ctype_digit($action)) kick();
$action = (int)$action;
if($action < 1 || $action > 64) kick();
$aX = ($action - 1) % 8;
$aY = floor(($action - 1) / 8);
if(isset($_SESSION['selected'])) {
if($_SESSION['selected'] !== $action) {
# Make sure the piece can actually move there.
# If it can, move.
# "Highlight" the places that the piece can move:
$highlight = validMoves(($_SESSION['selected'] - 1) % 8, floor(($_SESSION['selected'] - 1) / 8));
if(shouldHighlight($aX, $aY)) {
# The move is good!
$sX = ($_SESSION['selected'] - 1) % 8;
$sY = floor(($_SESSION['selected'] - 1) / 8);
$board[$aY][$aX] = $board[$sY][$sX];
$board[$sY][$sX] = -1;
# Now, rotate the board for the next person to play:
$invertedBoard = invertBoard($board);
$rotatedBoard = array();
foreach($invertedBoard as $row) {
for($i = 0; $i < 4; $i++) {
$row[$i] ^= $row[7 - $i];
$row[7 - $i] ^= $row[$i];
$row[$i] ^= $row[7 - $i];
}
$rotatedBoard[] = $row;
}
$board = $rotatedBoard;
}
}
unset($_SESSION['selected']);
} elseif(($board[$aY][$aX] & 8) === 0) {
# Select a piece:
$_SESSION['selected'] = $action;
}
}
if(isset($_SESSION['selected'])) {
# Highlight the places that the piece can move:
$highlight = validMoves(($_SESSION['selected'] - 1) % 8, floor(($_SESSION['selected'] - 1) / 8));
}
# Draw the background:
$background = imagecreatetruecolor(96, 96);
$black = imagecolorallocate($background, 0, 0, 0);
$white = imagecolorallocate($background, 255, 255, 255);
$red = imagecolorallocatealpha($background, 255, 0, 0, 100);
if(($image + floor(($image - 1) / 8)) % 2) {
imagefilledrectangle($background, 0, 0, 96, 96, $black);
} else {
imagefilledrectangle($background, 0, 0, 96, 96, $white);
}
# Draw a piece, if there is one:
$piece = $board[floor(($image - 1) / 8)][($image - 1) % 8];
if($piece > -1) {
if($piece & 8) {
$piece &= ~8;
$draw = $front[$piece];
} else {
$draw = $back[$piece];
}
imagecopy($background, $draw, 0, 0, 0, 0, 96, 96);
}
# Should we highlight this place?
if(shouldHighlight(($image - 1) % 8, floor(($image - 1) / 8))) {
imagefilledrectangle($background, 0, 0, 96, 96, $red);
}
header("Content-Type: image/png\r\n");
imagepng($background);
$_SESSION['board'] = $board;
?>