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