PHP Classes
elePHPant
Icontem

OPBE: Ogame probabilistic battle engine

Recommend this page to a friend!
  Info   View files View files (115)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2014-02-01 (2 years ago) RSS 2.0 feedNot enough user ratingsTotal: 190 This week: 1All time: 7,899 This week: 1,047Up
Version License PHP version Categories
opbe 1.0Artistic License5.3PHP 5, Games
Description Author

This package implements a Ogame probabilistic battle engine.

It can process the game play of combats of Web based space war games involving groups of players with fleets of ships.

The classes can process battles and generate results in the form of reports to inform the players.

Innovation Award
PHP Programming Innovation award nominee
November 2013
Number 4
Space wars are a common type of topic used in strategy games.

This class implements a game engine for space war games.

Manuel Lemos
Picture of Nicola Covolo
  Performance   Level  
Innovation award
Innovation award
Nominee: 2x

Details
OPBE
====

**O**game **P**robabilistic **B**attle **E**ngine  
live: http://opbe.altervista.org


![http://www.phpclasses.org/package/8318-PHP-Ogame-probabilistic-battle-engine.html](http://www.phpclasses.org/award/innovation/nominee.gif)

1. [Introduction](#introduction)
2. [Quick start](#quick-start-installation)
3. [Accuracy](#accuracy)
4. [Performance](#performance)
5. [TestCases](#making-new-test-cases-to-share)
6. [Developers guide](#implementation-developing-guide)
    * [ShipType](#shiptype)
    * [Fleet](#fleet)
    * [Player](#player)
    * [PlayerGroup](#playergroup)
    * [Battle](#battle)
    * [BattleReport](#battlereport)
7. [License](#license)
8. [Questions](#questions)
9. [Who is using OPBE](#who-is-using-opbe)

## Introduction
OPBE is the first (and only) battle engine in the world that uses Probability theory:  
battles are processed very very fast and required little memory resources.  
Also, memory and CPU usage are O(1), this means they are CONSTANT and independent of the ships amount.    

**Features:**
* Multiple players and fleets (ACS)
* Fake targets (Fodder)
* Rapid fire
* Randomic rapid fire with [normal distribution](http://education-portal.com/cimages/multimages/16/Normal_distribution_and_scales.PNG)
* Ordered fires
* Bounce rule
* Waste of damage
* Moon attempt
* Plunder algorithm (resources partition)
* Defenses rebuilt
* Report generated by templates
* Report can be stored as object in database
* Cross-platform (XgProyect,2moons,Xnova,Wootook etc)

**Future features**
* automatic Bcmath detect and usage if needed

---

## Quick start (installation)
This seems so cool! How can I use it?  
You can check in [implementations directory](https://github.com/jstar88/opbe/tree/master/implementations) for your game version,
read the installation.txt file.  
Be sure you have read the *license* with respect for the author.

---

## Accuracy
One of main concepts used in this battle engine is the **expected value**: instead calculate each ship case, OPBE
creates an estimation of their behavior.   
This estimation is improved by analyzing behavior for infinite simulations, so,
to test OPBE's accuracy you have to set speedsim (or dragosim)'s battles amount to a big number, such as 3k.  
Recently was added a feature to simulate a randomic rapid fire, making the combat more realistic.  Anyway you can enable or disable it inside the *constants/battle_constants* file.  
Note: randomic rapid fire will only change the amount of shots,but the way it do is particularly...Infact the deviaton from the mean is made by a special random number generator implementing Gauss algorithm.  
This ensure a [bell curve](http://courses.ttu.edu/rreddick/images/law/bell_curve.gif) of shots close to the ideality.  
Also,the system can be bounded by values that can be setted in the constants/battle_constants* file.

---

## Performance
It seems that noone knows the O() notation, so this is the definition from the Wiki:  
*big O notation is used to classify algorithms by how they respond (e.g., in their processing time or working space requirements) to changes in input size.*   
There are different possibilities, such as O(n) (linear), O(n^2) (quadratic) etc.   
OPBE is O(1) in both CPU and MEMORY usage:    
In practice, that means that the computional requirements to solve an algoritm **don't increase** with the input size.  
It's awesome! You can simulate 20 ships or 20 Tera ships and nothing should change.  
In reality, there is a small difference because the arithmetic operations aren't O(1) for CPU, and also a *double* requires more space than an *integer*.  

Let's do some test:

##### Double's limit test 
Write a lot of nines in both defender's BC and attacker's BC.  
Because of the *double* limit, your number will be trunked to *9223372036854775807*.  
Anyway the battle starts and are calculated as well (some overflow errors maybe).  

    Battle calculated in 2.54 ms.
    Memory used: 335 KB

##### Worst case, OPBE max requirements!
The only thing that requires a lot of memory in OPBE is the Report, because it stores all ships in every round... this means that more   
rounds = more memory.  
Also, the worst case for CPU and memory is to have all types of ships(iteration of them).  
So we set 1'000'000 of ships in each type(defenses only for defender),not a big number just to avoid overflow in calculations.  
And we got:

    Battle calculated in 144.88 ms.
    Memory used: 6249 KB

* These values really depend on your hardware and PHP configuration: expecially, caching the bytecode will decrease a lot the CPU usage but increase RAM usage.

Seems a lot? Try a O(n^2) algorithm and you will crash with insane small amount of ships :)  
Anyway you can decrease a lot the memory usage setting, in *constants/battle_constants.php*,  

```php 
    define('ONLY_FIRST_AND_LAST_ROUND',true);
```

---

## Making new test cases to share
Something wrong with OPBE? The fastest way to share the simulation is to make a test case.  

1. Set your prefered class name,but it must extends **RunnableTest**.
2. Override two functions:
  * *getAttachers()* : return a PlayerGroup that rappresent the attackers
  * *getDefenders()* : return a PlayerGroup that rappresent the defenders

3. Instantiate your class inside the file.
4. Put the file in opbe/test/runnable/

An example:

```php 
<?php
require ("../RunnableTest.php");
class MyTest extends RunnableTest
{
    public function getAttachers()
    {
        $fleet = new Fleet(1,array(
            $this->getShipType(206, 50),
            $this->getShipType(207, 50),
            $this->getShipType(204, 150)));
        $player = new Player(1, array($fleet));
        return new PlayerGroup(array($player));
    }
    public function getDefenders()
    {
        $fleet = new Fleet(2,array(
            $this->getShipType(210, 150),
            $this->getShipType(215, 50),
            $this->getShipType(207, 20)));
        $player = new Player(2, array($fleet));
        return new PlayerGroup(array($player));
    }
}
new MyTest();
?>
```
* You can check the combat result entering with a browser in *opbe/test/runnable/MyTest.php*
* Please use Github issue system

---
## Implementation developing guide 
The system organization is like :
* PlayerGroup
    * Player1
    * Player2
        * Fleet1
        * Fleet2
            * ShipType1
            * ShipType2

So in a PlayerGroup there are different *Player*s,  
each Player have different *Fleet*s,  
each Fleet have different *ShipType*s. 

* All these classes implements Iterator interface, so you can iterate them as arrays.

  ```php
   foreach($playerGroup as $idPlayer => $player)
    {
        foreach($player as $idFleet => $fleet)
        {
            foreach($fleet as $idShipType => $shipType)
            {
                // do something
            }
        }
    }
  ```
  But to increase performace it's better to call *getIterator()* function.

* Another good point is that there aren't side effects in all OPBE classes. This means something like this:

```php
class A
    private $store=array();
    function put($id,$object)
    {
       $this->store[$id] = $object->clone();
    }
    function get($id) 
    {
        return $this->store[$id];    
    }
} 

$a= new A();
$obj = new Object();
$obj->x= "hello";
$a->store(1,$obj);

$obj->x .=" word"; // $object is edited only outside A, no side effects!

echo $a->get(1); // print "hello" instead "hello world"  
```
Sometimes it's not really required to clone, but this good practice ensure less bugs.

#### ShipType

ShipType is the smallest unit in the system: it reppresents a group of specific object type able to fight.  
For some reasons, OPBE needs to categorize it in either one of these two types extending ShipType:
* Defense
* Ship

You shouldn't ened to care about this fact because this automatic code will do it for you:

```php
    $shipType =  $this->getShipType($idShipType, $count);
```    

```php
   
function getShipType($id, $count)
{
    global $CombatCaps, $pricelist;
    $rf = $CombatCaps[$id]['sd'];
    $shield = $CombatCaps[$id]['shield'];
    $cost = array($pricelist[$id]['metal'], $pricelist[$id]['crystal']);
    $power = $CombatCaps[$id]['attack'];
    if ($id >= SHIP_MIN_ID && $id <= SHIP_MAX_ID)
    {
        return new Ship($id, $count, $rf, $shield, $cost, $power);
    }
    return new Defense($id, $count, $rf, $shield, $cost, $power);
}
   
```
- Note that you can assign different technology levels to each ShipType, see functions inside this class.
- By default, ShipType will give tech levels by its Fleet container .   

#### Fleet

Fleet is a group of ShipType and it is extended by a single object 
* HomeFleet : represent the ships and defense in the target's planet

This time you have to manually choose the right class and HomeFleet should have $id = 0;

```php
    $fleet = new Fleet($idFleet); // $idFleet is a must
    $fleet = new HomeFleet(0); // 0 is a must
    $fleet->add($shipType);
```

- Note that you can assign differents techs to each *Fleet*, see functions inside this class.   
- By default, Fleet will give tech levels by its Player container . 
- Fleet has a __toString method that automatically fill-up the corrispective *views/fleet.html* and return the result html.   
So you can echo it.

```php
  echo $fleet; 
```

#### Player

Player is a group of Fleets, don't care about the question attacker or defender.

```php
    $player = new Player($idPlayer); // $idPlayer is a must
    $player->addFleet($fleet);
```
- Player has a __toString method that automatically fill-up the corrispective *views/player2.html* and return the result html.   
So you can echo it.

```php
  echo $player; 
```

#### PlayerGroup

PlayerGroup is a group of Player, don't care about the question attacker or defender.

```php
    $playerGroup = new PlayerGroup();
    $playerGroup->addPlayer($player);
```

- PlayerGroup has a __toString method that automatically fill-up the corrispective *views/PlayerGroup.html* and return the result html.   
So you can echo it.

```php
  echo $playerGroup; 
```

#### Bring them together

An easy way to display them:
```php   
    $fleet = new Fleet($idFleet);
    $fleet->add($this->getShipType($id, $count));
    
    $player = new Player($idPlayer);
    $player->addFleet($fleet);
    
    $playerGroup = new PlayerGroup();
    $playerGroup->addPlayer($player);
    
```

#### Battle

Battle is the main class of OPBE.  
The first argument of constructor is the **attacking** PlayerGroup, the second one is the **defending** PlayerGroup.  

There are two methods you need to know about:
* startBattle(boolean $debug) : start the battle, if $debug == true, informations will be written in output.
* getReport() : return an object useful to retrieve all kinds of battle information.


```php
    $engine = new Battle($attackingPlayerGroup, $defendingPlayerGroup);
    $engine->startBattle(false);
    $info = $engine->getReport();
```

#### BattleReport

BattleReport is a big container of data about the simulated battle.  
In the web interface of OPBE, the instance of BattleReport is injected in templates.   

```php
    $info = $engine->getReport();
```

- BattleReport contains all the ships status in every round, and also has useful functions to fill templates or update  
the database after the battle.
- BattleReport has a __toString method that automatically fill-up the corrispective *views/report.html* and return the result html.   
So you can echo it.

```php
   echo $info; 
```

This is very usefull to store only the object in database and generate the html when needed. For example:

```php
    $obj = serialize($info);
    mysql_query("INSERT INTO Reports (id , obj) VALUES ($id, $obj)");
    
    $result = mysql_fetch_array(mysql_query("SELECT obj FROM Reports WHERE id = $id"));    
    $info = unserialize($result['obj']);
    echo $info;
```

---

## License

![license](http://www.gnu.org/graphics/agplv3-155x51.png)  
    
    Copyright (C) 2013  Jstar

    OPBE is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    OPBE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
[why affero GPL](http://www.gnu.org/licenses/why-affero-gpl.html)

---

## Questions

> I would like to include your battle engine but the code of my game won't be published

You can keep secret your code because OPBE can be seen as a external module with own license, it's only required to share changes on OPBE.

> I would like to have some profits with my game 

GNU affero v3 accepts profits as well

> I would like use OPBE with numbers greater than double

You should replace any PHP native mathematical with [BC math](http://php.net/manual/en/ref.bc.php) functions

> I would like change ships/defense repair probability

```php
    You have to change only constats/battle_constants.php  
    define('DEFENSE_REPAIR_PROB', 0.7); // 0.7 = 70%
    define('SHIP_REPAIR_PROB', 0);
```
---
    

## Who is using OPBE?

I'm happy to deliver this software giving others the possibility to have a good battle engine.  
On the other hand, it's a pleasure to see people using my OPBE.  
Send me an email to put your game logo here!  [frascafresca@gmail.com](mailto:frascafresca@gmail.com)

![xgproyect](http://www.xgproyect.net/images/misc/xg-logo.png)

  Files folder image Files  
File Role Description
Files folder imagecombatObject (4 files)
Files folder imageconstants (1 file)
Files folder imagecore (3 files)
Files folder imageimplementations (2 directories)
Files folder imagemodels (8 files)
Files folder imagepublic (1 file)
Files folder imagetests (2 files, 1 directory)
Files folder imageutils (10 files)
Files folder imageviews (11 files)
Accessible without login Plain text file .htaccess Data Auxiliary data
Accessible without login Plain text file github.php Aux. Auxiliary script
Accessible without login Plain text file index.php Aux. Class source
Accessible without login Plain text file LICENSE.txt Lic. Documentation
Accessible without login Plain text file README.md Doc. Documentation

 Version Control Unique User Downloads Download Rankings  
 100%
Total:190
This week:1
All time:7,899
This week:1,047Up