├── .gitignore ├── LICENSE ├── README.MD ├── composer.json ├── composer.lock ├── doc ├── niuniu.md ├── sangong.md └── texas.md ├── src ├── Games │ ├── NiuNiu.php │ ├── SanGong.php │ └── Texas.php ├── Poker.php └── Traits │ └── CardWithValue.php └── tests └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 goodspb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # 扑克游戏算法 for php 2 | 3 | * [德州扑克算法规则](/doc/texas.md) 4 | * [牛牛算法规则](/doc/niuniu.md) 5 | * [三公算法规则](/doc/sangong.md) 6 | 7 | ## 使用 8 | 9 | 10 | ### 1. 德州扑克 11 | 12 | ```php 13 | generate(2); 19 | //输出玩家牌 和 公共牌 20 | var_dump($texas->getPlayersCards(), $texas->getPublicCards()); 21 | //输出比较结果 22 | echo "
";
23 | print_r($texas->comparePlayer($texas->getPlayersCards()[1], $texas->getPlayersCards()[2]));
24 | ```
25 | 
26 | ### 2. 牛牛
27 | 
28 | ```php
29 | generate(3);
36 | //手工填入2位玩家
37 | //$niu->setPlayerCard(1, [[1, 4], [2, 4], [3, 4], [4, 4], [5, 2]]);
38 | //$niu->setPlayerCard(2, [[1, 3], [2, 3], [3, 3], [4, 3], [5, 3]]);
39 | 
40 | //执行计算
41 | $result = $niu->execute();
42 | $players = $niu->getPlayersCards();
43 | 
44 | //输出剩余的牌
45 | //var_dump($niu->getRound());
46 | 
47 | //输出玩家牌
48 | var_dump($players);
49 | 
50 | //输出结果
51 | echo '
';
52 | print_r($result);
53 | ```
54 | 
55 | ### 3. 三公
56 | 
57 | ```php
58 | generate(3);
65 | 
66 | //执行计算
67 | $result = $niu->execute();
68 | 
69 | //输出结果
70 | echo '
';
71 | print_r($result);
72 | ```
73 | 
74 | ## 问题
75 | 
76 | 欢迎 issues 哦。
77 | 


--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
 1 | {
 2 |     "name": "goodspb/poker-algorithm",
 3 |     "description": "poker algorithm for php",
 4 |     "type": "library",
 5 |     "minimum-stability": "dev",
 6 |     "require": {
 7 |         "php": ">=5.5"
 8 |     },
 9 |     "require-dev": {
10 |         "phpunit/phpunit": "~5.7"
11 |     },
12 |     "autoload": {
13 |         "psr-4": {
14 |             "Goodspb\\PokerAlgorithm\\": "src/"
15 |         }
16 |     },
17 |     "autoload-dev": {
18 |         "psr-4": {
19 |             "Tests\\": "tests/"
20 |         }
21 |     }
22 | }
23 | 


--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
   1 | {
   2 |     "_readme": [
   3 |         "This file locks the dependencies of your project to a known state",
   4 |         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
   5 |         "This file is @generated automatically"
   6 |     ],
   7 |     "content-hash": "ecf1d07ec21ae5ee301f13396f3d3886",
   8 |     "packages": [],
   9 |     "packages-dev": [
  10 |         {
  11 |             "name": "doctrine/instantiator",
  12 |             "version": "dev-master",
  13 |             "source": {
  14 |                 "type": "git",
  15 |                 "url": "https://github.com/doctrine/instantiator.git",
  16 |                 "reference": "7af8066e48b8a4cbd90849bbe9234ab444057968"
  17 |             },
  18 |             "dist": {
  19 |                 "type": "zip",
  20 |                 "url": "https://files.phpcomposer.com/files/doctrine/instantiator/7af8066e48b8a4cbd90849bbe9234ab444057968.zip",
  21 |                 "reference": "7af8066e48b8a4cbd90849bbe9234ab444057968",
  22 |                 "shasum": ""
  23 |             },
  24 |             "require": {
  25 |                 "php": "^7.1"
  26 |             },
  27 |             "require-dev": {
  28 |                 "ext-pdo": "*",
  29 |                 "ext-phar": "*",
  30 |                 "phpunit/phpunit": "^6.2.3"
  31 |             },
  32 |             "type": "library",
  33 |             "extra": {
  34 |                 "branch-alias": {
  35 |                     "dev-master": "1.2.x-dev"
  36 |                 }
  37 |             },
  38 |             "autoload": {
  39 |                 "psr-4": {
  40 |                     "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
  41 |                 }
  42 |             },
  43 |             "notification-url": "https://packagist.org/downloads/",
  44 |             "license": [
  45 |                 "MIT"
  46 |             ],
  47 |             "authors": [
  48 |                 {
  49 |                     "name": "Marco Pivetta",
  50 |                     "email": "ocramius@gmail.com",
  51 |                     "homepage": "http://ocramius.github.com/"
  52 |                 }
  53 |             ],
  54 |             "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
  55 |             "homepage": "https://github.com/doctrine/instantiator",
  56 |             "keywords": [
  57 |                 "constructor",
  58 |                 "instantiate"
  59 |             ],
  60 |             "time": "2017-09-19T12:41:22+00:00"
  61 |         },
  62 |         {
  63 |             "name": "myclabs/deep-copy",
  64 |             "version": "1.7.0",
  65 |             "source": {
  66 |                 "type": "git",
  67 |                 "url": "https://github.com/myclabs/DeepCopy.git",
  68 |                 "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
  69 |             },
  70 |             "dist": {
  71 |                 "type": "zip",
  72 |                 "url": "https://files.phpcomposer.com/files/myclabs/DeepCopy/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e.zip",
  73 |                 "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
  74 |                 "shasum": ""
  75 |             },
  76 |             "require": {
  77 |                 "php": "^5.6 || ^7.0"
  78 |             },
  79 |             "require-dev": {
  80 |                 "doctrine/collections": "^1.0",
  81 |                 "doctrine/common": "^2.6",
  82 |                 "phpunit/phpunit": "^4.1"
  83 |             },
  84 |             "type": "library",
  85 |             "autoload": {
  86 |                 "psr-4": {
  87 |                     "DeepCopy\\": "src/DeepCopy/"
  88 |                 },
  89 |                 "files": [
  90 |                     "src/DeepCopy/deep_copy.php"
  91 |                 ]
  92 |             },
  93 |             "notification-url": "https://packagist.org/downloads/",
  94 |             "license": [
  95 |                 "MIT"
  96 |             ],
  97 |             "description": "Create deep copies (clones) of your objects",
  98 |             "keywords": [
  99 |                 "clone",
 100 |                 "copy",
 101 |                 "duplicate",
 102 |                 "object",
 103 |                 "object graph"
 104 |             ],
 105 |             "time": "2017-10-19T19:58:43+00:00"
 106 |         },
 107 |         {
 108 |             "name": "phpdocumentor/reflection-common",
 109 |             "version": "dev-master",
 110 |             "source": {
 111 |                 "type": "git",
 112 |                 "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
 113 |                 "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
 114 |             },
 115 |             "dist": {
 116 |                 "type": "zip",
 117 |                 "url": "https://files.phpcomposer.com/files/phpDocumentor/ReflectionCommon/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6.zip",
 118 |                 "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
 119 |                 "shasum": ""
 120 |             },
 121 |             "require": {
 122 |                 "php": ">=5.5"
 123 |             },
 124 |             "require-dev": {
 125 |                 "phpunit/phpunit": "^4.6"
 126 |             },
 127 |             "type": "library",
 128 |             "extra": {
 129 |                 "branch-alias": {
 130 |                     "dev-master": "1.0.x-dev"
 131 |                 }
 132 |             },
 133 |             "autoload": {
 134 |                 "psr-4": {
 135 |                     "phpDocumentor\\Reflection\\": [
 136 |                         "src"
 137 |                     ]
 138 |                 }
 139 |             },
 140 |             "notification-url": "https://packagist.org/downloads/",
 141 |             "license": [
 142 |                 "MIT"
 143 |             ],
 144 |             "authors": [
 145 |                 {
 146 |                     "name": "Jaap van Otterdijk",
 147 |                     "email": "opensource@ijaap.nl"
 148 |                 }
 149 |             ],
 150 |             "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
 151 |             "homepage": "http://www.phpdoc.org",
 152 |             "keywords": [
 153 |                 "FQSEN",
 154 |                 "phpDocumentor",
 155 |                 "phpdoc",
 156 |                 "reflection",
 157 |                 "static analysis"
 158 |             ],
 159 |             "time": "2017-09-11T18:02:19+00:00"
 160 |         },
 161 |         {
 162 |             "name": "phpdocumentor/reflection-docblock",
 163 |             "version": "4.1.1",
 164 |             "source": {
 165 |                 "type": "git",
 166 |                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
 167 |                 "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2"
 168 |             },
 169 |             "dist": {
 170 |                 "type": "zip",
 171 |                 "url": "https://files.phpcomposer.com/files/phpDocumentor/ReflectionDocBlock/2d3d238c433cf69caeb4842e97a3223a116f94b2.zip",
 172 |                 "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2",
 173 |                 "shasum": ""
 174 |             },
 175 |             "require": {
 176 |                 "php": "^7.0",
 177 |                 "phpdocumentor/reflection-common": "^1.0@dev",
 178 |                 "phpdocumentor/type-resolver": "^0.4.0",
 179 |                 "webmozart/assert": "^1.0"
 180 |             },
 181 |             "require-dev": {
 182 |                 "mockery/mockery": "^0.9.4",
 183 |                 "phpunit/phpunit": "^4.4"
 184 |             },
 185 |             "type": "library",
 186 |             "autoload": {
 187 |                 "psr-4": {
 188 |                     "phpDocumentor\\Reflection\\": [
 189 |                         "src/"
 190 |                     ]
 191 |                 }
 192 |             },
 193 |             "notification-url": "https://packagist.org/downloads/",
 194 |             "license": [
 195 |                 "MIT"
 196 |             ],
 197 |             "authors": [
 198 |                 {
 199 |                     "name": "Mike van Riel",
 200 |                     "email": "me@mikevanriel.com"
 201 |                 }
 202 |             ],
 203 |             "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
 204 |             "time": "2017-08-30T18:51:59+00:00"
 205 |         },
 206 |         {
 207 |             "name": "phpdocumentor/type-resolver",
 208 |             "version": "0.4.0",
 209 |             "source": {
 210 |                 "type": "git",
 211 |                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
 212 |                 "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
 213 |             },
 214 |             "dist": {
 215 |                 "type": "zip",
 216 |                 "url": "https://files.phpcomposer.com/files/phpDocumentor/TypeResolver/9c977708995954784726e25d0cd1dddf4e65b0f7.zip",
 217 |                 "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
 218 |                 "shasum": ""
 219 |             },
 220 |             "require": {
 221 |                 "php": "^5.5 || ^7.0",
 222 |                 "phpdocumentor/reflection-common": "^1.0"
 223 |             },
 224 |             "require-dev": {
 225 |                 "mockery/mockery": "^0.9.4",
 226 |                 "phpunit/phpunit": "^5.2||^4.8.24"
 227 |             },
 228 |             "type": "library",
 229 |             "extra": {
 230 |                 "branch-alias": {
 231 |                     "dev-master": "1.0.x-dev"
 232 |                 }
 233 |             },
 234 |             "autoload": {
 235 |                 "psr-4": {
 236 |                     "phpDocumentor\\Reflection\\": [
 237 |                         "src/"
 238 |                     ]
 239 |                 }
 240 |             },
 241 |             "notification-url": "https://packagist.org/downloads/",
 242 |             "license": [
 243 |                 "MIT"
 244 |             ],
 245 |             "authors": [
 246 |                 {
 247 |                     "name": "Mike van Riel",
 248 |                     "email": "me@mikevanriel.com"
 249 |                 }
 250 |             ],
 251 |             "time": "2017-07-14T14:27:02+00:00"
 252 |         },
 253 |         {
 254 |             "name": "phpspec/prophecy",
 255 |             "version": "dev-master",
 256 |             "source": {
 257 |                 "type": "git",
 258 |                 "url": "https://github.com/phpspec/prophecy.git",
 259 |                 "reference": "ddd9d7ffff1d7c3acd1a79a8e21d5ee5ea7beace"
 260 |             },
 261 |             "dist": {
 262 |                 "type": "zip",
 263 |                 "url": "https://files.phpcomposer.com/files/phpspec/prophecy/ddd9d7ffff1d7c3acd1a79a8e21d5ee5ea7beace.zip",
 264 |                 "reference": "ddd9d7ffff1d7c3acd1a79a8e21d5ee5ea7beace",
 265 |                 "shasum": ""
 266 |             },
 267 |             "require": {
 268 |                 "doctrine/instantiator": "^1.0.2",
 269 |                 "php": "^5.3|^7.0",
 270 |                 "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
 271 |                 "sebastian/comparator": "^1.1|^2.0",
 272 |                 "sebastian/recursion-context": "^1.0|^2.0|^3.0"
 273 |             },
 274 |             "require-dev": {
 275 |                 "phpspec/phpspec": "^2.5|^3.2",
 276 |                 "phpunit/phpunit": "^4.8.35 || ^5.7"
 277 |             },
 278 |             "type": "library",
 279 |             "extra": {
 280 |                 "branch-alias": {
 281 |                     "dev-master": "1.7.x-dev"
 282 |                 }
 283 |             },
 284 |             "autoload": {
 285 |                 "psr-0": {
 286 |                     "Prophecy\\": "src/"
 287 |                 }
 288 |             },
 289 |             "notification-url": "https://packagist.org/downloads/",
 290 |             "license": [
 291 |                 "MIT"
 292 |             ],
 293 |             "authors": [
 294 |                 {
 295 |                     "name": "Konstantin Kudryashov",
 296 |                     "email": "ever.zet@gmail.com",
 297 |                     "homepage": "http://everzet.com"
 298 |                 },
 299 |                 {
 300 |                     "name": "Marcello Duarte",
 301 |                     "email": "marcello.duarte@gmail.com"
 302 |                 }
 303 |             ],
 304 |             "description": "Highly opinionated mocking framework for PHP 5.3+",
 305 |             "homepage": "https://github.com/phpspec/prophecy",
 306 |             "keywords": [
 307 |                 "Double",
 308 |                 "Dummy",
 309 |                 "fake",
 310 |                 "mock",
 311 |                 "spy",
 312 |                 "stub"
 313 |             ],
 314 |             "time": "2017-11-07T12:00:44+00:00"
 315 |         },
 316 |         {
 317 |             "name": "phpunit/php-code-coverage",
 318 |             "version": "4.0.x-dev",
 319 |             "source": {
 320 |                 "type": "git",
 321 |                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
 322 |                 "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
 323 |             },
 324 |             "dist": {
 325 |                 "type": "zip",
 326 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/php-code-coverage/ef7b2f56815df854e66ceaee8ebe9393ae36a40d.zip",
 327 |                 "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
 328 |                 "shasum": ""
 329 |             },
 330 |             "require": {
 331 |                 "ext-dom": "*",
 332 |                 "ext-xmlwriter": "*",
 333 |                 "php": "^5.6 || ^7.0",
 334 |                 "phpunit/php-file-iterator": "^1.3",
 335 |                 "phpunit/php-text-template": "^1.2",
 336 |                 "phpunit/php-token-stream": "^1.4.2 || ^2.0",
 337 |                 "sebastian/code-unit-reverse-lookup": "^1.0",
 338 |                 "sebastian/environment": "^1.3.2 || ^2.0",
 339 |                 "sebastian/version": "^1.0 || ^2.0"
 340 |             },
 341 |             "require-dev": {
 342 |                 "ext-xdebug": "^2.1.4",
 343 |                 "phpunit/phpunit": "^5.7"
 344 |             },
 345 |             "suggest": {
 346 |                 "ext-xdebug": "^2.5.1"
 347 |             },
 348 |             "type": "library",
 349 |             "extra": {
 350 |                 "branch-alias": {
 351 |                     "dev-master": "4.0.x-dev"
 352 |                 }
 353 |             },
 354 |             "autoload": {
 355 |                 "classmap": [
 356 |                     "src/"
 357 |                 ]
 358 |             },
 359 |             "notification-url": "https://packagist.org/downloads/",
 360 |             "license": [
 361 |                 "BSD-3-Clause"
 362 |             ],
 363 |             "authors": [
 364 |                 {
 365 |                     "name": "Sebastian Bergmann",
 366 |                     "email": "sb@sebastian-bergmann.de",
 367 |                     "role": "lead"
 368 |                 }
 369 |             ],
 370 |             "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
 371 |             "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
 372 |             "keywords": [
 373 |                 "coverage",
 374 |                 "testing",
 375 |                 "xunit"
 376 |             ],
 377 |             "time": "2017-04-02T07:44:40+00:00"
 378 |         },
 379 |         {
 380 |             "name": "phpunit/php-file-iterator",
 381 |             "version": "1.4.x-dev",
 382 |             "source": {
 383 |                 "type": "git",
 384 |                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
 385 |                 "reference": "63304292f3cf89b2382b90dd7a2abf9e0ba232f9"
 386 |             },
 387 |             "dist": {
 388 |                 "type": "zip",
 389 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/php-file-iterator/63304292f3cf89b2382b90dd7a2abf9e0ba232f9.zip",
 390 |                 "reference": "63304292f3cf89b2382b90dd7a2abf9e0ba232f9",
 391 |                 "shasum": ""
 392 |             },
 393 |             "require": {
 394 |                 "php": ">=5.3.3"
 395 |             },
 396 |             "type": "library",
 397 |             "extra": {
 398 |                 "branch-alias": {
 399 |                     "dev-master": "1.4.x-dev"
 400 |                 }
 401 |             },
 402 |             "autoload": {
 403 |                 "classmap": [
 404 |                     "src/"
 405 |                 ]
 406 |             },
 407 |             "notification-url": "https://packagist.org/downloads/",
 408 |             "license": [
 409 |                 "BSD-3-Clause"
 410 |             ],
 411 |             "authors": [
 412 |                 {
 413 |                     "name": "Sebastian Bergmann",
 414 |                     "email": "sb@sebastian-bergmann.de",
 415 |                     "role": "lead"
 416 |                 }
 417 |             ],
 418 |             "description": "FilterIterator implementation that filters files based on a list of suffixes.",
 419 |             "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
 420 |             "keywords": [
 421 |                 "filesystem",
 422 |                 "iterator"
 423 |             ],
 424 |             "time": "2017-10-30T04:21:02+00:00"
 425 |         },
 426 |         {
 427 |             "name": "phpunit/php-text-template",
 428 |             "version": "1.2.1",
 429 |             "source": {
 430 |                 "type": "git",
 431 |                 "url": "https://github.com/sebastianbergmann/php-text-template.git",
 432 |                 "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
 433 |             },
 434 |             "dist": {
 435 |                 "type": "zip",
 436 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/php-text-template/31f8b717e51d9a2afca6c9f046f5d69fc27c8686.zip",
 437 |                 "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
 438 |                 "shasum": ""
 439 |             },
 440 |             "require": {
 441 |                 "php": ">=5.3.3"
 442 |             },
 443 |             "type": "library",
 444 |             "autoload": {
 445 |                 "classmap": [
 446 |                     "src/"
 447 |                 ]
 448 |             },
 449 |             "notification-url": "https://packagist.org/downloads/",
 450 |             "license": [
 451 |                 "BSD-3-Clause"
 452 |             ],
 453 |             "authors": [
 454 |                 {
 455 |                     "name": "Sebastian Bergmann",
 456 |                     "email": "sebastian@phpunit.de",
 457 |                     "role": "lead"
 458 |                 }
 459 |             ],
 460 |             "description": "Simple template engine.",
 461 |             "homepage": "https://github.com/sebastianbergmann/php-text-template/",
 462 |             "keywords": [
 463 |                 "template"
 464 |             ],
 465 |             "time": "2015-06-21T13:50:34+00:00"
 466 |         },
 467 |         {
 468 |             "name": "phpunit/php-timer",
 469 |             "version": "dev-master",
 470 |             "source": {
 471 |                 "type": "git",
 472 |                 "url": "https://github.com/sebastianbergmann/php-timer.git",
 473 |                 "reference": "d107f347d368dd8a384601398280c7c608390ab7"
 474 |             },
 475 |             "dist": {
 476 |                 "type": "zip",
 477 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/php-timer/d107f347d368dd8a384601398280c7c608390ab7.zip",
 478 |                 "reference": "d107f347d368dd8a384601398280c7c608390ab7",
 479 |                 "shasum": ""
 480 |             },
 481 |             "require": {
 482 |                 "php": "^5.3.3 || ^7.0"
 483 |             },
 484 |             "require-dev": {
 485 |                 "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
 486 |             },
 487 |             "type": "library",
 488 |             "extra": {
 489 |                 "branch-alias": {
 490 |                     "dev-master": "1.0-dev"
 491 |                 }
 492 |             },
 493 |             "autoload": {
 494 |                 "classmap": [
 495 |                     "src/"
 496 |                 ]
 497 |             },
 498 |             "notification-url": "https://packagist.org/downloads/",
 499 |             "license": [
 500 |                 "BSD-3-Clause"
 501 |             ],
 502 |             "authors": [
 503 |                 {
 504 |                     "name": "Sebastian Bergmann",
 505 |                     "email": "sb@sebastian-bergmann.de",
 506 |                     "role": "lead"
 507 |                 }
 508 |             ],
 509 |             "description": "Utility class for timing",
 510 |             "homepage": "https://github.com/sebastianbergmann/php-timer/",
 511 |             "keywords": [
 512 |                 "timer"
 513 |             ],
 514 |             "time": "2017-03-07T15:42:04+00:00"
 515 |         },
 516 |         {
 517 |             "name": "phpunit/php-token-stream",
 518 |             "version": "dev-master",
 519 |             "source": {
 520 |                 "type": "git",
 521 |                 "url": "https://github.com/sebastianbergmann/php-token-stream.git",
 522 |                 "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0"
 523 |             },
 524 |             "dist": {
 525 |                 "type": "zip",
 526 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/php-token-stream/9a02332089ac48e704c70f6cefed30c224e3c0b0.zip",
 527 |                 "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0",
 528 |                 "shasum": ""
 529 |             },
 530 |             "require": {
 531 |                 "ext-tokenizer": "*",
 532 |                 "php": "^7.0"
 533 |             },
 534 |             "require-dev": {
 535 |                 "phpunit/phpunit": "^6.2.4"
 536 |             },
 537 |             "type": "library",
 538 |             "extra": {
 539 |                 "branch-alias": {
 540 |                     "dev-master": "2.0-dev"
 541 |                 }
 542 |             },
 543 |             "autoload": {
 544 |                 "classmap": [
 545 |                     "src/"
 546 |                 ]
 547 |             },
 548 |             "notification-url": "https://packagist.org/downloads/",
 549 |             "license": [
 550 |                 "BSD-3-Clause"
 551 |             ],
 552 |             "authors": [
 553 |                 {
 554 |                     "name": "Sebastian Bergmann",
 555 |                     "email": "sebastian@phpunit.de"
 556 |                 }
 557 |             ],
 558 |             "description": "Wrapper around PHP's tokenizer extension.",
 559 |             "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
 560 |             "keywords": [
 561 |                 "tokenizer"
 562 |             ],
 563 |             "time": "2017-08-20T05:47:52+00:00"
 564 |         },
 565 |         {
 566 |             "name": "phpunit/phpunit",
 567 |             "version": "5.7.x-dev",
 568 |             "source": {
 569 |                 "type": "git",
 570 |                 "url": "https://github.com/sebastianbergmann/phpunit.git",
 571 |                 "reference": "4683365268a066342d6a829496c58d89a431ad72"
 572 |             },
 573 |             "dist": {
 574 |                 "type": "zip",
 575 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/phpunit/4683365268a066342d6a829496c58d89a431ad72.zip",
 576 |                 "reference": "4683365268a066342d6a829496c58d89a431ad72",
 577 |                 "shasum": ""
 578 |             },
 579 |             "require": {
 580 |                 "ext-dom": "*",
 581 |                 "ext-json": "*",
 582 |                 "ext-libxml": "*",
 583 |                 "ext-mbstring": "*",
 584 |                 "ext-xml": "*",
 585 |                 "myclabs/deep-copy": "~1.3",
 586 |                 "php": "^5.6 || ^7.0",
 587 |                 "phpspec/prophecy": "^1.6.2",
 588 |                 "phpunit/php-code-coverage": "^4.0.4",
 589 |                 "phpunit/php-file-iterator": "~1.4",
 590 |                 "phpunit/php-text-template": "~1.2",
 591 |                 "phpunit/php-timer": "^1.0.6",
 592 |                 "phpunit/phpunit-mock-objects": "^3.2",
 593 |                 "sebastian/comparator": "^1.2.4",
 594 |                 "sebastian/diff": "^1.4.3",
 595 |                 "sebastian/environment": "^1.3.4 || ^2.0",
 596 |                 "sebastian/exporter": "~2.0",
 597 |                 "sebastian/global-state": "^1.1",
 598 |                 "sebastian/object-enumerator": "~2.0",
 599 |                 "sebastian/resource-operations": "~1.0",
 600 |                 "sebastian/version": "~1.0.3|~2.0",
 601 |                 "symfony/yaml": "~2.1|~3.0|~4.0"
 602 |             },
 603 |             "conflict": {
 604 |                 "phpdocumentor/reflection-docblock": "3.0.2"
 605 |             },
 606 |             "require-dev": {
 607 |                 "ext-pdo": "*"
 608 |             },
 609 |             "suggest": {
 610 |                 "ext-xdebug": "*",
 611 |                 "phpunit/php-invoker": "~1.1"
 612 |             },
 613 |             "bin": [
 614 |                 "phpunit"
 615 |             ],
 616 |             "type": "library",
 617 |             "extra": {
 618 |                 "branch-alias": {
 619 |                     "dev-master": "5.7.x-dev"
 620 |                 }
 621 |             },
 622 |             "autoload": {
 623 |                 "classmap": [
 624 |                     "src/"
 625 |                 ]
 626 |             },
 627 |             "notification-url": "https://packagist.org/downloads/",
 628 |             "license": [
 629 |                 "BSD-3-Clause"
 630 |             ],
 631 |             "authors": [
 632 |                 {
 633 |                     "name": "Sebastian Bergmann",
 634 |                     "email": "sebastian@phpunit.de",
 635 |                     "role": "lead"
 636 |                 }
 637 |             ],
 638 |             "description": "The PHP Unit Testing framework.",
 639 |             "homepage": "https://phpunit.de/",
 640 |             "keywords": [
 641 |                 "phpunit",
 642 |                 "testing",
 643 |                 "xunit"
 644 |             ],
 645 |             "time": "2017-11-10T09:13:14+00:00"
 646 |         },
 647 |         {
 648 |             "name": "phpunit/phpunit-mock-objects",
 649 |             "version": "3.4.x-dev",
 650 |             "source": {
 651 |                 "type": "git",
 652 |                 "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
 653 |                 "reference": "a23b761686d50a560cc56233b9ecf49597cc9118"
 654 |             },
 655 |             "dist": {
 656 |                 "type": "zip",
 657 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/phpunit-mock-objects/a23b761686d50a560cc56233b9ecf49597cc9118.zip",
 658 |                 "reference": "a23b761686d50a560cc56233b9ecf49597cc9118",
 659 |                 "shasum": ""
 660 |             },
 661 |             "require": {
 662 |                 "doctrine/instantiator": "^1.0.2",
 663 |                 "php": "^5.6 || ^7.0",
 664 |                 "phpunit/php-text-template": "^1.2",
 665 |                 "sebastian/exporter": "^1.2 || ^2.0"
 666 |             },
 667 |             "conflict": {
 668 |                 "phpunit/phpunit": "<5.4.0"
 669 |             },
 670 |             "require-dev": {
 671 |                 "phpunit/phpunit": "^5.4"
 672 |             },
 673 |             "suggest": {
 674 |                 "ext-soap": "*"
 675 |             },
 676 |             "type": "library",
 677 |             "extra": {
 678 |                 "branch-alias": {
 679 |                     "dev-master": "3.2.x-dev"
 680 |                 }
 681 |             },
 682 |             "autoload": {
 683 |                 "classmap": [
 684 |                     "src/"
 685 |                 ]
 686 |             },
 687 |             "notification-url": "https://packagist.org/downloads/",
 688 |             "license": [
 689 |                 "BSD-3-Clause"
 690 |             ],
 691 |             "authors": [
 692 |                 {
 693 |                     "name": "Sebastian Bergmann",
 694 |                     "email": "sb@sebastian-bergmann.de",
 695 |                     "role": "lead"
 696 |                 }
 697 |             ],
 698 |             "description": "Mock Object library for PHPUnit",
 699 |             "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
 700 |             "keywords": [
 701 |                 "mock",
 702 |                 "xunit"
 703 |             ],
 704 |             "time": "2017-06-30T09:13:00+00:00"
 705 |         },
 706 |         {
 707 |             "name": "sebastian/code-unit-reverse-lookup",
 708 |             "version": "dev-master",
 709 |             "source": {
 710 |                 "type": "git",
 711 |                 "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
 712 |                 "reference": "3488be0a7b346cd6e5361510ed07e88f9bea2e88"
 713 |             },
 714 |             "dist": {
 715 |                 "type": "zip",
 716 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/code-unit-reverse-lookup/3488be0a7b346cd6e5361510ed07e88f9bea2e88.zip",
 717 |                 "reference": "3488be0a7b346cd6e5361510ed07e88f9bea2e88",
 718 |                 "shasum": ""
 719 |             },
 720 |             "require": {
 721 |                 "php": "^5.6 || ^7.0"
 722 |             },
 723 |             "require-dev": {
 724 |                 "phpunit/phpunit": "^5.7 || ^6.0"
 725 |             },
 726 |             "type": "library",
 727 |             "extra": {
 728 |                 "branch-alias": {
 729 |                     "dev-master": "1.0.x-dev"
 730 |                 }
 731 |             },
 732 |             "autoload": {
 733 |                 "classmap": [
 734 |                     "src/"
 735 |                 ]
 736 |             },
 737 |             "notification-url": "https://packagist.org/downloads/",
 738 |             "license": [
 739 |                 "BSD-3-Clause"
 740 |             ],
 741 |             "authors": [
 742 |                 {
 743 |                     "name": "Sebastian Bergmann",
 744 |                     "email": "sebastian@phpunit.de"
 745 |                 }
 746 |             ],
 747 |             "description": "Looks up which function or method a line of code belongs to",
 748 |             "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
 749 |             "time": "2017-03-04T10:23:55+00:00"
 750 |         },
 751 |         {
 752 |             "name": "sebastian/comparator",
 753 |             "version": "1.2.x-dev",
 754 |             "source": {
 755 |                 "type": "git",
 756 |                 "url": "https://github.com/sebastianbergmann/comparator.git",
 757 |                 "reference": "18a5d97c25f408f48acaf6d1b9f4079314c5996a"
 758 |             },
 759 |             "dist": {
 760 |                 "type": "zip",
 761 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/comparator/18a5d97c25f408f48acaf6d1b9f4079314c5996a.zip",
 762 |                 "reference": "18a5d97c25f408f48acaf6d1b9f4079314c5996a",
 763 |                 "shasum": ""
 764 |             },
 765 |             "require": {
 766 |                 "php": ">=5.3.3",
 767 |                 "sebastian/diff": "~1.2",
 768 |                 "sebastian/exporter": "~1.2 || ~2.0"
 769 |             },
 770 |             "require-dev": {
 771 |                 "phpunit/phpunit": "~4.4"
 772 |             },
 773 |             "type": "library",
 774 |             "extra": {
 775 |                 "branch-alias": {
 776 |                     "dev-master": "1.2.x-dev"
 777 |                 }
 778 |             },
 779 |             "autoload": {
 780 |                 "classmap": [
 781 |                     "src/"
 782 |                 ]
 783 |             },
 784 |             "notification-url": "https://packagist.org/downloads/",
 785 |             "license": [
 786 |                 "BSD-3-Clause"
 787 |             ],
 788 |             "authors": [
 789 |                 {
 790 |                     "name": "Jeff Welch",
 791 |                     "email": "whatthejeff@gmail.com"
 792 |                 },
 793 |                 {
 794 |                     "name": "Volker Dusch",
 795 |                     "email": "github@wallbash.com"
 796 |                 },
 797 |                 {
 798 |                     "name": "Bernhard Schussek",
 799 |                     "email": "bschussek@2bepublished.at"
 800 |                 },
 801 |                 {
 802 |                     "name": "Sebastian Bergmann",
 803 |                     "email": "sebastian@phpunit.de"
 804 |                 }
 805 |             ],
 806 |             "description": "Provides the functionality to compare PHP values for equality",
 807 |             "homepage": "http://www.github.com/sebastianbergmann/comparator",
 808 |             "keywords": [
 809 |                 "comparator",
 810 |                 "compare",
 811 |                 "equality"
 812 |             ],
 813 |             "time": "2017-03-07T10:34:43+00:00"
 814 |         },
 815 |         {
 816 |             "name": "sebastian/diff",
 817 |             "version": "1.4.x-dev",
 818 |             "source": {
 819 |                 "type": "git",
 820 |                 "url": "https://github.com/sebastianbergmann/diff.git",
 821 |                 "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
 822 |             },
 823 |             "dist": {
 824 |                 "type": "zip",
 825 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/diff/7f066a26a962dbe58ddea9f72a4e82874a3975a4.zip",
 826 |                 "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
 827 |                 "shasum": ""
 828 |             },
 829 |             "require": {
 830 |                 "php": "^5.3.3 || ^7.0"
 831 |             },
 832 |             "require-dev": {
 833 |                 "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
 834 |             },
 835 |             "type": "library",
 836 |             "extra": {
 837 |                 "branch-alias": {
 838 |                     "dev-master": "1.4-dev"
 839 |                 }
 840 |             },
 841 |             "autoload": {
 842 |                 "classmap": [
 843 |                     "src/"
 844 |                 ]
 845 |             },
 846 |             "notification-url": "https://packagist.org/downloads/",
 847 |             "license": [
 848 |                 "BSD-3-Clause"
 849 |             ],
 850 |             "authors": [
 851 |                 {
 852 |                     "name": "Kore Nordmann",
 853 |                     "email": "mail@kore-nordmann.de"
 854 |                 },
 855 |                 {
 856 |                     "name": "Sebastian Bergmann",
 857 |                     "email": "sebastian@phpunit.de"
 858 |                 }
 859 |             ],
 860 |             "description": "Diff implementation",
 861 |             "homepage": "https://github.com/sebastianbergmann/diff",
 862 |             "keywords": [
 863 |                 "diff"
 864 |             ],
 865 |             "time": "2017-05-22T07:24:03+00:00"
 866 |         },
 867 |         {
 868 |             "name": "sebastian/environment",
 869 |             "version": "2.0.x-dev",
 870 |             "source": {
 871 |                 "type": "git",
 872 |                 "url": "https://github.com/sebastianbergmann/environment.git",
 873 |                 "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
 874 |             },
 875 |             "dist": {
 876 |                 "type": "zip",
 877 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/environment/5795ffe5dc5b02460c3e34222fee8cbe245d8fac.zip",
 878 |                 "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
 879 |                 "shasum": ""
 880 |             },
 881 |             "require": {
 882 |                 "php": "^5.6 || ^7.0"
 883 |             },
 884 |             "require-dev": {
 885 |                 "phpunit/phpunit": "^5.0"
 886 |             },
 887 |             "type": "library",
 888 |             "extra": {
 889 |                 "branch-alias": {
 890 |                     "dev-master": "2.0.x-dev"
 891 |                 }
 892 |             },
 893 |             "autoload": {
 894 |                 "classmap": [
 895 |                     "src/"
 896 |                 ]
 897 |             },
 898 |             "notification-url": "https://packagist.org/downloads/",
 899 |             "license": [
 900 |                 "BSD-3-Clause"
 901 |             ],
 902 |             "authors": [
 903 |                 {
 904 |                     "name": "Sebastian Bergmann",
 905 |                     "email": "sebastian@phpunit.de"
 906 |                 }
 907 |             ],
 908 |             "description": "Provides functionality to handle HHVM/PHP environments",
 909 |             "homepage": "http://www.github.com/sebastianbergmann/environment",
 910 |             "keywords": [
 911 |                 "Xdebug",
 912 |                 "environment",
 913 |                 "hhvm"
 914 |             ],
 915 |             "time": "2016-11-26T07:53:53+00:00"
 916 |         },
 917 |         {
 918 |             "name": "sebastian/exporter",
 919 |             "version": "2.0.x-dev",
 920 |             "source": {
 921 |                 "type": "git",
 922 |                 "url": "https://github.com/sebastianbergmann/exporter.git",
 923 |                 "reference": "5e8e30670c3f36481e75211dbbcfd029a41ebf07"
 924 |             },
 925 |             "dist": {
 926 |                 "type": "zip",
 927 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/exporter/5e8e30670c3f36481e75211dbbcfd029a41ebf07.zip",
 928 |                 "reference": "5e8e30670c3f36481e75211dbbcfd029a41ebf07",
 929 |                 "shasum": ""
 930 |             },
 931 |             "require": {
 932 |                 "php": "^5.3.3 || ^7.0",
 933 |                 "sebastian/recursion-context": "^2.0"
 934 |             },
 935 |             "require-dev": {
 936 |                 "ext-mbstring": "*",
 937 |                 "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
 938 |             },
 939 |             "type": "library",
 940 |             "extra": {
 941 |                 "branch-alias": {
 942 |                     "dev-master": "2.0.x-dev"
 943 |                 }
 944 |             },
 945 |             "autoload": {
 946 |                 "classmap": [
 947 |                     "src/"
 948 |                 ]
 949 |             },
 950 |             "notification-url": "https://packagist.org/downloads/",
 951 |             "license": [
 952 |                 "BSD-3-Clause"
 953 |             ],
 954 |             "authors": [
 955 |                 {
 956 |                     "name": "Jeff Welch",
 957 |                     "email": "whatthejeff@gmail.com"
 958 |                 },
 959 |                 {
 960 |                     "name": "Volker Dusch",
 961 |                     "email": "github@wallbash.com"
 962 |                 },
 963 |                 {
 964 |                     "name": "Bernhard Schussek",
 965 |                     "email": "bschussek@2bepublished.at"
 966 |                 },
 967 |                 {
 968 |                     "name": "Sebastian Bergmann",
 969 |                     "email": "sebastian@phpunit.de"
 970 |                 },
 971 |                 {
 972 |                     "name": "Adam Harvey",
 973 |                     "email": "aharvey@php.net"
 974 |                 }
 975 |             ],
 976 |             "description": "Provides the functionality to export PHP variables for visualization",
 977 |             "homepage": "http://www.github.com/sebastianbergmann/exporter",
 978 |             "keywords": [
 979 |                 "export",
 980 |                 "exporter"
 981 |             ],
 982 |             "time": "2017-03-07T10:36:49+00:00"
 983 |         },
 984 |         {
 985 |             "name": "sebastian/global-state",
 986 |             "version": "1.1.x-dev",
 987 |             "source": {
 988 |                 "type": "git",
 989 |                 "url": "https://github.com/sebastianbergmann/global-state.git",
 990 |                 "reference": "cea85a84b00f2795341ebbbca4fa396347f2494e"
 991 |             },
 992 |             "dist": {
 993 |                 "type": "zip",
 994 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/global-state/cea85a84b00f2795341ebbbca4fa396347f2494e.zip",
 995 |                 "reference": "cea85a84b00f2795341ebbbca4fa396347f2494e",
 996 |                 "shasum": ""
 997 |             },
 998 |             "require": {
 999 |                 "php": ">=5.3.3"
1000 |             },
1001 |             "require-dev": {
1002 |                 "phpunit/phpunit": "~4.2|~5.0"
1003 |             },
1004 |             "suggest": {
1005 |                 "ext-uopz": "*"
1006 |             },
1007 |             "type": "library",
1008 |             "extra": {
1009 |                 "branch-alias": {
1010 |                     "dev-master": "1.0-dev"
1011 |                 }
1012 |             },
1013 |             "autoload": {
1014 |                 "classmap": [
1015 |                     "src/"
1016 |                 ]
1017 |             },
1018 |             "notification-url": "https://packagist.org/downloads/",
1019 |             "license": [
1020 |                 "BSD-3-Clause"
1021 |             ],
1022 |             "authors": [
1023 |                 {
1024 |                     "name": "Sebastian Bergmann",
1025 |                     "email": "sebastian@phpunit.de"
1026 |                 }
1027 |             ],
1028 |             "description": "Snapshotting of global state",
1029 |             "homepage": "http://www.github.com/sebastianbergmann/global-state",
1030 |             "keywords": [
1031 |                 "global state"
1032 |             ],
1033 |             "time": "2017-02-23T14:11:06+00:00"
1034 |         },
1035 |         {
1036 |             "name": "sebastian/object-enumerator",
1037 |             "version": "2.0.x-dev",
1038 |             "source": {
1039 |                 "type": "git",
1040 |                 "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1041 |                 "reference": "c956fe7a68318639f694fc6bba0c89b7cdf1b08c"
1042 |             },
1043 |             "dist": {
1044 |                 "type": "zip",
1045 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/object-enumerator/c956fe7a68318639f694fc6bba0c89b7cdf1b08c.zip",
1046 |                 "reference": "c956fe7a68318639f694fc6bba0c89b7cdf1b08c",
1047 |                 "shasum": ""
1048 |             },
1049 |             "require": {
1050 |                 "php": "^5.6 || ^7.0",
1051 |                 "sebastian/recursion-context": "^2.0"
1052 |             },
1053 |             "require-dev": {
1054 |                 "phpunit/phpunit": "^5.7"
1055 |             },
1056 |             "type": "library",
1057 |             "extra": {
1058 |                 "branch-alias": {
1059 |                     "dev-master": "2.0.x-dev"
1060 |                 }
1061 |             },
1062 |             "autoload": {
1063 |                 "classmap": [
1064 |                     "src/"
1065 |                 ]
1066 |             },
1067 |             "notification-url": "https://packagist.org/downloads/",
1068 |             "license": [
1069 |                 "BSD-3-Clause"
1070 |             ],
1071 |             "authors": [
1072 |                 {
1073 |                     "name": "Sebastian Bergmann",
1074 |                     "email": "sebastian@phpunit.de"
1075 |                 }
1076 |             ],
1077 |             "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1078 |             "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1079 |             "time": "2017-03-07T10:37:45+00:00"
1080 |         },
1081 |         {
1082 |             "name": "sebastian/recursion-context",
1083 |             "version": "2.0.x-dev",
1084 |             "source": {
1085 |                 "type": "git",
1086 |                 "url": "https://github.com/sebastianbergmann/recursion-context.git",
1087 |                 "reference": "7e4d7c56f6e65d215f71ad913a5256e5439aca1c"
1088 |             },
1089 |             "dist": {
1090 |                 "type": "zip",
1091 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/recursion-context/7e4d7c56f6e65d215f71ad913a5256e5439aca1c.zip",
1092 |                 "reference": "7e4d7c56f6e65d215f71ad913a5256e5439aca1c",
1093 |                 "shasum": ""
1094 |             },
1095 |             "require": {
1096 |                 "php": ">=5.3.3"
1097 |             },
1098 |             "require-dev": {
1099 |                 "phpunit/phpunit": "~4.4"
1100 |             },
1101 |             "type": "library",
1102 |             "extra": {
1103 |                 "branch-alias": {
1104 |                     "dev-master": "2.0.x-dev"
1105 |                 }
1106 |             },
1107 |             "autoload": {
1108 |                 "classmap": [
1109 |                     "src/"
1110 |                 ]
1111 |             },
1112 |             "notification-url": "https://packagist.org/downloads/",
1113 |             "license": [
1114 |                 "BSD-3-Clause"
1115 |             ],
1116 |             "authors": [
1117 |                 {
1118 |                     "name": "Jeff Welch",
1119 |                     "email": "whatthejeff@gmail.com"
1120 |                 },
1121 |                 {
1122 |                     "name": "Sebastian Bergmann",
1123 |                     "email": "sebastian@phpunit.de"
1124 |                 },
1125 |                 {
1126 |                     "name": "Adam Harvey",
1127 |                     "email": "aharvey@php.net"
1128 |                 }
1129 |             ],
1130 |             "description": "Provides functionality to recursively process PHP variables",
1131 |             "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1132 |             "time": "2017-03-08T08:21:15+00:00"
1133 |         },
1134 |         {
1135 |             "name": "sebastian/resource-operations",
1136 |             "version": "dev-master",
1137 |             "source": {
1138 |                 "type": "git",
1139 |                 "url": "https://github.com/sebastianbergmann/resource-operations.git",
1140 |                 "reference": "fadc83f7c41fb2924e542635fea47ae546816ece"
1141 |             },
1142 |             "dist": {
1143 |                 "type": "zip",
1144 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/resource-operations/fadc83f7c41fb2924e542635fea47ae546816ece.zip",
1145 |                 "reference": "fadc83f7c41fb2924e542635fea47ae546816ece",
1146 |                 "shasum": ""
1147 |             },
1148 |             "require": {
1149 |                 "php": ">=5.6.0"
1150 |             },
1151 |             "type": "library",
1152 |             "extra": {
1153 |                 "branch-alias": {
1154 |                     "dev-master": "1.0.x-dev"
1155 |                 }
1156 |             },
1157 |             "autoload": {
1158 |                 "classmap": [
1159 |                     "src/"
1160 |                 ]
1161 |             },
1162 |             "notification-url": "https://packagist.org/downloads/",
1163 |             "license": [
1164 |                 "BSD-3-Clause"
1165 |             ],
1166 |             "authors": [
1167 |                 {
1168 |                     "name": "Sebastian Bergmann",
1169 |                     "email": "sebastian@phpunit.de"
1170 |                 }
1171 |             ],
1172 |             "description": "Provides a list of PHP built-in functions that operate on resources",
1173 |             "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1174 |             "time": "2016-10-03T07:43:09+00:00"
1175 |         },
1176 |         {
1177 |             "name": "sebastian/version",
1178 |             "version": "dev-master",
1179 |             "source": {
1180 |                 "type": "git",
1181 |                 "url": "https://github.com/sebastianbergmann/version.git",
1182 |                 "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
1183 |             },
1184 |             "dist": {
1185 |                 "type": "zip",
1186 |                 "url": "https://files.phpcomposer.com/files/sebastianbergmann/version/99732be0ddb3361e16ad77b68ba41efc8e979019.zip",
1187 |                 "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
1188 |                 "shasum": ""
1189 |             },
1190 |             "require": {
1191 |                 "php": ">=5.6"
1192 |             },
1193 |             "type": "library",
1194 |             "extra": {
1195 |                 "branch-alias": {
1196 |                     "dev-master": "2.0.x-dev"
1197 |                 }
1198 |             },
1199 |             "autoload": {
1200 |                 "classmap": [
1201 |                     "src/"
1202 |                 ]
1203 |             },
1204 |             "notification-url": "https://packagist.org/downloads/",
1205 |             "license": [
1206 |                 "BSD-3-Clause"
1207 |             ],
1208 |             "authors": [
1209 |                 {
1210 |                     "name": "Sebastian Bergmann",
1211 |                     "email": "sebastian@phpunit.de",
1212 |                     "role": "lead"
1213 |                 }
1214 |             ],
1215 |             "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1216 |             "homepage": "https://github.com/sebastianbergmann/version",
1217 |             "time": "2016-10-03T07:35:21+00:00"
1218 |         },
1219 |         {
1220 |             "name": "symfony/yaml",
1221 |             "version": "dev-master",
1222 |             "source": {
1223 |                 "type": "git",
1224 |                 "url": "https://github.com/symfony/yaml.git",
1225 |                 "reference": "686c7fc416b454fe4019f1a225206b133ceb4fc1"
1226 |             },
1227 |             "dist": {
1228 |                 "type": "zip",
1229 |                 "url": "https://files.phpcomposer.com/files/symfony/yaml/686c7fc416b454fe4019f1a225206b133ceb4fc1.zip",
1230 |                 "reference": "686c7fc416b454fe4019f1a225206b133ceb4fc1",
1231 |                 "shasum": ""
1232 |             },
1233 |             "require": {
1234 |                 "php": "^7.1.3"
1235 |             },
1236 |             "conflict": {
1237 |                 "symfony/console": "<3.4"
1238 |             },
1239 |             "require-dev": {
1240 |                 "symfony/console": "~3.4|~4.0"
1241 |             },
1242 |             "suggest": {
1243 |                 "symfony/console": "For validating YAML files using the lint command"
1244 |             },
1245 |             "type": "library",
1246 |             "extra": {
1247 |                 "branch-alias": {
1248 |                     "dev-master": "4.0-dev"
1249 |                 }
1250 |             },
1251 |             "autoload": {
1252 |                 "psr-4": {
1253 |                     "Symfony\\Component\\Yaml\\": ""
1254 |                 },
1255 |                 "exclude-from-classmap": [
1256 |                     "/Tests/"
1257 |                 ]
1258 |             },
1259 |             "notification-url": "https://packagist.org/downloads/",
1260 |             "license": [
1261 |                 "MIT"
1262 |             ],
1263 |             "authors": [
1264 |                 {
1265 |                     "name": "Fabien Potencier",
1266 |                     "email": "fabien@symfony.com"
1267 |                 },
1268 |                 {
1269 |                     "name": "Symfony Community",
1270 |                     "homepage": "https://symfony.com/contributors"
1271 |                 }
1272 |             ],
1273 |             "description": "Symfony Yaml Component",
1274 |             "homepage": "https://symfony.com",
1275 |             "time": "2017-11-10T19:37:45+00:00"
1276 |         },
1277 |         {
1278 |             "name": "webmozart/assert",
1279 |             "version": "dev-master",
1280 |             "source": {
1281 |                 "type": "git",
1282 |                 "url": "https://github.com/webmozart/assert.git",
1283 |                 "reference": "4a8bf11547e139e77b651365113fc12850c43d9a"
1284 |             },
1285 |             "dist": {
1286 |                 "type": "zip",
1287 |                 "url": "https://files.phpcomposer.com/files/webmozart/assert/4a8bf11547e139e77b651365113fc12850c43d9a.zip",
1288 |                 "reference": "4a8bf11547e139e77b651365113fc12850c43d9a",
1289 |                 "shasum": ""
1290 |             },
1291 |             "require": {
1292 |                 "php": "^5.3.3 || ^7.0"
1293 |             },
1294 |             "require-dev": {
1295 |                 "phpunit/phpunit": "^4.6",
1296 |                 "sebastian/version": "^1.0.1"
1297 |             },
1298 |             "type": "library",
1299 |             "extra": {
1300 |                 "branch-alias": {
1301 |                     "dev-master": "1.3-dev"
1302 |                 }
1303 |             },
1304 |             "autoload": {
1305 |                 "psr-4": {
1306 |                     "Webmozart\\Assert\\": "src/"
1307 |                 }
1308 |             },
1309 |             "notification-url": "https://packagist.org/downloads/",
1310 |             "license": [
1311 |                 "MIT"
1312 |             ],
1313 |             "authors": [
1314 |                 {
1315 |                     "name": "Bernhard Schussek",
1316 |                     "email": "bschussek@gmail.com"
1317 |                 }
1318 |             ],
1319 |             "description": "Assertions to validate method input/output with nice error messages.",
1320 |             "keywords": [
1321 |                 "assert",
1322 |                 "check",
1323 |                 "validate"
1324 |             ],
1325 |             "time": "2016-11-23T20:04:41+00:00"
1326 |         }
1327 |     ],
1328 |     "aliases": [],
1329 |     "minimum-stability": "dev",
1330 |     "stability-flags": [],
1331 |     "prefer-stable": false,
1332 |     "prefer-lowest": false,
1333 |     "platform": {
1334 |         "php": ">=5.5"
1335 |     },
1336 |     "platform-dev": []
1337 | }
1338 | 


--------------------------------------------------------------------------------
/doc/niuniu.md:
--------------------------------------------------------------------------------
 1 | ## 牛牛规则
 2 | 
 3 | > 牌型有如下几种,牌型大小: 五小牛 > 炸弹 > 五花牛 > 四花牛 > 牛牛 > 有牛 > 无牛
 4 | 
 5 | |牌型|说明|
 6 | |:---:|:----|
 7 | |五小牛|五张牌的点数加起来小于10,且每张牌点数都小于5,例如a、3、2、a、2。|
 8 | |炸弹|五张牌中有4张牌点数相同的牌型,例如:2、2、2、2、k。|
 9 | |五花牛|五张牌全由j~k组成,例如j、j、q、q、k。|
10 | |四花牛|五张牌全由10~k组成且只有一张10,例如10、j、j、q、k。|
11 | |牛牛|五张牌中第一组三张牌和第一组二张牌之和分别为10的整数倍。 3、7、k、10、j。|
12 | |有牛|五张牌中有三张的点数之和为10点的整数倍,并且另外两张牌之和与10进行取余,所得之数即为牛几。例如: 2、8、j、6、3,即为牛9。牛一到牛6为1倍,牛七到牛九位2倍!|
13 | |无牛|五张牌中没有任意三张牌点数之和为10的整数倍。例如: a、8、4、k、7。|
14 | 
15 | > 当牌型相同的情况下,按照一下标准分大小:
16 | 
17 | 依次比较单牌大小,单牌大的获胜;所有单牌相同的情况下,比较最大那张牌的花色,花色大的牌大;
18 | (花色大小依次:黑桃 > 红桃 > 梅花 > 方块)
19 | 


--------------------------------------------------------------------------------
/doc/sangong.md:
--------------------------------------------------------------------------------
 1 | ## 三公规则
 2 | 
 3 | ### 先比较牌型
 4 | 
 5 | > 大三公 > 小三公 > 混三公 > 单牌
 6 | 
 7 | |牌型|说明|举例|
 8 | |:--:|:--|:--|
 9 | |至尊九|三只3牌|即:333|
10 | |三条|相同的三张公仔牌|KKK > QQQ > JJJ > 101010 > 999 > 888 > …… > 222 > AAA|
11 | |三公|公仔牌的差异配合|KQJ、QQJ、JJK,如果大家都是混三公,则先比较玩家最大的那张公牌的大小,如果还是相同,则比较玩家最大公牌的花色|
12 | |点数牌|0-9点的牌型|QJ10、A38、678、K107|
13 | 
14 | 
15 | ### 再比较点数
16 | 
17 | 如果玩家都是点数牌,并且点数相等的情况下则先比较玩家的公牌数(如 J Q 9>J 10 9)如果公牌数还是一样则比较最大的那张单牌的的大小,(如K Q 9>J Q 9)如果大小还相同则比较最大牌的花色,(如:一方是:黑桃2、方块3、方块4(即9点),另一方是:红桃3、梅花4、方块2(即9点),梅花4>方块4,所以后者胜。)
18 | 


--------------------------------------------------------------------------------
/doc/texas.md:
--------------------------------------------------------------------------------
 1 | ## 德州扑克规则
 2 | 
 3 | > 先比较牌型大小 
 4 | 
 5 |     牌型大小:
 6 |     (1)基本法则是:“先比牌型后比点数”。
 7 |     (2)牌型的大小顺序为:同花顺>铁支>葫芦>同花>顺子>三条>二对>对子>散牌
 8 |     (3)点数大小顺序为:A>K>Q>J>10>9>8>7>6>5>4>3>2
 9 |     (4)共有9种牌型。分别是:同花顺 铁支 葫芦 同花 顺子 三条 二对 对子 散牌
10 |     (5)牌型的大小顺序为:同花顺>铁支>葫芦>同花>顺子>三条>二对>对子>散牌
11 |     (6)不同牌型之间的大小按上方的大小顺序来比较。如果是相同牌型之间的比较呢?下面将逐一介绍
12 | 
13 | > 当牌型相同的时候,按照以下规则比较大小
14 | 
15 |     1. 皇家同花顺之间的比较:
16 |         2个玩家都是皇家同花顺,和。
17 | 
18 |     2. 同花顺之间的比较:
19 |         A、同花顺虽然以花色成牌型,但两个同花顺相比时不比花色,只比点数,从最大的一张牌开始比起,大者胜;
20 |         B、如果相同,则再比稍小一点的那张,大者胜;
21 |         C、如果再相同再往下比,直到分出大小来;
22 |         D、若是五张牌的点数都一样大,则两个同花顺同样大小。
23 |         E、比如黑桃的10、J、Q、K、A与梅花的10、J、Q、K、A相比,两者是同样大小的。
24 |     
25 |     3. 铁支之间的比较:
26 |         A、铁支的大小比较只看4条的点数。
27 |         B、4条点数大的胜。
28 |         C、如果4条点数相同(只有都取公牌时才会出现这种情况),则比杂牌大小,杂牌大者胜。如果杂牌点数也相等,则同大。
29 |     
30 |     4. 葫芦之间的比较:
31 |         A、葫芦的大小比较只看3条的点数。
32 |         B、3条点数大的胜。
33 |         C、如果3条点数相同(只有都取公牌时才会出现这种情况),则比一对的大小,一对大者胜,如果一对也相等,则同大。
34 |         
35 |     5. 同花之间的比较:
36 |         A、同花之间的比较不看花色,而看单张最大一张牌的点数。
37 |         B、如果最大的一张牌的点数一样大,则比相对小一点的那张牌点数;
38 |         C、如果还一样大,再往下比,直到分出大小来;
39 |         D、如果五张牌的点数都一样大,那么判断为同等大小。 (同花中,“A”为最大的牌)
40 |     
41 |     6. 顺子之间的比较:
42 |         A、顺子之间的比较跟同花顺的相同,也是从最大的第一张牌比起。
43 |         B、如果最大的第一张牌相同,则再比稍小一点的那张。
44 |         C、如果再相同再往下比,直到分出大小来。
45 |         D、若是五张牌的点数都一样大,则两个顺子同样大小。
46 |         E、A在做顺子牌型的时候,只会出现在顺首和顺尾,并且会有截然不同的效果。比如下面的例子:
47 |         A、K、Q、J、10 在此牌型中“A”为顺尾,它作为最大的牌使用。
48 |         5、4、3、2、A 在此牌型中“A”为顺首,它作为最小的牌使用。
49 |         比如: 5、4、3、2、A 就比 6、5、4、3、2 要小。
50 |     
51 |     7. 三条之间的比较
52 |         三条之间的比较是先比3条的点数,3条大者胜。如果3条同大。则比最大的一张杂牌的大小,大者胜。如果最大的杂牌点数也相等,则比第二张杂牌的大小,大者胜。若还是相等,则同大。
53 |     
54 |     8. 二对之间的比较
55 |         A、二对之间的比较先看最大的一对,点数大的胜;
56 |         B、如果点数相同,则比第二对,同样是点数大的胜;
57 |         C、若第二对也相同,则比杂牌的大小,杂牌点数大者胜;
58 |         D、要是连杂牌点数都一样了,判断为相同大小。
59 |     
60 |     9. 对子之间的比较
61 |         A、对子之间的比较先看对子的大小,点数大的胜;
62 |         B、若点数相同,则再看最大的第一张杂牌,点数大的胜;
63 |         C、最大的一张杂牌点数相同的话,比第二张大的杂牌,点数大的胜;
64 |         D、如果再相同,则比最后一张杂牌的大小,点数大的胜;
65 |         E、若都相同,则判断为相同大小。
66 |     
67 |     10. 散牌之间的比较
68 |         A、散牌之间的比较先看最大的一张牌的点数,大者胜;
69 |         B、最大的牌相同的话,比第二大牌的点数,大者胜;
70 |         C、再相同,再比下一张,大者胜;一直到比出为止;
71 |         D、如果五张牌点数都一样大,则判断为相同大小。
72 |         E、散牌比较中,“A”为最大的牌。
73 | 


--------------------------------------------------------------------------------
/src/Games/NiuNiu.php:
--------------------------------------------------------------------------------
  1 | playerCards as $player => &$playerCard) {
 23 |             //按照从大到小排序
 24 |             $this->sortCard($playerCard);
 25 |             $result[] = [
 26 |                 'name' => $player,
 27 |                 'shape' => $this->judge($playerCard),
 28 |                 'cards' => $playerCard,
 29 |             ];
 30 |         }
 31 |         //计算结果
 32 |         $this->sortResult($result);
 33 |         return $result;
 34 |     }
 35 | 
 36 |     /**
 37 |      * 计算结果
 38 |      * @param $result
 39 |      */
 40 |     public function sortResult(&$result)
 41 |     {
 42 |         usort($result, function($value, $next) {
 43 |             //当牌型相同的时候,比较牌的大小和卡
 44 |             if ($value['shape'] == $next['shape']) {
 45 |                 return $this->compareWithNumberAndColor($value['cards'], $next['cards']);
 46 |             }
 47 |             return $value['shape'] < $next['shape'] ? 1 : -1;
 48 |         });
 49 |     }
 50 | 
 51 |     /**
 52 |      * 判断牌型
 53 |      * @param $cards
 54 |      * @return int 0:没有牛 | 牛1~9:1~9 |  10:牛牛 |  11:4花牛 | 12: 5花牛 | 13:炸弹 | 14:五小牛
 55 |      */
 56 |     public function judge($cards)
 57 |     {
 58 |         $numbers = [];
 59 |         $smallerThanFive = 0;
 60 |         foreach ($cards as $card) {
 61 |             $numbers[] = $cardNumber = $this->getCardNumber($card);
 62 |             if ($cardNumber < 5) {
 63 |                 $smallerThanFive++;
 64 |             }
 65 |         }
 66 |         // 5小牛
 67 |         if (array_sum($numbers) < 10 && $smallerThanFive == 5) {
 68 |             return 14;
 69 |         }
 70 |         // 炸弹, 4张牌进行排列
 71 |         $fourCardArrangements = $this->arrangement($numbers, 4);
 72 |         foreach ($fourCardArrangements as $fourCardArrangement) {
 73 |             //去重值, 如果只剩下1个, 证明4张牌相同
 74 |             if (count(array_unique($fourCardArrangement)) == 1) {
 75 |                 return 13;
 76 |             }
 77 |         }
 78 |         //所有卡牌的数字总和
 79 |         $allCardSum = $this->cardsSum($cards);
 80 |         //计算牛牛,3张牌一组进行排列
 81 |         $arrangements = $this->arrangement($cards, 3);
 82 |         //初始化结果,没有牛
 83 |         $result = 0;
 84 |         foreach ($arrangements as $arrangement) {
 85 |             $sum = $this->cardsSum($arrangement);
 86 |             //有牛
 87 |             if ($sum % 10 ==  0) {
 88 |                 $left = ($allCardSum - $sum) % 10;
 89 |                 //牛牛
 90 |                 if ($left == 0 ) {
 91 |                     $biggerThanEleven = 0;
 92 |                     $biggerThanTen = 0;
 93 |                     //所有牌的牌面数字
 94 |                     $numbers = [];
 95 |                     foreach ($cards as $card) {
 96 |                         $numbers[] = $cardNumber = $this->getCardNumber($card);
 97 |                         if ($cardNumber >= 11) {
 98 |                             $biggerThanEleven++;
 99 |                             $biggerThanTen++;
100 |                         } elseif($cardNumber == 10) {
101 |                             $biggerThanTen++;
102 |                         }
103 |                     }
104 |                     // 5花牛
105 |                     if ($biggerThanEleven == 5) {
106 |                         return 12;
107 |                     }
108 |                     // 4花牛
109 |                     if ($biggerThanTen == 5) {
110 |                         return 11;
111 |                     }
112 |                     //普通牛牛
113 |                     return 10;
114 |                 }
115 |                 //牛1~9
116 |                 else {
117 |                     //当前值大于另外的组合的值,则代替
118 |                     if ($left >= $result) {
119 |                         $result = $left;
120 |                     }
121 |                 }
122 |             }
123 |         }
124 |         return $result;
125 |     }
126 | }
127 | 


--------------------------------------------------------------------------------
/src/Games/SanGong.php:
--------------------------------------------------------------------------------
  1 |  '至尊九',
 32 |         self::SHAPE_FULL_HOUSE => '三条',
 33 |         self::SHAPE_THREE => '三公',
 34 |         self::SHAPE_POINT_9 => '9点',
 35 |         self::SHAPE_POINT_8 => '8点',
 36 |         self::SHAPE_POINT_7 => '7点',
 37 |         self::SHAPE_POINT_6 => '6点',
 38 |         self::SHAPE_POINT_5 => '5点',
 39 |         self::SHAPE_POINT_4 => '4点',
 40 |         self::SHAPE_POINT_3 => '3点',
 41 |         self::SHAPE_POINT_2 => '2点',
 42 |         self::SHAPE_POINT_1 => '1点',
 43 |         self::SHAPE_POINT_0 => '0点',
 44 |     ];
 45 | 
 46 |     public function execute($playerCards = [])
 47 |     {
 48 |         $playerCards = empty($playerCards) ? $this->getPlayersCards() : $playerCards;
 49 |         $result = [];
 50 |         foreach ($playerCards as $player => &$playerCard) {
 51 |             //手牌中按照大小来排序
 52 |             $this->sortCard($playerCard);
 53 |             $result[] = [
 54 |                 'player' => $player,                    //用户手牌
 55 |                 'cards' => $playerCard,                 //排序过后的手牌
 56 |                 'shape' => $this->judge($playerCard),   //判断牌型
 57 |             ];
 58 |         }
 59 |         $this->sortResult($result);
 60 |         return $result;
 61 |     }
 62 | 
 63 |     public function sortResult(&$result)
 64 |     {
 65 |         usort($result, function($value, $next){
 66 |             if ($value['shape'] == $next['shape']) {
 67 |                 return $this->compareWithNumberAndColor($value['cards'], $next['cards']);
 68 |             }
 69 |             return $value['shape'] < $next['shape'] ? 1 : -1;
 70 |         });
 71 |     }
 72 | 
 73 |     /**
 74 |      * 判断牌型
 75 |      * @param array $cards
 76 |      * @return int
 77 |      */
 78 |     public function judge(array $cards)
 79 |     {
 80 |         //获取所有Numbers
 81 |         $numbers = $this->getCardNumbers($cards);
 82 |         //三条
 83 |         if (1 === count($uniqueNumber = array_unique($numbers))) {
 84 |             //至尊九牌型
 85 |             if (3 == $uniqueNumber) {
 86 |                 return self::SHAPE_TOP_NINE;
 87 |             }
 88 |             return self::SHAPE_FULL_HOUSE;
 89 |         }
 90 |         $values = $this->getCardValues($cards);
 91 |         //值都是10以上
 92 |         if ([10] == array_unique($values)) {
 93 |             //是否数字全部都是公仔
 94 |             $allAboveTen = true;
 95 |             foreach($numbers as $number) {
 96 |                 $number == 10 and $allAboveTen = false;
 97 |             }
 98 |             if ($allAboveTen) {
 99 |                 return self::SHAPE_THREE;
100 |             }
101 |         }
102 |         //返回点数
103 |         return array_sum($values) % 10;
104 |     }
105 | 
106 | 
107 | 
108 | }
109 | 


--------------------------------------------------------------------------------
/src/Games/Texas.php:
--------------------------------------------------------------------------------
  1 | publicCards;
 25 |     }
 26 | 
 27 |     /**
 28 |      * 设置公共牌
 29 |      * @param $publicCards
 30 |      * @return mixed
 31 |      */
 32 |     public function setPublicCards($publicCards)
 33 |     {
 34 |         return $this->publicCards = $publicCards;
 35 |     }
 36 | 
 37 |     /**
 38 |      * 随机生成玩家牌 & 公共牌
 39 |      * @param int $playerNumbers
 40 |      * @param int $perCardsNumber
 41 |      * @param bool $needPublic
 42 |      * @return array
 43 |      */
 44 |     public function generate($playerNumbers, $perCardsNumber = 2, $needPublic = true)
 45 |     {
 46 |         $needPublic and $this->generatePublicCard();
 47 |         return parent::generate($playerNumbers, $perCardsNumber);
 48 |     }
 49 | 
 50 |     /**
 51 |      * 创建公共牌
 52 |      * @param int $cardsNumber 公共牌数量
 53 |      * @return array
 54 |      */
 55 |     public function generatePublicCard($cardsNumber = 5)
 56 |     {
 57 |         return $this->publicCards = array_splice($this->round, 0, $cardsNumber);
 58 |     }
 59 | 
 60 |     /**
 61 |      * @param array $player1
 62 |      * @param array $player2
 63 |      * @return array 'result' = 0 相同,1 前者小,-1 后者小
 64 |      */
 65 |     public function comparePlayer(array $player1, array $player2)
 66 |     {
 67 |         $player1Biggest = $this->getBiggestCardFromPlayerAndPublic($player1);
 68 |         $player2Biggest = $this->getBiggestCardFromPlayerAndPublic($player2);
 69 |         $type1 = $this->judge($player1Biggest);
 70 |         $type2 = $this->judge($player2Biggest);
 71 |         $result = $type1 < $type2 ? 1 : -1;
 72 |         if ($type1 == $type2) {
 73 |             $result = $this->compareTwoEqualType($type1, $player1Biggest, $player2Biggest);
 74 |         }
 75 |         return [
 76 |             'result' => $result,
 77 |             'player_1' => [
 78 |                 'cards' => $player1Biggest,
 79 |                 'type' => $type1
 80 |             ],
 81 |             'player_2' => [
 82 |                 'cards' => $player2Biggest,
 83 |                 'type' => $type2
 84 |             ],
 85 |         ];
 86 |     }
 87 | 
 88 |     /**
 89 |      * 从玩家和公共牌的组合中选出最优解
 90 |      * @param array $player
 91 |      * @param array $public
 92 |      * @return mixed
 93 |      */
 94 |     public function getBiggestCardFromPlayerAndPublic(array $player, array $public = [])
 95 |     {
 96 |         $public = empty($public) ? $this->publicCards : $public;
 97 |         $combinations = $this->getUniqueCombinationWithSort(array_merge($player, $public));
 98 |         usort($combinations, function ($first, $next) {
 99 |             //先比较牌型
100 |             $firstType = $this->judge($first);
101 |             $nextType = $this->judge($next);
102 |             if ($firstType == $nextType) {
103 |                 return $this->compareTwoEqualType($firstType, $first, $next);
104 |             }
105 |             return $firstType < $nextType ? 1 : -1;
106 |         });
107 |         return reset($combinations);
108 |     }
109 | 
110 |     /**
111 |      * 相同牌型的比较的牌的大小
112 |      * @param int $type
113 |      * @param array $cards1
114 |      * @param array $cards2
115 |      * @return int 0 相同,1 前者小,-1 后者小
116 |      */
117 |     public function compareTwoEqualType($type, array $cards1, array $cards2)
118 |     {
119 |         switch ($type) {
120 |             case 10://皇家同花顺
121 |                 return 0;
122 |             case 9://同花顺
123 |             case 5://顺子
124 |                 return $this->compareFlushNumber($this->getCardNumbers($cards1), $this->getCardNumbers($cards2));
125 |             case 8://四条
126 |                 $same = 4;
127 |             case 7://葫芦
128 |                 $same = isset($same) ? $same : 3;
129 |                 $left = 5 - $same;
130 |                 $cards1SameCount = $cards2SameCount = [];
131 |                 $this->checkSame($this->getCardNumbers($cards1), $same, $cards1SameCount);
132 |                 $this->checkSame($this->getCardNumbers($cards2), $same, $cards2SameCount);
133 |                 $_temp1 = array_flip($cards1SameCount);
134 |                 $_temp2 = array_flip($cards2SameCount);
135 |                 //先比较4/3张牌是否相同,如果相同,就比较最后1/2张牌的大小
136 |                 if ($_temp1[$same] == $_temp2[$same]) {
137 |                     return $_temp1[$left] == $_temp2[$left] ? 0 : ($_temp1[$left] < $_temp2[$left] ? 1 : -1);
138 |                 }
139 |                 return $_temp1[$same] < $_temp2[$same] ? 1 : -1;
140 |             case 6://同花
141 |             case 1://高牌
142 |                 return $this->compareNumber($this->getCardNumbers($cards1), $this->getCardNumbers($cards2));
143 |             case 4://三条
144 |                 $same = 3;
145 |             case 2://一对
146 |                 $same = isset($same) ? $same : 2;
147 |                 $cards1SameCount = $cards2SameCount = [];
148 |                 $this->checkSame($this->getCardNumbers($cards1), $same, $cards1SameCount);
149 |                 $this->checkSame($this->getCardNumbers($cards2), $same, $cards2SameCount);
150 |                 $_temp1 = array_flip($cards1SameCount);
151 |                 $_temp2 = array_flip($cards2SameCount);
152 |                 //先比较3/2张牌是否相同,如果相同,就比较最后2张牌的大小
153 |                 if ($_temp1[$same] == $_temp2[$same]) {
154 |                     return $this->compareNumber(array_unique($this->getCardNumbers($cards1)), array_unique($this->getCardNumbers($cards2)));
155 |                 }
156 |                 return $_temp1[$same] < $_temp2[$same] ? 1 : -1;
157 |             case 3://两对
158 |                 $cards1SameCount = $cards2SameCount = [];
159 |                 $this->checkSame($this->getCardNumbers($cards1), 2, $cards1SameCount);
160 |                 $this->checkSame($this->getCardNumbers($cards2), 2, $cards2SameCount);
161 |                 $two1 = $two2 = [];
162 |                 $one1 = $one2 = [];
163 |                 foreach ($cards1SameCount as $key1 => $value1) {
164 |                     if ($value1 == 1){
165 |                         $one1[] = $key1;
166 |                     } elseif ($value1 == 2) {
167 |                         $two1[] = $key1;
168 |                     }
169 |                 }
170 |                 foreach ($cards2SameCount as $key2 => $value2) {
171 |                     if ($value2 == 1){
172 |                         $one2[] = $key2;
173 |                     } elseif ($value2 == 2) {
174 |                         $two2[] = $key2;
175 |                     }
176 |                 }
177 |                 //先比较2对的大小
178 |                 if (0 == $compare2Res = $this->compareNumber($two1, $two2)) {
179 |                     //如果相同,再比较单牌的大小
180 |                     return $this->compareNumber($one1, $one2);
181 |                 }
182 |                 return $compare2Res;
183 |         }
184 |     }
185 | 
186 |     /**
187 |      * 比较非顺子以外牌型的 2个牌面的大小
188 |      * @param array $numbers1
189 |      * @param array $numbers2
190 |      * @return int  0 相同,1 前者小,-1 后者小
191 |      */
192 |     public function compareNumber(array $numbers1, array $numbers2)
193 |     {
194 |         //做一个大小的映射, A最大,2最小
195 |         $order = array_flip([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1]);
196 |         //排序
197 |         $orderClosure = function ($first, $second) use ($order) {
198 |             return $order[$first] == $order[$second] ? 0 : ($order[$first] < $order[$second] ? 1 : -1);
199 |         };
200 |         usort($numbers1, $orderClosure);
201 |         usort($numbers2, $orderClosure);
202 |         foreach ($numbers1 as $key => $value) {
203 |             if ($order[$value] < $order[$numbers2[$key]]) {
204 |                 return 1;
205 |             } elseif ($order[$value] > $order[$numbers2[$key]]) {
206 |                 return -1;
207 |             }
208 |         }
209 |         return 0;
210 |     }
211 | 
212 |     /**
213 |      * 比较顺子的 2个牌面的大小
214 |      * @param array $numbers1
215 |      * @param array $numbers2
216 |      * @return int  0 相同,1 前者小,-1 后者小
217 |      *
218 |      * A在做顺子牌型的时候,只会出现在顺首和顺尾,并且会有截然不同的效果。比如下面的例子:
219 |      * A、K、Q、J、10 在此牌型中“A”为顺尾,它作为最大的牌使用。
220 |      * 5、4、3、2、A 在此牌型中“A”为顺首,它作为最小的牌使用。
221 |      * 比如: 5、4、3、2、A 就比 6、5、4、3、2 要小。
222 |      *
223 |      */
224 |     public function compareFlushNumber(array $numbers1, array $numbers2)
225 |     {
226 |         $orderClosure = function ($first, $second) {
227 |             return $first == $second ? 0 : ($first < $second ? 1 : -1);
228 |         };
229 |         usort($numbers1, $orderClosure);
230 |         $numbers1 == [13, 12, 11, 10, 1] and $numbers1 = [14, 13, 12, 11, 10];
231 |         usort($numbers2, $orderClosure);
232 |         $numbers2 == [13, 12, 11, 10, 1] and $numbers2 = [14, 13, 12, 11, 10];
233 |         foreach ($numbers1 as $key => $value) {
234 |             if ($value < $numbers2[$key]) {
235 |                 return 1;
236 |             } elseif ($value > $numbers2[$key]) {
237 |                 return -1;
238 |             }
239 |         }
240 |         return 0;
241 |     }
242 | 
243 |     /**
244 |      * 判断牌型
245 |      * @param array $cards 从大到小排序过的牌
246 |      * @return int 10:皇家同花顺 | 9:同花顺 | 8:四条 | 7:葫芦 | 6:同花 | 5:顺子 | 4:三条 | 3:两对 | 2:一对 | 1:高牌
247 |      */
248 |     public function judge(array $cards)
249 |     {
250 |         $numbers = $this->getCardNumbers($cards);
251 |         $color = $this->getCardColors($cards);
252 |         //皇家同花顺
253 |         if ($numbers == [13, 12, 11, 10, 1]) {
254 |             return 10;
255 |         }
256 |         //同花顺
257 |         if ($this->checkStraight($numbers) && $this->checkFlush($color)) {
258 |             return 9;
259 |         }
260 |         //四条
261 |         if ($this->checkSame($numbers, 4) == 1) {
262 |             return 8;
263 |         }
264 |         //葫芦, 有1个3条 和 2个2条
265 |         if ($this->checkSame($numbers, 3) == 1 && $this->checkSame($numbers, 2) == 2) {
266 |             return 7;
267 |         }
268 |         //同化
269 |         if ($this->checkFlush($color)) {
270 |             return 6;
271 |         }
272 |         //顺子
273 |         if ($this->checkStraight($numbers)) {
274 |             return 5;
275 |         }
276 |         //三条
277 |         if ($this->checkSame($numbers, 3) == 1) {
278 |             return 4;
279 |         }
280 |         //两对
281 |         if ($this->checkSame($numbers, 2) == 2) {
282 |             return 3;
283 |         }
284 |         //一对
285 |         if ($this->checkSame($numbers, 2) == 1) {
286 |             return 2;
287 |         }
288 |         //高牌
289 |         return 1;
290 |     }
291 | 
292 |     /**
293 |      * 检查是否相同牌面,可判断 4条,3条,2条
294 |      * @param array $numbers
295 |      * @param int   $same
296 |      * @param array $sameCounts 相同的结果
297 |      * @return int
298 |      */
299 |     public function checkSame(array $numbers, $same = 4, array &$sameCounts = [])
300 |     {
301 |         // 桶方法
302 |         foreach ($numbers as $number) {
303 |             if (!isset($sameCounts[$number])) {
304 |                 $sameCounts[$number] = 1;
305 |             } else {
306 |                 $sameCounts[$number]++;
307 |             }
308 |         }
309 |         $sameNumber = 0;
310 |         foreach ($sameCounts as $key => $sameCount) {
311 |             if (($ceil = (int)($sameCount / $same)) > 0) {
312 |                 $sameNumber += $ceil;
313 |             }
314 |         }
315 |         return $sameNumber;
316 |     }
317 | 
318 |     /**
319 |      * 检查是不是 顺子
320 |      * @param $numbers
321 |      * @return bool
322 |      */
323 |     public function checkStraight($numbers)
324 |     {
325 |         $isStraight = true;
326 |         foreach ($numbers as $key => $number) {
327 |             $nextKey = $key + 1;
328 |             if (isset($numbers[$nextKey]) && ($number - $numbers[$nextKey] != 1)) {
329 |                 $isStraight = false;
330 |                 break;
331 |             }
332 |         }
333 |         return $isStraight;
334 |     }
335 | 
336 |     /**
337 |      * 检查是不是 同花
338 |      * @param $color
339 |      * @return bool
340 |      */
341 |     public function checkFlush($color)
342 |     {
343 |         return count(array_unique($color)) == 1;
344 |     }
345 | 
346 |     /**
347 |      * 获取唯一的排列
348 |      * @param array $cards
349 |      * @param int   $number
350 |      * @return array
351 |      */
352 |     public function getUniqueCombinationWithSort(array $cards, $number = 5)
353 |     {
354 |         $combinations = $this->arrangement($cards, $number);
355 |         $result = [];
356 |         foreach ($combinations as $combination) {
357 |             $unique = true;
358 |             $this->sortCard($combination);
359 |             foreach ($result as $item) {
360 |                 if ($item == $combination) {
361 |                     $unique = false;
362 |                     break;
363 |                 }
364 |             }
365 |             if ($unique) {
366 |                 $result[] = $combination;
367 |             }
368 |         }
369 |         return $result;
370 |     }
371 | }
372 | 


--------------------------------------------------------------------------------
/src/Poker.php:
--------------------------------------------------------------------------------
  1 | pack = $this->generatePack();
 68 |         if ($autoBegin) {
 69 |             $this->begin();
 70 |         }
 71 |     }
 72 | 
 73 |     /**
 74 |      * 开始一局
 75 |      */
 76 |     public function begin()
 77 |     {
 78 |         if (is_null($this->round)) {
 79 |             $this->round = $this->pack;
 80 |         }
 81 |         //洗牌
 82 |         $this->shuffle();
 83 |     }
 84 | 
 85 |     /**
 86 |      * 创建一副牌
 87 |      * @return array
 88 |      */
 89 |     protected function generatePack()
 90 |     {
 91 |         $pack = [];
 92 |         foreach(self::$numbers as $number) {
 93 |             foreach (self::$colors as $color) {
 94 |                 $pack[] = [
 95 |                     'number' => $number,
 96 |                     'color' => $color
 97 |                 ];
 98 |             }
 99 |         }
100 |         return $pack;
101 |     }
102 | 
103 |     /**
104 |      * 随机生成玩家牌
105 |      * @param int $playerNumbers
106 |      * @param int $perCardsNumber
107 |      * @return array
108 |      */
109 |     public function generate($playerNumbers, $perCardsNumber = 5)
110 |     {
111 |         $beginAt = count($this->playerCards);
112 |         for ($i = 1; $i <= $playerNumbers; $i++) {
113 |             $this->playerCards[$beginAt + $i] = array_splice($this->round, 0, $perCardsNumber);
114 |         }
115 |         return $this->playerCards;
116 |     }
117 | 
118 |     /**
119 |      * 获取剩余的牌
120 |      * @return array
121 |      */
122 |     public function getRound()
123 |     {
124 |         return $this->round;
125 |     }
126 | 
127 |     /**
128 |      * 设置一张忽略的牌
129 |      * @param array $card
130 |      * @return array
131 |      */
132 |     public function setExclude(array $card)
133 |     {
134 |         foreach ($this->round as $key => $nowLeftCard) {
135 |             if ($nowLeftCard == $card) {
136 |                 unset($this->round[$key]);
137 |             }
138 |         }
139 |         return $this->round;
140 |     }
141 | 
142 |     /**
143 |      * 洗牌
144 |      */
145 |     public function shuffle()
146 |     {
147 |         shuffle($this->round);
148 |     }
149 | 
150 |     /**
151 |      * 获取牌面数字
152 |      * @param $card
153 |      * @return mixed
154 |      */
155 |     protected function getCardNumber($card)
156 |     {
157 |         return $card['number'];
158 |     }
159 | 
160 |     /**
161 |      * 获取花色
162 |      * @param $card
163 |      * @return mixed
164 |      */
165 |     protected function getCardColor($card)
166 |     {
167 |         return $card['color'];
168 |     }
169 | 
170 |     /**
171 |      * 获取所有牌的牌面
172 |      * @param $cards
173 |      * @return array
174 |      */
175 |     protected function getCardNumbers($cards)
176 |     {
177 |         $numbers = [];
178 |         foreach ($cards as $card) {
179 |             $numbers[] = $this->getCardNumber($card);
180 |         }
181 |         return $numbers;
182 |     }
183 | 
184 |     /**
185 |      * 获取所有牌的花色
186 |      * @param $cards
187 |      * @return array
188 |      */
189 |     protected function getCardColors($cards)
190 |     {
191 |         $colors = [];
192 |         foreach ($cards as $card) {
193 |             $colors[] = $this->getCardColor($card);
194 |         }
195 |         return $colors;
196 |     }
197 | 
198 |     /**
199 |      * 获取玩家牌
200 |      * @param string $player 玩家 key
201 |      * @return array
202 |      */
203 |     public function getPlayersCards($player = null)
204 |     {
205 |         return is_null($player) ? $this->playerCards : (isset($this->playerCards[$player]) ? $this->playerCards[$player] : []);
206 |     }
207 | 
208 |     /**
209 |      * 批量设置玩家手牌
210 |      * @param array $cards
211 |      * @return array
212 |      */
213 |     public function setPlayersCards(array $cards)
214 |     {
215 |         foreach ($cards as $player => $card) {
216 |             $this->setPlayerCard($player, $card);
217 |         }
218 |         return $this->playerCards;
219 |     }
220 | 
221 |     /**
222 |      * 设置玩家手牌
223 |      * @param string $player 玩家标识
224 |      * @param array $cards
225 |      */
226 |     public function setPlayerCard($player, array $cards)
227 |     {
228 |         $playerCards = [];
229 |         foreach ($cards as $card) {
230 |             $hasThisCard = false;
231 |             $unsetKey = null;
232 |             foreach ($this->round as $nowLeftCardKey => $nowLeftCard) {
233 |                 if ($card == $nowLeftCard) {
234 |                     $hasThisCard = true;
235 |                     $unsetKey = $nowLeftCardKey;
236 |                 }
237 |             }
238 |             if ($hasThisCard) {
239 |                 $playerCards[] = $card;
240 |                 unset($this->round[$unsetKey]);
241 |             }
242 |         }
243 |         $this->playerCards[$player] = $playerCards;
244 |     }
245 | 
246 |     /**
247 |      * 根据牌面,花色的大小从大到小排序
248 |      * @param array  $cards 一手牌
249 |      * @param bool   $sortColor 是否比较花色
250 |      * @param string $sort 降序(desc),还是升序(asc)
251 |      */
252 |     protected function sortCard(array &$cards, $sortColor = true, $sort = 'desc')
253 |     {
254 |         $desc = strtolower($sort) == 'desc';
255 |         usort($cards, function ($value, $next) use ($sortColor, $desc) {
256 |             $number = $this->getCardNumber($value);
257 |             $nextNumber = $this->getCardNumber($next);
258 |             if ($number == $nextNumber) {
259 |                 // 比较花色
260 |                 if ($sortColor) {
261 |                     return $this->getCardColor($value) < $this->getCardColor($next) ? ($desc ? 1 : -1) : ($desc ? -1 : 1);
262 |                 }
263 |                 return 0;
264 |             }
265 |             return $number < $nextNumber ? ($desc ? 1 : -1) : ($desc ? -1 : 1);
266 |         });
267 |     }
268 | 
269 |     /**
270 |      * 比较2张牌的大小,一次比较单牌的大小,如单牌牌面都相同,比较最大单牌的花色
271 |      * @param $firstCards
272 |      * @param $secondCards
273 |      * @return int 返回 1 表示前者比后者大,返回 -1 表示前者比后者细
274 |      */
275 |     public function compareWithNumberAndColor($firstCards, $secondCards)
276 |     {
277 |         foreach ($firstCards as $key => $value) {
278 |             if (($firstNumber = $this->getCardNumber($value)) < ($secondNumber = $this->getCardNumber($secondCards[$key]))) {
279 |                 return 1;
280 |             } elseif ($firstNumber > $secondNumber) {
281 |                 return -1;
282 |             }
283 |         }
284 |         //当所有的牌都是等于的时候,比较最大单牌的花色
285 |         return $this->getCardColor($firstCards[0]) < $this->getCardColor($secondCards[0]) ? 1 : -1;
286 |     }
287 | 
288 |     /**
289 |      * 排列
290 |      * @param $array
291 |      * @param $number
292 |      * @return array
293 |      */
294 |     protected function arrangement($array, $number = 3)
295 |     {
296 |         $result = [];
297 |         $count = count($array);
298 |         if ($number <= 0 || $number > $count) {
299 |             return $result;
300 |         }
301 |         for ($i = 0; $i < $count; $i++) {
302 |             $_temp = $array;
303 |             //每次取一个数字,并从数组中删除
304 |             $single = array_splice($_temp, $i, 1);
305 |             if ($number == 1) {
306 |                 $result[] = $single;
307 |             } else {
308 |                 $deep = $this->arrangement($_temp, $number - 1);
309 |                 foreach ($deep as $deepItem) {
310 |                     $result[] = array_merge($single, $deepItem);
311 |                 }
312 |             }
313 |         }
314 |         return $result;
315 |     }
316 | }
317 | 


--------------------------------------------------------------------------------
/src/Traits/CardWithValue.php:
--------------------------------------------------------------------------------
 1 | getCardNumber($card);
22 |         return $cardNumber < 10 ? $cardNumber : 10;
23 |     }
24 | 
25 |     /**
26 |      * 获取所有牌的数值
27 |      * @param $cards
28 |      * @return array
29 |      */
30 |     protected function getCardValues($cards)
31 |     {
32 |         $values = [];
33 |         foreach ($cards as $card) {
34 |             $values[] = $this->getCardValue($card);
35 |         }
36 |         return $values;
37 |     }
38 | 
39 |     /**
40 |      * 卡牌求和
41 |      * @param $cards
42 |      * @return int
43 |      */
44 |     protected function cardsSum($cards)
45 |     {
46 |         return array_sum($this->getCardValues($cards));
47 |     }
48 | }
49 | 


--------------------------------------------------------------------------------
/tests/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goodspb/poker-algorithm/2ea0f6d4b910f4df770ed0558b158ac40799d8ab/tests/.gitkeep


--------------------------------------------------------------------------------