There are N cards in the pack. Each card has a name (for example, King, Mag, Thief, Dragon, etc). Each card can be stronger than one or more other cards and weaker than some others at the same time (principle is a bit similar to extended “Rock–paper–scissors” games), it should be defined in the game settings or in database. If cards don’t beat each other - they are counted as equal. Cards in the pack are unique.
Thief stronger than Mag, Mag stronger than Dragon and King, King stronger than Thief, etc. There can be different amount of players. On the game start players get equal amount of cards from the pack in a random order. On each round every player select a card from his “hand” to give out and result of the round gets calculated. Player get 1 point for each card “weaker” than his card and -1 point for each stronger card.
You need to build an application component/module/service which can serve described game logic. Component interface should provide following:
- Get current configuration in readable text format (or as an object, prepared for output) to see the list of existing cards and cards they can beat.
- Get a list of stronger cards for presented card name.
- Get a list of cards, randomly distributed for presented amount of players, without storing it, so each
call gives different distribution. Cards are unique, which means each card can be used only once per game. Each player should have the same amount of cards. - Calculate a result of the game round for a list of cards on table. (Input: [King, Thief, Dragon], Output: [1,-1,0] or [King: 1, Thief: -1, Dragon: 0]) Cards in the set can’t repeat.
I have implemented the solution using a local card game named "Stu" invented in a little town named "Montorio al Vomano".
The backend use a Sqlite database built using Eloquent ORM Laravel.
The database data are initially populated using "Laravel Seed" file.
The same seed is used to populate the "in memory" database used for the unit test (phpunit, see config file .env.testing).
The card are stored in a database table "cards" and the relation between on card to another is stored in the table "card_compares" that is used to calculate if a card
is stronger o weaker than another.
You need PHP 7.1 for this project. To run the project you have to follow the following instructions:
- extract the file in a folder
- run composer with "composer install"
- generate the database and the seed using "php artisan migrate:refresh --seed" command
- run the web app with the command "php artisan serve"
- open the WEB API REST indicated in the relative chapter using the URL "http://127.0.0.1:8000"
You can find the file in the Laravel structure. Any other files are generated by Laravel framework and you could not consider,
The model files are the following:
- app\Card.php
- app\CardCompare.php
those files are connected to the relative database table via Eloquent ORM.
The controller are used to implement the web API and are the following:
- app\Http\CardController.php
- app\Http\RoundController.php Both file are coverd by PHPUnit tests. See the documentation in the files.
The configuration of the app database and the testing database are stored in the file:
- config\database.php The schema is created using the following files:
- database\migrations\2019_04_03_055502_create_cards_table.php
- database\migrations\2019_04_03_055502_create_card_compares_table.php The initial data are stored in the seed file:
- database\seed\DatabaseSeeder.php
In the Seeder file are created also the relation weaker/strong bwtween the cards, based on internal value of the first 15 cards for each color. You can change the configuration modifying the internal value of the card.
All the REST API are stored file:
- routes\web.php
In this file you can find the all the API with the relative Controller and method used for it. The API are the following :
- "/card": Return the list of all cards, call using the URL http://127.0.0.1:8000/card
- "/card/canbeat": Return the list of all cards and cards that can beat, call the URL http://127.0.0.1:8000/card/canbeat
- "/card/canbeatcard/{card}": Return the list of all cards that can beat a given card, call as example http://127.0.0.1:8000/card/canbeatcard/III red
- "/card/stronger": Return the list of all cards and card stronger, call the url http://127.0.0.1:8000/card/stronger
- "/game/new/{playersNumber}": Create a new Game given a number of players, call the URL http://127.0.0.1:8000/game/new/5
- "/game/roundpoint/{cardName}/{cardList}": Given a presented card and a set of card calculate the points, call the URL as example http://127.0.0.1:8000/game/roundpoint/SALTA green/VII red,SECCHIO red,LEONE red,SALTA green,MASCHERONE green,IIII green
The PHPUnit test file are the following:
- tests\Feature\CardTest.php, Testing of the model class Card
- tests\Feature\CardControllerTest.php, Testing of the Controller CardController
- tests\Feature\RoundControllerTet.php, Testing of the controller Round Controller
The PHPUnit configuration is stored in the file phpunit.xml
The code coverage HTML file are store in the file resources\coverage