I joined the ghost walk just after sundown, the air cooling quick in that Blue Ridge way, where the warmth of day drains fast once the sun slips behind the ridges. The guide’s lantern cast a soft circle as we moved through Salem’s narrow streets. Crickets stitched their steady chorus into the background, and every so often a breeze carried the faint scent of woodsmoke from a chimney already preparing for autumn.
Most of the stories were familiar shapes, soldiers, sudden deaths, whispered names of old hotels and graveyards, but when the guide began to speak of the Pinkard house the tone shifted. The group leaned in as if pulled closer by the story itself.
She told us about John Henry Pinkard, the folk healer of the late 1800s, known for his jars of roots and tinctures. People came to him when doctors had no answers, and sometimes he helped. Sometimes he did not. What lingered, though, was stranger. The shelves of jugs were said to cry at night, their sealed mouths releasing low moans like breath struggling to escape. Some neighbors said it was only the gases of fermenting herbs. Others believed the jars had absorbed the voices of sickness, that the house itself had become a keeper of grief.
Even after Pinkard was gone, the house never grew quiet. Passersby swore they saw a figure slip across the windows, or felt a heaviness press against their chest as they walked by, as if the building itself was paying close attention. The guide paused then, and the silence of the street seemed to deepen. The insects still sang, but softer, and the cool air carried just enough stillness to make the tale feel near.
There was no violent history to anchor the story, no single bloody tragedy. Just a house that remembered every whispered prayer and every final breath that crossed its threshold. The kind of haunting that does not scream but sighs.
By the time the walk ended and I made my way back toward the car, the streets were nearly empty. Porch lights glowed here and there, throwing shadows across old fences. I found myself glancing up at the darker houses, wondering which one might have been the Pinkard place, wondering if even now it still remembered, if somewhere inside, a jar was letting out a slow, sorrowful breath into the night air.
All posts by scottobear
Day 20663
Saturday night, rain steady outside. One of those nights where the streetlights look blurry and the whole world feels a little softer. Made some chamomile tea and put on Working Girl. Been a while since I last saw it, but it’s still such a comfort watch.
Melanie Griffith’s Tess McGill is the heart of it. A Staten Island secretary with brains, nerve, and that quiet kind of hope you recognize if you’ve ever felt underestimated. Sigourney Weaver is all sleek suits and sharp edges as Katharine Parker. Harrison Ford grins his way through as Jack Trainer, but he softens in the right places.
Mike Nichols captures late 80s New York like a living thing. Office lights buzzing, taxis honking, the smell of copier toner and coffee you can almost taste. Carly Simon’s “Let the River Run” rolls over it all like a hymn, and suddenly you believe Tess can climb her way to the top with nothing but grit and a borrowed suit.
Watching it now feels like finding an old Polaroid in a shoebox — colors faded, but alive. Tess feels real. She could be someone you’d see at a diner counter, scribbling plans in a notebook over a cup of coffee that’s gone cold.
Saw a possum wander past the window while the rain kept on, steady and soft. The kind of small moment that makes you smile without thinking. By the time the credits rolled, I felt lighter. The movie’s a reminder that ambition can be kind, and stubbornness can be gentle.
A good film for a rainy night.
Robin’s nest



Morning window-light, cat perched sentinel, ears flicking at the robin’s sharp tut-tut-tut from the flag stake outside. She has claimed the yard as her kingdom for now. Her breast is bright as ember, feathers ruffled with purpose. Every step past the hedge, every tilt of the curtain, draws her vigilance. I imagine her heart beating faster than my own, a drumbeat of protection.
Later, I peek into the maple and find the reason: two tiny beaks stretching skyward, tufted crowns of down and pinfeathers, not yet ready to know the sky. The nest is a woven cradle of sticks and hope, a cradle that breathes with each soft tremor of chicks begging for more. Their eyes are half-closed, but their hunger burns awake.
The robin watches me watching, neither of us entirely trusting, but both bound to this moment. She sings less now, too busy with duty, worms plucked from the damp soil and delivered with tenderness disguised as efficiency. Fierce and tireless, a flame against the green world.
The cat sighs from the sill, thwarted hunter behind glass, while I feel the tug of seasons, how life unfurls in branches, how small voices become the loud chorus of summer. For now, the robin stands guard, and I stand witness.
The butterfly emerges!

