Welcome to Code Immersion

September 6, 2009
by Lee Spector (lspector)

Code Immersion is a course at Hampshire College taught by Lee Spector in the fall semester of 2009. “Code Immersion” is also the name of software developed to support this course by Ian McEwen.

Information on the course can be found at:

http://courses.hampshire.edu/S299380

The Code Immersion software can be obtained from:

http://github.com/ianmcorvidae/code-immersion

The purpose of this i3ci blog is to serve as a distribution point for links and other items of interest to the class, and to serve as a vehicle for the submission of code portfolios.

Note: Use the “Preformatted” style for code or attach larger code fragments as files using the “Add Media” button in the message composition interface.


Schush Code Working

April 24, 2010
by David Warshow (diw08)

Wit some help from Lee I have code working in schush that successfully evolves applications that predict  river levels 150 minutes in advance based on fake data. The fake data just counts up one cubic foot per second every 75 minutes. The downstream samples are always exactly 10 cubic feet per second higher then the upstream value. Now that we have a working program we can input our actual data and see what we get. We also need to implement into the fitness test so that it runs the program against multiple data sets to make sure it isn’t just finding the correct value by accident. Right now about 90% of the time it doesn’t even use the data reference functions it just happens to guess the right value. However we now have a running program that we can build from, which while we should have had  this a while ago, at least it is now done.

-David Warshow


Exploding a symbol

December 10, 2009
by Lee Spector (lspector)

Here’s a procedure to turn a symbol into a list of symbols, each made from one character of the original symbol:

(define explode
  (lambda (sym)
    (map string->symbol
         (map (lambda (c) (make-string 1 c))
              (string->list (symbol->string sym))))))

