Skip to content

stavarengo/php-tic-tac-toe

Repository files navigation

php-tic-tac-toe

About the project

  • To see it in action, go to http://php-tic-tac-toe.stavarengo.me, or you can run it locally with Docker, by running sudo docker run stavarengo/php-tic-tac-toe and then .
  • The bot uses the Minimax Algorithm to decide its moves. You can see it on \TicTacToe\App\Bot\MinimaxBot.
  • The application is 100% covered with tests using PHPUnit.
  • This is a modular application, compound of three modules:
    1. App: Where you can find behaviors not related to an API nor to a Web Interface, as the game board and the bots.
    2. Api: This is where reside the API. This module only has behaviors related to API requests. There you will find the Requests Handlers (AKA controllers), entities used in the API responses, etc.
    3. WebUi: The main responsibility of WebUi is to render views, but not only that. More generally, it is responsible for respond all requests that the API does not know how to handle.
  • No dependency on third-party code other than PHPUnit, Bootstrap (CSS library) and FontAwesome (icon library). Everything has been written from scratch. Why? Just because.
  • This is a object-oriented PHP, thus it use principles like S.O.L.I.D., G.R.A.S.P., etc.

Getting Started

Start the project with composer:

$ composer install

Running with PHP's Built-in web server

After installing the packages, start PHP's built-in web server:

$ composer run --timeout=0 serve

You can then browse to http://127.0.0.1:4000

If you want to start the serve using port different of 4000, you can start the server manually:

$ php -S 0.0.0.0:_YOU_PORT_ -t public/
Linux users

On PHP versions prior to 7.1.14 and 7.2.2, this command might not work as expected due to a bug in PHP that only affects linux environments. In such scenarios, you will need to start the built-in web server yourself using the following command:

$ php -S 0.0.0.0:4000 -t public/ public/index.php

WebUi Module

Bellow is a list of all the JS API and JS objects this the front-end uses.

Api Module

The php-tic-tac-toe provides an RESTful API that allows you to manipulate the game. The operations you can do, through the API, are:

Layout of the Responses: The Game State

All endpoints (except for DELETE /api/board), when completed successfully, respond with a JSON representing the current game state. The following is the JSON used to represent the game state.

If the request fails, then it responds with The Error Response Layout.

{
    // The `game` attribute will be `null` when there is no game started yet.
    "game": {
    
        // The `winner` attribute will be `null` if the game does not have a winner yet.
        "winner": {
        
            // It will be the string `draw` or the unit of the player that won.
            "result":"X",
            
            // The coordinates in the board where the victory was found.
            // It will be null in case of `draw`.
            "coordinates":[[0, 0], [1, 0], [2, 0]]
        }
    },
    
    // The current board status.
    // Each position will be either an empty string or one of the units chosen by the players.
    "board": [
        ["X", "", "O"],
        ["X", "O", ""],
        ["X", "", "O"]
    ],
    
    // The `units` attribute contains the units of each player.
    // For example, the "human" could be "X" and the bot "O".
    "units": { 
        "human": "X",
        "bot": "O"
    }
}

Layout of the Responses: The Error Response

All endpoints (including DELETE /api/board), when end in failure, respond with a JSON trying to describe why the error happens (for example, it would fail if you forget to send a required parameter). The following is the JSON used to represent and error response.

If the request ends successfully, then it responds with The Game State.

{
 // This attribute will always be `true`
 "error": true,
 
 // An string containing more details about the error.
 "detail": "Missing the \"botUnit\" attribute."
}

API endpoints

GET /api/board

Returns de current game state. This endpoint can be consumed even if there is no game has started yet.

Curl example

$ curl -X GET 'http://127.0.0.1:4000/api/board'

Expected responses code

  • 200 - Success: In this case the response body will be The Game State.

POST /api/board

Starts a new game. It expect that the request body contains a JSON with the following layout:

{
  // The unit the human choose for this game: "X" or "O".
  "humanUnit": "X",
  // The unit the bot should use: "X" or "O".
  "botUnit": "O"
}

Curl example

$ curl -X POST 'http://127.0.0.1:4000/api/board' --data-binary '{"humanUnit": "X", "botUnit": "O"}'

Expected responses code

  • 201 - Created: It means that a new game started. In this case the response body will be The Game State.
  • 422 - Unprocessable Entity: When there were missing parameters or invalid parameters. In this case the response body will be The Error Response Layout.
  • 409 - Conflict: If there is already a game started. In this case the response body will be The Error Response Layout.
  • 400 - Bad Request: If there the request could not be processed for an unexpected reason. In this case the response body will be The Error Response Layout.

PUT /api/board

Set the human move. This endpoint will store the human move and also perform the bot move. It expect that the request body contains a JSON with the following layout:

{
  // The attributes `row` and `column` indicates the position the human choose do move.
  // It sould be an integer greate or equals to 0, and less or equals to 2.
  "row": 0,
  "column": 2
}

Curl example
First we need to start a game with POST /api/board and get the PHP Session ID where the game were started. Only after that we can set a human move using PUT /api/board endpoint and the same Session ID we get from the POST request.

$ curl -X POST 'http://127.0.0.1:4000/api/board' --data-binary '{"humanUnit": "X", "botUnit": "O"}' -H 'Cookie: PHPSESSID=1;'
$ curl -X PUT 'http://127.0.0.1:4000/api/board' --data-binary '{"row": 0, "column": 2}' -H 'Cookie: PHPSESSID=1;'

Expected responses code

  • 200 - Success: In this case the response body will be The Game State (already with the human and the bot move).
  • 422 - Unprocessable Entity: When there are missing parameters or invalid parameters. In this case the response body will be The Error Response Layout.
  • 400 - Bad Request: If The bot chosen an invalid move to perform or if the move you choose can not be performed by any reason (For example, when you choose to move in a place already in use). The Error Response Layout.
  • 409 - Conflict: If there is no game started yet or if there is a game but it is already done. In this case the response body will be The Error Response Layout.

DELETE /api/board

Delete the current game. No error will be throw if there is no game to be deleted. You can consume this endpoint even if no game exists. After this, you will going to need to start a new game if you want to play again.

Curl example

$ curl -X DELETE 'http://127.0.0.1:4000/api/board'

Expected responses code

  • 204 - No Content: It means that the game was deleted, therefor you need to start a new game if you want to play again.

About

Single player Tic Tac Toe game with a bot as the opponent. The bot uses Minimax algorithm to decides its moves.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published