the hanging lantern opened
early afternoon, porch still cool. stepped outside to find a small miracle clinging under the eaves. a monarch had slipped free from its glassy coffin. wings damp, folded tight, slowly breathing into shape. the chrysalis above it, once green and gold, now nothing more than a hollow paper lantern. finished.
the butterfly trembled against it, orange sails heavy with gravity. veins filling, colors darkening, each beat of the heart writing a little more of the story in black and gold.
thoughts drifted toward patience. all that unseen work in silence, days of dissolution and rearrangement, until one quiet morning something new opens its eyes. sunlight stitched into wings. the world noisy all around, but here was proof of stillness doing its work.
fragile. defiant. not yet ready for air. it hangs and waits, wings drying, gathering strength. i wait too. remembering that emergence takes its own time.
milkweed moves in the breeze. far south, a forest waits. for now, just this bright spark, clinging to its empty lantern, preparing.
today, i witnessed transformation. tomorrow, it will be gone, riding the wind.
🦋
current mood: quiet delight
current music: wind through leaves, somewhere a dove calling
#roanokeva
#monarch #butterfly #chrysalis
Day 20,660 It’s the monarch!

Over the front door, a chrysalis hangs. Monarch. Green jade lantern with a seam of gold, balanced in its little hook. I open the door and it sways just slightly, steadying again, as if nothing at all can disturb its long dream.
It changes there, unseen. Inside, the body is rewritten, cells unspooling, wings folded like secret letters. From the outside, only stillness, except for the shimmer of gold dots, like stars pinned to its surface.
Every time I step out, I look up. A reminder. A spell. The threshold feels different with this little guardian over it, a quiet companion of the in between. Doorways are always a kind of crossing. This one now more so.
Soon it will split, and from silence will come the crackle of wings, orange and black, lifting into air. For now, I pass under it, carrying the hush of transformation into my day.
Number converter – python
# number_converter.py
# Works in Pydroid 3 (Android Python environment)
import inflect
# Create engine for number-to-words
p = inflect.engine()
# Function to convert to Roman numerals
def to_roman(num):
if not (0 < num < 4000):
return “Roman numerals only support 1–3999”
values = [
(1000, “M”), (900, “CM”), (500, “D”), (400, “CD”),
(100, “C”), (90, “XC”), (50, “L”), (40, “XL”),
(10, “X”), (9, “IX”), (5, “V”), (4, “IV”), (1, “I”)
]
result = “”
for val, symbol in values:
while num >= val:
result += symbol
num -= val
return result
# Function to convert number to binary
def to_binary(num):
return bin(num)[2:]
# Function to convert number to hexadecimal
def to_hex(num):
return hex(num)[2:].upper()
# Function to convert number to words
def to_words(num):
return p.number_to_words(num)
# Main interactive loop
def main():
while True:
try:
num = int(input(“\nEnter a number (or -1 to quit): “))
if num == -1:
print(“Goodbye!”)
break
print(“\nChoose conversion:”)
print(“1. Roman Numerals”)
print(“2. Binary”)
print(“3. Hexadecimal”)
print(“4. Words”)
choice = input(“Enter choice (1-4): “)
if choice == “1”:
print(“Roman Numeral:”, to_roman(num))
elif choice == “2”:
print(“Binary:”, to_binary(num))
elif choice == “3”:
print(“Hexadecimal:”, to_hex(num))
elif choice == “4”:
print(“Words:”, to_words(num))
else:
print(“Invalid choice!”)
except ValueError:
print(“Please enter a valid integer.”)
if __name__ == “__main__”:
main()

