Skip to content

Instantly share code, notes, and snippets.

View mbforbes's full-sized avatar
🖋️
Sketches

Maxwell Forbes mbforbes

🖋️
Sketches
View GitHub Profile
@mbforbes
mbforbes / tic_tac_toe.py
Created August 29, 2025 12:19
Tic Tac Toe - For Recurse Pair Interview
"""
Before your interview, write a program that lets two humans play a game of Tic Tac Toe
in a terminal. The program should let the players take turns to input their moves. The
program should report the outcome of the game.
During your interview, you will pair on adding support for a computer player to your
game. You can start with random moves and make the AI smarter if you have time.
---
@mbforbes
mbforbes / dumpTouchEvent.ts
Created March 8, 2025 20:22
Dump touch event
function dumpTouchEvent(event: TouchEvent): string {
// Start with the basics
const result = {
type: event.type,
timeStamp: event.timeStamp,
isTrusted: event.isTrusted,
bubbles: event.bubbles,
cancelable: event.cancelable,
defaultPrevented: event.defaultPrevented,
eventPhase: event.eventPhase,
async function getWikiImageURL(searchQuery) {
const PROXY = "https://cors-anywhere.herokuapp.com/";
const WIKI_API_ENDPOINT = `${PROXY}https://en.wikipedia.org/w/api.php`;
// First fetch to get the page ID
let pageId;
try {
console.log("Trying request 1");
const response1 = await fetch(
`${WIKI_API_ENDPOINT}?action=query&list=search&srsearch=${encodeURIComponent(
@mbforbes
mbforbes / ecs-dirty-aspects.ts
Created January 4, 2022 22:22
TypeScript ECS w/ dirty Component optimization and Aspects
/**
* An entity is just an ID. This is used to look up its associated
* Components.
*/
export type Entity = number
/**
* A Component is a bundle of state. Each instance of a Component is
* associated with a single Entity.
@mbforbes
mbforbes / ecs-dirty.ts
Last active August 24, 2025 12:07
ECS implementation w/ dirty Component optimization
namespace P02 {
/**
* An entity is just an ID. This is used to look up its associated
* Components.
*/
type Entity = number
/**
@mbforbes
mbforbes / minimal-ecs.ts
Created September 5, 2021 06:50
A minimal but complete Entity Component System (ECS) implementation in 99 lines.
type Entity = number
abstract class Component { }
abstract class System {
public abstract componentsRequired: Set<Function>
public abstract update(entities: Set<Entity>): void
public ecs: ECS
}
type ComponentClass<T extends Component> = new (...args: any[]) => T
class ComponentContainer {
private map = new Map<Function, Component>();
@mbforbes
mbforbes / from_scruples.py
Created June 18, 2021 18:30
scruples preprocess
"""Compare preprocessed scruples to original titles.
Usage:
python -m sc.scripts.from_scruples
"""
import code # code.interact(local=dict(globals(), **locals()))
import json
import os
from typing import List, Tuple, Set, Dict, Any, Optional, NamedTuple, Iterator, Callable
@mbforbes
mbforbes / paper.sh
Created October 11, 2018 02:49
Script that turns a pdf from pixels into paper near you (well, near me).
#!/bin/bash
# ______ ______ ______ ______ ______
# /\ == \/\ __ \ /\ == \/\ ___\ /\ == \
# \ \ _-/\ \ __ \\ \ _-/\ \ __\ \ \ __<
# \ \_\ \ \_\ \_\\ \_\ \ \_____\\ \_\ \_\
# \/_/ \/_/\/_/ \/_/ \/_____/ \/_/ /_/
#
#
# Script that turns a pdf from pixels into paper near you (well, near me).
@mbforbes
mbforbes / fallgate-freesound.org.txt
Created August 21, 2018 04:32
Fallgate sounds from freesound.org
https://freesound.org/people/vacuumfan7072/sounds/396031/
https://freesound.org/people/DSOADigital/sounds/362256/
https://freesound.org/people/MichelleGrobler/sounds/410560/
https://freesound.org/people/LukeSharples/sounds/209127/
https://freesound.org/people/JoelAudio/sounds/135464/
https://freesound.org/people/tim.kahn/sounds/140455/
https://freesound.org/people/et_graham/sounds/366345/
https://freesound.org/people/kristinhamby/sounds/382637/
https://freesound.org/people/LiamG_SFX/sounds/334238/
https://freesound.org/people/kolczok/sounds/198987/
@mbforbes
mbforbes / python-gzip.py
Created April 12, 2018 22:19
Python compress file
def compress(bytes_path: str, compressed_path: str) -> None:
logging.info('Compressing "{}" to "{}"'.format(
bytes_path, compressed_path,
))
with open(bytes_path, 'rb') as f_in:
with gzip.open(compressed_path, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
logging.info('Removing "{}"'.format(bytes_path))
os.remove(bytes_path)