(explode 'boom)

-Lee


print-list-as-line

December 8, 2009
by Lee Spector (lspector)

Here’s a version of that procedure that I wrote in class, by request:

(define print-list-as-line
  (lambda (lst)
    (map (lambda (item)
           (printf "~A " item))
         lst)
    (printf "\n")))

(print-list-as-line '(here is a list))

-Lee


lrm-hitfn

December 6, 2009
by Lee Morgan (lrm07)

(define lrm1-hitfn
  (lambda (mine others)
    (letrec ((lrm-plus
              (lambda (l)
                (cond ((null? l)
                       0)
                      ((not (pair? (car l)))
                       (+ (car l) (lrm-plus (cdr l))))
                      (else (+ (lrm-plus (car l))
                               (lrm-plus (cdr l))))))))
      (cond ((and (> (apply + mine) 7)
                  (< (apply + mine) 12)
                  (member '1 mine))
             #f)
            ((> (apply + mine) 16)
             #f)
            ((and (> (apply + mine) 14)
                  (< (/ (lrm-plus others)
                        (length others)) 5.5))
             #f)
            (else #t)))))

If anyone else has a problem with using greater than and less than signs on the blog, use (without quotes and spaces) “& g t ;” and “& l t ;”


Coke Machine Card Player

December 3, 2009
by Arielle Soutar (as07)

This code is very messy, as I wrote it hastily after my previous card-player failed miserably against mr15.

It takes three inputs and keeps hitting until the stand variable exceeds 1, at which it stands.

Soda machine dispenser circuits take three inputs, which is why it’s called the “Coke Machine”.
This awesome AI’s brains (or hard artificial life) are made solely of soda machine circuits arranged in a neural network: Genghis

(define coke-machine
     (lambda (mine others)
    (let ((stand 0))
      (when (< stand 1)
        (cond
          ((> (best-total mine) 18)
            (set! stand (+ stand 2)))
          ((< (- 21 (best-total mine)) 7)
           (set! stand (+ stand (* .1 (modulo (- 21 (best-total mine)) 7)))))
          ((< (best-total (list-ref others (random (length others)))) 10)
           (set! stand (- stand .2)))
          ))
      (if (>= stand 1) #f #t)
      )))

1-dimensional cellular automaton code

December 3, 2009
by Lee Spector (lspector)

Here is the 1-dimensional cellular automaton code that I presented in class.

-Lee


Blackjack code

November 24, 2009
by Lee Spector (lspector)

My first version of code to support the blackjack tournaments that we discussed in class is here (Updated several times: here. See comments below.)

If you grab it and run it as-is it will play a 100-game tournament between two simple strategies, one of which asks for another card (a “hit” — sorry if I’m not using exactly the right casino terminology) whenever its cards sum to less than 15, and one of which asks for another card whenever its cards sum to less than 18. Neither even looks at the cards that have been dealt to the other players, and neither even considers using an ace (1) as 11 rather than 1. So they’re not very smart, but they run and you could try to beat them. And let me know if you find any bugs.

Recall that your job is to write your strategy as a “hit function” that takes two arguments, the first of which will be the list of the cards in your own hand (numbers from 1 to 10, with all face cards being 10) and the second of which will be a list of lists, each of which will contain all of the up-facing cards of another player. (Recall that in blackjack each player also has a down-facing card — you can see yours, but not anyone else’s.) So for example if I’ve been dealt a 4 and an ace so far then the first argument to my hit function will be (4 1). If there are two other players, one of whom has been dealt a 3 (face down) and a queen (face up), and the other of whom has been dealt a 7 (face down) and an ace (face up) then the second argument to my hit function will be ((10) (1)). Notice that I don’t see the other players’ down cards. The hit function should return #t if you want another card and #f otherwise.

In class we said that each student would send just a lambda expression for his or her hit function to the server, but it occurs to me now that you may want to use a bunch of utility functions in your hit functions. It would be possible to define all of these within your hit function (using let or let-rec), but I think we might just let you all do a “sendcode” with all of your utility functions before you send your hit function, and we might ask you to send a define expression that gives your hit function a name. If you’re going to do this then it’d be nice if you gave your utility functions weird names so that they’re not likely to conflict with anyone else’s. Ian and I will work out something for the “glue” to connect your code to the server, and we’ll either post something more about it here or just go over it in class. But in the meantime you could experiment with the code and try to come up with a good strategy.

-Lee

Update: I wonder if we shouldn’t make it use only a single deck, since we’re playing only single games between shuffles. A single game doesn’t allow one to see many cards, unless there are a lot of players.

Update 2: I just found and fixed a bug. Make sure you use the version containing the following note and explanation:

;; Update 20091125: fixed bug that treated wrong card of opponents' hands
;;                  as the down card (first card in hand is down card, but
;;                  prev version consed new cards onto front)

Update 3: Fixed another bug:

;; Update 20091201: fixed bug that allowed busted agents to keep getting cards

Update 4:

;; Update 20091202: fixed bug that allowed agents to have only one card

More complicated input from files

November 16, 2009
by Lee Spector (lspector)

In an earlier post I showed how to open a file and to read a single item of Scheme data from it. (By the way, in the earlier post I used the phrase “Scheme object” to mean a single item of Scheme data, meaning an atom or a list — the kinds of data we’ve been manipulating in Scheme all along. Don’t confuse this with the more specialized and non-standard “object” things that are part of PLT Scheme’s object-oriented programming support. I’ve used those specialized objects occasionally in our graphics code, but we haven’t gone over them in any systematic way in class.)

But suppose that you want to open and read from a text file that contains more than one Scheme data item, and in fact maybe it contains special characters that you want to handle in some unusual way, etc. What to do?

The main thing that you’ll want to know about is “read-line”. This is like “read” except that it returns what it read as a string of characters, not as an atom or list, etc., and it reads until it finds a line separator or the end of the file. You can call it repeatedly to read multiple lines. See section 12.2 of the PLT reference for details.

Once you’ve read in the string you can do a variety of things with it. If you just want the string to remain a string then you’re done. You can look at characters in the string with the string-ref procedure, or use other string-manipulating procedures to modify it or produce new strings based on the contents, etc. By the way, the “format” procedure is particularly handy for forming new strings — it’s like “printf” except that it returns a string instead of printing it.

But what if you then want to read the resulting string as an ordinary Scheme data item? For example, suppose you read a line of a file that contains a bunch of numbers using read-line. Then the result of read-line will actually be a string of characters that represent the numbers and spaces, not actual numbers. Suppose you put this in the variable nums-in-string. You could then do something like:

(set! list-in-string (format "(~A)" nums-in-string))

to create a new string that now contains an open “(“, followed by the characters representing all of the numbers and spaces, followed by a close “)”. But it’s still just a string of characters. How do you get normal Scheme data out of that?

The answer is that “read” can also take an argument, which must be a port, and that you can make a port from a string using “open-input-string”. So that means that you can do:

(read (open-input-string list-in-string))

and that this will return a list of numbers, as normal Scheme data (not as a string of characters).

-Lee


combat

November 15, 2009
by Stefan Terry (smt09)

A couple folk have asked to take a look at this, so I’m putting the combat system up on the blog.

It be here:

combat