Refactor bot server setup to use Waitress for production; fallback to Flask dev server for local development. Added timeout to HTTP requests in Fun and Test cogs. Improved error handling for missing environment variables. Enhanced secret key management in Flask app. Added request timeout configuration. Introduced new experimental features including user profile and balance cards, and a Tic-Tac-Toe game with Minimax AI. Addressed various database and security issues, and improved code quality across multiple files.
This commit is contained in:
@@ -1,90 +0,0 @@
|
||||
ticket
|
||||
jail (Mute)
|
||||
|
||||
### 1. **Games and Minigames**
|
||||
- **Text-based RPG**: Allow users to battle monsters, level up, and collect loot.
|
||||
- **Trivia**: Users can answer questions in various categories like movies, history, or general knowledge.
|
||||
- **Hangman, Tic-Tac-Toe, and Word Games**: Classic games with visual feedback using emojis.
|
||||
- **Coin Flip, Dice Roll, Rock-Paper-Scissors**: Simple yet fun games to settle bets.
|
||||
- **Roulette / Slots**: Casino-style games where users can win (or lose!) virtual currency.
|
||||
- **Adventure Games**: Story-driven choices where users select paths that influence outcomes.
|
||||
|
||||
### 2. **Economy System**
|
||||
- **Currency**: Earn coins or points by chatting, completing tasks, or winning games.
|
||||
- **Jobs**: Users can “work” jobs (e.g., doctor, hacker, miner) to earn currency.
|
||||
- **Shops**: Buy items like badges, roles, or even upgrades for minigames.
|
||||
- **Trading**: Allow users to trade items or currency with each other.
|
||||
- **Bank System**: Deposit or withdraw money to earn interest or protect against theft.
|
||||
|
||||
### 3. **Social Features**
|
||||
- **Profile Cards**: Show off user stats, badges, levels, and custom titles.
|
||||
- **Reputation and Karma**: Users can give each other points for positive interactions.
|
||||
- **Pet System**: Adopt virtual pets that can be trained, fed, and leveled up.
|
||||
- **Marriage or Friendship**: Allow users to "marry" or form friendships with others.
|
||||
- **User Stats Tracking**: Track things like messages sent, hours active, or games played.
|
||||
|
||||
### 4. **Leveling and Experience System**
|
||||
- **XP for Messages**: Users earn XP based on their activity in the server.
|
||||
- **Rank Roles**: Unlock new roles or titles as users level up.
|
||||
- **Leaderboards**: Display top users for XP, messages, or currency.
|
||||
- **Achievements**: Users earn badges or points for reaching milestones.
|
||||
|
||||
### 5. **Custom Commands**
|
||||
- **Random Meme or Joke**: Pull memes or jokes from popular APIs.
|
||||
- **Anime and Movie Information**: Pull information from APIs like MyAnimeList or IMDb.
|
||||
- **Image Manipulation**: Create fun images, like a user’s avatar in various frames or situations.
|
||||
- **Quote Generator**: Save memorable messages and recall them with a command.
|
||||
- **Insults / Compliments**: Light-hearted fun with random funny (and friendly) insults or compliments.
|
||||
|
||||
### 6. **Music and Sound Effects**
|
||||
- **Music Queueing and Playback**: Allow users to play music in voice channels.
|
||||
- **Soundboard**: Play sound effects when commands are triggered (like applause or laughter).
|
||||
- **DJ Commands**: Give advanced controls like bass boost, speed change, or filters.
|
||||
|
||||
### 7. **Notifications and Alerts**
|
||||
- **Birthday Reminders**: Keep track of user birthdays and announce them in the server.
|
||||
- **Reminders and Timers**: Users can set personal reminders that DM them later.
|
||||
- **Daily Rewards**: Encourage users to come back daily for bonuses in your economy system.
|
||||
- **Event Announcements**: Set up periodic reminders for server events.
|
||||
|
||||
### 8. **Mini Competitions and Challenges**
|
||||
- **Daily / Weekly Challenges**: Daily puzzles, word games, or math problems.
|
||||
- **Polls and Voting**: Let users vote on topics, and maybe even earn rewards for participating.
|
||||
- **Custom Leaderboards**: Create leaderboards for almost anything—XP, currency, reputation points, etc.
|
||||
- **Scavenger Hunts**: Have clues hidden in messages or require users to find hidden “items” around the server.
|
||||
|
||||
### 9. **Image and GIF Fun**
|
||||
- **Avatar Fusion**: Merge two users’ avatars to create a funny, blended image.
|
||||
- **Random Reaction GIFs**: Send GIFs for certain triggers or reactions, like “!slap” or “!hug.”
|
||||
- **Custom Frames**: Place avatars inside funny or themed frames (like a “wanted” poster).
|
||||
- **Color-Changing Roles**: Allow users to purchase role colors and dynamically update them.
|
||||
|
||||
### 10. **Learning and Educational Features**
|
||||
- **Word of the Day**: Share new vocabulary daily.
|
||||
- **Facts and Trivia**: Random facts or trivia about different topics like science or history.
|
||||
- **Language Translation**: Translate text to other languages on request.
|
||||
- **Quiz Mode**: Let users compete in quick quiz rounds.
|
||||
|
||||
### 11. **Community Interaction and Moderation**
|
||||
- **Anonymous Confessions**: Allow users to send anonymous messages to a specific channel.
|
||||
- **Polls and Feedback**: Use polls to gather community feedback.
|
||||
- **Reaction Roles**: Set up roles that users can self-assign by reacting to messages.
|
||||
- **Moderation Levels**: Give moderators points or levels for active contributions to the server.
|
||||
|
||||
### 12. **Miscellaneous Fun**
|
||||
- **Fortune Telling / Magic 8-Ball**: Answer user questions with fun responses.
|
||||
- **Horoscope**: Provide daily horoscopes based on the user’s zodiac sign.
|
||||
- **Fake Virus Prank**: A harmless "fake virus" message that freaks out the user momentarily.
|
||||
- **Custom Emote Creator**: Generate small emotes using user avatars or custom text.
|
||||
- **Virtual Marketplace**: Allow users to set up small shops and sell items to each other.
|
||||
|
||||
### 13. **Interactive Roleplay Features**
|
||||
- **Adventures and Storylines**: Create episodic adventures with options that affect the story.
|
||||
- **Character Sheets**: Track character stats for users, which they can upgrade over time.
|
||||
- **Combat System**: PvP or PvE combat system where users can fight with each other or NPCs.
|
||||
- **Collectibles**: Users can collect items, weapons, pets, etc., and trade them.
|
||||
|
||||
### 14. **Seasonal Events and Rewards**
|
||||
- **Seasonal Currency or Items**: Introduce limited-time items for holidays.
|
||||
- **Server-Wide Events**: Organize events like scavenger hunts, trivia contests, or tournaments.
|
||||
- **Exclusive Roles**: Give out special roles for participation in events.
|
||||
@@ -1,251 +0,0 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageOps
|
||||
import io
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
import requests
|
||||
from random import randint
|
||||
|
||||
# Bot setup
|
||||
load_dotenv()
|
||||
|
||||
TOKEN = os.getenv("TOKEN")
|
||||
intents = discord.Intents.all()
|
||||
|
||||
bot = commands.Bot(command_prefix="!?", intents=intents)
|
||||
|
||||
# Simple user data structure
|
||||
user_data = {}
|
||||
|
||||
|
||||
def get_user_data(user_id):
|
||||
"""Get or initialize user data."""
|
||||
if user_id not in user_data:
|
||||
user_data[user_id] = {"xp": 0, "level": 53}
|
||||
return user_data[user_id]
|
||||
|
||||
|
||||
import io
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
|
||||
async def create_profile_card(user, background_image_path):
|
||||
"""
|
||||
Create a profile card image for a user with a custom background and text overlay.
|
||||
|
||||
Args:
|
||||
user (discord.Member): The user whose profile card is being generated.
|
||||
background_image_path (str): Path to the background image.
|
||||
|
||||
Returns:
|
||||
io.BytesIO: A BytesIO object containing the profile card image.
|
||||
"""
|
||||
# Profile card dimensions
|
||||
card_width, card_height = 400, 200
|
||||
text_color = (255, 255, 255)
|
||||
progress_bar_color = (0, 255, 0)
|
||||
outline_color = (255, 255, 255)
|
||||
tint_color = (50, 50, 50)
|
||||
transparency = 25
|
||||
opacity = int(255 * transparency / 100)
|
||||
|
||||
# Load and resize the background image
|
||||
background_image = Image.open(background_image_path).resize((card_width, card_height))
|
||||
|
||||
# Create a new image with the background
|
||||
card_image = Image.new("RGBA", (card_width, card_height))
|
||||
card_image.paste(background_image, (0, 0))
|
||||
|
||||
# Create a semi-transparent overlay
|
||||
overlay = Image.new("RGBA", card_image.size, tint_color + (opacity,))
|
||||
card_image = Image.alpha_composite(card_image, overlay)
|
||||
|
||||
draw = ImageDraw.Draw(card_image)
|
||||
|
||||
# Load fonts
|
||||
font_path = "arial.ttf"
|
||||
font = ImageFont.truetype(font_path, 20)
|
||||
|
||||
# Draw user info
|
||||
draw.text((10, 10), f"User: {user.display_name}", fill=text_color, font=font)
|
||||
user_info = get_user_data(user.id)
|
||||
draw.text((10, 40), f"Level: {user_info['level']}", fill=text_color, font=font)
|
||||
draw.text((10, 70), f"XP: {user_info['xp']}/{user_info['level'] * 100}", fill=text_color, font=font)
|
||||
|
||||
# Draw the progress bar
|
||||
max_xp = user_info['level'] * 100
|
||||
progress_ratio = user_info['xp'] / max_xp if max_xp > 0 else 0
|
||||
progress_width = int(progress_ratio * 200)
|
||||
|
||||
draw.rectangle([(10, 100), (210, 120)], outline=outline_color, width=2)
|
||||
draw.rectangle([(10, 100), (10 + progress_width, 120)], fill=progress_bar_color)
|
||||
|
||||
# Draw the user's profile picture
|
||||
try:
|
||||
profile_size = 96
|
||||
margin = 30
|
||||
profile_picture_data = await user.avatar.read()
|
||||
profile_image = Image.open(io.BytesIO(profile_picture_data)).resize((profile_size, profile_size))
|
||||
card_image.paste(profile_image, (card_width - profile_size - margin, margin), profile_image.convert("RGBA"))
|
||||
except Exception as error:
|
||||
print(f"Error fetching profile picture: {error}")
|
||||
|
||||
# Save image to a BytesIO object
|
||||
image_bytes = io.BytesIO()
|
||||
card_image.save(image_bytes, format="PNG")
|
||||
image_bytes.seek(0)
|
||||
|
||||
return image_bytes
|
||||
|
||||
|
||||
async def create_balance_card(user, credits, tokens, bucks):
|
||||
# Card dimensions
|
||||
width, height = 450, 250
|
||||
card = Image.new("RGB", (width, height), (255, 255, 255))
|
||||
draw = ImageDraw.Draw(card)
|
||||
|
||||
# Gradient Background
|
||||
gradient_color_1 = (38, 0, 77) # Dark purple
|
||||
gradient_color_2 = (128, 0, 128) # Purple
|
||||
for y in range(height):
|
||||
blend = y / height
|
||||
r = int(gradient_color_1[0] * (1 - blend) + gradient_color_2[0] * blend)
|
||||
g = int(gradient_color_1[1] * (1 - blend) + gradient_color_2[1] * blend)
|
||||
b = int(gradient_color_1[2] * (1 - blend) + gradient_color_2[2] * blend)
|
||||
draw.line([(0, y), (width, y)], fill=(r, g, b))
|
||||
|
||||
# Avatar with circular border
|
||||
avatar_asset = user.avatar
|
||||
avatar_response = requests.get(avatar_asset)
|
||||
avatar = Image.open(io.BytesIO(avatar_response.content)).resize((60, 60))
|
||||
mask = Image.new("L", avatar.size, 0)
|
||||
ImageDraw.Draw(mask).ellipse((0, 0, 60, 60), fill=255)
|
||||
avatar = ImageOps.fit(avatar, mask.size, centering=(0.5, 0.5))
|
||||
avatar.putalpha(mask)
|
||||
|
||||
# Draw avatar circle background
|
||||
avatar_bg = Image.new("RGBA", (70, 70), (255, 255, 255, 0))
|
||||
draw_bg = ImageDraw.Draw(avatar_bg)
|
||||
draw_bg.ellipse((0, 0, 70, 70), fill=(255, 255, 255, 100)) # Border color
|
||||
|
||||
card.paste(avatar_bg, (20, height - 110), avatar_bg)
|
||||
card.paste(avatar, (25, height - 105), avatar)
|
||||
|
||||
# Fonts
|
||||
title_font = ImageFont.load_default()
|
||||
balance_font = ImageFont.load_default()
|
||||
|
||||
# Header Text
|
||||
draw.text((110, 20), "tatsu.", font=title_font, fill="white")
|
||||
draw.text((width - 90, 25), "Member", font=title_font, fill="white")
|
||||
|
||||
# Balance Background Box
|
||||
balance_box = (100, 70, width - 20, 200)
|
||||
draw.rounded_rectangle(balance_box, radius=15, fill=(255, 255, 255, 50))
|
||||
|
||||
# Balance Items
|
||||
icon_x = 120
|
||||
text_x = icon_x + 35
|
||||
|
||||
# Credits
|
||||
draw.ellipse((icon_x, 90, icon_x + 25, 115), fill=(255, 215, 0)) # Coin icon color
|
||||
draw.text((text_x, 90), f"{credits:,} Credits", font=balance_font, fill="black")
|
||||
|
||||
# Tokens
|
||||
draw.ellipse(
|
||||
(icon_x, 125, icon_x + 25, 150), fill=(0, 255, 127)
|
||||
) # Token icon color
|
||||
draw.text((text_x, 125), f"{tokens:,} Tokens", font=balance_font, fill="black")
|
||||
|
||||
# Bucks
|
||||
draw.ellipse(
|
||||
(icon_x, 160, icon_x + 25, 185), fill=(50, 205, 50)
|
||||
) # Bucks icon color
|
||||
draw.text((text_x, 160), f"{bucks:,} Guild Bucks", font=balance_font, fill="black")
|
||||
|
||||
# User tag
|
||||
user_tag = f"{user.name}#{user.discriminator}"
|
||||
draw.text((110, height - 35), user_tag, font=title_font, fill="white")
|
||||
|
||||
# Add Chip (Credit Card Style)
|
||||
chip_width, chip_height = 50, 35
|
||||
chip_x = width - 80
|
||||
chip_y = 100
|
||||
draw.rectangle(
|
||||
[chip_x, chip_y, chip_x + chip_width, chip_y + chip_height],
|
||||
fill=(192, 192, 192), # Light gray color for the chip
|
||||
outline="white",
|
||||
width=2,
|
||||
)
|
||||
|
||||
# Chip lines for texture
|
||||
line_spacing = 7
|
||||
for i in range(1, chip_height // line_spacing):
|
||||
y = chip_y + i * line_spacing
|
||||
draw.line(
|
||||
[(chip_x + 5, y), (chip_x + chip_width - 5, y)], fill="white", width=1
|
||||
)
|
||||
|
||||
# Save to a BytesIO object to send on Discord
|
||||
with io.BytesIO() as image_binary:
|
||||
card.save(image_binary, "PNG")
|
||||
image_binary.seek(0)
|
||||
return discord.File(fp=image_binary, filename="balance_card.png")
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
if bot.user is not None:
|
||||
print(f"Logged in as {bot.user.name}")
|
||||
else:
|
||||
print(f"Logged in")
|
||||
|
||||
|
||||
@bot.command(name="profile")
|
||||
async def profile(ctx):
|
||||
"""Command to display user profile."""
|
||||
user = ctx.author
|
||||
user_info = get_user_data(user.id)
|
||||
|
||||
# Create profile card image
|
||||
profile_image = create_profile_card(user, f"images/image_{randint(1,100)}.jpg")
|
||||
|
||||
# Send the image in the channel
|
||||
await ctx.send(file=discord.File(await profile_image, "profile.png"))
|
||||
|
||||
|
||||
@bot.command()
|
||||
async def balance(ctx):
|
||||
user = ctx.author
|
||||
# Example balance data; replace with actual data retrieval
|
||||
|
||||
credits = 9493006
|
||||
tokens = 58
|
||||
bucks = 234328
|
||||
|
||||
file = await create_balance_card(user, credits, tokens, bucks)
|
||||
await ctx.send(file=file)
|
||||
|
||||
|
||||
# Example command to add XP for testing
|
||||
@bot.command(name="addxp")
|
||||
async def add_xp(ctx, amount: int):
|
||||
"""Command to add XP for testing."""
|
||||
user_info = get_user_data(ctx.author.id)
|
||||
user_info["xp"] += amount
|
||||
|
||||
# Level up logic (example: every 100 XP earns a level)
|
||||
if user_info["xp"] >= user_info["level"] * 100:
|
||||
user_info["level"] += 1
|
||||
user_info["xp"] = 0 # Reset XP after leveling up
|
||||
|
||||
await ctx.send(
|
||||
f"Added {amount} XP to {ctx.author.mention}. Total XP: {user_info['xp']} | Level: {user_info['level']}"
|
||||
)
|
||||
|
||||
|
||||
if TOKEN is not None:
|
||||
bot.run(TOKEN)
|
||||
else:
|
||||
print(f"{TOKEN=}")
|
||||
@@ -1,62 +0,0 @@
|
||||
import random
|
||||
|
||||
|
||||
class User:
|
||||
def __init__(self, xp_formula, level_formula):
|
||||
self.level = 1
|
||||
self.xp = 0
|
||||
self.xp_to_next_level = xp_formula(
|
||||
self.level
|
||||
) # XP needed to reach the next level
|
||||
self.xp_formula = xp_formula
|
||||
self.level_formula = level_formula
|
||||
|
||||
def earn_xp(self, amount):
|
||||
self.xp += amount
|
||||
print(f"You earned {amount} XP! Total XP: {self.xp}")
|
||||
|
||||
# Check for level up
|
||||
while self.xp >= self.xp_to_next_level:
|
||||
self.level_up()
|
||||
|
||||
def level_up(self):
|
||||
self.xp -= self.xp_to_next_level
|
||||
self.level += 1
|
||||
self.xp_to_next_level = self.xp_formula(
|
||||
self.level
|
||||
) # Calculate next level requirement
|
||||
print(
|
||||
f"Congratulations! You've reached Level {self.level}! XP to next level: {self.xp_to_next_level}"
|
||||
)
|
||||
|
||||
|
||||
def simulate_xp_gain(user, num_messages, xp_per_message):
|
||||
for _ in range(num_messages):
|
||||
user.earn_xp(xp_per_message())
|
||||
|
||||
|
||||
def main():
|
||||
# Define your formulas here
|
||||
def xp_formula(level):
|
||||
return int(100 * (1.5 ** (level - 1))) # Example: 100, 150, 225, 338, ...
|
||||
|
||||
def random_xp_per_message():
|
||||
return random.randint(1, 5) # Random XP between 1 and 10
|
||||
|
||||
user = User(xp_formula, random_xp_per_message)
|
||||
|
||||
while True:
|
||||
num_messages = input("Enter the number of messages (or 'quit' to exit): ")
|
||||
|
||||
if num_messages.lower() == "quit":
|
||||
break
|
||||
|
||||
if num_messages.isdigit():
|
||||
num_messages = int(num_messages)
|
||||
simulate_xp_gain(user, num_messages, random_xp_per_message)
|
||||
else:
|
||||
print("Please enter a valid number.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,36 +0,0 @@
|
||||
import requests
|
||||
import os
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
from random import shuffle
|
||||
|
||||
# Step 1: Fetch JSON data from the URL
|
||||
url = "https://picsum.photos/v2/list?limit=1000"
|
||||
response = requests.get(url)
|
||||
data = response.json()
|
||||
|
||||
# Step 2: Extract image download links
|
||||
image_urls = [item["download_url"] for item in data]
|
||||
|
||||
shuffle(image_urls)
|
||||
# Step 3: Create a directory to save images
|
||||
os.makedirs("images", exist_ok=True)
|
||||
|
||||
# Desired size for resizing
|
||||
desired_size = (450, 250)
|
||||
|
||||
# Step 4: Download and resize each image
|
||||
for i, image_url in enumerate(image_urls):
|
||||
img_response = requests.get(image_url)
|
||||
if img_response.status_code == 200:
|
||||
# Open image from response content
|
||||
img = Image.open(BytesIO(img_response.content))
|
||||
# Resize the image
|
||||
img = img.resize(desired_size, Image.Resampling.LANCZOS)
|
||||
# Save the resized image
|
||||
img.save(f"images/image_{17}.jpg")
|
||||
print(f"Downloaded and resized: image_{17}.jpg")
|
||||
else:
|
||||
print(f"Failed to download image from {image_url}")
|
||||
if input() !="":
|
||||
break
|
||||
@@ -1,30 +0,0 @@
|
||||
from minimax import aiO, aiX, Terminal, Value
|
||||
# from player import player
|
||||
|
||||
|
||||
def display_board(board):
|
||||
print('-------------')
|
||||
for row in [board[i:i + 3] for i in range(0, 9, 3)]:
|
||||
print(f'| {row[0]} | {row[1]} | {row[2]} |')
|
||||
print('-------------')
|
||||
|
||||
def main():
|
||||
results = []
|
||||
while True:
|
||||
board = [" " for _ in range(9)]
|
||||
# board = ['O', 'X', 'O','O', 'X', 'X',' ', ' ', 'X']
|
||||
display_board(board)
|
||||
while True:
|
||||
board[aiX(board)] = "X"
|
||||
display_board(board)
|
||||
if Terminal(board):
|
||||
break
|
||||
board[aiO(board)] = "O"
|
||||
display_board(board)
|
||||
if Terminal(board):
|
||||
break
|
||||
results.append(Value(board))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,93 +0,0 @@
|
||||
import random
|
||||
|
||||
win_states = [
|
||||
(0, 1, 2), (3, 4, 5), (6, 7, 8), # horizontal
|
||||
(0, 3, 6), (1, 4, 7), (2, 5, 8), # vertical
|
||||
(0, 4, 8), (2, 4, 6) # diagonal
|
||||
]
|
||||
|
||||
|
||||
def Terminal(state: list):
|
||||
for win_state in win_states:
|
||||
if all(state[i] == "O" for i in win_state) or all(state[i] == "X" for i in win_state):
|
||||
return True
|
||||
if state.count(" ") == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def Value(state):
|
||||
for win_state in win_states:
|
||||
if all(state[i] == "O" for i in win_state):
|
||||
return -1
|
||||
elif all(state[i] == "X" for i in win_state):
|
||||
return 1
|
||||
if state.count(" ") == 0:
|
||||
return 0
|
||||
|
||||
|
||||
def Player(state: list):
|
||||
if state.count("X") == state.count("O"):
|
||||
return "X"
|
||||
else:
|
||||
return "O"
|
||||
|
||||
|
||||
def Actions(state):
|
||||
indexes = []
|
||||
for i in range(9):
|
||||
if state[i] == " ":
|
||||
indexes.append(i)
|
||||
return indexes
|
||||
|
||||
|
||||
def Result(state, index, player):
|
||||
state[index] = player
|
||||
return state
|
||||
|
||||
|
||||
def Minimax(state):
|
||||
if Terminal(state):
|
||||
return Value(state)
|
||||
if Player(state) == "X":
|
||||
value = -9999
|
||||
for a in Actions(state):
|
||||
value = max(value, Minimax(Result(state.copy(), a, "X")))
|
||||
return value
|
||||
|
||||
elif Player(state) == "O":
|
||||
value = 9999
|
||||
for a in Actions(state):
|
||||
value = min(value, Minimax(Result(state.copy(), a, "O")))
|
||||
return value
|
||||
|
||||
|
||||
def aiO(state):
|
||||
best_score = float('inf')
|
||||
best_move = None
|
||||
for move in Actions(state):
|
||||
state[move] = 'O'
|
||||
score = Minimax(state)
|
||||
state[move] = ' '
|
||||
if score < best_score:
|
||||
best_score = score
|
||||
best_move = move
|
||||
return best_move
|
||||
|
||||
|
||||
def aiX(state):
|
||||
best_score = float('-inf')
|
||||
best_move = None
|
||||
for move in Actions(state):
|
||||
state[move] = 'X'
|
||||
score = Minimax(state)
|
||||
state[move] = ' '
|
||||
if score > best_score:
|
||||
best_score = score
|
||||
best_move = move
|
||||
return best_move
|
||||
|
||||
|
||||
def aiRandom(state):
|
||||
return random.choice(Actions(state))
|
||||
@@ -1,10 +0,0 @@
|
||||
from minimax import Actions
|
||||
|
||||
|
||||
def player(state):
|
||||
actions = Actions(state)
|
||||
choice = -1
|
||||
while choice not in actions:
|
||||
choice = int(input("Pick a spot between 1-9.> ")) - 1
|
||||
|
||||
return choice
|
||||
@@ -1,68 +0,0 @@
|
||||
from random import randint
|
||||
|
||||
"""def player(start_board):
|
||||
player_choice = input("Pick a place: ")
|
||||
if start_board.count(player_choice) == 1:
|
||||
start_board[start_board.index(player_choice)] = "X"
|
||||
else:
|
||||
player(start_board)"""
|
||||
|
||||
|
||||
def player(start_board):
|
||||
com_choice = str(randint(1, 9))
|
||||
if start_board.count(com_choice) == 1:
|
||||
start_board[start_board.index(com_choice)] = "X"
|
||||
else:
|
||||
player(start_board)
|
||||
|
||||
|
||||
def com(start_board):
|
||||
com_choice = str(randint(1, 9))
|
||||
if start_board.count(com_choice) == 1:
|
||||
start_board[start_board.index(com_choice)] = "O"
|
||||
else:
|
||||
com(start_board)
|
||||
|
||||
|
||||
def print_board(s_board):
|
||||
board = "".join(s_board)
|
||||
print(board)
|
||||
|
||||
|
||||
def check(s_b):
|
||||
if s_b[0] == s_b[2] == s_b[4] == 'X' or s_b[6] == s_b[8] == s_b[10] == 'X' or s_b[12] == s_b[14] == s_b[16] == 'X' \
|
||||
or s_b[0] == s_b[6] == s_b[12] == 'X' or s_b[2] == s_b[8] == s_b[14] == 'X' or s_b[4] == s_b[10] == s_b[16] \
|
||||
== 'X' or s_b[0] == s_b[8] == s_b[16] == 'X' or s_b[4] == s_b[8] == s_b[12] == 'X':
|
||||
print("you won")
|
||||
main()
|
||||
elif s_b[0] == s_b[2] == s_b[4] == 'O' or s_b[6] == s_b[8] == s_b[10] == 'O' or s_b[12] == s_b[14] == s_b[16] == 'O' \
|
||||
or s_b[0] == s_b[6] == s_b[12] == 'O' or s_b[2] == s_b[8] == s_b[14] == 'O' or s_b[4] == s_b[10] == s_b[16] \
|
||||
== 'O' or s_b[0] == s_b[8] == s_b[16] == 'O' or s_b[4] == s_b[8] == s_b[12] == 'O':
|
||||
print('computer won')
|
||||
print_board(s_b)
|
||||
main()
|
||||
|
||||
|
||||
def main():
|
||||
# main program
|
||||
start_board = ["1", "|", "2", "|", "3", "\n",
|
||||
"4", "|", "5", "|", "6", "\n",
|
||||
"7", "|", "8", "|", "9", "\n", ]
|
||||
print_board(start_board)
|
||||
while 1:
|
||||
try:
|
||||
player(start_board)
|
||||
check(start_board)
|
||||
|
||||
com(start_board)
|
||||
check(start_board)
|
||||
|
||||
print_board(start_board)
|
||||
except RecursionError:
|
||||
print_board(start_board)
|
||||
print("draw")
|
||||
main()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user