Hi,
To expand a bit on what @Brent_Easton said. I will be thinking of a traditional Hex’n’Counter wargame.
For an automated opponent (I’ll use AI as a short-hand), a great deal of information need to be available to it.
- The map coordinate system - which a VASSAL module somewhat has.
- Terrain and other features of the map - which a VASSAL module could have though it quickly becomes cumbersome.
- Pieces at all map locations - which can be done, but again quickly becomes cumbersome
- Piece factors - which can be done via
Marker
traits and similar
- … and many other things I cannot begin to think of
The AI also needs to know how to move pieces. This could be done via an A* algorithm implemented in VASSAL. This algorithm would then make appropriate call-backs to the module to gain information about movement costs. These callbacks need to provide a fair bit of information to the module, such as
- which location is the piece moving from
- which location is the piece moving to
- which piece is moving
- which units are present in the location moved to
- …
The module must then also be able to resolve combats. This is doable in the current VASSAL, but does require a bit of coding.
To do all this, it would make sense if VASSAL exposed a lot of scripting capabilities. E.g., when a user selects a piece, a script would be called to calculate possible moves, and VASSAL would then display that to the user. Or when a battle is declared and resolved, then a (set of) scripts would be called with all the relevant information, and VASSAL would then display the results. I could imagine that each module would be implemented as a class a la (in Python)
class MyModule(BaseModule):
def __init__(self):
# Set up the module
self.buildPieces()
self.buildBoard()
self.registerTerrain()
...
def piecesSelected(self,locatedPieces,when):
# Calculate possible moves when when=movement, attacks when when=combat
for location,pieces in locatedPieces.items():
# ...
if 'movement' in when:
displayPossibleMoves(moves)
if 'combat' in when:
displayPossibleAttacks(moves)
def declareCombat(self,locatedPieces,when):
# Calculate combat 'odds'
attackerCF = 0
defenderCF = 0
for location,pieces in locatedPieces.items()
isWoods = self.isWoods(location)
for piece in pieces:
if self.isAttacker(piece,when):
attackerCF += piece.AF()
else:
defenderCF += piece.DF() * (2 if isWoods else 1)
odds = self.calculateOdds(attackerCF,defenderCF)
Clearly, this would make VASSAL modules much more programming-heavy to do, and there could be options to have “dump” modules too (predefined base modules and so on).
An example of a module with a somewhat automated opponent is One-Minute Bulge (GitLab snippet, VASSAL module
- The player selects which kind of surprise attack to do
- The module then calculates the results
- Depending on the result of the surprise attack and following automated actions, the player then has the option to attack again, or to trust in its oratory skills in the a Führer conference.
- The module than determines the result of either, calculates victory points, and displays the result
It takes as long to play as it takes to load the module, if not shorter To make this requires 474+13+542=1029 lines of LaTeX code, and 637 lines of Python code.
Yours,
Christian