TODO
| package org.vanillaweb; | |
| import java.io.*; | |
| import java.net.ServerSocket; | |
| import java.net.Socket; | |
| import java.net.URLDecoder; | |
| import java.nio.charset.StandardCharsets; | |
| import java.util.concurrent.*; | |
| public class FullDuplexRelay { |
| import java.io.*; | |
| import java.net.ServerSocket; | |
| import java.net.Socket; | |
| import java.net.URLDecoder; | |
| import java.nio.charset.StandardCharsets; | |
| import java.util.concurrent.ArrayBlockingQueue; | |
| import java.util.concurrent.BlockingQueue; | |
| public class BrowserRelay { |
| import com.ibm.as400.access.AS400 | |
| import com.ibm.as400.access.DataQueue | |
| import com.ibm.as400.access.DataQueueEntry | |
| import com.ibm.as400.access.KeyedDataQueue | |
| import java.nio.charset.Charset | |
| fun main() { | |
| // Connect to IBM i | |
| val system = AS400( |
| /// Selects the best legal move for the current player using a trained NeuralNetwork. | |
| public enum AIPlayer { | |
| /// Returns the move that maximises P(currentPlayer wins) according to the network. | |
| public static func bestMove(for state: GameState, network: NeuralNetwork) -> Move { | |
| let moves = uniqueByResult(MoveGenerator.legalMoves(for: state), from: state) | |
| let player = state.currentPlayer | |
| return moves.max { a, b in | |
| score(move: a, state: state, network: network, player: player) | |
| < score(move: b, state: state, network: network, player: player) |
| (ns backgammon.ai | |
| "TD-Gammon inspired reinforcement learning AI for backgammon. | |
| Architecture: | |
| - Neural network: input(198) → hidden(40) → output(1) | |
| - Input: Tesauro's 198-feature encoding of board state | |
| - Output: estimated probability that White wins | |
| - Training: TD(λ) temporal difference learning | |
| - Eligibility traces for credit assignment across moves |
I'm using the Calva extension in IntelliJ IDEA and sometimes I run the game from the REPL.
(play-until-winner initial-game-state)
Sometimes I run it from the bash command line.
java -cp "lib/spec.alpha-0.6.249.jar:lib/core.specs.alpha-0.5.81.jar:lib/clojure-1.12.0.jar:src/main/clojure" clojure.main -i src/main/clojure/backgammon/core.clj -e "(in-ns 'backgammon.core)" -e "(play-until-winner initial-game-state)"
| (ns my-project.core | |
| (:require [clojure.spec.alpha :as s])) | |
| ;; Define a simple spec for a 'User' map | |
| (s/def ::name string?) | |
| (s/def ::age int?) | |
| (s/def ::user (s/keys :req [::name ::age])) | |
| (defn -main [& args] | |
| (let [valid-data {::name "Greg" ::age 30} |
Install emacs on a Mac
Commands Run:
brew install emacs
/opt/homebrew/opt/emacs/bin/emacs --fg-daemon
open new terminal tab
emacsclient -c
Using emacs
Note that on the Mac keyboard, Meta is ⌥ and Control is ^
Whenever I write some code to deal with data about people then functional programming seems to work best. Whenever I write some code to simulate people then object-oriented programming seems to work best.
— Michael Fogus
Object oriented programming makes code understandable by encapsulating moving parts. Functional programming makes code understandable by minimizing moving parts.
— Michael Feathers
• A function doesn’t have to be 100% pure to get many of the benefits of purity.
• Of course you don’t want to use the fact that it’s not 100% pure as an excuse for making it even less pure.
• A more functional programming style often results in more parameters to a function.
• A functional style does lead to more parameters but, it is much easier to test the functions in isolation.