clue solver – now in TypeScript!

Here’s a new version of my Clue solver! It works exactly the same as the old version, but now it uses a more standard React build system (so maybe it’s a little faster?) and I ported it to TypeScript.

TypeScript is now my favorite way to write React apps. It’s really nice to have a real type system with compile-time errors, and it gives me much more confidence when I refactor things.

For a comparison, here’s the old code in plain JavaScript, and here’s the new code in TypeScript. One representative sample of how much nicer things are, in the History class’s render method:

Old code:

for (var i = 0; i < this.props.history.length; ++i)
{
    var event = this.props.history[i][0];
    var eventType = event[0];
    var description = '';
    if (eventType === "suggestion") {
        description = this.props.playerInfo[event[1]][0] + " suggested " + CARD_NAMES[0][event[2]].external + ", " + CARD_NAMES[1][event[3]].external + ", " + CARD_NAMES[2][event[4]].external + " ";
        if (event[5] == -1) {
            description += " - no one refuted";
        }
        else {
            description += " - refuted by " + this.props.playerInfo[event[5]][0] + " with card ";
            if (event[6][0] == -1 && event[6][1] == -1) {
                description += "Unknown";
            }
            else {
                description += CARD_NAMES[event[6][0]][event[6][1]].external;
            }
        }
    } else if (eventType === "whoOwns") {
        var player = "Solution (case file)";
        if (event[1] < this.props.playerInfo.length) {
            player = this.props.playerInfo[event[1]][0];
        }
        description = CARD_NAMES[event[2][0]][event[2][1]].external + " owned by " + player;
    }
    entries.push(<li key={i}>{description}</li>);
}

New code:

let entries = [];
for (let i = 0; i < this.props.history.length; ++i)
{
    let event = this.props.history[i].event;
    let description = '';
    switch (event.history_type) {
        case "suggestion":
            description = this.props.playerInfos[event.suggester_index].name + " suggested " +
                cardNameFromCardIndex({ card_type: CardType.Suspects, index: event.suspect_index }).external + ", " +
                cardNameFromCardIndex({ card_type: CardType.Weapons, index: event.weapon_index }).external + ", " +
                cardNameFromCardIndex({ card_type: CardType.Rooms, index: event.room_index }).external + " ";
            if (event.refuter_index == -1) {
                description += " - no one refuted";
            }
            else {
                description += " - refuted by " + this.props.playerInfos[event.refuter_index].name + " with card ";
                if (isNull(event.refuted_card_index) || isNone(event.refuted_card_index)) {
                    description += "Unknown";
                }
                else {
                    description += cardNameFromCardIndex(event.refuted_card_index).external;
                }
            }
            break;
        case "whoOwns":
            let player = "Solution (case file)";
            if (event.player_index < this.props.playerInfos.length) {
                player = this.props.playerInfos[event.player_index].name;
            }
            description = cardNameFromCardIndex(event.card_index).external + " owned by " + player;
            break;
    }
    entries.push(<li key={i}>{description}</li>);
}

The new code is so much more readable! To be fair, some of the refactoring I could have done in JavaScript to begin with, but TypeScript gives me much more confidence to do bigger refactors.

Also, Visual Studio gives me Intellisense and the ability to rename variables and whatnot. I really don’t want to go back to writing JavaScript in a non-IDE!

clue solver redux!

After revamping gregstoll.com to support SSL, I spent some time looking at all of my projects and making sure that they still worked with SSL. Turns out most of them didn’t! (although the fixes were generally pretty quick)

That led me to revisit the Clue Solver, which seemed to have partially broken since I wrote it almost 10(!) years ago, probably because I used an ancient version of the Google Web Toolkit.

So I rewrote the UI from scratch using React, which I’m trying to get more experience in and is just generally a really nice Javascript framework. And now it’s done! Here’s the new version, and here’s the original one.

clue solver done!

So we played another game of Clue yesterday with wildrice13 and abstractseaweed and despite the fact that the clue solver declares it inconsistent, I’m going to be optimistic and assume I wrote something down wrong. Also fixed a few bugs and added a special case for a weird situation that came up. (I knew David had Conservatory or Ms. White, and Andrew had Conservatory or Ms. White, so no one else can have either of those cards) Thinks like that would have made using first-order logic or propositional logic nicer (since it would have presumably taken care of them automatically), but oh well.

Thus, I am declaring the Clue Solver done! Put a few example games up so you can load them and see how they work. (and the pretty colors on the simulation tab!) Been working on it for a while so it’s nice to have it done. I’ll take a little while off (what with starting work and all) and see what I feel like doing next. I do feel like I got a decent handle on the Google Web Toolkit, so that’s nice.

shirts I want, internet options

Dumbledore is gay! And shirts to match.

I still want this WiFi detector shirt but I feel a little bad spending money when none’s coming in yet.

Speaking of computer stuff, we have Internet through Time Warner and it seems to go down reasonably often. But not really down – often just resetting the cable modem will restore things to normal. Hence my idea for a robot that can detect when I can’t reach the Internet (easy) and reset the cable modem (hard unless there’s some software way to do it, which I doubt).

So I looked into alternatives. Grande Communications doesn’t recognize our address, AT&T/SBC/Yahoo/whatever DSL doesn’t service our address, and Verizon DSL (I hate Verizon because of how difficult it was to cancel local phone service in MD, but whatever) finds a lot of different streets named Austin (our street is Austin Center Blvd) in various cities around here even though I put in the freaking zip code. GG verizon. So I guess we’re stuck until I build a robot or someone reminds me of some other company I forgot.

Very stuck on simulations in clue solver, going to try to let it go for a few days and come back to it. Frustrating because I’m so close to done.