The cat has made me into a wizard, at least in the quiet story she tells with her eyes. She believes I can summon food from the hidden places. An empty bowl waits, and with a few simple gestures, it is full again. To her, this is not routine – it is magic.
She approaches with ceremony: weaving circles around my legs, chanting her meows, tail coiling like a ribbon of smoke. Each time she comes, it feels like a chapter retold – the faithful one calling upon the hearth wizard to bring forth plenty. I answer, as good wizards do. The bowl fills, and the covenant holds true.
In her folklore, I suspect she keeps me as the household mage, draped not in robes but in the ordinary, bending the world to keep her safe and fed. She believes in the ritual completely, and there is power in being so believed in.
She eats, and her purr is the hymn that seals the tale – a soft song of trust, love and satisfaction.
And outside, the day lingers. The cicadas chant, the stars scratch their worn runes across the sky… the sun and moon drift above us like gold and silver lanterns.
In moments like these, it feels true enough: the simplest acts are often the deepest spells, and love itself is the oldest magic we know.
#doodle #digitalmarkers #roanokeva #cat #magic #love #hungry #fish
Day 20,658
Morning robot divination, the runes clattered out:
ᚱ Raidho – the road, the turning wheel, journeys both on foot and inward.
ᛗ Mannaz – humanity, cooperation, the reflection of self through others.
ᚺ Hagalaz – hail, disruption, sudden ice cracking branches, unasked but clarifying.
Together, a reminder: movement is happening, best shared with others, even if the storm comes along to shake it all loose.
The I Ching followed with Hexagram 53 – 漸 (Jiàn), Gradual Progress. The lines stacked like this:
7 — (young yang)
9 — — (old yang, changing to yin)
6 — (old yin, changing to yang)
7 — (young yang)
8 — — (young yin)
8 — — (young yin)
Like the flight of the wild goose: slow, patient, finding safe landings step by step. The changes in the middle — strength softening, softness firming — say that flexibility is part of progress.
So the whole spread leans into:
ᚱ the road opens,
ᛗ companionship matters,
ᚺ the storm disrupts,
but 漸 Gradual Progress carries through, steady wings in the long arc of travel.
Later, I walked the greenway and watched a gaggle of geese settling at the water’s edge, right on cue. The sky broke open with a shaft of sunlight between gray banks of cloud. A couple of strangers paused to chat at the benches – small, welcome echoes of ᛗ. Storm brewing on the horizon, but storms move on. Step by step, wheel by wheel, goose by goose.
Polygons python test
I need to work on the 12 sider

