This is a JAVA API to play Mastermind made with spring-webmvc to process the endpoints, and I did a front-end webapp just to test the API.

How it works? (Single Player)

To start a new single player game you need to post to this endpoint first to get gameId and playerId:

/endpoints/startNewGame

with these information Ex:

{"players": 1, "allowDuplicates": false, "name": "Leandro Berbel"}

Players: 1, allowDuplicates: true/false and player's name.

The API will return to you:

{
"gameId":"501a4c30-7114-4b91-8e14-d4fe33d70544",
"playerId":"0f566b3b-72f5-4aaa-82cf-0a1a946db383",
"status":"STARTED",
"start":1463947123395,
"maxAttempts":10,
"positions":8,
"colors":["red","green","blue","yellow","brown","orange","purple","cyan"]
}

Now you can post the player guesses to this endpoint:

/endpoints/guessColors

With these information: gameId, playerId and your guess using the colors you receveid from startNewGame:

{
"gameId": "501a4c30-7114-4b91-8e14-d4fe33d70544", 
"playerId": "0f566b3b-72f5-4aaa-82cf-0a1a946db383", 
"colorPattern": ["red","green","blue","yellow","brown","orange","purple","cyan"]
}

The API will return to you:

{
"attempts":1,
"solved":false,
"result":["black","white","white","white","white","white","white","white"]
}

Black = Correct color, correct position

White = Correct color, wrong position

The player can try until get solved = true or its attempts reaches maxAttempts from startNewGame (10).

When it ends, you need to get from this endpoint the results:

endpoints/finishStats/{gameId}

Ex:

endpoints/finishStats/501a4c30-7114-4b91-8e14-d4fe33d70544

The API will return to you:

{
"game":
{
    "status":"ENDED",
    "uuid":"501a4c30-7114-4b91-8e14-d4fe33d70544",
    "players":1,
    "allowDuplicates":false,
    "start":1463947123395,
    "end":1463948185693,
    "colorPattern":["cyan","purple","red","brown","yellow","orange","green","blue"],
    "playersList":[
        {"uuid":"0f566b3b-72f5-4aaa-82cf-0a1a946db383",
        "name":"Leandro Berbel",
        "attempts":4,
        "end":1463948185692,
        "solved":true,
        "history":[
                ["red","green","blue","yellow","brown","orange","purple","cyan"],
                ["blue","green","brown","orange","purple","cyan","yellow","blue"],
                ["red","blue","green","brown","orange","cyan","brown","yellow"],
                ["cyan","purple","red","brown","yellow","orange","green","blue"]
            ]
        }
    ]
},
"player": {
    "uuid":"0f566b3b-72f5-4aaa-82cf-0a1a946db383",
    "name":"Leandro Berbel",
    "attempts":4,
    "end":1463948185692,
    "solved":true,
    "history":[
        ["red","green","blue","yellow","brown","orange","purple","cyan"],
        ["blue","green","brown","orange","purple","cyan","yellow","blue"],
        ["red","blue","green","brown","orange","cyan","brown","yellow"],
        ["cyan","purple","red","brown","yellow","orange","green","blue"]
    ]
}
}

game: all information about the played game

player: the winner player (if exists)

How it works? (Multiplayer)

To start a new multiplayer game you need to post to this endpoint first to get gameId and playerId:

/endpoints/startNewGame

with these information Ex:

{"players": 2, "allowDuplicates": false, "name": "Leandro Berbel"}

Players: 2, allowDuplicates: true/false and player's name.

The API will search for opened games with the same number of players and same preference for allowDuplicates.

If you are the first player, the API will return to you:

{
"gameId":"80714383-769a-4e96-bd7f-7c9e3e45b634",
"playerId":"c43d1be4-532e-431e-ab77-e1ab2c88f90a",
"status":"WAITING",
"start":null,
"maxAttempts":10,
"positions":8,
"colors":["red","green","blue","yellow","brown","orange","purple","cyan"]
}

Status = WAITING

Now you need to wait for another player, and get from this endpoint the confirmation from API when there is another player ready to play:

endpoints/checkMultiplayer/{gameId}

Ex:

endpoints/checkMultiplayer/80714383-769a-4e96-bd7f-7c9e3e45b634

The client needs to check until get another player ready to play, on front-end test, the interval is 1s for each check.

The API will return to you:

{
"gameId":"80714383-769a-4e96-bd7f-7c9e3e45b634",
"start":null,
"playersList":[
{
    "uuid":"c43d1be4-532e-431e-ab77-e1ab2c88f90a",
    "name":"Leandro Berbel",
    "attempts":0,
    "end":null,
    "solved":false,
    "history":[]
}],
"status":"WAITING"
}

When another player connect to API and send a post to startNewGame, the second player will receive this from startNewGame endpoint:

Post:

{"players": 2, "allowDuplicates": false, "name": "Player 2"}

Return from API:

{
"gameId":"80714383-769a-4e96-bd7f-7c9e3e45b634",
"playerId":"8a9dfef8-55f2-47e6-9010-3ec12cc56d58",
"status":"STARTED",
"start":1463949644641,
"maxAttempts":10,
"positions":8,
"colors":["red","green","blue","yellow","brown","orange","purple","cyan"]}
]

Status = STARTED

The API add 30 seconds to start date, for both clients start together, so the start date is the date when the game will start for both players, the client needs to implement a countdown until this date. On the front-end test webapp, this countdown occurs each 1s.

After that, when the client of first player check the endpoint:

