Skip to content

Commit

Permalink
Add a second type of player with a different strategy.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Baker committed May 12, 2016
1 parent 016fd99 commit 62ac7a2
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 4 deletions.
4 changes: 4 additions & 0 deletions exceptions/IllegalArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php

class IllegalArgumentException extends Exception {
}
33 changes: 33 additions & 0 deletions line.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ public function length() {
return count($this->placements);
}

public function contains($searchTile) {
foreach ($this->tiles() as $tile) {
if ($tile === $searchTile) {
return true;
}
}
return false;
}

public function sharedProperty() {
$sharedProperty = null;
foreach (Color::colors() as $color) {
foreach ($this->tiles() as $tile) {
if ($sharedProperty === null || $sharedProperty === $tile->color()) {
$sharedProperty = $tile->color();
} else {
$sharedProperty = null;
break 2;
}
}
}
foreach (Shape::shapes() as $shape) {
foreach ($this->tiles() as $tile) {
if ($sharedProperty === null || $sharedProperty === $tile->shape()) {
$sharedProperty = $tile->shape();
} else {
return null;
}
}
}
return $sharedProperty;
}

public function __toString() {
$a = [];
foreach ($this->placements as $placement) {
Expand Down
17 changes: 13 additions & 4 deletions player.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,16 @@ public function move(Board $board, $bagIsEmpty) {
if ($board->isEmpty()) {
return $this->startingMove($tiles);
}
return $this->chooseMove($tiles, $board, $bagIsEmpty);
}

protected function chooseMove(array $tiles, Board $board, $bagIsEmpty) {
$usefulSets = $this->usefulSets($tiles);
list($max, $bestMove) = [0, new Move([])];
foreach ($usefulSets as $usefulSet) {
$move = $this->bestMoveWith($usefulSet, $board);
if ($move) {
$score = $board->score($move);
if (count($move->placements()) === count($tiles) && $bagIsEmpty) {
$score += Score::FINISHING_BONUS;
}
$score = $this->evaluate($tiles, $move, $board, $bagIsEmpty);
if ($score > $max) {
$max = $score;
$bestMove = $move;
Expand All @@ -83,6 +84,14 @@ public function move(Board $board, $bagIsEmpty) {
return $bestMove;
}

protected function evaluate(array $tiles, Move $move, Board $board, $bagIsEmpty) {
$score = $board->score($move);
if (count($move->placements()) === count($tiles) && $bagIsEmpty) {
$score += Score::FINISHING_BONUS;
}
return $score;
}

private function usefulSets(array $tiles) {
Assert::type($tiles, Tile);
if (array_unique($tiles) !== $tiles) {
Expand Down
65 changes: 65 additions & 0 deletions players/cautiousplayer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

class CautiousPlayer extends Player {
public function evaluate(array $tiles, Move $move, Board $board, $bagIsEmpty) {
$score = $board->score($move);
if (count($move->placements()) === count($tiles) && $bagIsEmpty) {
$score += Score::FINISHING_BONUS;
} elseif ($this->enablesQwirkle($move, $board, $bagIsEmpty) && $score < 9) {
$score -= 3.5;
}
return $score;
}

private function enablesQwirkle(Move $move, Board $board, $bagIsEmpty) {
foreach ($move->lines($board) as $line) {
if ($line->length() === count(Color::colors()) - 1) {
$missingPiece = $this->missingPieces($line)[0];
if ($this->notAccountedFor($missingPiece, $board)) {
return false;
}
}
}
return false;
}

private function missingPieces($line) {
if ($line->length() <= 1) {
throw new IllegalArgumentException("Qwirkle this lines is part of is ambiguous ($line).");
}
$sharedProperty = $line->sharedProperty();
if ($sharedProperty === null) {
throw new IllegalArgumentException("This line does not have a shared property ($line).");
}
$missing = [];
if (get_class($sharedProperty) === Shape) {
foreach (Color::colors() as $color) {
$tile = Tile::getTile($color, $sharedProperty);
if (!$line->contains($tile)) {
$missing[] = $tile;
}
}
} elseif (get_class($sharedProperty) === Color) {
foreach (Shape::shapes() as $shape) {
$tile = Tile::getTile($sharedProperty, $shape);
if (!$line->contains($tile)) {
$missing[] = $tile;
}
}
} else {
throw new IllegalArgumentException("Unrecognized property $sharedProperty");
}
return $missing;
}

private function notAccountedFor($searchTile, Board $board) {
$tiles = Tile::allTiles();
foreach ($board->tiles() as $tile) {
if ($tile === $searchTile) {
$pos = array_search($tile, $tiles);
unset($tiles[$pos]);
}
}
return in_array($tile, $tiles);
}
}

0 comments on commit 62ac7a2

Please sign in to comment.