Sunday, August 13, 2017

Searching for 1 1/2 designs in cyclic codes with MAGMA

Here we try to find 1 1/2-designs in cyclic codes. 1 1/2-designs are interesting since they correspond to directed strongly regular graphs.
 D := function(d,p,n)        //creates set of dth power residues in GF(p,n)
    x := PrimitiveElement(GF(p,n))^d;
    DD := {GF(p,n)|};
    for i in {0..p^n-1} do
        Include(~DD,x^i);
    end for;
    return DD;
end function;
Di := function(d,p,n,i)     //creates ith class of dth power residues in GF(p,n)
    x := PrimitiveElement(GF(p,n))^i;
    return {GF(p,n)|x*a:a in D(d,p,n)};
end function;

C_union := function(A,d,p,n)  //creates union of cyclotomic classes over set A of indices
    X := {};
    for i in A do
        X := X join Di(d,p,n,i);
    end for;
    return X;
end function;

cTrans:=function(C,i)   //creates additive translate of union by i of dth power power residues
    X:={};
    for c in C do
        Include(~X,c+i);
    end for;
    return X;
end function;

CycBuild:=function(D,N,k,q)  //builds cyclic code of length N with D as defining set
    G:=ZeroMatrix(GF(q),k,N);
    for i in {1..k} do
        for j in {1..N} do
            if j-1 in cTrans(D,i-1,N) then
                G[i,j]:=1;
            else
                G[i,j]:=0;
            end if;
        end for;
    end for;
    return G;
end function;

ZeroCols:=function(G)   //creates set of zero columns of matrix
    X:={};
    for j in {1..NumberOfColumns(G)} do
        if Transpose(G)[j] eq ZeroMatrix(GF(2),1,NumberOfRows(G)) then
            Include(~X,j);
        end if;
    end for;
    return # X;
end function;

Build_supps:=function(C,l)   //collects supports of words in code into set
    X:={};
    for c in Words(C,l) do
        Include(~X,Support(c));
    end for;
    return X;
end function;

