Rubix cube

Description

un "simulateur" de rubix cube "cubique" n*n

le code est objet, simple, clair.

l'interface et le code html sont plutot mauvais, mais pour un si petit projet, j'allais pas prendre 2h a coder un truc clean.

Source / Exemple :


<?php

session_start();

?>
<html>
<head>
<title>rubix</title>
<style>
body{
background-color: gray;
}

td.case{
	width:40px;
	height:40px;
}

.cube{
	float:left;
}

.actions{
	float:left;
}
</style>
</head>
<body>

<?php

class InvalidParam extends Exception{}
class TypeException extends InvalidParam{}

function integer($i){
	if (!is_integer($i)) throw new Exception('param is not an integer');
}
function in_range($i, $a, $b){
	if ($i < $a || $i > $b) throw new Exception('param is not an integer');
}

class Color{
	public static function getColor($n = -1){
		switch ($n){
			case 0: return 'white';
			case 1: return 'green';
			case 2: return 'yellow';
			case 3: return 'blue';
			case 4: return 'orange';
			case 5: return 'red';
			default: return 'gray';
		}
	}
}

class Face{
	private $colors;
	private $nbr;
	private $c;
	public function __construct($c, $nbr){
		$this->c = $c;
		$this->nbr = $nbr;
		$this->colors = array();
		for ($i = 0; $i < $nbr; $i++){
			$this->colors[$i] = array();
			for ($j = 0; $j < $nbr; $j++){
				$this->colors[$i][$j] = $c; // * 100 + $i * 10 + $j;
			}
		}
	}

	public function __toString(){
		$out = '<table>';
		foreach ($this->colors as $t){
			$out .= '<tr>';
			foreach ($t as $y){
				$out .= '<td class="case" style="background-color:'.
				// Color::getColor(intval($y / 100 )).'">'.($y % 100).'</td>';
				Color::getColor($y).'"></td>';
			}
			$out .= '</tr>';
		}
		return $out . '</table>';
	}
	public function getLine($l){
		return $this->colors[$l];
	}

	public function setLine($l, $f){
		$this->colors[$l] = $f;
	}

	public function getCol($l){
		$a = array();
		for ($i=0;$i<$this->nbr;$i++)
			$a[$i]=$this->colors[$i][$l];
		return $a;
	}

	public function setCol($l, $f){
		for ($i=0;$i<$this->nbr;$i++)
			$this->colors[$i][$l] = $f[$i];
	}

	public function rotate($n = false){
		$c = array();
		for ($i = 0; $i < $this->nbr; $i++){
			$c[$i] = array();
			for ($j = 0; $j < $this->nbr; $j++){
				if ($n)
					$c[$i][$j] = $this->colors[$this->nbr - $j - 1][$i];
				else
					$c[$i][$j] = $this->colors[$j][$this->nbr - $i - 1];
			}
		}
		$this->colors = $c;
	}
}

class Cube{
	private $nbr, $faces;
	public function __construct($nbr){
		$this->nbr = $nbr;
		$this->faces = array();
		for ($i = 0; $i < 6; $i++){
			$this->faces[$i] = new Face($i, $nbr);
		}
	}
	private function getLine($f, $l){
		return $this->faces[$f]->getLine($l);
	}
	private function setLine($f, $l, $t){
		return $this->faces[$f]->setLine($l, $t);
	}
	private function getCol($f, $l){
		return $this->faces[$f]->getCol($l);
	}
	private function setCol($f, $l, $t){
		return $this->faces[$f]->setCol($l, $t);
	}

