Py421

Py421 is the first HackaGames game, a simple dice game where players try to optimize their dices combination after a maximum of 2 roll dice steps.

Try the game:

HackaGames comes with a commant to start and try the game with an interactive interface in a shell.

hacka-py421-play

However, it is also possible to edit and execute a short script launching a game with the interactive interface.

from hackagames.py421 import GameMaster
from hacka.player import PlayerShell

gameMaster= GameMaster("Solo")
gameMaster.launchLocal( [PlayerShell()], 1 )  

Py421 is a 3-dice game. The player can roll several times to get a combination. The player can perform one and only one action on his turn, and the game stops automatically after 2 turns.

The actions consist in keeping or rolling each of the 3 dices. So there are 8 possible actions:

  • keep-keep-keep, keep-keep-roll, keep-roll-keep, keep-roll-roll, roll-keep-keep, roll-keep-roll, roll-roll-keep and roll-roll-roll

The goal is to optimize the combination of dices before the end of the 2 turns. The best combination ever is 4-2-1 for 800 points. But you can explore other combinations.

Initialize a Bot

If you are implementing your first bot, please follow the first bot tutorial.

As for any Hackagames bots, a Py421 bot implements the the 4 player/bot methods wakeUp, perceive, decide and sleep. Theire is no information to get from The gameConf. The gameState parameter of the perceive includes 2 elements (2 gameState childs). First child model the roll-again horizon (one integer value), the second child the dices (\(3\) intergers and \(1\) floating point value for the score of the combinaison).

from hacka import Pod
import random

class RandomBot :

    def actions(self):
        return [ 'keep-keep-keep', 'keep-keep-roll', 'keep-roll-keep', 'keep-roll-roll',
            'roll-keep-keep', 'roll-keep-roll', 'roll-roll-keep', 'roll-roll-roll' ]

    # Player interface :
    def wakeUp(self, playerId, numberOfPlayers, gameConf):
        self._horizon= 3
        self._dices= [0, 0, 0]
        self._score= 0.0

    def perceive(self, gameState):
        self._horizon= gameState.child(1).integer(1)
        self._dices= gameState.child(2).integers()
        self._score= gameState.child(2).value(1)

    def decide(self):
        return Pod( random.choice( self.actions() ) )

    def sleep(self, result):
        self._lastResult= result

You can try your Bot AI by importing the GameMaster into a launch script:

from hackagames.py421 import GameMaster
from py421Bot import RandomBot as Bot

# Instanciate Game-Master and bot
gameMaster= GameMaster("Solo")
bot= Bot()

# Start 1000 games with your bot:
results= gameMaster.launchLocal( [bot], 1000 )
botResults= results[0]
print( f"Average score: {sum(botResults)/len(botResults)}" )

Multi-player version

You can confront 2 Bot-AIs by by configuring the GameMaster on Duo mode into your launch script:

from hackagames.py421 import GameMaster
from py421Bot import RandomBot as Bot

# Instanciate Game-Master and bot
gameMaster= GameMaster("Duo")
bot1= Bot()
bot2= Bot()

# Start 1000 games with your bot:
results= gameMaster.launchLocal( [bot1, bot2], 100 )

# Analyze the result
print( f"Average scores: " )
for i in [0, 1] :
    botResults= results[i]
    print( f"  - Player-{i+1}: {sum(botResults)/len(botResults)}" )

The launch script returns the results for all bots players. In duo mode, the game result (sleep) is not longer the combinaition value but 1, -1 or 0, respectivelly if the player win, lose or in case or no winner. Ideally the tow bot should be defined diferently, with two different class for instance.

Optimize a 2-player Bot :

A Bot designed for solo mode of 421 can also play to duo mode. However, the wakeUp methods informative and the perception method is incresed in duo mode. The player identifier of the wakeUp inform if the bot is the first or the second player. The gameState also include the conbinaison of your opponent:

def perceive(self, gameState):
    self._horizon= gameState.child(1).integer(1)
    self._dices= gameState.child(2).integers()
    self._score= gameState.child(2).value(1)
    self._oppo_dices= gameState.child(3).integers()
    self._oppo_score= gameState.child(3).value(1)
    print( f'\t> H: {self._horizon}, DICES: {self._dices}, SCORE: {self._score} (VS: {self._oppo_dices} {self._oppo_score})' )

Use this to increase the state definition and to optimize the bot's strategies.

Server Mode

It is possible to start 421 in solo or duo mode. To try this version executes the following command:

hacka-py421-launch duo -n 1000

That starts 1000 games 4.2.1 where you have to confront 2 players as web-client process. Those players can be started on 2 differences terminal (in the same machine or not). You can add the following lines at the end of your py421Bot.py file before to execute it:

from hacka.interprocess import SeatClient

if __name__ == "__main__" :
    print( "Connect..." )
    client= SeatClient( RandomBot() )
    results= client.takeASeat( "localhost" )
    print( f"  - Results : {sum(results)/len(results)}" )

Then in a terminal : python3 ./py421Bot.py. To notice that you have to change 'localhost' to the machine name or IP to target the one running the game serve, if the game and players are not on the same.