+import xml.etree.ElementTree as et
+from ollama import Client
+import re
+
+class commissioner():
+ def __init__(self):
+ self.instability = 0
+ self.log = []
+ self.dream = ""
+
+ self.client = Client(host='http://127.0.0.1:11434')
+
+ self.gamespace = """
+ <cardGame>
+ <player name='max'>
+ <card suit='diamonds' color='red'>2</card>
+ <card suit='spades' color='black'>6</card>
+ <state>playing</state>
+ </player>
+ <player name='will'>
+ <state>playing</state>
+ </player>
+ <player name='rebecca'>
+ <state>playing</state>
+ </player>
+ <rule lifespan='permanent'>This rule has no effect</rule>
+ <rule lifespan='permanent'>If all players have the state 'stuck' or 'bust': the player with the largest hand with the state 'stuck' should have the state 'winner'</rule>
+ <rule lifespan='deleteAfter'>If a player has 0 'card' elements, deal them 2 random cards.</rule>
+ <message>Initialized the gamespace</message>
+ </cardGame>
+ """
+
+ def ratify(self, rule, lifespan="permanent"):
+
+ root = et.fromstring(self.gamespace)
+
+ new_rule = et.Element('rule')
+ new_rule.text = rule
+ new_rule.attrib = {"lifespan": lifespan}
+
+ root.insert(-1, new_rule)
+
+ self.gamespace = et.tostring(root, encoding="unicode")
+
+ def observe(self):
+ root = et.fromstring(self.gamespace)
+ rules = root.findall("rule")
+
+ self.instability = 0
+ self.log = []
+
+ response = self.client.chat(model='deepseek-r1:14b', messages=[{
+ 'role': 'user',
+ 'content': f"""
+ Below is some XML describing a card game.\n
+ The outer element is the "cardGame" element. Inside the game there are the "player" elements (denoting players), the "message" element and "rule" elements (denoting the rules of the game that should be applied). "rule" elements have the attribute "lifespan" describing when they should be removed from "cardGame". "player" elements contain cards but also the "state" element.\n
+ The state can either be "playing", "stuck", "bust" or "winner".\n
+ The "message" element contains a short description of the action taken. This should be replaced with a new message after each alteration you make to the gamespace.\n
+ Apply all rules to the XML. Return the resultant XML first, followed by your explaination of your actions.\n\n
+ Card game XML follows:\n
+ {self.gamespace}
+ """
+ }])
+
+ think = re.search(r"<think>[\n\D\d]*<\/think>", response.message.content) # get bounds of <think>
+ body = response.message.content[think.span()[1]:] # get body by removing <think>
+ think = re.sub(r"<\/*think>", "", think.group()) # get think by extracting and removing <think>
+ xml = re.findall(r"(?<=```xml)[\d\D]*(?=```)", body) # get the xml portion
+ if len(xml) == 0:
+ self.instability = 999
+ self.log.append("failed! no vaild XML produced")
+ return
+
+ elif len(xml) > 1:
+ self.instability += 1
+ self.log.append("multiple valid gamespaces... collapsing")
+
+ # remove everying before and after <cardGame> and remove \n and \t
+ xml = re.sub(r"\\n|\\t", "", xml[-1])
+
+ try:
+ root = et.fromstring(xml)
+ if len(root.findall("rule")) == 0: # if there are no rules...
+ for rule in rules:
+ root.insert(-1, rule) # add old rules
+ self.instability += 2 # increce instability by 2 for each fixed rule (will be at least one)
+ self.log.append("rules dissapeared... attempting fix")
+
+ self.gamespace = et.tostring(root, encoding="unicode")
+
+ except et.ParseError:
+ self.instability = 999 # increce instability by 2 for each fixed rule (will be at least one)
+ self.log.append("failed! parser error")