First Bot
In this tutorial, we will learn about how the games and the players/bots communicate together. In Hackagames several players can play simultaneously to games.
That for, the loop control of the program is handled by the game. Then, the player bots have to generate the appropriate responses to situations.
Initialize a Bot environment
First, let implement a simple script, instantiating a game and a player.
from hackagames.py421 import GameMaster
from py421bot import FirstBot
# Instanciate Game-Master (handling the game and the players) and a bot player
gameMaster= GameMaster("Solo")
bot= FirstBot()
# Start 1000 games with your bot:
results= gameMaster.launchLocal( [bot], 1000 )
# And analyze the result:
botResults= results[0]
print( f"Average score: {sum(botResults)/len(botResults)}" )
This script starts \(1000\) games with bot an instance of a FirstBot as main player.
It returns the average endgame results of bot.
At this point your script should not work, we need to create our FirstBot bot class, into a py421bot.py file.
Initialize your First Bot, i.e. an Autonomous Player
A hackagames-formatted Bot is a class, implementing \(4\) specific methods: wakeUp, perceive,decide and sleep. wakeUp takes as parameters the initial configuration of a game, perceive the evolutive game state, and sleep the final result of the game.
The method decide does not take any parameter, but it should return the bot action.
The informations transiting between games and bots are formated as Pod (PieaceOfData), an hackaGames feature.
So, the minimal Bot implementation should be (in a new py421bot.py file):
from hacka import Pod
class FirstBot :
# Player interface :
def wakeUp(self, playerId, numberOfPlayers, gameConf):
pass
def perceive(self, gameState):
pass
def decide(self):
return Pod('keep-keep-keep')
def sleep(self, result):
pass
Multi-Files structuration
It is encuraged to work on your own computer with your favoryte Python IDE. As so, you should distribute your code into several files:
py421Bot.py, with the implementation of your Bot classes (FirstBotas a first class).py421-launch.py, the script instanciating a game-master and a bot player (and starting with afrom py421Bot import FirstBot).README.md, the simple text description of this directory (in markdown syntaxe)
For instance for your README.md:
# Tutorial Of HackaGames
This directory regroup my realization by following the tutorial of [hackagames](https://ktorz-net.github.io/hackagames).
## Structuration:
- `py421Bot.py`, The implementation of my Bot for the 421 game.
- `py421-launch.py`, the script to test a bot on the 421 game.
Then you can increase your file collection, following the tutorials with a strategy: one file - one functionnality.
If you are in a web-based Python IDE like Google Colab, the py421-launch.py matches your jupiter notebook and the other file can be created aside.
Understand Bot methods :
Games and Bots rely on the hacka library, to exchange information about the game and the players' intentions (game configuration, game states and decisions).
The players can be human interfaces or bots.
Game Loop:
A game mainly relies on perceive and decide capability for players and bots to update the information about the game and to ask for player action.
The perceive method has \(1\) argument: the gameState, the current configuration of the game from the point of view of the player.
In fact, gameState can be different from one player to another in multiplayer games with partial observation (typically card games). In our example (421), there is only one player with the full information about the game.
So the basic configuration of Py421 (Solo mode), the gameState informs about the $3$ dice values and the horizon counter (the number of remaining roll-again possibilities).
ThegameStateread and associate to the bot instanceself` is as follows:
def perceive(self, gameState):
self._horizon= gameState.child(1).integer(1)
self._dices= gameState.child(2).integers()
self._score= gameState.child(2).value(1)
The decide method has no argument, but should return the player action.
The action is formatted as a string.
decide is always triggered after at least one perceive call.
So, the bot instance self as all the required informations to process a decision.
For instance, in FirstBot, we can keep the \(4.2.1\) combination and roll the others.
def decide( self ):
stateString= f"{self._horizon} - {self._dices} ({self._score})"
action= 'roll-roll-roll'
if self._dices == [4, 2, 1] :
action= "keep-keep-keep"
return Pod(action)
As a result, this new decide method should statistically increase the obtained scores on \(1000\) games.
It is possible to add a print( stateString + ": "+ action ) to check each decision before the return instruction.
Multiple Games :
Furthermore, A GameMaster can start several games sequentially.
Therefore, the methods wakeUp and sleep are triggered respectively when a new game is started and stopped.
They are triggered 100 times in our script.
During a game, players are activated at turn with the perceive and the decide methods.
The wakeUp has \(3\) arguments: playerId, numberOfPlayers, gameConf informing in the place of the player in the game, the number of players and the initial configuration.
At this stage, there is no information to get from playerId, numberOfPlayers and gameConf in Py421, into Solo mode.
Finally, the sleep informs about the obtained score with its argument result.
The score is computed for the player regarding the ending game.
In Py421 into Solo mode, the result matches the final combination value.
- You have to try to increase decisions to increase average scores after \(1000\) games.
Pod - Hacka's Piece-Of-Data :
The method arguments gameConf and gameState as the expected return of decide method are formatted as hacka.Pod (Piece Of Data), a tree data structure packing integers, values, and strings data.
It is not required to understand Pod.
Examples are always provided to get the game information from Pod.
However, you can go to the Under the hood - Pod page for more detail on this core element of HackaGames.