Check_ades:=function(b0,B,t); //check replication number of incidence structure
    X:={};
    for Y in Subsets(b0,t) do
        Z:={};
        for b in B do
            if Y subset b then
                Include(~Z,b);
            end if;
        end for;
        Include(~X,# Z);
    end for;
    return X;
end function;

Check_112:=function(F,B)  //checks whether incidence structure is a 1 1/2 design
    U:={};
    V:={};
    for x in F do
        for b in B do
            X:={};
            Y:={};
            for y in (b diff {x}) do
                for c in (B diff {b}) do
                    if y in c and x in c then
                        if x in b then
                            Include(~X,);
                        else
                            Include(~Y,);
                        end if;
                    end if;
                end for;
            end for;
            if x in b then
                Include(~U,# X);
            else
                Include(~V,# Y);
            end if;
        end for;
    end for;
    return [* U, V *];
end function;\
Here we carry out a search.
 d:=2;           //searches for 1 1/2 designs in codes
n:=1;
q:=2;
for p in {5..201} do
    if IsPrime(p) then
        if p^n mod d eq 1 then
            G:=Set(GF(p,n));
            for A in Subsets({0..d-1},1) do
                for k in {p} do
                    C:=LinearCode(CycBuild(C_union(A,d,p,n),p,k,q));
                    for l in {3..p} do
                        B:=Build_supps(C,l);
                        if B ne {} then
                            if # Check_112(G,B)[1] eq 1 and # Check_112(G,B)[2] eq 1 and {Check_112(G,B)[1],Check_112(G,B)[2]} ne {{0},{0}} then
                                print C,A,p,k,l,Check_112(G,B),Check_ades(G,B,1),Check_ades(G,B,2),ZeroCols(CycBuild(C_union(A,d,p,n),p,k,q));
                            end if;
                        end if;
                    end for;
                end for;
            end for;
        end if;
    end if;
end for;

Searching for symmetric incidence structures in finite fields with MAGMA

Here we write MAGMA code to search for difference sets and almost difference sets in finite fields. We begin by creating several functions.
 
D := function(d,p,n)                    //creates set of dth power residues in GF(p,n)
    x := PrimitiveElement(GF(p,n))^d;
    DD := {GF(p,n)|};
    for i in {0..p^n-1} do
        Include(~DD,x^i);
    end for;
    return DD;
end function;
Di := function(d,p,n,i)             //creates set ith class of dth power residues in GF(p,n)
    x := PrimitiveElement(GF(p,n))^i;
    return {GF(p,n)|x*a:a in D(d,p,n)};
end function;
C_union := function(A,d,p,n)            //creates union of cyclotomic classes over set A of indices
    X := {};
    for i in A do
        X := X join Di(d,p,n,i);
    end for;
    return X;
end function;
C_un_plus := function(A,d,p,n,w1)       //creates additive translate of union by w1 of dth power power residues
    X := {};
    for x in C_union(A,d,p,n) do
        Include(~X,x + w1);
    end for;
    return X;
end function;
C_C_un_plus := function(A,d,p,n,w1)   //returns intersection of union of classes with additive translate of union
    return C_union(A,d,p,n) meet C_un_plus(A,d,p,n,w1);
end function;
All_d_C := function(A,d,p,n)      //collects all intersection sizes into set and returns the set       
    Z := {};
    for w1 in GF(p,n) do
        Include(~Z,# C_C_un_plus(A,d,p,n,w1));
    end for;
    return Z;
end function;end function;
And here we carry out some searches.
 d:=6;
for n in {3} do   //searching in GF(7,3) for almost difference sets by taking unions of 6th power residues
for p in {7} do
    if IsPrime(p) then
        if p^n mod 6 eq 1 then    
            for A in Subsets({0..d-1}) do
                if # All_d_C(A,d,p,n) lt 10 then
                    print A,d,p,n,All_d_C(A,d,p,n);
                end if;
            end for;
        end if;
    end if;
end for;
end for;

d:=4;
n:=3;
for p in {5..101} do
    if IsPrime(p) then
        if p^n mod 4 eq 1 then    
            for A in Subsets({0,2},2) do
                if # All_d_C(A,d,p,n) eq 3 then
                    print A,d,p,n,All_d_C(A,d,p,n);
                end if;
            end for;
        end if;
    end if;
end for;

Wednesday, August 14, 2013

Berlekamp's Algorithm and Sage

We want to factor \(f(x)=x^8+x^6+x^4+x^3+1\) over \(\mathbb{F}_{2}\) using Berlekamp's algorithm. You can check up on the algorithm here: http://www.johnkerl.org/doc/iw2009/berlekamp.pdf It is easy to see that \(f'(x) = x^2\) does not divide \(f(x)\), but one can check this using the euclidean algorithm. In sage one checks this as follows:
 S.<x> = PolynomialRing(GF(2),'x')  
 f = x**8 + x**6 + x**4 + x**3 + 1; g = x**2  
 f.gcd(g)  
which will result in 1 when it is run. Next we compute \(x^{iq}\) (mod \(f(x)\)) for \(q=2, 0 <= i <= 7\). By using the Euclidean algorithm we get: $$x^0 \equiv 1$$ $$x^2 \equiv x^2$$ $$x^4 \equiv x^{4}$$ $$x^6 \equiv x^{6}$$ $$x^8 \equiv 1+x^3+x^4+x^6$$ $$x^{10} \equiv 1+x^2+x^4+x^5+x^6+x^7$$ $$x^{12} \equiv x^2+x^4+x^5+x^6+x^7$$ $$x^{14} \equiv 1+x+x^3+x^4+x^5$$ This gives us the matrix (now using sage again):
   
   
 [1 0 0 0 0 0 0 0]  
 [0 0 1 0 0 0 0 0]  
 [0 0 0 0 1 0 0 0]  
 [0 0 0 0 0 0 1 0]  
 [1 0 0 1 1 0 1 0]  
 [1 0 1 1 1 1 0 0]  
 [0 0 1 0 1 1 1 1]  
 [1 1 0 1 1 1 0 0]  
   
 
Then subtracting the identity matrix we get:
   
   
 [0 0 0 0 0 0 0 0]  
 [0 1 1 0 0 0 0 0]  
 [0 0 1 0 1 0 0 0]  
 [0 0 0 1 0 0 1 0]  
 [1 0 0 1 0 0 1 0]  
 [1 0 1 1 1 0 0 0]  
 [0 0 1 0 1 1 0 1]  
 [1 1 0 1 1 1 0 1]  
   
We can now use sage to find the basis of the null space of the above matrix as follows:
 M = MatrixSpace(GF(2), 8, 8)  
 A = M([0, 0, 0, 0, 0, 0, 0, 0,   
       0, 1, 1, 0, 0, 0, 0, 0,  
       0, 0, 1, 0, 1, 0, 0, 0,  
       0, 0, 0, 1, 0, 0, 1, 0,  
       1, 0, 0, 1, 0, 0, 1, 0,  
       1, 0, 1, 1, 1, 0, 0, 0,  
       0, 0, 1, 0, 1, 1, 0, 1,  
       1, 1, 0, 1, 1, 1, 0, 1])  
         
 A.kernel()  
Which will give the following result:
 Vector space of degree 8 and dimension 2 over Finite Field of size 2  
 Basis matrix:  
 [1 0 0 0 0 0 0 0]  
 [0 1 1 0 0 1 1 1]  
   
These correspond to the polynomials \(g_{1}(x)=1\) and \(g_{2}(x)=x+x^2+x^5+x^6+x^7\). Again using Euclidean algorithm we get \(gcd(f(x),g_{2}(x))=x^6+x^5+x^4+x+1\) and \(gcd(f(x),g_{2}(x)-1)=x^2+x+1\). Then, over \(\mathbb{F_{2}}\), the canonical factorization is: $$f(x)=(x^6+x^5+x^4+x+1)(x^2+x+1)$$

Sunday, August 11, 2013

Cubic Spline (natural) with Sage

A spline is a interpolating function. When data has a cubic shape (i.e. if plotted resembles the graph of a cubic polynomial) one can try to model the data using a cubic spline. A natural cubic spline must have a knot at every point and if x is an endpoint, the f''(x) = 0. The following shows how to find a cubic spline in Sage with the five points given by: X = (0, 1.5, 3, 4.5, 6), Y = (1, 4, .5, 0, 3.5). I had some help from here:


1:  import numpy as np  
2:    
3:  # Array Array Array -> Array Array Array  
4:  # interp. helper function whose input is three parameters (from data_curvtr function) and output is three parameters  
5:  # to give to the first3solv function  
6:    
7:  def first3(c,d,e):  
8:    n = d.shape[0]  
9:    for i in xrange(1,n):  
10:      kappa = c[i-1]/d[i-1]  
11:      d[i] = d[i] - kappa*e[i-1]  
12:      c[i-1] = kappa  
13:    return c,d,e  
14:    
15:  # Array Array Array Array -> Array  
16:  # interp. helper function whose input is four arrays (three from the first3 function, and one from the data_curvtr  # function) whose output is a single array  
17:    
18:  def first3solv(c,d,e,b):  
19:    n = d.shape[0]  
20:    for i in xrange(1,n):  
21:      b[i] = b[i] - c[i-1]*b[i-1]  
22:    
23:    b[n-1] = b[n-1]/d[n-1]  
24:    for i in xrange(n-2,-1,-1):  
25:      b[i] = (b[i] - e[i]*b[i+1])/d[i]  
26:    
27:    return b  
28:    
29:  # Array Array -> Array  
30:  # interp. consumes a list of x-values and a list of y-values and returns the curvatures to be used in the cubic spline  
31:  # algorithm  
32:          
33:  def data_curvtr(xArray,yArray):  
34:    n = len(xArray) - 1  
35:    c = np.zeros(n)  
36:    d = np.ones(n+1)  
37:    e = np.zeros(n)  
38:    k = np.zeros(n+1)  
39:    c[0:n-1]= xArray[0:n-1] - xArray[1:n]  
40:    d[1:n] = 2.0*(xArray[0:n-1] - xArray[2:n+1])  
41:    e[1:n] = xArray[1:n] - xArray[2:n+1]  
42:    k[1:n] = 6.0*(yArray[0:n-1] - yArray[1:n]) \  
43:      /(xArray[0:n-1] - xArray[1:n]) \  
44:      -6.0*(yArray[1:n] - yArray[2:n+1]) \  
45:      /(xArray[1:n] - xArray[2:n+1])  
46:    first3(c,d,e)  
47:    print "c =",c,"d =",d,"e =",e  
48:    first3solv(c,d,e,k)  
49:    return k  
50:    
51:  # Array Array Array Number -> Number  
52:  # interp. consumes the data lists, the curvatures, and an x-value, and carries out the cubic spline algorithm   
53:  # to produce the height of the spline at the x-value  
54:    
55:    
56:  def get_spline(xArray,yArray,k,x):  
57:    def get_segment(xArray,x):  
58:      i_left = 0  
59:      i_right = len(xArray)- 1  
60:      while 1:  
61:        if (i_right-i_left)<=1: return i_left  
62:        i=(i_left+i_right)//2  
63:        if x < xArray[i]: i_right=i  
64:        else: i_left=i  
65:    i=get_segment(xArray,x)  
66:    h = xArray[i]-xArray[i+1]   
67:    y = ((x-xArray[i+1])**3/h-(x-xArray[i+1])*h)*k[i]/6.0 \  
68:      - ((x-xArray[i])**3/h-(x-xArray[i])*h)*k[i+1]/6.0 \  
69:      + (yArray[i]*(x-xArray[i+1])           \  
70:      - yArray[i+1]*(x-xArray[i]))/h  
71:    return y   
72:    
73:  xA1=np.array([0.,1.5,3.,4.5,6.])  
74:  yA1=np.array([1.,4.,.5,0.,3.5])  
75:  print "X =",xA1,"Y =",yA1   
76:    
77:  k= data_curvtr(xA1,yA1)  
78:  print "k =",k  
79:    
80:  y= get_spline(xA1,yA1,k,.5)  
81:  print "y =",y  
82:    
83:  var ( 'x t' )  
84:  n=len(xA1)  
85:  P=list_plot(zip(xA1,yA1), color="green", size=30)  
86:  C=sum(point((t,get_spline(xA1,yA1,k,t))) for t in [xA1[0]..xA1[n-1], step=0.1])  
87:  show(P+C)  


In the above code I have found a cubic spline for the following five points: X = (0, 1.5, 3, 4.5, 6), Y = (1, 4, .5, 0, 3.5) (one can see these entered in lines 73 and 74 above). When run in sage you get:

 X = [ 0.  1.5 3.  4.5 6. ] Y = [ 1.  4.  0.5 0.  3.5]  
 c = [-1.5     0.25    0.26666667 -0.    ] d = [ 1.  -6.  -5.625 -5.6  1.  ] e = [ 0. -1.5 -1.5 -1.5]  
 k = [ 0.     -5.02380952 2.76190476 1.97619048 0.    ]  
 y = 2.5582010582  

Saturday, August 3, 2013

Circle Fractal using DrRacket

1:  (require 2htdp/image)  
2:    
3:    
4:  ;; =================  
5:  ;; Constants:  
6:    
7:  (define STEP (/ 2 5))  
8:  (define TRIVIAL-SIZE 5)  
9:    
10:  ;; Funtions  
11:    
12:  ;; Number -> Image  
13:  ;; produce the above fractal of the given size  
14:  (check-expect (circle_frac TRIVIAL-SIZE) (circle 5 "solid" "darkgreen"))  
15:  (check-expect (circle_frac (* (/ 5 2) TRIVIAL-SIZE))  
16:         (local [(define sub (circle 5 "solid" "darkgreen"))]  
17:          (above sub  
18:              (beside sub (circle (* (/ 5 2) TRIVIAL-SIZE) "solid" "darkgreen") sub)  
19:              sub)))  
20:    
21:    
22:  ;(define (circle_frac s)      ;stub  
23:  ; (square 0 "solid" "white"))  
24:    
25:  (define (circle_frac s)  
26:   (if (<= s TRIVIAL-SIZE)  
27:     (circle s "solid" "darkgreen")  
28:     (local [(define sub (circle_frac (* STEP s)))]  
29:      (above sub  
30:          (beside sub (circle s "solid" "darkgreen") sub)  
31:          sub))))  
32:    
33:    
34:    

Simple text editor with Dr Racket

1:  (require 2htdp/image)  
2:  (require 2htdp/universe)  
3:    
4:  ;;
5:  ;;  
6:  ;;  
7:  ;;  
8:  ;; The screen looks like:  
9:  ;;   
10:  ;;   abc|def  
11:  ;;  
12:  ;; where | is the cursor.  
13:  ;;  
14:  ;; Typing a character inserts that character before the cursor.  
15:  ;; The backspace key deletes the character before the cursor.  
16:  ;; The left and right arrow keys move the cursor left and right.  
17:    
18:    
19:    
20:  ;; =================================================================================  
21:  ;; Constants:  
22:    
23:  (define WIDTH 200)  
24:  (define HEIGHT 20)  
25:    
26:  (define TEXT-SIZE 18)  
27:  (define TEXT-COLOR "BLACK")  
28:    
29:  (define CURSOR (rectangle 1 20 "solid" "red"))  
30:    
31:  (define MTS (empty-scene WIDTH HEIGHT))  
32:    
33:    
34:    
35:  ;; =================================================================================  
36:  ;; Data Definitions:  
37:    
38:  (define-struct editor (txt cp))  
39:  ;; Editor is (make-editor String Natural)  
40:  ;; interp. the current text (txt) and cursor position (cp) using a 0-based index  
41:    
42:  (define ED1 (make-editor ""    0)) ; empty  
43:  (define ED2 (make-editor "abcdef" 0)) ; cursor at beginning as in |abcdef  
44:  (define ED3 (make-editor "abcdef" 3)) ; cursor in middle of text as in abc|def  
45:  (define ED4 (make-editor "abcdef" 6)) ; cursor at end as in abcdef|  
46:    
47:  #;  
48:  (define (fn-for-editor e)  
49:   (... (editor-txt e)  
50:      (editor-cp e)))  
51:    
52:  ;; =================================================================================  
53:  ;; Functions:  
54:    
55:  ;; Editor -> Editor  
56:  ;; start the world with an initial state e, for example (main (make-editor "" 0))  
57:  (define (main e)  
58:   (big-bang e  
59:        (to-draw  render)         ; Editor -> Image  
60:        (on-key   handle-key)))      ; Editor KeyEvent -> Editor  
61:    
62:    
63:    
64:  ;; Editor -> Image  
65:  ;; place text with cursor at left, middle edge of MTS  
66:  (check-expect (render (make-editor "abcdef" 3))  
67:         (overlay/align "left"  
68:                 "middle"  
69:                 (beside (text "abc" TEXT-SIZE TEXT-COLOR)  
70:                     CURSOR  
71:                     (text "def" TEXT-SIZE TEXT-COLOR))  
72:                 MTS))  
73:    
74:  ;(define (render e) MTS) ;stub  
75:    
76:  (define (render e)  
77:   (overlay/align "left"  
78:           "middle"  
79:           (beside (text (substring (editor-txt e) 0 (editor-cp e)) TEXT-SIZE TEXT-COLOR)  
80:               CURSOR  
81:               (text (substring (editor-txt e) (editor-cp e) (string-length (editor-txt e))) TEXT-SIZE TEXT-COLOR))  
82:           MTS))  
83:    
84:    
85:    
86:  ;; Editor KeyEvent -> Editor  
87:  ;; call appropriate function for each keyboard command  
88:    
89:    
90:  ;(define (handle-key e key) e) ;stub  
91:  (check-expect (curs-left ED1) ED1)  
92:  (check-expect (curs-left ED2) ED2)  
93:  (check-expect (curs-left ED3) (make-editor "abcdef" 2))  
94:  (check-expect (curs-left ED4) (make-editor "abcdef" 5))  
95:    
96:  (define (handle-key e key)  
97:   (cond [(key=? key "left")    (curs-left e)]  
98:      [(key=? key "right")    (curs-right e)]  
99:      [(key=? key "\b")     (take-out e)]      
100:      [(= (string-length key) 1) (write e key)]  
101:      [else (make-editor (editor-txt e) (editor-cp e))]))  
102:    
103:  ; Note:   
104:  ; "left" is the left arrow key, "right" is the right arrow key, and   
105:  ; "\b" is the backspace key.  
106:    
107:    
108:  ;; Editor -> Editor  
109:  ;; consumes editor and returns editor with cursor position decreased by one  
110:  (check-expect (curs-left ED1) ED1)  
111:  (check-expect (curs-left ED2) ED2)  
112:  (check-expect (curs-left ED3) (make-editor "abcdef" 2))  
113:  (check-expect (curs-left ED4) (make-editor "abcdef" 5))  
114:    
115:  (define (curs-left e)  
116:   (if (> (editor-cp e) 0)  
117:     (make-editor (editor-txt e) (- (editor-cp e) 1))  
118:     (make-editor (editor-txt e) (editor-cp e))))  
119:  ;; Editor -> Editor  
120:  ;; consumes editor and returns editor with cursor position increased by one  
121:  (check-expect (curs-right ED1) (make-editor "" 0))  
122:  (check-expect (curs-right ED2) (make-editor "abcdef" 1))  
123:  (check-expect (curs-right ED3) (make-editor "abcdef" 4))  
124:  (check-expect (curs-right ED4) (make-editor "abcdef" 6))  
125:    
126:  (define (curs-right e)  
127:   (if (< (editor-cp e) (string-length (editor-txt e)))  
128:       (make-editor (editor-txt e) (+ (editor-cp e) 1))  
129:       (make-editor (editor-txt e) (editor-cp e))))  
130:    
131:  ;; Editor -> Editor  
132:  ;; deletes one character from the editor, leaving cursor in place of deleted character  
133:  (check-expect (take-out ED1) ED1)  
134:  (check-expect (take-out ED2) ED2)  
135:  (check-expect (take-out ED3) (make-editor "abdef" 2))  
136:  (check-expect (take-out ED4) (make-editor "abcde" 5))  
137:    
138:  (define (take-out e)  
139:   (make-editor (string-append (substring (editor-txt e) 0 (editor-cp (curs-left e)))   
140:                 (substring (editor-txt e) (editor-cp e))) (editor-cp (curs-left e))))  
141:  ;; Editor String -> Editor  
142:  ;; inserts characters corresponding to keys on keyboard into   
143:  ;; the editor and cursor position  
144:  (check-expect (write ED3 "what?") (make-editor "abcwhat?def" 4))  
145:    
146:  (define (write e s)  
147:   (make-editor (string-append (substring (editor-txt e)   
148:                          0 (editor-cp e))   
149:                          s (substring (editor-txt e) (editor-cp e)   
150:                          (string-length (editor-txt e))))   
151:                          (+ (editor-cp e) 1)))  
152:    
153:  (main (make-editor "abcdef" 3))  
154:    
155:    

Simple world using big bang with DrRacket (click and rain drops appear at position of cursor)

1:  (require 2htdp/image)  
2:  (require 2htdp/universe)  
3:    
4:    
5:    
6:  ;; =================  
7:  ;; Constants:  
8:    
9:  (define WIDTH 300)  
10:  (define HEIGHT 300)  
11:    
12:  (define SPEED 1)  
13:    
14:  (define DROP (ellipse 4 8 "solid" "blue"))  
15:    
16:  (define MTS (rectangle WIDTH HEIGHT "solid" "light blue"))  
17:    
18:  ;; =================  
19:  ;; Data definitions:  
20:    
21:  (define-struct drop (x y))  
22:  ;; Drop is (make-drop Integer Integer)  
23:  ;; interp. A raindrop on the screen, with x and y coordinates.  
24:    
25:  (define D1 (make-drop 10 30))  
26:    
27:  #;  
28:  (define (fn-for-drop d)  
29:   (... (drop-x d)   
30:      (drop-y d)))  
31:    
32:  ;; Template Rules used:  
33:  ;; - compound: 2 fields  
34:    
35:    
36:  ;; ListOfDrop is one of:  
37:  ;; - empty  
38:  ;; - (cons Drop ListOfDrop)  
39:  ;; interp. a list of drops  
40:    
41:  (define LOD1 empty)  
42:  (define LOD2 (cons (make-drop 10 20) (cons (make-drop 3 6) empty)))  
43:    
44:  #;  
45:  (define (fn-for-lod lod)  
46:   (cond [(empty? lod) (...)]  
47:      [else  
48:       (... (fn-for-drop (first lod))  
49:         (fn-for-lod (rest lod)))]))  
50:    
51:  ;; Template Rules used:  
52:  ;; - one-of: 2 cases  
53:  ;; - atomic distinct: empty  
54:  ;; - compound: (cons Drop ListOfDrop)  
55:  ;; - reference: (first lod) is Drop  
56:  ;; - self reference: (rest lod) is ListOfDrop  
57:    
58:  ;; =================  
59:  ;; Functions:  
60:    
61:  ;; ListOfDrop -> ListOfDrop  
62:  ;; start rain program by evaluating (main empty)  
63:  (define (main lod)  
64:   (big-bang lod  
65:        (on-mouse handle-mouse)  ; ListOfDrop Integer Integer MouseEvent -> ListOfDrop  
66:        (on-tick next-drops)   ; ListOfDrop -> ListOfDrop  
67:        (to-draw render-drops))) ; ListOfDrop -> Image  
68:    
69:    
70:  ;; ListOfDrop Integer Integer MouseEvent -> ListOfDrop  
71:  ;; if mevt is "button-down" add a new drop at that position  
72:  ;; !!!  
73:  ;(define (handle-mouse lod x y mevt) empty) ; stub  
74:    
75:  (define (handle-mouse lod x y mevt)  
76:   (if (mouse=? mevt "button-down")  
77:     (cons (make-drop x y) lod)  
78:     lod))  
79:    
80:  ;; ListOfDrop -> ListOfDrop  
81:  ;; produce filtered and ticked list of drops  
82:  ;; !!!  
83:  ;(define (next-drops lod) empty) ; stub  
84:    
85:  (define (next-drops lod)  
86:   (cond [(empty? lod) lod]  
87:      [else  
88:       (cons (make-drop (drop-x (first lod)) (+ (drop-y (first lod)) SPEED))  
89:       (next-drops (rest lod)))]))  
90:    
91:    
92:  ;; ListOfDrop -> Image  
93:  ;; Render the drops onto MTS  
94:  ;; !!!  
95:  ;(define (render-drops lod) MTS) ; stub  
96:    
97:  (define (render-drops lod)  
98:   (cond [(empty? lod) MTS]  
99:      [else  
100:       (if (< (drop-y (first lod)) HEIGHT)  
101:         (place-image DROP (drop-x (first lod)) (drop-y (first lod))  
102:               (render-drops (rest lod)))  
103:         (render-drops (rest lod)))]))  
104:    
105:  ;(define (place-drop lod)  
106:  ; (cond [(empty? lod) lod]  
107:  ;    [else  
108:  ;     (... (fn-for-drop (first lod))  
109:  ;       (place-drop (rest lod)))]))  
110:    
111:  (define (place-drop d)  
112:   (if (< (drop-y d) HEIGHT)  
113:     (place-image DROP (drop-x d) (drop-y d) MTS)  
114:     (...)))  
115:       
116:    
117:  (main empty)  
118:    
119:    

Asteroids with Python (for codeskulptor)


1:  import simplegui  
2:  import math  
3:  import random  
4:    
5:  # globals for user interface  
6:  WIDTH = 800  
7:  HEIGHT = 600  
8:  score = 0  
9:  lives = 3  
10:  time = 0.5  
11:  started = False  
12:  rock_group = set()  
13:  missile_group = set()  
14:  explosion_group = set()  
15:  collisions = 0  
16:  n_collisions = 0  
17:  r_collisions = 0  
18:    
19:  class ImageInfo:  
20:    def __init__(self, center, size, radius = 0, lifespan = None, animated = False):  
21:      self.center = center  
22:      self.size = size  
23:      self.radius = radius  
24:      if lifespan:  
25:        self.lifespan = lifespan  
26:      else:  
27:        self.lifespan = float('inf')  
28:      self.animated = animated  
29:    
30:    def get_center(self):  
31:      return self.center  
32:    
33:    def get_size(self):  
34:      return self.size  
35:    
36:    def get_radius(self):  
37:      return self.radius  
38:    
39:    def get_lifespan(self):  
40:      return self.lifespan  
41:    
42:    def get_animated(self):  
43:      return self.animated  
44:    
45:      
46:  # art assets created by Kim Lathrop, may be freely re-used in non-commercial projects, please credit Kim  
47:      
48:  # debris images - debris1_brown.png, debris2_brown.png, debris3_brown.png, debris4_brown.png  
49:  #         debris1_blue.png, debris2_blue.png, debris3_blue.png, debris4_blue.png, debris_blend.png  
50:  debris_info = ImageInfo([320, 240], [640, 480])  
51:  debris_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png")  
52:    
53:  # nebula images - nebula_brown.png, nebula_blue.png  
54:  nebula_info = ImageInfo([400, 300], [800, 600])  
55:  nebula_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_blue.png")  
56:    
57:  # splash image  
58:  splash_info = ImageInfo([200, 150], [400, 300])  
59:  splash_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png")  
60:    
61:  # ship image  
62:  ship_info = ImageInfo([45, 45], [90, 90], 35)  
63:  ship_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png")  
64:    
65:  # missile image - shot1.png, shot2.png, shot3.png  
66:  missile_info = ImageInfo([5,5], [10, 10], 3, 50)  
67:  missile_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png")  
68:    
69:  # asteroid images - asteroid_blue.png, asteroid_brown.png, asteroid_blend.png  
70:  asteroid_info = ImageInfo([45, 45], [90, 90], 40)  
71:  asteroid_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png")  
72:    
73:  # animated explosion - explosion_orange.png, explosion_blue.png, explosion_blue2.png, explosion_alpha.png  
74:  explosion_info = ImageInfo([64, 64], [128, 128], 17, 24, True)  
75:  explosion_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png")  
76:    
77:  # sound assets purchased from sounddogs.com, please do not redistribute  
78:  # .ogg versions of sounds are also available, just replace .mp3 by .ogg  
79:  soundtrack = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.ogg")  
80:  missile_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.ogg")  
81:  missile_sound.set_volume(.5)  
82:  ship_thrust_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.ogg")  
83:  explosion_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg")  
84:    
85:  # helper functions to handle transformations  
86:  def angle_to_vector(ang):  
87:    return [math.cos(ang), math.sin(ang)]  
88:    
89:  def dist(p, q):  
90:    return math.sqrt((p[0] - q[0]) ** 2 + (p[1] - q[1]) ** 2)  
91:    
92:    
93:  # Ship class  
94:  class Ship:  
95:    
96:    def __init__(self, pos, vel, angle, image, info):  
97:      self.pos = [pos[0], pos[1]]  
98:      self.vel = [vel[0], vel[1]]  
99:      self.thrust = False  
100:      self.angle = angle  
101:      self.angle_vel = 0  
102:      self.image = image  
103:      self.image_center = info.get_center()  
104:      self.image_size = info.get_size()  
105:      self.radius = info.get_radius()  
106:        
107:    def draw(self,canvas):  
108:      if self.thrust:  
109:        canvas.draw_image(self.image, [self.image_center[0] + self.image_size[0], self.image_center[1]] , self.image_size,  
110:                 self.pos, self.image_size, self.angle)  
111:      else:  
112:        canvas.draw_image(self.image, self.image_center, self.image_size,  
113:                 self.pos, self.image_size, self.angle)  
114:      # canvas.draw_circle(self.pos, self.radius, 1, "White", "White")  
115:    
116:    def update(self):  
117:      # update angle  
118:      self.angle += self.angle_vel  
119:        
120:      # update position  
121:      self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH  
122:      self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT  
123:    
124:      # update velocity  
125:      if self.thrust:  
126:        acc = angle_to_vector(self.angle)  
127:        self.vel[0] += acc[0] * .5  
128:        self.vel[1] += acc[1] * .5  
129:          
130:      self.vel[0] *= .95  
131:      self.vel[1] *= .95  
132:    
133:    def set_thrust(self, on):  
134:      self.thrust = on  
135:      if on:  
136:        ship_thrust_sound.rewind()  
137:        ship_thrust_sound.play()  
138:      else:  
139:        ship_thrust_sound.pause()  
140:        
141:    def increment_angle_vel(self):  
142:      self.angle_vel += .05  
143:        
144:    def decrement_angle_vel(self):  
145:      self.angle_vel -= .05  
146:        
147:    def shoot(self):  
148:      global a_missile  
149:      forward = angle_to_vector(self.angle)  
150:      missile_pos = [self.pos[0] + self.radius * forward[0], self.pos[1] + self.radius * forward[1]]  
151:      missile_vel = [self.vel[0] + 6 * forward[0], self.vel[1] + 6 * forward[1]]  
152:      a_missile = Sprite(missile_pos, missile_vel, self.angle, 0, missile_image, missile_info, missile_sound)  
153:      missile_group.add(a_missile)  
154:      
155:      
156:      
157:  # Sprite class  
158:  class Sprite:  
159:    def __init__(self, pos, vel, ang, ang_vel, image, info, sound = None):  
160:      self.pos = [pos[0],pos[1]]  
161:      self.vel = [vel[0],vel[1]]  
162:      self.angle = ang  
163:      self.angle_vel = ang_vel  
164:      self.image = image  
165:      self.image_center = info.get_center()  
166:      self.image_size = info.get_size()  
167:      self.radius = info.get_radius()  
168:      self.lifespan = info.get_lifespan()  
169:      self.animated = info.get_animated()  
170:      self.age = 0  
171:      if sound:  
172:        sound.rewind()  
173:        sound.play()  
174:      
175:    def draw(self, canvas):  
176:      if self.animated == True:  
177:        center = [self.image_center[0] + 2*self.image_center[0]*self.age, self.image_center[1]]  
178:        canvas.draw_image(self.image, center, self.image_size,  
179:               self.pos, self.image_size, self.angle)  
180:      else:  
181:        canvas.draw_image(self.image, self.image_center, self.image_size,  
182:               self.pos, self.image_size, self.angle)  
183:    
184:    def update(self):  
185:      # update angle  
186:      self.angle += self.angle_vel  
187:        
188:      # update position  
189:      self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH  
190:      self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT  
191:      self.age += 1  
192:      if self.age >= self.lifespan:  
193:        return True  
194:      else:  
195:        return False  
196:        
197:    def collide(self, other_object):  
198:      if dist(self.pos, other_object.pos) > self.radius + other_object.radius:  
199:        return False  
200:      else:  
201:        return True  
202:          
203:     
204:        
205:  # key handlers to control ship    
206:  def keydown(key):  
207:    if key == simplegui.KEY_MAP['left']:  
208:      my_ship.decrement_angle_vel()  
209:    elif key == simplegui.KEY_MAP['right']:  
210:      my_ship.increment_angle_vel()  
211:    elif key == simplegui.KEY_MAP['up']:  
212:      my_ship.set_thrust(True)  
213:    elif key == simplegui.KEY_MAP['space']:  
214:      my_ship.shoot()  
215:        
216:  def keyup(key):  
217:    if key == simplegui.KEY_MAP['left']:  
218:      my_ship.increment_angle_vel()  
219:    elif key == simplegui.KEY_MAP['right']:  
220:      my_ship.decrement_angle_vel()  
221:    elif key == simplegui.KEY_MAP['up']:  
222:      my_ship.set_thrust(False)  
223:        
224:  # mouseclick handlers that reset UI and conditions whether splash image is drawn  
225:  def click(pos):  
226:    global started, lives, score  
227:    center = [WIDTH / 2, HEIGHT / 2]  
228:    size = splash_info.get_size()  
229:    inwidth = (center[0] - size[0] / 2) < pos[0] < (center[0] + size[0] / 2)  
230:    inheight = (center[1] - size[1] / 2) < pos[1] < (center[1] + size[1] / 2)  
231:    if (not started) and inwidth and inheight:  
232:      started = True  
233:      lives = 3  
234:      score = 0  
235:      soundtrack.play()  
236:    
237:  def draw(canvas):  
238:    global time, started, lives, score, rock_group  
239:      
240:    # animiate background  
241:    time += 1  
242:    center = debris_info.get_center()  
243:    size = debris_info.get_size()  
244:    wtime = (time / 8) % center[0]  
245:    canvas.draw_image(nebula_image, nebula_info.get_center(), nebula_info.get_size(), [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])  
246:    canvas.draw_image(debris_image, [center[0] - wtime, center[1]], [size[0] - 2 * wtime, size[1]],   
247:                  [WIDTH / 2 + 1.25 * wtime, HEIGHT / 2], [WIDTH - 2.5 * wtime, HEIGHT])  
248:    canvas.draw_image(debris_image, [size[0] - wtime, center[1]], [2 * wtime, size[1]],   
249:                  [1.25 * wtime, HEIGHT / 2], [2.5 * wtime, HEIGHT])  
250:    
251:    if group_collide(rock_group, my_ship) > 0:  
252:      lives -= 1  
253:        
254:    if group_group_collide(rock_group, missile_group) > 0:  
255:      score += 1  
256:        
257:    if lives == 0:  
258:      started = False  
259:      rock_group = set()  
260:      soundtrack.rewind()  
261:      lives = 3  
262:        
263:    # draw UI  
264:    canvas.draw_text("Lives", [50, 50], 22, "White")  
265:    canvas.draw_text("Score", [680, 50], 22, "White")  
266:    canvas.draw_text(str(lives), [50, 80], 22, "White")  
267:    canvas.draw_text(str(score), [680, 80], 22, "White")  
268:    
269:    # draw ship and sprites  
270:    my_ship.draw(canvas)  
271:      
272:    process_sprite_group(rock_group, canvas)  
273:    process_sprite_group(missile_group, canvas)  
274:    process_sprite_group(explosion_group, canvas)  
275:      
276:        
277:    for a_missile in set(missile_group):  
278:      if a_missile.age >= a_missile.lifespan:  
279:        missile_group.remove(a_missile)  
280:      else:  
281:        pass  
282:      a_missile.draw(canvas)  
283:      a_missile.update()  
284:      
285:    # update ship and sprites  
286:    my_ship.update()  
287:    
288:    # draw splash screen if not started  
289:    if not started:  
290:      canvas.draw_image(splash_image, splash_info.get_center(),   
291:               splash_info.get_size(), [WIDTH / 2, HEIGHT / 2],   
292:               splash_info.get_size())  
293:    
294:  # timer handler that spawns a rock    
295:  def rock_spawner():  
296:    global a_rock, rock_group, score  
297:    if started:  
298:      if len(rock_group) < 12:  
299:        rock_pos = [random.randrange(0, WIDTH), random.randrange(0, HEIGHT)]  
300:        rock_vel = [random.random() * .6 - .3, random.random() * .6 - .3]  
301:        rock_avel = random.random() * .2 - .1  
302:        if score > 10:  
303:          rock_vel[0] *= 4  
304:          rock_vel[1] *= 4  
305:        elif score > 20:  
306:          rock_vel[0] *= 6  
307:          rock_vel[1] *= 6  
308:        elif score > 30:  
309:          rock_vel[0] *= 10  
310:          rock_vel[1] *= 10  
311:        elif score > 40:  
312:          rock_vel[0] *= 20  
313:          rock_vel[1] *= 20  
314:            
315:        a_rock = Sprite(rock_pos, rock_vel, 0, rock_avel, asteroid_image, asteroid_info)  
316:        if dist(my_ship.pos, rock_pos) > 3*my_ship.radius:  
317:          rock_group.add(a_rock)  
318:        else:  
319:          pass  
320:      else:  
321:        pass  
322:      
323:  def process_sprite_group(group, canvas):  
324:    global collisions, lives  
325:      
326:    for sprite in set(group):  
327:      sprite.draw(canvas)  
328:      if sprite.update() == True:  
329:        group.remove(sprite)  
330:      else:  
331:        pass  
332:        
333:      sprite.update()  
334:    
335:  def group_collide(group, sprite):  
336:    global collisions, explosion_group  
337:    for item in set(group):  
338:      if item.collide(sprite) == True:  
339:        group.remove(item)  
340:        exp = Sprite(item.pos, [0, 0], 0, 0, explosion_image, explosion_info, explosion_sound)  
341:        explosion_group.add(exp)  
342:        collisions += 1  
343:        return collisions  
344:      else:  
345:        pass  
346:       
347:        
348:  def group_group_collide(group1, group2):  
349:    global n_collisions, r_collisions  
350:    for item1 in set(group1):  
351:      if group_collide(group2, item1) > 0:  
352:        r_collisions += 1  
353:        group1.remove(item1)  
354:        return r_collisions  
355:      else:  
356:        pass  
357:          
358:    
359:          
360:  # initialize stuff  
361:  frame = simplegui.create_frame("Asteroids", WIDTH, HEIGHT)  
362:    
363:  # initialize ship and two sprites  
364:  my_ship = Ship([WIDTH / 2, HEIGHT / 2], [0, 0], 0, ship_image, ship_info)  
365:    
366:  #a_rock = Sprite([WIDTH / 3, HEIGHT / 3], [1, 1], 0, .1, asteroid_image, asteroid_info)  
367:  #a_missile = Sprite([2 * WIDTH / 3, 2 * HEIGHT / 3], [-1,1], 0, 0, missile_image, missile_info, missile_sound)  
368:    
369:    
370:  # register handlers  
371:  frame.set_keyup_handler(keyup)  
372:  frame.set_keydown_handler(keydown)  
373:  frame.set_mouseclick_handler(click)  
374:  frame.set_draw_handler(draw)  
375:    
376:  timer = simplegui.create_timer(1000.0, rock_spawner)  
377:    
378:  # get things rolling  
379:  timer.start()  
380:  frame.start()  
381:    
382:    

Friday, August 2, 2013

Blackjack with Python (for codeskulptor)

1:  import simplegui  
2:  import random  
3:    
4:  # load card sprite - 949x392 - source: jfitz.com  
5:  CARD_SIZE = (73, 98)  
6:  CARD_CENTER = (36.5, 49)  
7:  card_images = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/cards.jfitz.png")  
8:    
9:  CARD_BACK_SIZE = (71, 96)  
10:  CARD_BACK_CENTER = (35.5, 48)  
11:  card_back = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/card_back.png")    
12:    
13:  # initialize some useful global variables  
14:  in_play = False  
15:  message1 = ""  
16:  wins = 0  
17:  losses = 0  
18:    
19:  # define globals for cards  
20:  SUITS = ('C', 'S', 'H', 'D')  
21:  RANKS = ('A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K')  
22:  VALUES = {'A':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':10, 'Q':10, 'K':10}  
23:    
24:    
25:  # define card class  
26:  class Card:  
27:    def __init__(self, suit, rank):  
28:      if (suit in SUITS) and (rank in RANKS):  
29:        self.suit = suit  
30:        self.rank = rank  
31:      else:  
32:        self.suit = None  
33:        self.rank = None  
34:        print "Invalid card: ", suit, rank  
35:    
36:    def __str__(self):  
37:      return self.suit + self.rank  
38:    
39:    def get_suit(self):  
40:      return self.suit  
41:    
42:    def get_rank(self):  
43:      return self.rank  
44:    
45:    def draw(self, canvas, pos):  
46:      card_loc = (CARD_CENTER[0] + CARD_SIZE[0] * RANKS.index(self.rank),   
47:            CARD_CENTER[1] + CARD_SIZE[1] * SUITS.index(self.suit))  
48:      canvas.draw_image(card_images, card_loc, CARD_SIZE, [pos[0] + CARD_CENTER[0], pos[1] + CARD_CENTER[1]], CARD_SIZE)  
49:        
50:    def draw_back(self, canvas, pos):  
51:      card_loc = (CARD_BACK_CENTER[0], CARD_BACK_CENTER[1])  
52:      canvas.draw_image(card_back, card_loc, CARD_BACK_SIZE, [pos[0] + CARD_CENTER[0], pos[1] + CARD_BACK_CENTER[1]], CARD_BACK_SIZE)  
53:        
54:        
55:  # define hand class  
56:  class Hand:  
57:    def __init__(self):  
58:      self.cards = []  
59:      pass     # create Hand object  
60:    
61:    def __str__(self):  
62:      ans = " "  
63:      for i in range(len(self.cards)):  
64:        ans += str(self.cards[i]) + " "  
65:      return "Hand contains" + ans  
66:      pass     # return a string representation of a hand  
67:    
68:    def add_card(self, card):  
69:      self.cards.append(card)  
70:      pass     # add a card object to a hand  
71:        
72:    def get_value(self):  
73:      hand_value = 0  
74:      check = 0  
75:      for card in self.cards:  
76:        card_rank = card.get_rank()  
77:        hand_value += VALUES[card.get_rank()]  
78:        if card_rank == 'A':  
79:          check += 1  
80:        else:  
81:          pass  
82:      if check != 0:  
83:        if hand_value + 10 <= 21:  
84:          hand_value += 10  
85:        else:  
86:          pass  
87:          
88:      return hand_value  
89:          
90:      # count aces as 1, if the hand has an ace, then add 10 to hand value if it doesn't bust  
91:      pass     # compute the value of the hand, see Blackjack video    
92:    
93:      
94:    def draw(self, canvas, pos):  
95:                       
96:      for card in self.cards:  
97:        if pos == [100, 350]:  
98:          if in_play == True:   
99:            card.draw_back(canvas, pos)  
100:          else:  
101:            card.draw(canvas, pos)  
102:        else:  
103:          card.draw(canvas, pos)  
104:        
105:        pos[0] += 50  
106:    
107:      pass     # draw a hand on the canvas, use the draw method for cards  
108:     
109:        
110:  # define deck class   
111:  class Deck:  
112:    def __init__(self):  
113:      self.card = []  
114:      for suit in SUITS:  
115:        for rank in RANKS:  
116:          self.card.append(Card(suit, rank))  
117:      pass     # create a Deck object  
118:    
119:    def shuffle(self):  
120:      # add cards back to deck and shuffle  
121:      self.card_shuffled = random.shuffle(self.card)  
122:      pass     # use random.shuffle() to shuffle the deck  
123:    
124:    def deal_card(self):  
125:      return self.card.pop()  
126:      pass     # deal a card object from the deck  
127:      
128:    def __str__(self):  
129:      s = ""  
130:      for i in self.card:  
131:        s += str(i) + " "  
132:      return s  
133:      pass     # return a string representing the deck   
134:    
135:    
136:    
137:  #define event handlers for buttons  
138:  def deal():  
139:    global outcome, in_play, p_hand, d_hand, deck, message1, message2, wins, losses  
140:    message1 = "Hit, Stand, or New Deal?"  
141:    deck = Deck()  
142:    deck.shuffle()  
143:    p_hand = Hand()  
144:    d_hand = Hand()  
145:    p_hand.add_card(deck.deal_card())  
146:    p_hand.add_card(deck.deal_card())  
147:    d_hand.add_card(deck.deal_card())  
148:    d_hand.add_card(deck.deal_card())  
149:    if in_play == True:  
150:      message1 = "Dealer Won-Hit, Stand or New Deal?"  
151:      losses += 1  
152:    print "Player's", p_hand  
153:    print "Dealer's", d_hand  
154:    print message1  
155:    print wins - losses  
156:    
157:    # your code goes here  
158:      
159:    in_play = True  
160:    
161:  def hit():  
162:    global message1, in_play, losses, wins  
163:    if in_play == True:  
164:      if p_hand.get_value() <= 21:   
165:        p_hand.add_card(deck.deal_card())  
166:      else:  
167:        message1 = "You bust-New Deal?"  
168:        in_play = False  
169:        losses += 1  
170:        print message1  
171:    print wins - losses  
172:    print "Player's", p_hand  
173:    print "Dealer's", d_hand  
174:    pass     # replace with your code below  
175:     
176:    # if the hand is in play, hit the player  
177:      
178:    # if busted, assign a message to outcome, update in_play and score  
179:        
180:  def stand():  
181:    global message1, in_play, losses, wins  
182:    if in_play == True:  
183:      if p_hand.get_value() > 21:  
184:        message1 = "You bust-New Deal?"  
185:        in_play = False  
186:        losses += 1  
187:        print message1  
188:      else:   
189:        while d_hand.get_value() < 17:  
190:          d_hand.add_card(deck.deal_card())  
191:        if d_hand.get_value() > 21:  
192:          message1 = "Dealer Busts-New Deal?"  
193:          wins += 1  
194:          print message1  
195:        else:  
196:          if p_hand.get_value() <= d_hand.get_value():  
197:            message1 = "Dealer Wins-New Deal?"  
198:            losses += 1  
199:            print message1  
200:          else:  
201:            message1 = "You Win-New Deal?"  
202:            wins += 1  
203:            print message1  
204:        in_play = False    
205:    print "Player's", p_hand  
206:    print "Dealer's", d_hand  
207:    print wins - losses  
208:    pass     # replace with your code below  
209:      
210:    # if hand is in play, repeatedly hit dealer until his hand has value 17 or more  
211:    
212:    # assign a message to outcome, update in_play and score  
213:    
214:  # draw handler    
215:  def draw(canvas):  
216:    p_pos = [100, 50]  #player hand position      
217:    d_pos = [100, 350]            #dealer draw position  
218:    p_hand.draw(canvas, p_pos)  
219:    d_hand.draw(canvas, d_pos)  
220:      
221:    #if in_play == True:  
222:      #d_hand.draw(canvas, d_pos)      
223:    #else:  
224:      #d_hand.draw(canvas, d_pos)  
225:      
226:    canvas.draw_text(message1, [30, 300], 30, "black")  
227:    canvas.draw_text("Blackjack", [300, 50], 50, "red")  
228:    canvas.draw_text("Player", [100, 170], 30, "blue")  
229:    canvas.draw_text("Dealer", [100, 470], 30, "blue")  
230:    canvas.draw_text("Score:" + str(wins - losses), [400, 130], 30, "white")  
231:      
232:      
233:  # initialization frame  
234:  p_hand = Hand()  
235:  d_hand = Hand()  
236:    
237:    
238:  frame = simplegui.create_frame("Blackjack", 600, 600)  
239:  frame.set_canvas_background("Green")  
240:    
241:    
242:  #create buttons and canvas callback  
243:  frame.add_button("Deal", deal, 200)  
244:  frame.add_button("Hit", hit, 200)  
245:  frame.add_button("Stand", stand, 200)  
246:  frame.set_draw_handler(draw)  
247:    
248:  # get things rolling  
249:  frame.start()  
250:    
251:    

Memory with Python (for codeskulptor)

1:  import simplegui  
2:  import random  
3:    
4:    
5:    
6:  # helper function to initialize globals  
7:  def init():  
8:    global lst1, lst2, deck, exposed, state, flipt1, flipt2, moves  
9:    moves = 0  
10:    flipt1 = -1  
11:    flipt2 = -2  
12:    state = 0  
13:    exposed = [False]*16  
14:    lst1 = range(8)  
15:    lst2 = range(8)  
16:    random.shuffle(lst1)  
17:    random.shuffle(lst2)  
18:    deck = lst1 + lst2  
19:    random.shuffle(deck)  
20:    pass   
21:    
22:       
23:  # define event handlers  
24:  def mouseclick(pos):  
25:    global moves, exposed, state, deck, flipt1, flipt2  
26:    a = 0  
27:    b = 0  
28:    # add game state logic here  
29:    moves += 1  
30:    num = pos[0] // 50  
31:    if exposed[num] == False:  
32:      if state == 0:  
33:        exposed[num] = True  
34:        state = 1  
35:        flipt1 = num  
36:          
37:      elif state == 1:  
38:        exposed[num] = True  
39:        state = 2  
40:        flipt2 = num  
41:          
42:      else:  
43:        state = 1  
44:        if deck[flipt1] != deck[flipt2]:  
45:          exposed[flipt1] = False  
46:          exposed[flipt2] = False  
47:        exposed[num] = True  
48:        flipt1 = num  
49:        flipt2 = -2  
50:          
51:      print num, exposed[num], state, flipt1, flipt2, moves  
52:    pass  
53:      
54:                
55:  # cards are logically 50x100 pixels in size    
56:  def draw(canvas):  
57:    spc = 0  
58:    x = 0  
59:    label.set_text("Moves =" + str(moves))  
60:    for crd in deck:  
61:      global exposed, state, flipt1, flipt2  
62:      if exposed[x] == True:  
63:        canvas.draw_text(str(crd), (spc, 80), 50, "white")  
64:          
65:      else:  
66:        canvas.draw_line((spc + 25, 0), (spc + 25, 100), 50, "Green")  
67:     
68:      x += 1  
69:      spc += 50  
70:      canvas.draw_polyline([(spc, 0), (spc, 100)], 2, "Red")  
71:    pass  
72:    
73:    
74:  # create frame and add a button and labels  
75:  frame = simplegui.create_frame("Memory", 800, 100)  
76:  frame.add_button("Restart", init)  
77:  label = frame.add_label("Moves = 0")  
78:    
79:  # initialize global variables  
80:  init()  
81:    
82:  # register event handlers  
83:  frame.set_mouseclick_handler(mouseclick)  
84:  frame.set_draw_handler(draw)  
85:    
86:  # get things rolling  
87:  frame.start()  
88:    
89:    

Guess the Number with Python

1:  import simplegui  
2:  import random  
3:    
4:  #define global variables  
5:  message = "Guess the Number!"  
6:  message1 = "Range: [0, 100]"  
7:  code = 0  
8:  counter = 0  
9:    
10:  def init():  
11:    global code, counter  
12:    code = random.randrange(100)  
13:    counter = 7  
14:    frame.start()  
15:    print code  
16:    
17:    
18:  # Handler for text input  
19:  def guess(num):  
20:    global message, counter  
21:    cai = int(num)  
22:    counter -= 1  
23:    print counter  
24:    if (cai == code) and (counter > 0):  
25:      message = "Correct!"  
26:    elif (cai == code) and (counter <= 0):  
27:      message = "No more guesses!"  
28:    elif (cai != code) and (counter <= 0):  
29:      message = "No more guesses!"  
30:    else:  
31:      if cai > code:  
32:        message = "Lower!"  
33:      else:  
34:        message = "Higher!"  
35:  # Handler for restart  
36:  def ng_button():  
37:    init()  
38:      
39:      
40:    
41:  # Handler to draw on canvas  
42:  def draw(canvas):  
43:    canvas.draw_text(message, [25,112], 15, "white")  
44:    canvas.draw_text(message1, [25,40], 15, "red")  
45:    canvas.draw_circle((150, 150), 20, 15, "green")  
46:    if counter >= 0:  
47:      canvas.draw_text("You have" + " " + str(counter) + " " + "guesses left", [35, 60], 15, "blue")  
48:    else:  
49:      canvas.draw_text("You have" + " " + "0" + " " + "guesses left", [35, 60], 15, "blue")  
50:    
51:  # Create a frame and assign callbacks to event handlers  
52:  frame = simplegui.create_frame("Home", 300, 200)  
53:  inp = frame.add_input("Guess:", guess, 100)  
54:  restart = frame.add_button("New Game", ng_button)  
55:  frame.set_draw_handler(draw)  
56:    
57:  # Start the frame animation  
58:    
59:    
60:  init()  
61:    
62:    

Linguistics and Information Theory