Closes 8 and resolved conflict

Conflicts:
	phpunit.xml
This commit is contained in:
Basilius Sauter
2016-04-18 07:23:07 +02:00
6 changed files with 363 additions and 0 deletions
+32
View File
@@ -73,3 +73,35 @@ cd core
composer install
./t
```
## Contributing
Some notes:
* Pull requests cannot be accepted that break the continuous integration checks we have in place (like tests, for example).
* Our git workflow requires squashing your commits into something that resembles a reasonable story, rebasing them onto master, and pushing instead of merging. We want our commit history to be as clean as possible.
Workflow should be something like:
```bash
# Start this flow from master:
git checkout master
# Create a new feature branch, tracking origin/master.
git checkout -b feature/my-feature-branch -t origin/master
# Make some awesome commits and put up a pull request! Don't forget to push your branch to remote before creating the PR. Try something like hub (https://hub.github.com/) if you want to create PRs from the command line.
...
# If necessary, squash your commits to ensure a clean commit history.
git rebase -i
# Edit the last commit message, saying you want to close the PR by adding "closes #[PR number]" to the message.
git commit --amend
# Rebase to ensure you have the latest changes.
git pull --rebase
# Push to remote.
git push origin feature/my-feature-branch:master
# Delete your feature branch.
git branch -D feature/my-feature-branch
```
+8
View File
@@ -5,4 +5,12 @@
<var name="DB_PASSWD" value="" />
<var name="DB_NAME" value="daenerys" />
</php>
<testsuites>
<testsuite name="Models">
<directory>tests/Models</directory>
</testsuite>
<testsuite name="Other">
<file>tests/TimeKeeperTest.php</file>
</testsuite>
</testsuites>
</phpunit>
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
class DiceBag {
public function chance(float $p): bool {
$r = $this->uniform(0., 1.);
return $r < $p;
}
public function uniform(float $min, float $max): float {
return (mt_rand(0, 100) / 100.0) * ($max - $min) + $min;
}
public function normal(float $min, float $max): float {
if ($min > $max) {
$tmp = $max;
$max = $min;
$min = $tmp;
} else if ($min == $max) {
return $min;
}
$mean = ($max - $min) / 2;
$r = 0;
do {
$u1 = mt_rand() / mt_getrandmax();
$u2 = mt_rand() / mt_getrandmax();
$r = sqrt(-2 * log($u1)) * cos(2 * pi() * $u2) + $mean;
} while ($r < $min || $r > $max);
return $r;
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
class TimeKeeper {
private $adjustedEpoch;
private $theBeginning;
private $secondsPerMinute = 60;
private $secondsPerHour = 60 * 60;
private $secondsPerDay = 60 * 60 * 24;
private $secondsPerGameYear;
private $secondsPerGameDay;
private $secondsPerGameHour;
private $secondsPerGameMinute;
private $secondsPerGameSecond;
public function __construct(\DateTime $gameEpoch, int $gameOffsetSeconds, int $gameDaysPerDay) {
$gameEpochCopy = clone($gameEpoch);
$this->adjustedEpoch = $gameEpochCopy->add(
$this->interval(0, 0, 0, 0, $gameOffsetSeconds)
);
$this->theBeginning = new \DateTime("0000-01-01 UTC");
$this->secondsPerGameDay = (float) $this->secondsPerDay / $gameDaysPerDay;
$this->secondsPerGameYear = $this->secondsPerGameDay * 365;
$this->secondsPerGameHour = $this->secondsPerGameDay / 24;
$this->secondsPerGameMinute = $this->secondsPerGameHour / 60;
$this->secondsPerGameSecond = $this->secondsPerGameMinute / 60;
}
public function isNewDay(DateTime $lastInteractionTime): bool {
if ($lastInteractionTime == null) {
return true;
}
$t1 = $this->gameTime();
$t2 = $this->convertToGameTime($lastInteractionTime);
$d1 = $t1->format("Y-m-d");
$d2 = $t2->format("Y-m-d");
return $d1 != $d2;
}
public function gameTime(): \DateTime {
return $this->convertToGameTime(new \DateTime());
}
public function convertFromGameTime(
\DateTime $time
): \DateTime {
// Game dates are in the distant past, better not use getTimestamp().
$i = $this->theBeginning->diff($time);
$seconds = 0;
$seconds += $i->days * $this->secondsPerGameDay;
$seconds += $i->h * $this->secondsPerGameHour;
$seconds += $i->i * $this->secondsPerGameMinute;
$seconds += $i->s * $this->secondsPerGameSecond;
$ret = clone($this->adjustedEpoch);
return $ret->add($this->interval(0, 0, 0, 0, (int) $seconds));
}
public function convertToGameTime(
\DateTime $time
): \DateTime {
$timeUnix = $time->getTimestamp();
$epochUnix = $this->adjustedEpoch->getTimestamp();
$interval = $timeUnix - $epochUnix;
$years = (int) ($interval / $this->secondsPerGameYear);
$interval -= $years * $this->secondsPerGameYear;
$days = (int) ($interval / $this->secondsPerGameDay);
$interval -= $days * $this->secondsPerGameDay;
$hours = (int) ($interval / $this->secondsPerGameHour);
$interval -= $hours * $this->secondsPerGameHour;
$minutes = (int) ($interval / $this->secondsPerGameMinute);
$interval -= $minutes * $this->secondsPerGameMinute;
$seconds = (int) ($interval / $this->secondsPerGameSecond);
$interval -= $seconds * $this->secondsPerGameSecond;
$ret = clone($this->theBeginning);
return $ret->add(
$this->interval($years, $days, $hours, $minutes, $seconds)
);
}
private function interval(
int $years,
int $days,
int $hours,
int $minutes,
int $seconds
): \DateInterval {
return new \DateInterval(
'P'.$years.'Y'.$days.'DT'.$hours.'H'.$minutes.'M'.$seconds.'S'
);
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests;
use LotGD\Core\DiceBag;
/**
* @backupGlobals disabled
* @backupStaticAttributes disabled
*/
class DiceBagTests extends \PHPUnit_Framework_TestCase {
public function testUniform() {
$db = new DiceBag();
$value = $db->uniform(0., 1.);
$this->assertGreaterThan(0, $value);
$this->assertLessThan(1, $value);
}
public function testNormal() {
$db = new DiceBag();
$value = $db->normal(0., 1.);
$this->assertGreaterThan(0, $value);
$this->assertLessThan(1, $value);
$value = $db->normal(1., 0.);
$this->assertGreaterThan(0, $value);
$this->assertLessThan(1, $value);
$this->assertEquals(0, $db->normal(0., 0.));
}
}
+152
View File
@@ -0,0 +1,152 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests;
use LotGD\Core\TimeKeeper;
/**
* @backupGlobals disabled
* @backupStaticAttributes disabled
*/
class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
private $gameEpoch;
private $gameOffsetSeconds;
private $gameDaysPerDay;
public function setUp() {
$this->gameEpoch = new \DateTime('2015-07-27 00:00:00 PDT');;
$this->gameOffsetSeconds = 0;
$this->gameDaysPerDay = 2;
}
public function testConvertToBasicConversion() {
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$date = new \DateTime('2015-07-27 23:59:59 PDT');
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
$date = new \DateTime('2015-07-27 12:00:00 PDT');
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 12:00:00', $converted->format('Y-m-d H:i:s'));
}
public function testConvertToRespectsGameDaysPerDayUpperBound() {
$date = new \DateTime('2015-07-27 05:59:59 PDT');
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01', $converted->format('Y-m-d'));
}
public function testConvertToRespectsGameDaysPerDayNextDay() {
$date = new \DateTime('2015-07-27 06:00:00 PDT');
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
}
public function testConvertToRespectsGameDaysPerDayNextDayUpperBound() {
$date = new \DateTime('2015-07-27 11:59:59 PDT');
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
}
public function testDetectsNewDay() {
}
public function testConvertToRespectsGameOffset() {
$date = new \DateTime('2015-07-27 01:01:15 PDT');
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 00:01:15', $converted->format('Y-m-d H:i:s'));
}
public function testConvertToRespectsGameOffsetUpperBound() {
$date = new \DateTime('2015-07-28 00:59:59 PDT');
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
}
public function testConvertToRespectsGameOffsetNextDay() {
$date = new \DateTime('2015-07-28 01:00:00 PDT');
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
}
public function testConvertToRespectsGameOffsetNextDayUpperBound() {
$date = new \DateTime('2015-07-29 00:59:59 PDT');
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
}
public function testConvertFromBasicConversion() {
$date = new \DateTime('0000-01-02 00:00:00 UTC');
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-28", $converted->format('Y-m-d'));
}
public function testConvertFromRespectsGameOffsetNextDay() {
$epoch = new \DateTime('2015-07-27 00:00:00 PDT');
$date = new \DateTime('0000-01-02 23:59:59 UTC');
$this->gameEpoch = $epoch;
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-29 00:59:59", $converted->format('Y-m-d H:i:s'));
}
public function testConvertFromRespectsGameDaysPerDayNextDay() {
$epoch = new \DateTime('2015-07-27 00:00:00 PDT');
$date = new \DateTime('0000-01-02 23:59:59 UTC');
$this->gameEpoch = $epoch;
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-27 11:59:59", $converted->format('Y-m-d H:i:s'));
}
public function testGameTimeSanity() {
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$this->assertNotNull($keeper->gameTime());
}
}