checkMultiplayer/{gameId}

The API will return to you:

{
"gameId":"80714383-769a-4e96-bd7f-7c9e3e45b634",
"start":1463949644641,
"playersList":
[{
    "uuid":"c43d1be4-532e-431e-ab77-e1ab2c88f90a",
    "name":"Leandro Berbel",
    "attempts":0,
    "end":null,
    "solved":false,
    "history":[]
},
{
    "uuid":"8a9dfef8-55f2-47e6-9010-3ec12cc56d58",
    "name":"Player 2",
    "attempts":0,
    "end":null,
    "solved":false,
    "history":[]
}]
,"status":"STARTED"
}

Status = STARTED

The API add 30 seconds to start date, for both clients start together, so the start date is the date when the game will start for both players, the client needs to implement a countdown until this date. On the front-end test webapp, this countdown occurs each 1s.

After countdown is over, both clients can post the player guesses to this endpoint:

/endpoints/guessColors

With these information: gameId, playerId and your guess using the colors you receveid from startNewGame:

{
"gameId": "501a4c30-7114-4b91-8e14-d4fe33d70544", 
"playerId": "0f566b3b-72f5-4aaa-82cf-0a1a946db383", 
"colorPattern": ["red","green","blue","yellow","brown","orange","purple","cyan"]
}

The API will return to you:

{
"attempts":1,
"solved":false,
"result":["black","white","white","white","white","white","white","white"]
}

Black = Correct color, correct position

White = Correct color, wrong position

The players can try until get solved = true or its attempts reaches maxAttempts from startNewGame (10).

When both players end (the client needs to wait it checking finishStats), you need to get from this endpoint the results:

endpoints/finishStats/{gameId}

Ex:

endpoints/finishStats/501a4c30-7114-4b91-8e14-d4fe33d70544

The API will return to you:

{
"game":{
    "status":"ENDED",
    "uuid":"ea78e92f-d92b-4cc4-99f5-db82acfba4c1",
    "players":2,
    "allowDuplicates":false,
    "start":1463951060641,
    "end":1463951296926,
    "colorPattern":["red","orange","green","cyan","purple","yellow","blue","brown"],
    "playersList":[{
        "uuid":"8ebb1813-4e9f-464a-856a-f9f087cbd03e",
        "name":"Leandro Berbel",
        "attempts":5,
        "end":1463951222726,
        "solved":true,
        "history":[
            ["red","green","blue","yellow","brown","orange","purple","cyan"],
            ["red","green","blue","yellow","brown","orange","purple","cyan"],
            ["cyan","orange","purple","brown","orange","yellow","brown","blue"],
            ["red","blue","green","brown","yellow","orange","purple","cyan"],
            ["red","orange","green","cyan","purple","yellow","blue","brown"]
        ]},
        {
        "uuid":"ae8fafd1-f807-4180-adfc-5df6ffdc5e42",
        "name":"Player 2",
        "attempts":10,
        "end":1463951296926,
        "solved":false,
        "history":[
            ["red","green","yellow","orange","brown","purple","cyan","orange"],
            ["cyan","purple","orange","brown","yellow","blue","green","red"],
            ["red","green","blue","yellow","brown","orange","purple","cyan"],
            ["red","green","blue","yellow","brown","orange","cyan","purple"],
            ["cyan","orange","purple","yellow","brown","green","blue","red"],
            ["red","yellow","brown","orange","blue","green","purple","orange"],
            ["red","blue","green","yellow","purple","orange","cyan","brown"],
            ["red","yellow","green","blue","brown","orange","yellow","cyan"],
            ["cyan","orange","purple","brown","yellow","blue","green","red"],
            ["red","blue","brown","orange","brown","yellow","purple","cyan"]
        ]
    }]
},
"player":{
    "uuid":"8ebb1813-4e9f-464a-856a-f9f087cbd03e",
    "name":"Leandro Berbel",
    "attempts":5,
    "end":1463951222726,
    "solved":true,
    "history":[
        ["red","green","blue","yellow","brown","orange","purple","cyan"],
        ["red","green","blue","yellow","brown","orange","purple","cyan"],
        ["cyan","orange","purple","brown","orange","yellow","brown","blue"],
        ["red","blue","green","brown","yellow","orange","purple","cyan"],
        ["red","orange","green","cyan","purple","yellow","blue","brown"]
    ]}
}

game: all information about the played game

player: the winner player (if exists)

Bonus: Color pattern

You can check the color pattern getting it from this endpoint:

endpoints/viewPattern/#{gameId}

Ex:

endpoints/viewPattern/319b13d0-485f-4965-9974-c9c3d7ffcc00

The API will return to you, Ex:

["orange","yellow","blue","green","purple","cyan","red","brown"]

1. What was the hardest part?

Implementing the multiplayer and the exceptions.

2. If you could go back and give yourself advice at the beginning of the project, what would it be?

Don't forget the exceptions.

3. If you could change something about this challenge, what would it be?

Possibility to play with 3 or more players. However, the API is ready for it :)

How to compile and run

You need to get the project from github, and you need to have maven 3.x in your machine.

https://github.com/lberbel/mastermind
mvn clean install

This command generates a war archive in /target folder.

After that, you can publish on any container you want, TomCat, Jboss, WildFly, etc... The live demo is running on WildFly 10.

This API doesn't require any database.

Live Demo

You can check the live demo at:

http://www.lberbel.com.br/mastermind

Built With

Share this project:

Updates