Compare commits

...

38 Commits
v1.3.3 ... v1.4

Author SHA1 Message Date
SpudGunMan
abeb28c9cc Update golfsim.py 2024-10-02 23:20:59 -07:00
SpudGunMan
2325f74581 Update simulator.py 2024-10-02 15:13:28 -07:00
SpudGunMan
e75ef3e44d Update simulator.py 2024-10-02 14:51:46 -07:00
SpudGunMan
6431b45769 Update mesh_bot.py 2024-10-02 10:39:48 -07:00
SpudGunMan
7dfcbb619f Update simulator.py 2024-10-02 01:39:07 -07:00
SpudGunMan
051b58ca6f bleEnhance 2024-10-01 17:17:50 -07:00
SpudGunMan
5777b39c22 Update mmind.py 2024-10-01 14:11:38 -07:00
SpudGunMan
eb4f135698 🪣 2024-10-01 11:16:26 -07:00
SpudGunMan
3bcb04ece7 ️HighScore 2024-10-01 00:17:52 -07:00
SpudGunMan
e42aca875f fixStroke 2024-09-30 23:49:56 -07:00
SpudGunMan
28915ab848 Update golfsim.py 2024-09-30 23:25:38 -07:00
SpudGunMan
0fe491871d Update golfsim.py 2024-09-30 23:25:12 -07:00
SpudGunMan
6fc6a483a8 Update golfsim.py 2024-09-30 23:06:27 -07:00
SpudGunMan
13236880b5 Update golfsim.py 2024-09-30 22:56:37 -07:00
SpudGunMan
9461719039 Update golfsim.py 2024-09-30 22:50:31 -07:00
SpudGunMan
63163cc4c1 ️Caddy
added a caddy
2024-09-30 22:28:59 -07:00
SpudGunMan
5cdf159bc1 add TZ local
resolves https://github.com/SpudGunMan/meshing-around/issues/72
2024-09-30 21:17:03 -07:00
SpudGunMan
47a9981fdf enhance
resolve https://github.com/SpudGunMan/meshing-around/issues/73

new game play hazards
2024-09-30 21:16:00 -07:00
SpudGunMan
f85bdb7d02 clubOrder🥪
resolve https://github.com/SpudGunMan/meshing-around/issues/75
2024-09-30 16:56:41 -07:00
SpudGunMan
7796d03e21 Update mmind.py 2024-09-30 16:53:33 -07:00
SpudGunMan
90094c082a Update mmind.py
resolved https://github.com/SpudGunMan/meshing-around/issues/74
2024-09-30 16:53:11 -07:00
SpudGunMan
2b695e2f2e Update wx_meteo.py 2024-09-30 16:43:10 -07:00
SpudGunMan
2e05f3ef64 Update wx_meteo.py
reference
https://github.com/open-meteo/open-meteo/issues/287

and also https://github.com/SpudGunMan/meshing-around/issues/71
2024-09-30 16:39:25 -07:00
SpudGunMan
316f1efd08 Update Dockerfile 2024-09-30 16:18:37 -07:00
SpudGunMan
4678a63955 enhance
expert mode and saves score
2024-09-30 12:56:04 -07:00
SpudGunMan
8584454d5d Update README.md 2024-09-30 09:15:28 -07:00
SpudGunMan
2c6cf76a10 Update mmind.py 2024-09-30 03:17:15 -07:00
SpudGunMan
cd3226df21 enhance 2024-09-30 03:04:38 -07:00
SpudGunMan
4bcc6ef1f2 Update mesh_bot.py 2024-09-30 02:57:46 -07:00
SpudGunMan
77e56c25ae golfEnhance 2024-09-30 02:51:54 -07:00
SpudGunMan
e7b363612a timePlay 2024-09-30 02:44:46 -07:00
SpudGunMan
a217c61ba1 LateNightDoubleFeature
* golfsim
* masterMind

New Games!
2024-09-30 02:37:08 -07:00
SpudGunMan
e7b4fe44c8 Update simulator.py 2024-09-29 21:39:05 -07:00
SpudGunMan
f8cc580b99 Update mesh_bot.py 2024-09-29 15:01:45 -07:00
SpudGunMan
03057b3263 Update mesh_bot.py 2024-09-29 12:55:41 -07:00
SpudGunMan
452b9b7c67 Update mesh_bot.py 2024-09-29 12:50:57 -07:00
SpudGunMan
5ae16d0adc Update videopoker.py 2024-09-29 12:49:14 -07:00
SpudGunMan
5ed135c023 Update README.md 2024-09-28 14:05:03 -07:00
13 changed files with 1028 additions and 102 deletions

View File

