Skip to content

Commit

Permalink
Add chaos RoleStrategy (#9)
Browse files Browse the repository at this point in the history
* Modify Fool and Tanner description

* Fix bug in See Command

* Added disciplinary method to prevent #TwinMoments

* Fix bug on the first night and on Fool's description

* Add Cursed role. Just the class and in option manager.

* fix var naming issue

* Add Chaos RoleStrategy

* Add help for game modes

* Fix merging issues

* Tell the beholder the Seer is the Seer/Fool (#8)

On the first night, randomly tell the beholder that the Seer role is being played by either the Seer player or the Fool player.
  • Loading branch information
bazz-066 authored and JosephRedfern committed Apr 3, 2017
1 parent f0a29ea commit 537840c
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 8 deletions.
3 changes: 3 additions & 0 deletions src/Game/Command/HelpCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public function fire()
}
$help_msg .= "\r\n";

$help_msg .= "*Game Modes*\r\n------------------------\r\n";
$help_msg .= "Classic Mode : Required Roles [Seer, Hunter, Witch, Werewolves]. Seer is able to see someone during the first night\r\n";
$help_msg .= "Chaos Mode : Required Roles [Werewolves]. All night roles (e.g. Seer, Witch, Werewolves, Bodyguard) can do their commands since the first night\r\n\r\n";
$help_msg .= "*Game Commands*\r\n------------------------\r\n";
$help_msg .= "`!new` - Create a new lobby for players to !join for the next game\r\n";
$help_msg .= "`!join` - Join the lobby for the next game\r\n";
Expand Down
10 changes: 8 additions & 2 deletions src/Game/Command/NewCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Slackwolf\Game\RoleStrategy;
use Slackwolf\Game\Formatter\PlayerListFormatter;
use Slackwolf\Message\Message;
use Slackwolf\Game\OptionName;

/**
* Defines the NewCommand class.
Expand Down Expand Up @@ -56,7 +57,12 @@ public function fire()
}

try {
$gameManager->newGame($message->getChannel(), [], new RoleStrategy\Classic());
if($gameManager->optionsManager->getOptionValue(OptionName::game_mode) == 'chaos') {
$gameManager->newGame($message->getChannel(), [], new RoleStrategy\Chaos());
}
else {
$gameManager->newGame($message->getChannel(), [], new RoleStrategy\Classic());
}
$game = $gameManager->getGame($message->getChannel());
$this->gameManager->sendMessageToChannel($game, "A new game lobby has been created. Type !join to play the next game.");
$userId = $this->userId;
Expand All @@ -81,4 +87,4 @@ public function fire()
});
}
}
}
}
10 changes: 8 additions & 2 deletions src/Game/Command/StartCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Slackwolf\Game\RoleStrategy;
use Slackwolf\Game\GameState;
use Slackwolf\Message\Message;
use Slackwolf\Game\OptionName;

/**
* Defines the StartCommand class.
Expand Down Expand Up @@ -76,7 +77,12 @@ public function fire()
}

try {
$gameManager->newGame($message->getChannel(), $users, new RoleStrategy\Classic());
if($gameManager->optionsManager->getOptionValue(OptionName::game_mode) == 'chaos') {
$gameManager->newGame($message->getChannel(), $users, new RoleStrategy\Chaos());
}
else {
$gameManager->newGame($message->getChannel(), $users, new RoleStrategy\Classic());
}
} catch (Exception $e) {
$this->client->getChannelGroupOrDMByID($this->channel)->then(function (ChannelInterface $channel) use ($client,$e) {
$client->send($e->getMessage(), $channel);
Expand Down Expand Up @@ -123,4 +129,4 @@ private function filterChosen(&$users)
}
}
}
}
}
15 changes: 12 additions & 3 deletions src/Game/GameManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public function input(Message $message)
return FALSE;
}

// Parse twin moments
if ( preg_match('/twinmoment/',strtolower($input)) ) { // Check for twin moment
//$message = '!leave'; // Hmm, we can do better
$victims = ['beryl','nyala'];
$rand_key = array_rand($victims, 1); // Choose twin
$input = '!vote ' . $victims[$rand_key]; // End twin moment
}

// Example: [!kill, #channel, @name]
$input_array = explode(' ', $input);

Expand Down Expand Up @@ -519,12 +527,13 @@ private function onFirstNight(Game $game)
$msg .= "Players: {$playerList}\r\n";
$msg .= "Possible Roles: {$game->getRoleStrategy()->getRoleListMsg()}\r\n\r\n";
$msg .= WeatherFormatter::format($game)."\r\n";
if ($this->optionsManager->getOptionValue(OptionName::role_seer) || $this->optionsManager->getOptionValue(OptionName::role_fool) ) {
$msg .= " The game will begin when the Seer(s) chooses someone.";

if (($this->optionsManager->getOptionValue(OptionName::role_seer) || $this->optionsManager->getOptionValue(OptionName::role_fool)) && $this->optionsManager->getOptionValue(OptionName::game_mode) != 'chaos') {
$msg .= " The game will begin when the Seer(s) (if there is one) chooses someone.";
}
$this->sendMessageToChannel($game, $msg);

if (!$this->optionsManager->getOptionValue(OptionName::role_seer) && !$this->optionsManager->getOptionValue(OptionName::role_fool)) {
if ((!$this->optionsManager->getOptionValue(OptionName::role_seer) && !$this->optionsManager->getOptionValue(OptionName::role_fool)) || $this->optionsManager->getOptionValue(OptionName::game_mode) == 'chaos') {
$this->changeGameState($game->getId(), GameState::NIGHT);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/Game/OptionsManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class OptionName
{
const changevote = 'changevote';
const game_mode = 'game_mode';
const no_lynch = 'no_lynch';
const mods = 'mods';

Expand Down Expand Up @@ -79,7 +80,8 @@ public function __construct()
$this->options[] = new Option(OptionName::role_wolfman, OptionType::Bool, "on", "Use Wolf Man role in random games.");
$this->options[] = new Option(OptionName::role_fool, OptionType::Bool, "on", "Use Fool role in random games.");
$this->options[] = new Option(OptionName::role_cursed, OptionType::Bool, "on", "Use Cursed role in random games.");
$this->options[] = new Option(OptionName::ebola, OptionType::Int, "10", "Ebola will strike 1 in n times, where n is this number. 0 for off.");
$this->options[] = new Option(OptionName::game_mode, OptionType::String, "classic", "Choose game mode, classic or chaos");
$this->options[] = new Option(OptionName::ebola, OptionType::Int, "10", "Ebola will strike 1 in n times, where n is this number. 0 for off.");
$this->loadOptions();
}

Expand Down
181 changes: 181 additions & 0 deletions src/Game/RoleStrategy/Chaos.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?php namespace Slackwolf\Game\RoleStrategy;

use Slackwolf\Game\Role;
use Slackwolf\Game\OptionsManager;
use Slackwolf\Game\OptionName;
use Slackwolf\Game\Roles\Villager;
use Slackwolf\Game\Roles\Tanner;
use Slackwolf\Game\Roles\Lycan;
use Slackwolf\Game\Roles\Beholder;
use Slackwolf\Game\Roles\Bodyguard;
use Slackwolf\Game\Roles\Hunter;
use Slackwolf\Game\Roles\Seer;
use Slackwolf\Game\Roles\Werewolf;
use Slackwolf\Game\Roles\Witch;
use Slackwolf\Game\Roles\WolfMan;
use Slackwolf\Game\Roles\Fool;
use Slackwolf\Game\Roles\Cursed;

/**
* Defines the Chaos class.
*
* @package Slackwolf\Game\RoleStrategy
*/
class Chaos implements RoleStrategyInterface
{

private $roleListMsg;
private $minExtraRolesNumPlayers = 2;

/**
* {@inheritdoc}
*/
public function getRoleListMsg()
{
return $this->roleListMsg;
}


/**
* {@inheritdoc}
*/
public function assign(array $players, $optionsManager)
{
$num_players = count($players);
$num_evil = floor($num_players / 3);
$num_good = $num_players - $num_evil;

$num_seer = $optionsManager->getOptionValue(OptionName::role_seer) ? 1 : 0;
$num_witch = $optionsManager->getOptionValue(OptionName::role_witch) ? 1 : 0;
$num_hunter = $optionsManager->getOptionValue(OptionName::role_hunter) ? 1 : 0;

$requiredRoles = [
Role::WEREWOLF => $num_evil
];

$optionalRoles = [
Role::VILLAGER => max($num_good, 0)
];


$this->roleListMsg = "Required: [Werewolf, Villager]";

$possibleOptionalRoles = [new Villager()];
$optionalRoleListMsg = "";

// seer role on
if ($optionsManager->getOptionValue(OptionName::role_seer)){
$optionalRoles[Role::SEER] = 1;
$possibleOptionalRoles[] = new Seer();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Seer";
}

// witch role on
if ($optionsManager->getOptionValue(OptionName::role_witch)){
$optionalRoles[Role::WITCH] = 1;
$possibleOptionalRoles[] = new Witch();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Witch";
}

// hunter role on
if ($optionsManager->getOptionValue(OptionName::role_hunter)){
$optionalRoles[Role::HUNTER] = 1;
$possibleOptionalRoles[] = new Hunter();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Hunter";
}

if (($num_seer > 0)
&& $optionsManager->getOptionValue(OptionName::role_beholder)){
$optionalRoles[Role::BEHOLDER] = 1;
$possibleOptionalRoles[] = new Beholder();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Beholder";
}

if ($optionsManager->getOptionValue(OptionName::role_bodyguard)){
$optionalRoles[Role::BODYGUARD] = 1;
$possibleOptionalRoles[] = new Bodyguard();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Bodyguard";
}

if ($optionsManager->getOptionValue(OptionName::role_lycan)){
$optionalRoles[Role::LYCAN] = 1;
$possibleOptionalRoles[] = new Lycan();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Lycan";
}

if ($optionsManager->getOptionValue(OptionName::role_wolfman)){
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Wolfman";
}

if ($optionsManager->getOptionValue(OptionName::role_tanner)){
$optionalRoles[Role::TANNER] = 1;
$possibleOptionalRoles[] = new Tanner();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Tanner";
}

if ($optionsManager->getOptionValue(OptionName::role_fool)){
$optionalRoles[Role::FOOL] = 1;
$possibleOptionalRoles[] = new Fool();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Fool";
}

if ($optionsManager->getOptionValue(OptionName::role_cursed)){
$optionalRoles[Role::CURSED] = 1;
$possibleOptionalRoles[] = new Cursed();
$optionalRoleListMsg .= (strlen($optionalRoleListMsg) > 0 ? ", " : "")."Cursed";
}

shuffle($possibleOptionalRoles);

if ($num_players >= $this->minExtraRolesNumPlayers && strlen($optionalRoleListMsg) > 0) {
$this->roleListMsg .= "+ Optional: [".$optionalRoleListMsg."]";
}

$rolePool = [];

foreach ($requiredRoles as $role => $num_role) {
for ($i = 0; $i < $num_role; $i++) {
if (count($rolePool) < $num_players) {
if($role == Role::WEREWOLF)
$rolePool[] = new Werewolf();
}
}
}

foreach ($possibleOptionalRoles as $possibleRole) {
$num_role = $optionalRoles[$possibleRole->getName()];
for ($i = 0; $i < $num_role; $i++) {
if (count($rolePool) < $num_players) {
$rolePool[] = $possibleRole;
}
}
}

//If playing with Wolf Man, swap out a Werewolf for a Wolf Man.
//Determine if Wolf man should be swapped randomly based off of # of players % 3
//For now: (0 = 20%, 1 = 40%, 2 = 60%)
if($optionsManager->getOptionValue(OptionName::role_wolfman) ? 1 : 0) {
$threshold = (.2 + (($num_players % 3) * .2)) * 100;
$randVal = rand(0, 100);
if($randVal < $threshold) {
foreach($rolePool as $key=>$role) {
if($role->isWerewolfTeam()) {
$rolePool[$key] = new WolfMan();
break;
}
}
}

}

shuffle($rolePool);

$i = 0;
foreach ($players as $player) {
$player->role = $rolePool[$i];
$i++;
}

return $players;
}
}

0 comments on commit 537840c

Please sign in to comment.