3 display options - coloured text, coloured background and emojis
This commit is contained in:
parent
cf288b348d
commit
24112abebb
37
colours.py
37
colours.py
|
|
@ -1,8 +1,10 @@
|
||||||
# SGR color constants
|
# SGR color constants
|
||||||
# rene-d 2018
|
# rene-d 2018, modified 2025 for background support
|
||||||
|
|
||||||
class Colours:
|
class Colours:
|
||||||
""" ANSI color codes """
|
""" ANSI color codes """
|
||||||
|
|
||||||
|
# Foreground colours
|
||||||
BLACK = "\033[0;30m"
|
BLACK = "\033[0;30m"
|
||||||
RED = "\033[0;31m"
|
RED = "\033[0;31m"
|
||||||
GREEN = "\033[0;32m"
|
GREEN = "\033[0;32m"
|
||||||
|
|
@ -19,6 +21,26 @@ class Colours:
|
||||||
LIGHT_PURPLE = "\033[1;35m"
|
LIGHT_PURPLE = "\033[1;35m"
|
||||||
LIGHT_CYAN = "\033[1;36m"
|
LIGHT_CYAN = "\033[1;36m"
|
||||||
LIGHT_WHITE = "\033[1;37m"
|
LIGHT_WHITE = "\033[1;37m"
|
||||||
|
|
||||||
|
# Background colours
|
||||||
|
BG_BLACK = "\033[40m"
|
||||||
|
BG_RED = "\033[41m"
|
||||||
|
BG_GREEN = "\033[42m"
|
||||||
|
BG_YELLOW = "\033[43m"
|
||||||
|
BG_BLUE = "\033[44m"
|
||||||
|
BG_PURPLE = "\033[45m"
|
||||||
|
BG_CYAN = "\033[46m"
|
||||||
|
BG_LIGHT_GRAY = "\033[47m"
|
||||||
|
BG_DARK_GRAY = "\033[100m"
|
||||||
|
BG_LIGHT_RED = "\033[101m"
|
||||||
|
BG_LIGHT_GREEN = "\033[102m"
|
||||||
|
BG_LIGHT_YELLOW = "\033[103m"
|
||||||
|
BG_LIGHT_BLUE = "\033[104m"
|
||||||
|
BG_LIGHT_PURPLE = "\033[105m"
|
||||||
|
BG_LIGHT_CYAN = "\033[106m"
|
||||||
|
BG_WHITE = "\033[107m"
|
||||||
|
|
||||||
|
# Styles
|
||||||
BOLD = "\033[1m"
|
BOLD = "\033[1m"
|
||||||
FAINT = "\033[2m"
|
FAINT = "\033[2m"
|
||||||
ITALIC = "\033[3m"
|
ITALIC = "\033[3m"
|
||||||
|
|
@ -27,15 +49,16 @@ class Colours:
|
||||||
NEGATIVE = "\033[7m"
|
NEGATIVE = "\033[7m"
|
||||||
CROSSED = "\033[9m"
|
CROSSED = "\033[9m"
|
||||||
END = "\033[0m"
|
END = "\033[0m"
|
||||||
# cancel SGR codes if we don't write to a terminal
|
|
||||||
if not __import__("sys").stdout.isatty():
|
# Cancel codes if not in a TTY
|
||||||
|
import sys, platform, ctypes
|
||||||
|
if not sys.stdout.isatty():
|
||||||
for _ in dir():
|
for _ in dir():
|
||||||
if isinstance(_, str) and _[0] != "_":
|
if isinstance(_, str) and _[0] != "_":
|
||||||
locals()[_] = ""
|
locals()[_] = ""
|
||||||
else:
|
else:
|
||||||
# set Windows console in VT mode
|
if platform.system() == "Windows":
|
||||||
if __import__("platform").system() == "Windows":
|
kernel32 = ctypes.windll.kernel32
|
||||||
kernel32 = __import__("ctypes").windll.kernel32
|
|
||||||
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
||||||
del kernel32
|
del kernel32
|
||||||
|
|
||||||
|
|
@ -43,4 +66,4 @@ class Colours:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
for i in dir(Colours):
|
for i in dir(Colours):
|
||||||
if i[0:1] != "_" and i != "END":
|
if i[0:1] != "_" and i != "END":
|
||||||
print("{:>16} {}".format(i, getattr(Colours, i) + i + Colours.END))
|
print("{:>20} {}".format(i, getattr(Colours, i) + i + Colours.END))
|
||||||
|
|
|
||||||
156
main.py
156
main.py
|
|
@ -1,42 +1,91 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from copy import deepcopy
|
|
||||||
from colours import Colours as C
|
from colours import Colours as C
|
||||||
import random
|
import random
|
||||||
import time
|
import json
|
||||||
|
|
||||||
# ===========================
|
# ===========================
|
||||||
# | Helper functions |
|
# | Helper functions |
|
||||||
# ===========================
|
# ===========================
|
||||||
|
|
||||||
def clear():
|
def clear():
|
||||||
os.system('cls' if sys.platform.startswith('win') else 'clear')
|
os.system('cls' if sys.platform.startswith('win') else 'clear')
|
||||||
|
|
||||||
def colourTile(tile):
|
def colourTile(tile):
|
||||||
|
try:
|
||||||
|
with open("settings.json", "r") as f:
|
||||||
|
settings = json.load(f)
|
||||||
|
mode = settings.get("display_mode", "coloured_text")
|
||||||
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
|
mode = "coloured_text"
|
||||||
|
|
||||||
|
if mode == "coloured_text":
|
||||||
if tile == 'R':
|
if tile == 'R':
|
||||||
return f"{C.BOLD}{C.RED}R{C.END}"
|
return f"{C.BOLD}{C.RED} R {C.END}"
|
||||||
elif tile == 'Y':
|
elif tile == 'Y':
|
||||||
return f"{C.BOLD}{C.YELLOW}Y{C.END}"
|
return f"{C.BOLD}{C.YELLOW} Y {C.END}"
|
||||||
elif tile == 'r':
|
elif tile == 'r':
|
||||||
return f"{C.BOLD}{C.LIGHT_GREEN}R{C.END}"
|
return f"{C.BOLD}{C.LIGHT_GREEN} R {C.END}"
|
||||||
elif tile == 'y':
|
elif tile == 'y':
|
||||||
return f"{C.BOLD}{C.LIGHT_GREEN}Y{C.END}"
|
return f"{C.BOLD}{C.LIGHT_GREEN} Y {C.END}"
|
||||||
else:
|
else:
|
||||||
return "O"
|
return " O "
|
||||||
|
|
||||||
|
elif mode == "coloured_background":
|
||||||
|
if tile == 'R':
|
||||||
|
return f"{C.BG_RED} {C.END}"
|
||||||
|
elif tile == 'Y':
|
||||||
|
return f"{C.BG_LIGHT_YELLOW} {C.END}"
|
||||||
|
elif tile == 'r':
|
||||||
|
return f"{C.BG_LIGHT_GREEN}{C.BOLD} R {C.END}"
|
||||||
|
elif tile == 'y':
|
||||||
|
return f"{C.BG_LIGHT_GREEN}{C.BOLD} Y {C.END}"
|
||||||
|
else:
|
||||||
|
return " "
|
||||||
|
|
||||||
|
elif mode == "emojis":
|
||||||
|
if tile.lower() == 'r':
|
||||||
|
return "🔴"
|
||||||
|
elif tile.lower() == 'y':
|
||||||
|
return "🟡"
|
||||||
|
else:
|
||||||
|
return "⚪"
|
||||||
|
|
||||||
|
return tile
|
||||||
|
|
||||||
def printBoard(board):
|
def printBoard(board):
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("settings.json", "r") as f:
|
||||||
|
settings = json.load(f)
|
||||||
|
mode = settings.get("display_mode", "coloured_text")
|
||||||
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
|
mode = "coloured_text"
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
for i in range(6):
|
for i in range(6):
|
||||||
row = ""
|
row = ""
|
||||||
for column in board:
|
for column in board:
|
||||||
row += f"{C.BOLD}| {C.END}" + colourTile(column[i]) + " "
|
row += f"{C.BOLD}|{C.END}{colourTile(column[i])}"
|
||||||
row += f"{C.BOLD}|{C.END}"
|
row += f"{C.BOLD}|{C.END}"
|
||||||
rows.append(row)
|
rows.append(row)
|
||||||
rows.reverse()
|
rows.reverse()
|
||||||
|
|
||||||
print(f""" {C.BOLD}CONNECT FOUR
|
if mode == "emojis":
|
||||||
============================={C.END}
|
top = f""" {C.BOLD}CONNECT FOUR
|
||||||
{'\n'.join(rows)}
|
======================{C.END}"""
|
||||||
{C.BOLD}==1===2===3===4===5===6===7=={C.END}""")
|
bottom = f"{C.BOLD}==1==2==3==4==5==6==7=={C.END}"
|
||||||
|
else:
|
||||||
|
top = f""" {C.BOLD}CONNECT FOUR
|
||||||
|
============================={C.END}"""
|
||||||
|
bottom = f"{C.BOLD}==1===2===3===4===5===6===7=={C.END}"
|
||||||
|
|
||||||
|
# print(f""" {C.BOLD}CONNECT FOUR
|
||||||
|
# ============================={C.END}
|
||||||
|
# {'\n'.join(rows)}
|
||||||
|
# {C.BOLD}==1===2===3===4===5===6===7=={C.END}""")
|
||||||
|
print(f"{top}\n{'\n'.join(rows)}\n{bottom}")
|
||||||
|
|
||||||
|
|
||||||
def getIntInput(prompt, board=None):
|
def getIntInput(prompt, board=None):
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -326,12 +375,93 @@ def play_vs_computer():
|
||||||
# ===========================
|
# ===========================
|
||||||
# | Menu |
|
# | Menu |
|
||||||
# ===========================
|
# ===========================
|
||||||
|
|
||||||
|
def edit_settings():
|
||||||
|
settings_file = "settings.json"
|
||||||
|
|
||||||
|
# Default settings if no file exists
|
||||||
|
default_settings = {
|
||||||
|
"display_mode": "coloured_text" # options: coloured_text, coloured_background, emojis
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load existing settings
|
||||||
|
if os.path.exists(settings_file):
|
||||||
|
with open(settings_file, "r") as f:
|
||||||
|
try:
|
||||||
|
settings = json.load(f)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
settings = default_settings.copy()
|
||||||
|
else:
|
||||||
|
settings = default_settings.copy()
|
||||||
|
|
||||||
|
# Keep a copy for detecting unsaved changes
|
||||||
|
original_settings = settings.copy()
|
||||||
|
|
||||||
|
def save_settings():
|
||||||
|
with open(settings_file, "w") as f:
|
||||||
|
json.dump(settings, f, indent=4)
|
||||||
|
print("Settings saved.")
|
||||||
|
input("Press Enter to return to main menu...")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
clear()
|
||||||
|
print("=== Settings Menu ===")
|
||||||
|
print("1. Display Mode")
|
||||||
|
print("--------------------")
|
||||||
|
print("S. Save and Exit")
|
||||||
|
print("E. Exit without Saving")
|
||||||
|
print()
|
||||||
|
print(f"Current Settings: {settings}")
|
||||||
|
|
||||||
|
choice = input("Choose a setting to edit, or Save/Exit: ").strip().lower()
|
||||||
|
|
||||||
|
if choice == "1":
|
||||||
|
# Display Mode submenu
|
||||||
|
while True:
|
||||||
|
clear()
|
||||||
|
print("=== Display Mode ===")
|
||||||
|
modes = [
|
||||||
|
("coloured_text", "Coloured Text"),
|
||||||
|
("coloured_background", "Coloured Background"),
|
||||||
|
("emojis", "Emojis")
|
||||||
|
]
|
||||||
|
for i, (key, label) in enumerate(modes, start=1):
|
||||||
|
if settings["display_mode"] == key:
|
||||||
|
print(f"{i}. {C.BOLD}{label}{C.END}")
|
||||||
|
else:
|
||||||
|
print(f"{i}. {label}")
|
||||||
|
print("B. Go Back")
|
||||||
|
sub_choice = input("Choose a display mode: ").strip().lower()
|
||||||
|
if sub_choice == "b":
|
||||||
|
break
|
||||||
|
elif sub_choice in [str(i) for i in range(1, len(modes) + 1)]:
|
||||||
|
settings["display_mode"] = modes[int(sub_choice) - 1][0]
|
||||||
|
print(f"Display mode set to {settings['display_mode']}")
|
||||||
|
else:
|
||||||
|
input("Invalid choice. Press Enter to try again...")
|
||||||
|
|
||||||
|
elif choice == "save" or choice == "s":
|
||||||
|
save_settings()
|
||||||
|
return
|
||||||
|
|
||||||
|
elif choice == "exit" or choice == "e":
|
||||||
|
if settings != original_settings:
|
||||||
|
confirm = input("You have unsaved changes. Exit without saving? (y/n): ").lower()
|
||||||
|
if confirm == "y":
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
input("Invalid choice. Press Enter to try again...")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
clear()
|
clear()
|
||||||
print("How do you want to play?")
|
print("How do you want to play?")
|
||||||
print("1. PvP (same device)")
|
print("1. PvP (same device)")
|
||||||
print("2. PvP (LAN)")
|
print("2. PvP (LAN)")
|
||||||
print("3. PvC (vs computer)")
|
print("3. PvC (vs computer)")
|
||||||
|
print("4. Edit settings")
|
||||||
print("4. Quit")
|
print("4. Quit")
|
||||||
choice = input("Choose 1-4: ").strip()
|
choice = input("Choose 1-4: ").strip()
|
||||||
if choice == "1":
|
if choice == "1":
|
||||||
|
|
@ -344,6 +474,8 @@ while True:
|
||||||
elif choice == "3":
|
elif choice == "3":
|
||||||
play_vs_computer()
|
play_vs_computer()
|
||||||
elif choice == "4":
|
elif choice == "4":
|
||||||
|
edit_settings()
|
||||||
|
elif choice == "5":
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
input("Invalid choice. Press Enter to try again...")
|
input("Invalid choice. Press Enter to try again...")
|
||||||
|
|
|
||||||
3
settings.json
Normal file
3
settings.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"display_mode": "coloured_background"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user