	private function getRLine($f, $l){
		return array_reverse($this->faces[$f]->getLine($l));
	}
	private function setRLine($f, $l, $t){
		return $this->faces[$f]->setLine($l, array_reverse($t));
	}
	private function getRCol($f, $l){
		return array_reverse($this->faces[$f]->getCol($l));
	}
	private function setRCol($f, $l, $t){
		return $this->faces[$f]->setCol($l, array_reverse($t));
	}
	public function rotateLine($f, $l){
		integer($f); integer($l);
		in_range($f, 0, 5); in_range($l, 0, $this->nbr);

		if ($f == 4 || $f == 5){ $f = 1; } // meme rotation
		else if ($f == 3){ $f = 1; $l = $this->nbr - 1 - $l; }

		if ($f == 2){
			$f = 0;
		}

		$cl = $this->nbr - $l - 1;
		if ($f == 1){
			$c0 = $this->getLine(1, $l);
			$this->setLine(1, $l, $this->getLine(4, $l));
			$this->setLine(4, $l, $this->getRLine(3, $cl));
			$this->setRLine(3, $cl, $this->getLine(5, $l));
			$this->setLine(5, $l, $c0);

			if ($l == 0){ $this->faces[0]->rotate(); }
			if ($l == $this->nbr - 1){ $this->faces[2]->rotate(true); }
		}else if ($f == 0){
			$c0 = $this->getRLine(0, $l);
			$this->setRLine(0, $l, $this->getRCol(5, $cl));
			$this->setRCol(5, $cl, $this->getLine(2, $cl));
			$this->setLine(2, $cl, $this->getCol(4, $l));
			$this->setCol(4, $l, $c0);

			if ($l == 0){ $this->faces[3]->rotate(true); }
			if ($l == $this->nbr - 1){ $this->faces[1]->rotate(); }
		}
	}
	public function rotateColone($f, $l){
		integer($f); integer($l);
		in_range($f, 0, 5); in_range($l, 0, $this->nbr);

		if ($f <= 3) $f = 1;

		if ($f == 4){ $f = 5; $l = $this->nbr - $l - 1; }

		$cl = $this->nbr - $l - 1;
		if ($f == 1){

			$c0 = $this->getCol(0, $l);
			$this->setCol(0, $l, $this->getCol(1, $l));
			$this->setCol(1, $l, $this->getCol(2, $l));
			$this->setCol(2, $l, $this->getCol(3, $l));
			$this->setCol(3, $l, $c0);

			if ($l == 0){ $this->faces[4]->rotate(); }
			if ($l == $this->nbr - 1){ $this->faces[5]->rotate(true); }
		}else{
			$this->rotateLine(0, $cl);
		}
		
	}
	public function getN(){ return $this->nbr; }
	public function __toString(){
		return '<table class="cube">
			<tr>
				<td></td>
				<td>'.$this->faces[0].'</td>
				<td></td>
			</tr>
			<tr>
				<td>'.$this->faces[4].'</td>
				<td>'.$this->faces[1].'</td>
				<td>'.$this->faces[5].'</td>
			</tr>
			<tr>
				<td></td>
				<td>'.$this->faces[2].'</td>
				<td></td>
			</tr>
			<tr>
				<td></td>
				<td>'.$this->faces[3].'</td>
				<td></td>
			</tr>
		</table>';
	}
}

if (isset($_GET['restart'])) unset($_SESSION['cube']);

if (!isset($_SESSION['cube']))
	$_SESSION['cube'] = new Cube(3);

$c = $_SESSION['cube'];

if (isset($_GET['rotate'], $_GET['f']) && is_numeric($_GET['f'])){
	if (isset($_GET['l'])){
		$c->rotateLine((int)$_GET['f'], (int)$_GET['l']);
	}
	if (isset($_GET['c'])){
		$c->rotateColone((int)$_GET['f'], (int)$_GET['c']);
	}
}

echo $c;

echo '<table class="actions">
';
for ($i = 0; $i < 6; $i++){
	echo '<tr>
		<td class="case" style="background-color:'.Color::getColor($i).'"></td>';
	for ($j = 0; $j < $c->getN(); $j++){
		echo '<td><a href="rubix.php?rotate&f='.$i.'&l='.$j.'">
			rotate line '.($j+1).'</a></td>';
		echo '<td><a href="rubix.php?rotate&f='.$i.'&c='.$j.'">
			rotate col '.($j+1).'</a></td>';
	}
	echo '</tr>';
}
echo '</table>';

?>
<div style="clear:both"></div>
<hr />
<a href="rubix.php?restart">restart</a>
</body>
</html>

Conclusion :


l'interface n'est pas terrible, mais ca reste valable

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.