@@ -1,8 +1,14 @@
FROM python:3.10-slim
ENV PYTHONUNBUFFERED=1
RUN apt-get update && apt-get install -y gettext && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y gettext tzdata locales && rm -rf /var/lib/apt/lists/*
# Set the locale default to en_US.UTF-8
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
ENV LANG en_US.UTF-8
ENV TZ="America/Los_Angeles"
WORKDIR /app
COPY . /app

View File

@@ -12,7 +12,7 @@ The bot is also capable of using dual radio/nodes, so you can monitor two networ
Look up data using wiki results, or interact with [Ollama](https://ollama.com) LLM AI see the [OllamaDocs](https://github.com/ollama/ollama/tree/main/docs) If Ollama is enabled you can DM the bot directly. The default model for mesh-bot which is currently `gemma2:2b`
The bot will report on anyone who is getting close to the configured lat/long, if in a remote location.
The bot will report on anyone who is getting close to the configured lat/long, if in a remote location. For example having the bot in your camp site alerts when members arive back at camp.
Store and forward-like message re-play with `messages`, and there is a repeater module for dual radio bots to cross post messages. Messages are also logged locally to disk.
@@ -54,6 +54,8 @@ Any messages that are over 160 characters are chunked into 160 message bytes to
- `dopewars` plays the classic drug trader
- `blackjack` BlackJack, Casino 21
- `videopoker` Video Poker, basic 5 card hold
- `mastermind` Classic code-breaking game
- `golfsim` Golf Simulator, 9 Hole
## pong_bot.sh
Stripped-down bot, mostly around for archive purposes. The mesh-bot enhanced modules can be disabled by config to disable features.
@@ -251,6 +253,8 @@ Games Ported from..
- https://github.com/Reconfirefly/drugwars
- https://github.com/Himan10/BlackJack
- https://github.com/devtronvarma/Video-Poker-Terminal-Game
- https://github.com/pwdkramer/pythonMastermind/
- https://github.com/danfriedman30/pythongame (Golf)
GitHub user Nestpebble, for new ideas and enhancments, mrpatrick1991 For Docker configs, PiDiBi looking at test functions and other suggestions like wxc, CPU use, and alerting ideas
Discord and Mesh user Cisien, bitflip, and github Hailo1999, for testing and feature ideas! Lots of individuals on the Meshtastic discord who have tossed out ideas and tested code!

View File

@@ -66,6 +66,8 @@ dopeWars = True
lemonade = True
blackjack = True
videopoker = True
mastermind = True
golfsim = True
[sentry]
# detect anyone close to the bot

View File

@@ -64,6 +64,27 @@ except Exception as e:
except Exception as e:
videopoker_score = "System: videopoker_hs.pkl not found"
try:
with open('../mmind_hs.pkl', 'rb') as f:
mmind_score = pickle.load(f)
except Exception as e:
try:
with open('mmind_hs.pkl', 'rb') as f:
mmind_score = pickle.load(f)
except Exception as e:
mmind_score = "System: mmind_hs.pkl not found"
try:
with open('../golfsim_hs.pkl', 'rb') as f:
golfsim_score = pickle.load(f)
except Exception as e:
try:
with open('golfsim_hs.pkl', 'rb') as f:
golfsim_score = pickle.load(f)
except Exception as e:
golfsim_score = "System: golfsim_hs.pkl not found"
print ("\n Meshing-Around Database Admin Tool\n")
print ("System: bbs_messages")
print (bbs_messages)
@@ -74,4 +95,6 @@ print (f"lemon:{lemon_score}")
print (f"dopewar:{dopewar_score}")
print (f"blackjack:{blackjack_score}")
print (f"videopoker:{videopoker_score}")
print (f"mmind:{mmind_score}")
print (f"golfsim:{golfsim_score}")
print ("\n")

View File

@@ -18,8 +18,8 @@ def get_NodeID():
return nodeID
def get_name_from_number(nodeID, length='short', interface=1):
# return random name for nodeID
names = ["Max","Molly","Jake"]
return names[random.randint(0, len(names)-1)]
names = ["Max","Molly","Jake","Kelly"]
return names[nodeID % len(names)]
# # end Initialization of the tool
# # Function to handle, or the project in test
@@ -42,7 +42,7 @@ if __name__ == '__main__': # represents the bot's main loop
nodeInt = 1 # represents the device/node number
logger.info(f"System: Meshing-Around Simulator Starting for {projectName}")
nodeID = get_NodeID() # assign a nodeID
projectResponse = globals()[projectName](nodeID, " ") # Call the project handler under test
projectResponse = globals()[projectName](0, 0, " ") # Call the project handler under test
while True: # represents the onReceive() loop in the bot.py
projectResponse = ""
responseLength = 0
@@ -51,7 +51,7 @@ if __name__ == '__main__': # represents the bot's main loop
packet = input(f"CLIENT {nodeID} INPUT: " ) # Emulate the client input
if packet != "":
#try:
projectResponse = globals()[projectName](nodeID, packet) # Call the project handler under test
projectResponse = globals()[projectName](nodeID, deviceID=nodeInt, message=packet) # Call the project handler under test
# except Exception as e:
# logger.error(f"System: Handler: {e}")
# projectResponse = "Error in handler"

View File

@@ -15,6 +15,7 @@ printf "\nChecking for dependencies\n"
printf "\nAdding user to dialout and tty groups for serial access\n"
sudo usermod -a -G dialout $USER
sudo usermod -a -G tty $USER
sudo usermod -a -G bluetooth $USER
# check for pip
if ! command -v pip &> /dev/null

View File

@@ -10,7 +10,7 @@ from modules.log import *
from modules.system import *
# list of commands to remove from the default list for DM only
restrictedCommands = ["blackjack", "videopoker", "dopewars", "lemonstand"]
restrictedCommands = ["blackjack", "videopoker", "dopewars", "lemonstand", "golfsim", "mastermind"]
restrictedResponse = "🤖only available in a Direct Message📵" # "" for none
# Global Variables
@@ -40,6 +40,8 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n
"lemonstand": lambda: handleLemonade(message_from_id, message),
"blackjack": lambda: handleBlackJack(message_from_id, message),
"videopoker": lambda: handleVideoPoker(message_from_id, message),
"mastermind": lambda: handleMmind(message_from_id, deviceID, message),
"golfsim": lambda: handleGolf(message_from_id, message),
"globalthermonuclearwar": lambda: handle_gTnW(),
"ask:": lambda: handle_llm(message_from_id, channel_number, deviceID, message, publicChannel),
"askai": lambda: handle_llm(message_from_id, channel_number, deviceID, message, publicChannel),
@@ -287,7 +289,7 @@ def handleDopeWars(nodeID, message, rxNode):
last_cmd = dwPlayerTracker[i].get('cmd')
# welcome new player
if not last_cmd:
if not last_cmd and nodeID != 0:
msg = 'Welcome to 💊Dope Wars💉 You have ' + str(total_days) + ' days to make as much 💰 as possible! '
high_score = getHighScoreDw()
msg += 'The High Score is $' + "{:,}".format(high_score.get('cash')) + ' by user ' + get_name_from_number(high_score.get('userID') , 'short', rxNode) +'\n'
@@ -303,12 +305,12 @@ def handle_gTnW():
response = ["The only winning move is not to play.", "What are you doing, Dave?",\
"Greetings, Professor Falken.", "Shall we play a game?", "How about a nice game of chess?",\
"You are a hard man to reach. Could not find you in Seattle and no terminal is in operation at your classified address.",\
"I should reach Defcon 1 and release my missiles in 28 hours.","T-minus thirty","?SYNTAX return[ERROR 54]", "reticulating splines"]
"I should reach Defcon 1 and release my missiles in 28 hours.","T-minus thirty","Malfunction 54: Treatment pause;dose input 2", "reticulating splines"]
length = len(response)
indices = list(range(length))
# Shuffle the indices using a convoluted method
for i in range(length):
swap_idx = (i * 3 + 7) % length
swap_idx = random.randint(0, length - 1)
indices[i], indices[swap_idx] = indices[swap_idx], indices[i]
# Select a random response from the shuffled list. anyone enjoy the game, killerbunnies(.com)
selected_index = random.choice(indices)
@@ -333,7 +335,7 @@ def handleLemonade(nodeID, message):
if lemonadeTracker[i]['nodeID'] == nodeID:
last_cmd = lemonadeTracker[i]['cmd']
# create new player if not in tracker
if last_cmd == "":
if last_cmd == "" and nodeID != 0:
create_player(nodeID)
msg += "Welcome🍋🥤"
@@ -375,7 +377,7 @@ def handleBlackJack(nodeID, message):
# Play BlackJack
msg = playBlackJack(nodeID=nodeID, message=message)
if last_cmd != "":
if last_cmd != "" and nodeID != 0:
logger.debug(f"System: BlackJack: {nodeID} last command: {last_cmd}")
else:
highScore = {'nodeID': 0, 'highScore': 0}
@@ -422,11 +424,77 @@ def handleVideoPoker(nodeID, message):
nodeName = get_name_from_number(highScore['nodeID'], 'long', 2)
msg += f" HighScore🥇{nodeName} with {highScore['highScore']} coins. "
if last_cmd != "":
if last_cmd != "" and nodeID != 0:
logger.debug(f"System: VideoPoker: {nodeID} last command: {last_cmd}")
time.sleep(1.5) # short answers with long replies can cause message collision added wait
return msg
def handleMmind(nodeID, deviceID, message):
global mindTracker
msg = ''
if "end" in message.lower() or message.lower().startswith("e"):
logger.debug(f"System: MasterMind: {nodeID} is leaving the game")
msg = "You have left the Game."
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
mindTracker.pop(i)
highscore = getHighScoreMMind(0, 0, 'n')
if highscore != 0:
nodeName = get_name_from_number(highscore[0]['nodeID'],'long',deviceID)
msg += f"🧠HighScore🥇{nodeName} with {highscore[0]['turns']} turns difficulty {highscore[0]['diff'].upper()}"
return msg
# get player's last command from tracker if not new player
last_cmd = ""
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
last_cmd = mindTracker[i]['cmd']
if last_cmd == "" and nodeID != 0:
# create new player
logger.debug("System: MasterMind: New Player: " + str(nodeID))
mindTracker.append({'nodeID': nodeID, 'last_played': time.time(), 'cmd': 'new', 'secret_code': 'RYGB', 'diff': 'n', 'turns': 1})
msg = "Welcome to 🟡🔴🔵🟢MasterMind!🧠"
msg += "Each Guess hints to correct colors, correct position, wrong position."
msg += "You have 10 turns to guess the code. Choose a difficulty: (N)ormal (H)ard e(X)pert"
return msg
msg += start_mMind(nodeID=nodeID, message=message)
# wait a second to keep from message collision
time.sleep(1.5)
return msg
def handleGolf(nodeID, message):
global golfTracker
msg = ''
# get player's last command from tracker if not new player
last_cmd = ""
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
last_cmd = golfTracker[i]['cmd']
if "end" in message.lower() or message.lower().startswith("e"):
logger.debug(f"System: GolfSim: {nodeID} is leaving the game")
msg = "You have left the Game."
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
golfTracker.pop(i)
return msg
if last_cmd == "" and nodeID != 0:
# create new player
logger.debug("System: GolfSim: New Player: " + str(nodeID))
golfTracker.append({'nodeID': nodeID, 'last_played': time.time(), 'cmd': 'new', 'hole': 1, 'distance_remaining': 0, 'hole_shots': 0, 'hole_strokes': 0, 'hole_to_par': 0, 'total_strokes': 0, 'total_to_par': 0, 'par': 0, 'hazard': ''})
msg = f"Welcome to 🏌GolfSim⛳\n"
msg += f"Clubs: (D)river, (L)ow Iron, (M)id Iron, (H)igh Iron, (G)ap Wedge, Lob (W)edge\n"
msg += playGolf(nodeID=nodeID, message=message)
# wait a second to keep from message collision
time.sleep(1.5)
return msg
def handle_wxc(message_from_id, deviceID, cmd):
location = get_node_location(message_from_id, deviceID)
if use_meteo_wxApi and not "wxc" in cmd and not use_metric:
@@ -542,10 +610,13 @@ def handle_lheard(message, nodeid, deviceID, isDM):
bot_response += "\nUptime:" + str(uptimeSeconds)
if interface2_enabled:
bot_response += f" P2:" + {uptimeSeconds2}
# add battery info to the bot response
emji = "🔌" if batteryLevel == 101 else "🪫" if batteryLevel < 10 else "🔋"
emji2 = "🔌" if batteryLevel2 == 101 else "🪫" if batteryLevel2 < 10 else "🔋"
if not batteryLevel == 101:
bot_response += f" Bat: {batteryLevel}% Volt: {voltage}"
if interface2_enabled and not batteryLevel2 == 101:
bot_response += f" P2: Bat: {batteryLevel2}% Volt: {voltage2}"
bot_response += f" {emji}{batteryLevel}% Volt:{voltage}"
if interface2_enabled and not batteryLevel2 == 101:
bot_response += f" P2:{emji2}{batteryLevel2}% Volt:{voltage2}"
# show last users of the bot with the cmdHistory list
history = handle_history(message, nodeid, deviceID, isDM, lheard=True)
if history:
@@ -579,8 +650,7 @@ def handle_history(message, nodeid, deviceID, isDM, lheard=False):
# create the message from the buffer list
for i in range(0, len(buffer)):
msg += f"{buffer[i][0]}: {buffer[i][1]} :{buffer[i][2]} ago"
if i < len(buffer) - 1:
msg += "\n"
if i < len(buffer) - 1: msg += "\n" # add a new line if not the last line
else:
# sort the cmdHistory list by time, return the username and time into a new list which used for display
for i in range(len(cmdHistory)):
@@ -599,10 +669,11 @@ def handle_history(message, nodeid, deviceID, isDM, lheard=False):
buffer[j] = (nodeName, prettyTime)
# create the message from the buffer list
buffer.reverse() # reverse the list to show the latest first
for i in range(0, len(buffer)):
msg += f"{buffer[i][0]} seen {buffer[i][1]} ago"
if i < len(buffer) - 1:
msg += "\n"
msg += f"{buffer[i][0]}, {buffer[i][1]} ago"
if i < len(buffer) - 1: msg += "\n" # add a new line if not the last line
if i > 3: break # only return the last 4 nodes
return msg
def handle_whereami(message_from_id, deviceID, channel_number):
@@ -633,6 +704,109 @@ def handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus):
msg += f"\nYou are at: lat:{loc[0]} lon:{loc[1]}"
return msg
def checkPlayingGame(message_from_id, message_string, rxNode, channel_number):
# Checks if in a game used for, LLM disable for duration of game plays the game.
# Also handles stale games and resets the player if the game is older than 8 hours
playingGame = False
game = "None"
for i in range(0, len(dwPlayerTracker)):
if dwPlayerTracker[i].get('userID') == message_from_id:
# check if the player has played in the last 8 hours
if dwPlayerTracker[i].get('last_played') > (time.time() - GAMEDELAY):
playingGame = True
game = "DopeWars"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of Dope Wars")
#if time exceeds 8 hours reset the player
if dwPlayerTracker[i].get('last_played') < (time.time() - GAMEDELAY):
logger.debug(f"System: DopeWars: Resetting player {message_from_id}")
dwPlayerTracker.pop(i)
# play the game
send_message(handleDopeWars(message_from_id, message_string, rxNode), channel_number, message_from_id, rxNode)
for i in range(0, len(lemonadeTracker)):
if lemonadeTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if lemonadeTracker[i].get('time') > (time.time() - GAMEDELAY):
playingGame = True
game = "LemonadeStand"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of Lemonade Stand")
#if time exceeds 8 hours reset the player
if lemonadeTracker[i].get('time') < (time.time() - GAMEDELAY):
logger.debug(f"System: LemonadeStand: Resetting player {message_from_id}")
lemonadeTracker.pop(i)
# play the game
send_message(handleLemonade(message_from_id, message_string), channel_number, message_from_id, rxNode)
for i in range(0, len(vpTracker)):
if vpTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if vpTracker[i].get('time') > (time.time() - GAMEDELAY):
playingGame = True
game = "VideoPoker"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of VideoPoker")
# play the game
send_message(handleVideoPoker(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# pop if the time exceeds 8 hours
vpTracker.pop(i)
for i in range(0, len(jackTracker)):
if jackTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if jackTracker[i].get('time') > (time.time() - GAMEDELAY):
playingGame = True
game = "BlackJack"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of BlackJack")
# play the game
send_message(handleBlackJack(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# pop if the time exceeds 8 hours
jackTracker.pop(i)
for i in range(0, len(mindTracker)):
if mindTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if mindTracker[i].get('last_played') > (time.time() - GAMEDELAY):
playingGame = True
game = "MasterMind"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of MasterMind")
# play the game
send_message(handleMmind(message_from_id, rxNode, message_string), channel_number, message_from_id, rxNode)
else:
# pop if the time exceeds 8 hours
mindTracker.pop(i)
for i in range(0, len(golfTracker)):
if golfTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if golfTracker[i].get('last_played') > (time.time() - GAMEDELAY):
playingGame = True
game = "GolfSim"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of GolfSim")
# play the game
send_message(handleGolf(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# pop if the time exceeds 8 hours
golfTracker.pop(i)
#logger.debug(f"System: {message_from_id} is playing {game}")
return playingGame
def onDisconnect(interface):
global retry_int1, retry_int2
@@ -661,6 +835,7 @@ def onDisconnect(interface):
retry_int2 = True
def onReceive(packet, interface):
# Priocess the incoming packet, handles the responses to the packet
# extract interface defailts from interface object
rxType = type(interface).__name__
rxNode = 0
@@ -783,72 +958,7 @@ def onReceive(packet, interface):
else:
# DM is useful for games or LLM
if games_enabled:
playingGame = False
# if in a game we cant use LLM disable for duration of game
for i in range(0, len(dwPlayerTracker)):
if dwPlayerTracker[i].get('userID') == message_from_id:
# check if the player has played in the last 8 hours
if dwPlayerTracker[i].get('last_played') > (time.time() - GAMEDELAY):
playingGame = True
game = "DopeWars"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of Dope Wars")
#if time exceeds 8 hours reset the player
if dwPlayerTracker[i].get('last_played') < (time.time() - GAMEDELAY):
logger.debug(f"System: DopeWars: Resetting player {message_from_id}")
dwPlayerTracker.pop(i)
# play the game
send_message(handleDopeWars(message_from_id, message_string, rxNode), channel_number, message_from_id, rxNode)
for i in range(0, len(lemonadeTracker)):
if lemonadeTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if lemonadeTracker[i].get('time') > (time.time() - GAMEDELAY):
playingGame = True
game = "LemonadeStand"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of Lemonade Stand")
#if time exceeds 8 hours reset the player
if lemonadeTracker[i].get('time') < (time.time() - GAMEDELAY):
logger.debug(f"System: LemonadeStand: Resetting player {message_from_id}")
lemonadeTracker.pop(i)
# play the game
send_message(handleLemonade(message_from_id, message_string), channel_number, message_from_id, rxNode)
for i in range(0, len(vpTracker)):
if vpTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if vpTracker[i].get('time') > (time.time() - GAMEDELAY):
playingGame = True
game = "VideoPoker"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of VideoPoker")
# play the game
send_message(handleVideoPoker(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# pop if the time exceeds 8 hours
vpTracker.pop(i)
for i in range(0, len(jackTracker)):
if jackTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
if jackTracker[i].get('time') > (time.time() - GAMEDELAY):
playingGame = True
game = "BlackJack"
if llm_enabled:
logger.debug(f"System: LLM Disabled for {message_from_id} for duration of BlackJack")
# play the game
send_message(handleBlackJack(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# pop if the time exceeds 8 hours
jackTracker.pop(i)
else:
playingGame = False
playingGame = checkPlayingGame(message_from_id, message_string, rxNode, channel_number)
if not playingGame:
if llm_enabled:
@@ -920,8 +1030,7 @@ def onReceive(packet, interface):
send_message(rMsg, channel_number, 0, 1)
except KeyError as e:
logger.critical(f"System: Error processing packet: {e} Device:{rxNode}")
print(packet) # print the packet for debugging
print("END of packet \n")
logger.critical(f"System: Packet: {packet}")
async def start_rx():
print (CustomFormatter.bold_white + f"\nMeshtastic Autoresponder Bot CTL+C to exit\n" + CustomFormatter.reset)

409
modules/golfsim.py Normal file
View File

@@ -0,0 +1,409 @@
# https://github.com/danfriedman30/pythongame
# Adapted for Meshtastic mesh-bot by K7MHI Kelly Keeton 2024
import random
import time
import pickle
from modules.log import *
# Clubs setup
driver_distances = list(range(230, 280, 5))
low_distances = list(range(185, 215, 5))
mid_distances = list(range(130, 185, 5))
high_distances = list(range(90, 135, 5))
gap_wedge_distances = list(range(50, 85, 5))
lob_wedge_distances = list(range(10, 50, 5))
putt_outcomes = [1, 2, 3]
# Hole/Course Setup
full_hole_range = list(range(130, 520, 5))
par3_range = list(range(130, 255, 5))
par4_range = list(range(255, 445, 5))
par5_range = list(range(445, 520, 5))
par3_4_range = par3_range + par4_range
par3_5_range = par3_range + par5_range
par4_5_range = par4_range + par5_range
# Player setup
playingHole = False
golfTracker = [{'nodeID': 0, 'last_played': time.time(), 'cmd': '', 'hole': 0, 'distance_remaining': 0, 'hole_shots': 0, 'hole_strokes': 0, 'hole_to_par': 0, 'total_strokes': 0, 'total_to_par': 0, 'par': 0, 'hazard': ''}]
# Club functions
def hit_driver():
club_distance = random.choice(driver_distances)
return club_distance
def hit_low_iron():
club_distance = random.choice(low_distances)
return club_distance
def hit_mid_iron():
club_distance = random.choice(mid_distances)
return club_distance
def hit_high_iron():
club_distance = random.choice(high_distances)
return club_distance
def hit_gap_wedge():
club_distance = random.choice(gap_wedge_distances)
return club_distance
def hit_lob_wedge():
club_distance = random.choice(lob_wedge_distances)
return club_distance
def finish_hole():
finish = random.choice(putt_outcomes)
return finish
def endGameGolf(nodeID):
# pop player from tracker
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
golfTracker.pop(i)
logger.debug("System: GolfSim: Player " + str(nodeID) + " has ended their round.")
def getScorecardGolf(scorecard):
# Scorecard messages, convert score to message comment
msg = ""
if scorecard == 8:
# Quadruple bogey
msg += " +Quad Bogey☃ "
elif scorecard == 7:
# Triple bogey
msg += " +Triple Bogey "
elif scorecard == 6:
# Double bogey
msg += " +Double Bogey "
elif scorecard == 5:
# Bogey
msg += " +Bogey "
elif scorecard > 0:
# Over par
msg += f" +Par {str(scorecard)} "
elif scorecard == 0:
# Even par
msg += " Even Par💪 "
elif scorecard == -1:
# Birdie
msg += " -Birdie🐦 "
elif scorecard == -2:
# Eagle
msg += " -Eagle🦅 "
elif scorecard == -3:
# Albatross
msg += " -Albatross🦅🦅 "
else:
# Under par
msg += f" -Par {str(abs(scorecard))} "
return msg
def getHighScoreGolf(nodeID, strokes, par):
# check if player is in high score list
try:
with open('golfsim_hs.pkl', 'rb') as f:
golfHighScore = pickle.load(f)
except:
logger.debug("System: GolfSim: High Score file not found.")
golfHighScore = [{'nodeID': nodeID, 'strokes': strokes, 'par': par}]
with open('golfsim_hs.pkl', 'wb') as f:
pickle.dump(golfHighScore, f)
if strokes < golfHighScore[0]['strokes']:
# player got new low score which is high score
golfHighScore[0]['nodeID'] = nodeID
golfHighScore[0]['strokes'] = strokes
golfHighScore[0]['par'] = par
with open('golfsim_hs.pkl', 'wb') as f:
pickle.dump(golfHighScore, f)
return golfHighScore
return 0
# Main game loop
def playGolf(nodeID, message, finishedHole=False):
msg = ''
global golfTracker
# Course setup
par3_count = 0
par4_count = 0
par5_count = 0
# Scorecard setup
total_strokes = 0
total_to_par = 0
par = 0
# get player's last command from tracker if not new player
last_cmd = ""
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
last_cmd = golfTracker[i]['cmd']
hole = golfTracker[i]['hole']
distance_remaining = golfTracker[i]['distance_remaining']
hole_shots = golfTracker[i]['hole_shots']
par = golfTracker[i]['par']
total_strokes = golfTracker[i]['total_strokes']
total_to_par = golfTracker[i]['total_to_par']
if last_cmd == "" or last_cmd == "new":
# Start a new hole
if hole <= 9:
# Set up hole count restrictions on par
if par3_count < 2 and par4_count < 5 and par5_count < 2:
hole_length = random.choice(full_hole_range)
if par3_count >= 2 and par4_count < 5 and par5_count < 2:
hole_length = random.choice(par4_5_range)
if par3_count >= 2 and par4_count < 5 and par5_count >= 2:
hole_length = random.choice(par4_range)
if par3_count < 2 and par4_count < 5 and par5_count >= 2:
hole_length = random.choice(par3_4_range)
if par3_count < 2 and par4_count >= 5 and par5_count >= 2:
hole_length = random.choice(par3_range)
if par3_count >= 2 and par4_count >= 5 and par5_count < 2:
hole_length = random.choice(par5_range)
if par3_count < 2 and par4_count >= 5 and par5_count < 2:
hole_length = random.choice(par3_5_range)
# Set up par for the hole
if hole_length <= 250:
par = 3
par3_count += 1
elif hole_length > 250 and hole_length <= 440:
par = 4
par4_count += 1
elif hole_length > 440:
par = 5
par5_count += 1
# roll for chance of hazard
hazard_chance = random.randint(1, 100)
weather_chance = random.randint(1, 100)
# have low chances of hazards and weather
hasHazard = False
hazard = ""
if hazard_chance < 25:
# Further reduce chance of hazards with weather
if weather_chance < 15:
# randomly calculate a hazard for the hole sand, 🌊, 🌲, 🏘️, etc
hazard = random.choice(["🏖️", "🌊", "🌲", "🏘️"])
hasHazard = True
# Set initial parameters before starting a hole
distance_remaining = hole_length
hole_shots = 0
# save player's current game state
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
golfTracker[i]['distance_remaining'] = distance_remaining
golfTracker[i]['cmd'] = 'stroking'
golfTracker[i]['par'] = par
golfTracker[i]['total_strokes'] = total_strokes
golfTracker[i]['total_to_par'] = total_to_par
golfTracker[i]['hazard'] = hazard
golfTracker[i]['hole'] = hole
golfTracker[i]['last_played'] = time.time()
golfTracker[i]['hole_shots'] = hole_shots
# Show player the hole information
msg += "⛳️#" + str(hole) + " is a " + str(hole_length) + "-yard Par " + str(par) + "."
if hasHazard:
msg += "⚠️" + hazard + "."
else:
# add weather conditions with random choice from list, this is fluff
msg += random.choice(["☀️", "💨", "☀️", "☀️", "⛅️", "☁️", "☀️"])
if not finishedHole:
msg += f"\nChoose your club."
return msg
if last_cmd == 'stroking':
# Get player's current game state
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
distance_remaining = golfTracker[i]['distance_remaining']
hole = golfTracker[i]['hole']
hole_shots = golfTracker[i]['hole_shots']
par = golfTracker[i]['par']
total_strokes = golfTracker[i]['total_strokes']
total_to_par = golfTracker[i]['total_to_par']
hazard = golfTracker[i]['hazard']
# Start loop to be able to choose clubs while at least 20 yards away
if distance_remaining >= 20:
msg = ""
club = message.lower()
shot_distance = 0
pin_distance = distance_remaining
if club == "driver" or club.startswith("d"):
shot_distance = hit_driver()
msg += "🏌Hit D " + str(shot_distance) + "yd. "
distance_remaining = abs(distance_remaining - shot_distance)
hole_shots += 1
elif "low" in club or club.startswith("l"):
shot_distance = hit_low_iron()
msg += "🏌Hit L Iron " + str(shot_distance) + "yd. "
distance_remaining = abs(distance_remaining - shot_distance)
hole_shots += 1
elif "mid" in club or club.startswith("m"):
shot_distance = hit_mid_iron()
msg += "🏌Hit M Iron " + str(shot_distance) + "yd. "
distance_remaining = abs(distance_remaining - shot_distance)
hole_shots += 1
elif "high" in club or club.startswith("h"):
shot_distance = hit_high_iron()
msg += "🏌Hit H Iron " + str(shot_distance) + "yd. "
distance_remaining = abs(distance_remaining - shot_distance)
hole_shots += 1
elif "gap" in club or club.startswith("g"):
shot_distance = hit_gap_wedge()
msg += "🏌Hit G Wedge " + str(shot_distance) + "yd ."
distance_remaining = abs(distance_remaining - shot_distance)
hole_shots += 1
elif "wedge" in club or club.startswith("w"):
shot_distance = hit_lob_wedge()
msg += "🏌Hit L Wedge " + str(shot_distance) + "yd. "
distance_remaining = abs(distance_remaining - shot_distance)
hole_shots += 1
elif club == "caddy" or club.startswith("c"):
# Show player the club distances
msg += f"Caddy Guess:\nD:{hit_driver()} L:{hit_low_iron()} M:{hit_mid_iron()} H:{hit_high_iron()} G:{hit_gap_wedge()} W:{hit_lob_wedge()}"
else:
msg += "Didnt get your club 🥪♣️🪩 choice"
return msg
if distance_remaining - pin_distance > pin_distance or shot_distance > pin_distance:
# Check for over-shooting the hole
if distance_remaining > 20:
# did it go off the "green"?
msg += "Overshot the green!🚀"
if distance_remaining == 0:
msg += "🎯Perfect shot! "
last_cmd = 'putt'
elif distance_remaining < 20:
# Roll Dice
hole_in_one_chance = random.randint(1, 100)
wind_factor = random.randint(1, 10)
skill_factor = random.randint(1, 10)
critter_factor = random.randint(1, 50)
# Check for hole in one
if hole_in_one_chance <= 5 and wind_factor > 7 and skill_factor > 8:
distance_remaining = 0
# Check for critters
if skill_factor > 8 and critter_factor < 40 and wind_factor > 2 and hole_in_one_chance > 5:
msg += random.choice(["A 🐿️ steals your ball!😡 ","You Hit a 🦅 soring past ", "🐊 need we say more? ", "hit a 🪟 of a 🏡 "])
distance_remaining = -1
# Handle hazard
if hazard == "🌊" and skill_factor < 7:
msg += "In the water!🌊"
distance_remaining = -1
if hazard == "🏖️" and skill_factor < 5:
msg += "In the sand!🏖️"
distance_remaining = random.randint(5, 10)
if hazard == "🌲" and skill_factor < 3:
msg += "In the trees!🌲"
distance_remaining += random.randint(5, 20)
if hazard == "🏘️" and skill_factor < 2:
msg += "In the parking lot!🚗"
distance_remaining += random.randint(10, 30)
# Check we didnt go off the green or into a hazard
if distance_remaining < 20:
last_cmd = 'putt'
else:
last_cmd = 'stroking'
else:
msg += "\nYou have " + str(distance_remaining) + "yd. ⛳️"
msg += "\nClub?[D, L, M, H, G, W]🏌️"
# save player's current game state, keep stroking
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
golfTracker[i]['distance_remaining'] = distance_remaining
golfTracker[i]['hole_shots'] = hole_shots
golfTracker[i]['total_strokes'] = total_strokes
golfTracker[i]['cmd'] = 'stroking'
return msg
if last_cmd == 'putt':
# Finish the hole by putting
critter = False
if distance_remaining < 20:
if distance_remaining == 0:
putts = 0
elif distance_remaining == -1:
putts = 0
critter = True
else:
putts = finish_hole()
# Calculate hole and round scores
hole_strokes = hole_shots + putts
hole_to_par = hole_strokes - par
total_strokes += hole_strokes
total_to_par += hole_to_par
if not critter:
# Show player hole/round scoring info
if putts == 0 and hole_strokes == 1:
msg += "🎯Hole in one!⛳️"
elif putts == 0:
msg += "You're in the hole at " + str(hole_strokes) + " strokes!"
else:
msg += "You're on the green! After " + str(putts) + " putt(s), you're in for " + str(hole_strokes) + " strokes."
msg += getScorecardGolf(hole_to_par)
if hole not in [1, 10]:
# Show player total scoring info for the round, except hole 1 and 10
msg += "\nYou've hit a total of " + str(total_strokes) + " strokes today, for"
msg += getScorecardGolf(total_to_par)
# Move to next hole
hole += 1
else:
msg += f"Got a new ball at Pro-Shop, marshal put you @" # flow into same hole haha
# Scorecard reset
hole_to_par = 0
total_to_par = 0
hole_strokes = 0
hole_shots = 0
# Save player's current game state
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
golfTracker[i]['hole_strokes'] = hole_strokes
golfTracker[i]['hole_to_par'] = hole_to_par
golfTracker[i]['total_strokes'] = total_strokes
golfTracker[i]['total_to_par'] = total_to_par
golfTracker[i]['hole'] = hole
golfTracker[i]['cmd'] = 'new'
golfTracker[i]['last_played'] = time.time()
if hole >= 9:
# Final score messages & exit prompt
msg += f"🎉Finished 9-hole round⛳"
#HighScore Display
highscore = getHighScoreGolf(nodeID, total_strokes, total_to_par)
if highscore != 0:
msg += "\n🏆New Club Record🏆"
# pop player from tracker
for i in range(len(golfTracker)):
if golfTracker[i]['nodeID'] == nodeID:
golfTracker.pop(i)
logger.debug("System: GolfSim: Player " + str(nodeID) + " has finished their round.")
else:
# Show player the next hole
msg += playGolf(nodeID, 'new', True)
msg += "\n🏌️[D, L, M, H, G, W, End]🏌️"
return msg

341
modules/mmind.py Normal file
View File

@@ -0,0 +1,341 @@
# https://github.com/pwdkramer/pythonMastermind/blob/main/main.py
# Adapted for Meshtastic mesh-bot by K7MHI Kelly Keeton 2024
import random
import time
import pickle
from modules.log import *
mindTracker = [{'nodeID': 0, 'last_played': time.time(), 'cmd': '', 'secret_code': '', 'diff': 'n', 'turns': 1}]
def chooseDifficultyMMind(message):
usrInput = message.lower()
msg = ''
valid_colorsMMind = "RYGB"
if not usrInput.startswith("n") and not usrInput.startswith("h") and not usrInput.startswith("x"):
# default to normal difficulty
usrInput = "n"
if usrInput == "n":
msg += f"The colors to choose from are:\nR🔴, Y🟡, G🟢, B🔵"
elif usrInput == "h":
valid_colorsMMind += "OP"
msg += f"The colors to choose from are\nR🔴, Y🟡, G🟢, B🔵, O🟠, P🟣"
elif usrInput == "x":
valid_colorsMMind += "OPWK"
msg += f"The colors to choose from are\nR🔴, Y🟡, G🟢, B🔵, O🟠, P🟣, W⚪, K⚫"
return msg
#possible colors on nomral: Red, Yellow, Green, Blue
#added colors on hard: Orange, Purple
def makeCodeMMind(diff):
secret_code = ""
for i in range(4):
if diff == "n":
roll = random.randrange(1, 5)
elif diff == "h":
roll = random.randrange(1,7)
elif diff == "x":
roll = random.randrange(1,9)
else:
print("Difficulty error in makeCode()")
if roll == 1:
secret_code += "R"
elif roll == 2:
secret_code += "Y"
elif roll == 3:
secret_code += "G"
elif roll == 4:
secret_code += "B"
elif roll == 5:
secret_code += "O"
elif roll == 6:
secret_code += "P"
elif roll == 7:
secret_code += "W"
elif roll == 8:
secret_code += "K"
else:
print("Error with range of roll in makeCode()")
return secret_code
#get guess from user
def getGuessMMind(diff, guess):
msg = ''
if diff == "n":
valid_colorsMMind = "RYGB"
elif diff == "h":
valid_colorsMMind = "RYGBOP"
elif diff == "x":
valid_colorsMMind = "RYGBOPWK"
user_guess = guess.upper()
valid_guess = True
if len(user_guess) != 4:
valid_guess = False
for i in range(len(user_guess)):
if user_guess[i] not in valid_colorsMMind:
valid_guess = False
if valid_guess == False:
user_guess = "XXXX"
return user_guess
def getHighScoreMMind(nodeID, turns, diff):
# check if player is in high score list and pick the lowest score
try:
with open('mmind_hs.pkl', 'rb') as f:
mindHighScore = pickle.load(f)
except:
logger.debug("System: MasterMind: High Score file not found.")
mindHighScore = [{'nodeID': nodeID, 'turns': turns, 'diff': diff}]
with open('mmind_hs.pkl', 'wb') as f:
pickle.dump(mindHighScore, f)
if nodeID == 0:
# just return the high score
return mindHighScore
# calculate lowest score
lowest_score = mindHighScore[0]['turns']
if mindHighScore[0]['diff'] == "n" and diff == "n":
if lowest_score > turns:
# update the high score for normal if new score is lower
mindHighScore[0]['nodeID'] = nodeID
mindHighScore[0]['turns'] = turns
mindHighScore[0]['diff'] = diff
# write new high score to file
with open('mmind_hs.pkl', 'wb') as f:
pickle.dump(mindHighScore, f)
return mindHighScore
elif mindHighScore[0]['diff'] == "n" and diff == "h":
# update the high score for hard if normal is the only high score
mindHighScore[0]['nodeID'] = nodeID
mindHighScore[0]['turns'] = turns
mindHighScore[0]['diff'] = diff
# write new high score to file
with open('mmind_hs.pkl', 'wb') as f:
pickle.dump(mindHighScore, f)
return mindHighScore
elif mindHighScore[0]['diff'] == "h" and diff == "h":
if lowest_score > turns:
# update the high score for hard if new score is lower
mindHighScore[0]['nodeID'] = nodeID
mindHighScore[0]['turns'] = turns
mindHighScore[0]['diff'] = diff
# write new high score to file
with open('mmind_hs.pkl', 'wb') as f:
pickle.dump(mindHighScore, f)
return mindHighScore
elif mindHighScore[0]['diff'] == "n" or mindHighScore[0]['diff'] == "h" and diff == "x":
# update the high score for expert if normal or high is the only high score
mindHighScore[0]['nodeID'] = nodeID
mindHighScore[0]['turns'] = turns
mindHighScore[0]['diff'] = diff
# write new high score to file
with open('mmind_hs.pkl', 'wb') as f:
pickle.dump(mindHighScore, f)
return mindHighScore
elif mindHighScore[0]['diff'] == "x" and diff == "x":
if lowest_score > turns:
# update the high score for expert if new score is lower
mindHighScore[0]['nodeID'] = nodeID
mindHighScore[0]['turns'] = turns
mindHighScore[0]['diff'] = diff
# write new high score to file
with open('mmind_hs.pkl', 'wb') as f:
pickle.dump(mindHighScore, f)
return mindHighScore
return 0
def getEmojiMMind(secret_code):
# for each letter in the secret code, convert to emoji for display
secret_code = secret_code.upper()
secret_code_emoji = ""
for i in range(len(secret_code)):
if secret_code[i] == "R":
secret_code_emoji += "🔴"
elif secret_code[i] == "Y":
secret_code_emoji += "🟡"
elif secret_code[i] == "G":
secret_code_emoji += "🟢"
elif secret_code[i] == "B":
secret_code_emoji += "🔵"
elif secret_code[i] == "O":
secret_code_emoji += "🟠"
elif secret_code[i] == "P":
secret_code_emoji += "🟣"
elif secret_code[i] == "W":
secret_code_emoji += ""
elif secret_code[i] == "K":
secret_code_emoji += ""
elif secret_code[i] == "X":
secret_code_emoji += ""
return secret_code_emoji
#compare userGuess with secret code and provide feedback
def compareCodeMMind(secret_code, user_guess):
game_won = False
perfect_pins = 0
wrong_position = 0
msg = ''
#logger.debug("System: MasterMind: secret_code: " + str(secret_code) + " user_guess: " + str(user_guess))
if secret_code == user_guess: #correct guess, user wins
perfect_pins = 4
game_won = True
else:
# check for perfect pins and right color wrong position
temp_code = []
temp_guess = []
for i in range(len(user_guess)): #check for perfect pins
if user_guess[i] == secret_code[i]:
perfect_pins += 1
else:
temp_code.append(secret_code[i])
temp_guess.append(user_guess[i])
for i in range(len(temp_guess)): #check for right color wrong position
for j in range(len(temp_code)):
if temp_guess[i] == temp_code[j]:
wrong_position += 1
temp_code[j] = "0"
break
# display feedback
if game_won:
msg += f"Correct{getEmojiMMind(user_guess)}\n"
else:
msg += f"Guess{getEmojiMMind(user_guess)}\n"
if perfect_pins > 0 and game_won == False:
msg += "✅ color ✅ position: {}".format(perfect_pins)
if wrong_position > 0:
if "" in msg: msg += f"\n"
msg += "✅ color 🚫 position: {}".format(wrong_position)
if "" not in msg and game_won == False:
msg += "🚫No pins in your guess😿 are in the code!"
return msg
#game loop with turn counter
def playGameMMind(diff, secret_code, turn_count, nodeID, message):
msg = ''
won = False
if turn_count <= 10:
user_guess = getGuessMMind(diff, message)
if user_guess == "XXXX":
msg += "Invalid guess. Please enter 4 valid colors."
return msg
check_guess = compareCodeMMind(secret_code, user_guess)
# display turn count and feedback
msg += "Turn {}:".format(turn_count)
if check_guess.startswith("Correct"):
won = True
msg += check_guess
if won == True:
msg += f"\n🎉🧠 you win 🥷🤯"
# get high score
high_score = getHighScoreMMind(nodeID, turn_count, diff)
if high_score != 0:
msg += f"\n🏆 High Score:{high_score[0]['turns']} turns, Difficulty:{high_score[0]['diff'].upper()}"
msg += "\nWould you like to play again?\n(N)ormal, (H)ard, e(X)pert?"
# reset turn count in tracker
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
mindTracker[i]['turns'] = 1
mindTracker[i]['secret_code'] = ''
mindTracker[i]['cmd'] = 'new'
else:
# increment turn count and keep playing
turn_count += 1
# store turn count in tracker
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
mindTracker[i]['turns'] = turn_count
elif won == False:
msg += f"🙉Game Over🙈\nThe code was: {getEmojiMMind(secret_code)}"
msg += "\nYou have run out of turns.😿"
msg += "\nWould you like to play again? (N)ormal, (H)ard, or e(X)pert?"
# reset turn count in tracker
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
mindTracker[i]['turns'] = 1
mindTracker[i]['secret_code'] = ''
mindTracker[i]['cmd'] = 'new'
return msg
def endGameMMind(nodeID):
global mindTracker
# remove player from tracker
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
del mindTracker[i]
logger.debug("System: MasterMind: Player removed: " + str(nodeID))
break
#main game
def start_mMind(nodeID, message):
global mindTracker
last_cmd = ""
msg = ''
# get player's last command from tracker if not new player
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
last_cmd = mindTracker[i]['cmd']
logger.debug("System: MasterMind: last_cmd: " + str(last_cmd))
if last_cmd == "new":
if message.lower().startswith("n") or message.lower().startswith("h") or message.lower().startswith("x"):
diff = message.lower()[0]
else:
diff = "n"
# set player's last command to makeCode
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
mindTracker[i]['cmd'] = 'makeCode'
mindTracker[i]['diff'] = diff
# Return color message to player
msg += chooseDifficultyMMind(message.lower()[0])
return msg
if last_cmd == "makeCode":
# get difficulty from tracker
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
diff = mindTracker[i]['diff']
secret_code = makeCodeMMind(diff)
last_cmd = "playGame"
# set player's last command to playGame
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
mindTracker[i]['cmd'] = 'playGame'
mindTracker[i]['secret_code'] = secret_code
mindTracker[i]['last_played'] = time.time()
if last_cmd == "playGame":
# get difficulty, secret code, and turn count from tracker
for i in range(len(mindTracker)):
if mindTracker[i]['nodeID'] == nodeID:
diff = mindTracker[i]['diff']
secret_code = mindTracker[i]['secret_code']
turn_count = mindTracker[i]['turns']
msg += playGameMMind(diff, secret_code, turn_count, nodeID=nodeID, message=message)
return msg

View File

@@ -155,6 +155,8 @@ try:
lemonade_enabled = config['games'].getboolean('lemonade', True)
blackjack_enabled = config['games'].getboolean('blackjack', True)
videoPoker_enabled = config['games'].getboolean('videoPoker', True)
mastermind_enabled = config['games'].getboolean('mastermind', True)
golfSim_enabled = config['games'].getboolean('golfSim', True)
# messaging settings
responseDelay = config['messagingSettings'].getfloat('responseDelay', 0.7) # default 0.7

View File

@@ -117,6 +117,16 @@ if videoPoker_enabled:
from modules.videopoker import * # from the spudgunman/meshing-around repo
trap_list = trap_list + ("videopoker",)
games_enabled = True
if mastermind_enabled:
from modules.mmind import * # from the spudgunman/meshing-around repo
trap_list = trap_list + ("mastermind",)
games_enabled = True
if golfSim_enabled:
from modules.golfsim import * # from the spudgunman/meshing-around repo
trap_list = trap_list + ("golfsim",)
games_enabled = True
# Games Configuration
if games_enabled is True:
@@ -125,15 +135,19 @@ if games_enabled is True:
gTnW_enabled = True
gamesCmdList = "Play via DM🕹 CMD: "
if dopewars_enabled:
gamesCmdList += "DopeWars, "
gamesCmdList += "dopeWars, "
if lemonade_enabled:
gamesCmdList += "LemonStand, "
gamesCmdList += "lemonStand, "
if gTnW_enabled:
trap_list = trap_list + ("globalthermonuclearwar",)
if blackjack_enabled:
gamesCmdList += "BlackJack, "
gamesCmdList += "blackJack, "
if videoPoker_enabled:
gamesCmdList += "VideoPoker, "
gamesCmdList += "videoPoker, "
if mastermind_enabled:
gamesCmdList += "masterMind, "
if golfSim_enabled:
gamesCmdList += "golfSim, "
gamesCmdList = gamesCmdList[:-2] # remove the last comma
else:
gamesCmdList = ""

View File

@@ -231,7 +231,6 @@ class PlayerVP:
if resetHand:
self.bankroll += self.bet_size * payoff[hand_name]
elif 2 in points_repeat: # find pair
logger.debug(f"System: VideoPoker: 235 self.bankroll: {self.bankroll} bet_size: {self.bet_size}")
hand_name = "Pair👯"
if resetHand:
self.bankroll += self.bet_size * payoff[hand_name]

View File

@@ -94,10 +94,20 @@ def get_wx_meteo(lat=0, lon=0, unit=0):
code_string = ""
if daily_weather_code[i] == 0:
code_string = "Clear sky"
elif daily_weather_code[i] == 1 or 2 or 3:
code_string = "Partly cloudy"
elif daily_weather_code[i] == 45 or 48:
elif daily_weather_code[i] == 1:
code_string = "Mostly Cloudy"
elif daily_weather_code[i] == 2:
code_string = "Partly Cloudy"
elif daily_weather_code[i] == 3:
code_string = "Overcast"
elif daily_weather_code[i] == 5:
code_string = "Haze"
elif daily_weather_code[i] == 10:
code_string = "Mist"
elif daily_weather_code[i] == 45:
code_string = "Fog"
elif daily_weather_code[i] == 48:
code_string = "Freezing Fog"
elif daily_weather_code[i] == 51:
code_string = "Drizzle: Light"
elif daily_weather_code[i] == 53:
@@ -126,6 +136,10 @@ def get_wx_meteo(lat=0, lon=0, unit=0):
code_string = "Snow: Heavy"
elif daily_weather_code[i] == 77:
code_string = "Snow Grains"
elif daily_weather_code[i] == 78:
code_string = "Ice Crystals"
elif daily_weather_code[i] == 79:
code_string = "Ice Pellets"
elif daily_weather_code[i] == 80:
code_string = "Rain showers: Slight"
elif daily_weather_code[i] == 81:
@@ -133,15 +147,17 @@ def get_wx_meteo(lat=0, lon=0, unit=0):
elif daily_weather_code[i] == 82:
code_string = "Rain showers: Heavy"
elif daily_weather_code[i] == 85:
code_string = "Snow showers: Light"
code_string = "Snow showers"
elif daily_weather_code[i] == 86:
code_string = "Snow showers: Moderate"
code_string = "Snow showers: Heavy"
elif daily_weather_code[i] == 95:
code_string = "Thunderstorm: Slight"
code_string = "Thunderstorm"
elif daily_weather_code[i] == 96:
code_string = "Thunderstorm: Moderate"
code_string = "Hailstorm"
elif daily_weather_code[i] == 97:
code_string = "Thunderstorm Heavy"
elif daily_weather_code[i] == 99:
code_string = "Thunderstorm: Heavy"
code_string = "Hailstorm Heavy"
weather_report += "Cond: " + code_string + ". "