├── .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 --------------------------------------------------------------------------------