import pygame
import math
# — Configuration —
WIDTH, HEIGHT = 800, 600
BACKGROUND_COLOR = (10, 10, 20) # Dark Blue-Gray
LINE_COLOR = (255, 255, 255) # White
ROTATION_SPEED = 0.01
# — Menu Configuration —
pygame.font.init()
try:
MENU_FONT = pygame.font.SysFont(“sans”, 28)
except:
MENU_FONT = pygame.font.Font(None, 36)
MENU_TEXT_COLOR = (200, 200, 200) # Light Gray
MENU_HIGHLIGHT_COLOR = (255, 215, 0) # Gold
MENU_BACKGROUND_COLOR = (30, 30, 40)
MENU_WIDTH = 220
# — Platonic Solid Data —
def get_platonic_solid_data(name):
“””Provides the correctly scaled vertices and faces for a given Platonic solid.”””
if name == “Tetrahedron”:
scale = 150
v_base = [(1,1,1), (-1,-1,1), (-1,1,-1), (1,-1,-1)]
f = [(0,1,2), (0,2,3), (0,3,1), (1,3,2)]
v = [(p[0]*scale, p[1]*scale, p[2]*scale) for p in v_base]
return v, f
if name == “Cube”:
scale = 130
v_base = [(-1,-1,1), (1,-1,1), (1,1,1), (-1,1,1),
(-1,-1,-1), (1,-1,-1), (1,1,-1), (-1,1,-1)]
f = [(0,1,2,3), (4,5,1,0), (5,6,2,1), (6,7,3,2), (7,4,0,3), (7,6,5,4)]
v = [(p[0]*scale, p[1]*scale, p[2]*scale) for p in v_base]
return v, f
if name == “Octahedron”:
scale = 160
v_base = [(0,0,1), (0,0,-1), (1,0,0), (-1,0,0), (0,1,0), (0,-1,0)]
f = [(0,2,4), (0,4,3), (0,3,5), (0,5,2), (1,2,5), (1,5,3), (1,3,4), (1,4,2)]
v = [(p[0]*scale, p[1]*scale, p[2]*scale) for p in v_base]
return v, f
if name == “Dodecahedron”:
# — CORRECTED AND VERIFIED DATA —
scale = 100
phi = (1 + math.sqrt(5)) / 2
v_base = [
(-1, -1, -1), ( 1, -1, -1), ( 1, 1, -1), (-1, 1, -1),
(-1, -1, 1), ( 1, -1, 1), ( 1, 1, 1), (-1, 1, 1),
(0, -1/phi, -phi), (0, -1/phi, phi), (0, 1/phi, -phi), (0, 1/phi, phi),
(-1/phi, -phi, 0), ( 1/phi, -phi, 0), (-1/phi, phi, 0), ( 1/phi, phi, 0),
(-phi, 0, -1/phi), ( phi, 0, -1/phi), ( phi, 0, 1/phi), (-phi, 0, 1/phi)
]
f = [
(3, 11, 7, 18, 19), (3, 19, 16, 2, 14), (3, 14, 15, 1, 11),
(7, 11, 1, 5, 18), (1, 5, 13, 0, 10), (5, 13, 4, 17, 18),
(4, 13, 0, 8, 12), (0, 8, 16, 19, 18), (2, 14, 15, 9, 10),
(6, 17, 8, 12, 16), (6, 12, 4, 13, 5), (6, 17, 9, 15, 14)
]
v = [(p[0]*scale, p[1]*scale, p[2]*scale) for p in v_base]
return v, f
if name == “Icosahedron”:
scale = 130
phi = (1 + math.sqrt(5)) / 2
v_base = [
(-1, phi, 0), ( 1, phi, 0), (-1, -phi, 0), ( 1, -phi, 0),
(0, -1, phi), (0, 1, phi), (0, -1, -phi), (0, 1, -phi),
(phi, 0, -1), (phi, 0, 1), (-phi, 0, -1), (-phi, 0, 1)
]
f = [
(0, 11, 5), (0, 5, 1), (0, 1, 7), (0, 7, 10), (0, 10, 11), (1, 5, 9),
(5, 11, 4), (11, 10, 2), (10, 7, 6), (7, 1, 8), (3, 9, 4), (3, 4, 2),
(3, 2, 6), (3, 6, 8), (3, 8, 9), (4, 9, 5), (2, 4, 11), (6, 2, 10),
(8, 6, 7), (9, 8, 1)
]
v = [(p[0]*scale, p[1]*scale, p[2]*scale) for p in v_base]
return v, f
# — State Variables —
solid_names = [“Tetrahedron”, “Cube”, “Octahedron”, “Icosahedron”, “Dodecahedron”]
current_solid_name = solid_names[0]
vertices, faces = [], []
angle_x, angle_y, angle_z = 0, 0, 0
# — Function to load a solid —
def load_solid(name):
global current_solid_name, vertices, faces, angle_x, angle_y, angle_z
current_solid_name = name
vertices, faces = get_platonic_solid_data(name)
angle_x, angle_y, angle_z = 0, 0, 0
# — Build Menu Items —
menu_rects = {}
y_offset = 20
for name in solid_names:
text_surf = MENU_FONT.render(name, True, MENU_TEXT_COLOR)
rect = text_surf.get_rect(topleft=(20, y_offset))
menu_rects[name] = rect
y_offset += 40
# — Pygame Setup —
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(“Select and Spin a Platonic Solid”)
clock = pygame.time.Clock()
load_solid(current_solid_name)
# — Main Loop —
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_AC_BACK: running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for name, rect in menu_rects.items():
if rect.collidepoint(event.pos) and name != current_solid_name:
load_solid(name)
break
angle_x += ROTATION_SPEED
angle_y += ROTATION_SPEED
angle_z += ROTATION_SPEED
rotated_vertices = []
for x, y, z in vertices:
y_rot = y * math.cos(angle_x) – z * math.sin(angle_x)
z_rot = y * math.sin(angle_x) + z * math.cos(angle_x)
x_rot = x * math.cos(angle_y) – z_rot * math.sin(angle_y)
z_final = x * math.sin(angle_y) + z_rot * math.cos(angle_y)
x_final = x_rot * math.cos(angle_z) – y_rot * math.sin(angle_z)
y_final = x_rot * math.sin(angle_z) + y_rot * math.cos(angle_z)
rotated_vertices.append((x_final, y_final, z_final))
projected_vertices = []
for x, y, z in rotated_vertices:
distance = 5
scale = distance / (distance – z / 400)
proj_x = int(x * scale + (WIDTH + MENU_WIDTH) / 2)
proj_y = int(y * scale + HEIGHT / 2)
projected_vertices.append((proj_x, proj_y))
screen.fill(BACKGROUND_COLOR)
if projected_vertices:
# — MODIFIED DRAWING LOGIC FOR WIREFRAME —
for face in faces:
points = [projected_vertices[i] for i in face]
# Draw only the outline of the polygon
pygame.draw.polygon(screen, LINE_COLOR, points, 1)
pygame.draw.rect(screen, MENU_BACKGROUND_COLOR, (0, 0, MENU_WIDTH, HEIGHT))
for name, rect in menu_rects.items():
color = MENU_HIGHLIGHT_COLOR if name == current_solid_name else MENU_TEXT_COLOR
text_surf = MENU_FONT.render(name, True, color)
screen.blit(text_surf, rect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
I’m visiting a British seaside town called Margate. There’s a location here called ‘Shell Grotto’. In the 1800s, a landowner uncovered an ancient walkway and altar built underground and covered in thousands of seashells – and nobody knows why. What I’m saying is, prepare for the coming of Cthulu.




Freaky tree on the roanoke river


They say if you walk the banks of the Roanoke near Salem after sundown, best keep your eyes straight ahead and your feet moving. The river twists through those woods quiet as a whisper, and sometimes the quiet is watching back.
I found it in daylight, a tree with a face carved deep into the trunk. Heavy eyes, a frown that sank down like roots. Looked man-made at first, but the longer I stood there the more it felt alive. The cracks in the wood breathed. The shadows under the eyes shifted with no wind.
Old mountain tales say the Roanoke has its watchers. Spirits bound in bark, listening for names carried on the current. Folks claim if you speak too loud near them, the trees remember your voice, and call it back to you years later when you are alone in the hollow.
I didn’t linger. Just tipped my head in respect, the way you’d nod to a grave or a passing crow, and kept to the trail.
Along the river, even in daylight, you can feel the mountains breathing, and sometimes the trees breathe back.
Tic tac toe python test
#!/usr/bin/env python3
“””
Tic-Tac-Toe with simple reinforcement learning (Monte Carlo control)
– Runs in a terminal (works in Pydroid on Android)
– Can train by self-play, play human vs AI, or AI vs AI
– Learns state-action values and improves over time
– Save/Load the learned policy to/from JSON
How it learns (short version):
We record the sequence of (state, action, player) for a game. At the end:
winner’s actions get +1, loser’s actions get -1, draws get 0
We update a value table Q[(state, player)][action] by incremental averaging.
Policy is epsilon-greedy w.r.t. Q, so it explores a bit while learning.
“””
import json
import os
import random
from collections import defaultdict
from typing import Dict, List, Tuple
# =========================
# Game mechanics
# =========================
EMPTY = ” “
PLAYERS = (“X”, “O”)
WIN_LINES = [
(0, 1, 2), (3, 4, 5), (6, 7, 8), # rows
(0, 3, 6), (1, 4, 7), (2, 5, 8), # cols
(0, 4, 8), (2, 4, 6) # diagonals
]
Board = List[str]
State = str # 9-char string of ‘X’, ‘O’, or ‘ ‘
Action = int # index 0..8
QKey = Tuple[State, str] # (state, current_player)
def new_board() -> Board:
return [EMPTY] * 9
def board_to_state(board: Board) -> State:
return “”.join(board)
def legal_actions(board: Board) -> List[Action]:
return [i for i, c in enumerate(board) if c == EMPTY]
def check_winner(board: Board) -> str:
for a, b, c in WIN_LINES:
if board[a] != EMPTY and board[a] == board[b] == board[c]:
return board[a]
if EMPTY not in board:
return “DRAW”
return “” # game continues
def print_board(board: Board) -> None:
b = [c if c != EMPTY else str(i+1) for i, c in enumerate(board)]
rows = [f” {b[0]} | {b[1]} | {b[2]}”, f” {b[3]} | {b[4]} | {b[5]}”, f” {b[6]} | {b[7]} | {b[8]}”]
print(“\n” + “\n———–\n”.join(rows) + “\n”)
# =========================
# RL bits (First-Visit Monte Carlo control)
# =========================
class MonteCarloAgent:
def __init__(self, epsilon: float = 0.1):
self.epsilon = float(epsilon)
# Q maps (state, player) -> vector of 9 action values
self.Q: Dict[QKey, List[float]] = defaultdict(lambda: [0.0]*9)
# N maps (state, player, action) -> visit count for incremental mean
self.N: Dict[Tuple[State, str, Action], int] = defaultdict(int)
def policy(self, board: Board, player: str) -> Action:
acts = legal_actions(board)
if not acts:
return -1
if random.random() < self.epsilon:
return random.choice(acts)
state = board_to_state(board)
qvals = self.Q[(state, player)]
# choose best legal; tie-break randomly among maxima
best_val = max(qvals[a] for a in acts)
best_actions = [a for a in acts if qvals[a] == best_val]
return random.choice(best_actions)
def episode(self, starting_player: str = “X”, show: bool = False) -> str:
“””Play one game between two copies of this agent (self-play).
Returns the result: ‘X’, ‘O’, or ‘DRAW’.”””
board = new_board()
current = starting_player
# history of (state, player, action)
trajectory: List[Tuple[State, str, Action]] = []
while True:
action = self.policy(board, current)
if action == -1:
# no legal moves (shouldn’t happen)
result = “DRAW”
break
# record state before taking action
s = board_to_state(board)
trajectory.append((s, current, action))
# apply move
board[action] = current
outcome = check_winner(board)
if show:
print_board(board)
if outcome == “X” or outcome == “O”:
result = outcome
break
if outcome == “DRAW”:
result = “DRAW”
break
# switch player
current = “O” if current == “X” else “X”
# Assign returns
if result == “DRAW”:
G = {“X”: 0.0, “O”: 0.0}
else:
G = {“X”: 1.0 if result == “X” else -1.0,
“O”: 1.0 if result == “O” else -1.0}
# First-visit MC update
seen = set()
for s, p, a in trajectory:
key = (s, p, a)
if key in seen:
continue
seen.add(key)
qkey = (s, p)
self.N[(s, p, a)] += 1
n = self.N[(s, p, a)]
old = self.Q[qkey][a]
target = G[p]
self.Q[qkey][a] = old + (target – old) / n
return result
def choose_move(self, board: Board, player: str, greedy: bool = True) -> Action:
acts = legal_actions(board)
if not acts:
return -1
state = board_to_state(board)
qvals = self.Q[(state, player)]
if greedy:
best_val = max(qvals[a] for a in acts)
best_actions = [a for a in acts if qvals[a] == best_val]
return random.choice(best_actions)
else:
return self.policy(board, player)
# ———- persistence ———-
def save(self, path: str):
data = {f”{k[0]}|{k[1]}”: v for k, v in self.Q.items()}
with open(path, “w”, encoding=”utf-8″) as f:
json.dump({“epsilon”: self.epsilon, “Q”: data}, f)
print(f”Saved model to {path} ({len(self.Q)} states)”)
def load(self, path: str):
if not os.path.exists(path):
print(f”No such file: {path}”)
return
with open(path, “r”, encoding=”utf-8″) as f:
blob = json.load(f)
self.epsilon = float(blob.get(“epsilon”, 0.1))
rawQ = blob.get(“Q”, {})
self.Q = defaultdict(lambda: [0.0]*9)
for k, v in rawQ.items():
state, player = k.split(“|”)
vec = [float(x) for x in v]
if len(vec) != 9:
vec = (vec + [0.0]*9)[:9]
self.Q[(state, player)] = vec
print(f”Loaded model from {path} ({len(self.Q)} states), epsilon={self.epsilon}”)
# =========================
# Human interaction
# =========================
MODEL_PATH = “tictactoe_q.json”
def human_turn(board: Board, player: str) -> None:
while True:
try:
move = input(f”Your move ({player}). Enter 1-9: “).strip()
idx = int(move) – 1
if idx < 0 or idx > 8:
raise ValueError
if board[idx] != EMPTY:
print(“That spot is taken. Try again.”)
continue
board[idx] = player
return
except ValueError:
print(“Please type a number 1-9 corresponding to the board position.”)
def ai_turn(board: Board, player: str, agent: MonteCarloAgent, greedy: bool = True) -> None:
a = agent.choose_move(board, player, greedy=greedy)
if a == -1:
return
board[a] = player
def play_human_vs_ai(agent: MonteCarloAgent):
print(“\n=== Human vs AI ===”)
while True:
choice = input(“Do you want to be X (first) or O (second)? [X/O]: “).strip().upper()
if choice in (“X”, “O”):
human = choice
ai = “O” if human == “X” else “X”
break
print(“Please answer X or O.”)
greedy = input(“Should the AI play greedily (y) or allow exploration (n)? [y/n]: “).strip().lower() != ‘n’
board = new_board()
current = “X”
print_board(board)
while True:
if current == human:
human_turn(board, human)
else:
ai_turn(board, ai, agent, greedy=greedy)
print(“AI moves:”)
print_board(board)
outcome = check_winner(board)
if outcome in (“X”, “O”):
print(f”{outcome} wins!” + (” (You win!)” if outcome == human else ” (AI wins!)”))
break
if outcome == “DRAW”:
print(“It’s a draw.”)
break
current = “O” if current == “X” else “X”
def watch_ai_vs_ai(agent: MonteCarloAgent, games: int = 1, greedy: bool = True):
print(“\n=== AI vs AI ===”)
for g in range(1, games+1):
print(f”Game {g}:”)
result = agent.episode(starting_player=”X”, show=True)
if result == “DRAW”:
print(“Result: draw\n”)
else:
print(f”Result: {result} wins\n”)
def train_self_play(agent: MonteCarloAgent, episodes: int = 10000, report_every: int = 1000):
print(f”Training for {episodes} self-play games (epsilon={agent.epsilon})…”)
w = {“X”: 0, “O”: 0, “DRAW”: 0}
for i in range(1, episodes+1):
# alternate starting player to avoid bias
starter = “X” if i % 2 else “O”
result = agent.episode(starting_player=starter, show=False)
w[result] += 1
if report_every and i % report_every == 0:
total = i
wx, wo, d = w[“X”], w[“O”], w[“DRAW”]
print(f” After {total:6d}: X={wx} O={wo} Draw={d} | states learned={len(agent.Q)}”)
print(“Done.”)
# =========================
# Menu / main
# =========================
def main():
agent = MonteCarloAgent(epsilon=0.1)
if os.path.exists(MODEL_PATH):
try:
agent.load(MODEL_PATH)
except Exception as e:
print(f”(Could not auto-load model: {e})”)
while True:
print(“””
==============================
Tic-Tac-Toe RL (console)
==============================
1) Train by self-play
2) Play Human vs AI
3) Watch AI vs AI
4) Set exploration epsilon
5) Save model
6) Load model
7) Reset model
0) Exit
“””)
choice = input(“Select an option: “).strip()
if choice == “1”:
try:
n = int(input(“How many self-play games? (e.g., 5000): “).strip())
except ValueError:
print(“Please enter a number.”)
continue
report = max(1000, n // 10)
train_self_play(agent, episodes=n, report_every=report)
elif choice == “2”:
play_human_vs_ai(agent)
elif choice == “3”:
try:
g = int(input(“How many games to show? “).strip())
except ValueError:
g = 1
greedy = input(“Play greedily (y) or with exploration (n)? [y/n]: “).strip().lower() != ‘n’
watch_ai_vs_ai(agent, games=g, greedy=greedy)
elif choice == “4”:
try:
e = float(input(“Set epsilon (0 = greedy, 0.1 default, 1 = random): “).strip())
e = min(max(e, 0.0), 1.0)
agent.epsilon = e
print(f”epsilon set to {agent.epsilon}”)
except ValueError:
print(“Please enter a number (e.g., 0.1)”)
elif choice == “5”:
path = input(f”Save path [{MODEL_PATH}]: “).strip() or MODEL_PATH
agent.save(path)
elif choice == “6”:
path = input(f”Load path [{MODEL_PATH}]: “).strip() or MODEL_PATH
agent.load(path)
elif choice == “7”:
agent = MonteCarloAgent(epsilon=agent.epsilon)
print(“Model reset. (Learning starts fresh.)”)
elif choice == “0”:
print(“Goodbye!”)
break
else:
print(“Unknown option. Please choose from the menu.”)
if __name__ == “__main__”:
main()
Day 20654
Afternoon carried me and my companions into Evie’s Bakery, quiet hum of ovens and glass cases shining with sugar. Amanda, smiling and steady, steered us through the tasting like she’d been waiting just for us.
Better Than Sex cake first. Devil’s food rich and shadow dark, chocolate chips hidden in the crumb. Whipped white frosting smoothed over, tangled with chocolate and caramel. Each forkful heavy with sweetness, melt and bite together, little bursts of joy.
Then sunshine cake. Yellow crumb, tender as a cloud, holding its weight under a plate of milk chocolate icing. The balance of bright and sweet, golden light under a darker crown, lifted everything a little higher.
We lingered, fork tapping the empty plate, warm air rising from the ovens, downstairs. We put an order in for both full cakes for an upcoming birthday party later this month.
When we stepped back outside, the sidewalk carried its own invitation. Hopscotch chalked in pastel squares, the word dance scrawled in the final box. Sunlight caught it just so, and for a moment it felt like the cakes had followed us out, turning the street into something just as sweet.
#EviesBakery #CakeTasting #BetterThanSexCake #SunshineCake #SweetLife #ChalkHopscotch #DanceAtTheEnd
Day 20,653

The Y waited in the gray drizzle this morning, doors sliding open like a slow inhale. I went alone, bag on shoulder, carrying towel, lock, and swimsuit. The lobby carried its usual mix of coffee and chlorine, a scent that feels like both welcome and warning, as if the building wants to remind you that effort and comfort live side by side here.
First, I settled onto a recumbent bike. Low seat, pedals forward, the kind of machine that lets you lean back a little, legs moving like steady oars. The screen glowed with numbers I barely watched. Beyond the fogged windows the street blurred, people passing like shadows in watercolor. The bike seemed content to carry me through the minutes, humming beneath me as though pleased to share its rhythm.
Then the pool. Ninety degrees, five feet deep, a body of water that felt more like a living thing than a facility feature. Stepping in was like being welcomed into its arms, warm against the skin, the depth just enough to hold me without ever letting me disappear. Plenty of space, no rush, no crowding, the water stretching wide and patient. Each lap was less about distance and more about drifting through the gentle embrace, lights above shimmering like constellations stirred by the smallest stroke.
I briefly lingered at the edge after swimming, towel wrapped tight absorbing stray drops before I headed back to the changing area, listening to the pool breathe under the echoes of children’s laughter at the far end. The humid air wrapped itself around me, heavy but comforting, like the last word in a quiet conversation.
When I stepped outside again, drizzle cooled my skin and hair. I felt as though the pool had pressed its warmth into me, a secret gift from the water, carried out into the gray day like a blessing.
#roanokeva #salemva #ymca
The Painted Pig




They call him just the pig, though he’s more than that. A squat figure of concrete planted on West Main, round-bellied and silent, carrying the weight of Salem’s years in paint and shadow.
The elders whisper that when Henry’s barbecue joint closed, the town grew restless. Windows darkened, smoke gone from the pit, but people felt the loss in their bones. Something lingered, wanting a place to live on. So the pig stayed. And with each fresh coat of paint, he learned to listen.
Children mark his hide with birthday wishes and bright doodles, never knowing the stone soaks up their voices. Lovers scrawl their names, and months later, when the paint fades, their romance too crumbles like chipped acrylic. Preachers leave blessings, and for a season the air seems lighter. Protesters splash slogans in the night, and by dawn the town feels braced for change. What is written on him has a way of echoing back.
Some say if you pass him after midnight, when the street is empty and the lamps buzz with moths, you’ll hear him shifting his trotters against the pavement. Just enough to shake loose the old stories, to make room for the new. His eyes — blank and painted over a thousand times — are never the same color twice, yet they follow. Always watching.
It’s said Salem has been spared worse storms than its neighbors, spared fires that could have swept whole blocks, because the pig takes it on himself. He drinks down the town’s misfortune like rain. But he demands attention in return. If the paint ever stops, if people forget to mark him, his belly will grow heavy with unshed stories, and the luck of Salem will sour.
So the brushes keep coming. Small hands, weary hands, bold hands with spray cans in the dark. The pig wears it all, a patchwork shroud of human hope and folly. Protector, trickster, omen.
And he will not leave. Not until Salem does.
#salemva #paintedpig #appalachianfolklore #concretespirit #roanokeva