(load "writeln.scm") ;(load "LightCycle_RandomRobot.scm") (load "LightCycle_Dumb_Robot.scm") ;(load "LightCycle_Smarter_Robot.scm") ;(load "LightCycle_Aaron_Holck.scm") ;(load "LightCycle_Andrei_Buium.scm") ;(load "LightCycle_Antonio_Espinoza.scm") ;(load "LightCycle_Annette_Hatch.scm") ;(load "LightCycle_Bethanie_Shaw.scm") ;(load "LightCycle_Chad_Pickett.scm") ;(load "LightCycle_Christian_Romano.scm") ;(load "LightCycle_Daniel_Cabral.scm") ;(load "LightCycle_Daniel_McGraw.scm") ;(load "LightCycle_Derek_Stone.scm"); ;(load "LightCycle_Erik_Webb.scm") ;(load "LightCycle_Geoffrey_Alexander.scm") ;(load "LightCycle_Jeff_Knockel.scm") ; ;(load "LightCycle_Kenneth_Burke.scm") ;(load "LightCycle_Michael_Mellone.scm") ;(load "LightCycle_Michael_Murphy.scm") ;(load "LightCycle_Natalie_Klein.scm") ;(load "LightCycle_Rob_Pulsipher.scm") ;(load "LightCycle_Sam_Hopkins.scm") ;(load "LightCycle_Steven_Malins.scm") ;(load "LightCycle_Thomas_Gonzales.scm") ;(load "LightCycle_Travis_Patterson.scm") ;(load "LightCycle_Bug.scm") ;(load "LightCycle_Bad_Robot.scm") (load "Matrix.scm") (define Tron (lambda () (define gridSize 170) (define grid (matrix gridSize gridSize )) (define speed 100) (define boxSize 5) (define frameBorderWidth 8) (define frameBorderHeight 35) (define frameWidth (+ (* gridSize boxSize) frameBorderWidth)) (define frameHeight (+ (* gridSize boxSize) frameBorderHeight)) (define cycle_max 12) ;0 through 11 (define livingTeams 4) (define livingBits (- (expt 2 cycle_max) 1)) (define maxMilliSec 500.0) (define tempCycleVector (vector (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) ) ) (define teamCount 4) (define teamCallVector (vector ;Orchid, DodgerBlue, "Salmon, MediumSeaGreen ;;;(LightCycle_Travis_Patterson) ;;;(LightCycle_Erik_Webb) ;;;(LightCycle_Natalie_Klein) ;(LightCycle_Andrei_Buium) ;(LightCycle_Antonio_Espinoza) ;(LightCycle_Christian_Romano) ;(LightCycle_Daniel_Cabral) ;;;(LightCycle_Daniel_McGraw) ;(LightCycle_Geoffrey_Alexander) ;(LightCycle_Jeff_Knockel) ;(LightCycle_Michael_Murphy) ;(LightCycle_Rob_Pulsipher) ;(LightCycle_Smarter_Robot) ;(LightCycle_Derek_Stone) ;(LightCycle_Thomas_Gonzales) ;(LightCycle_Bad_Robot) (LightCycle_Dumb_Robot) (LightCycle_Dumb_Robot) (LightCycle_Dumb_Robot) (LightCycle_Dumb_Robot) )) (define averageTeamTime (vector 0.0 0.0 0.0 0.0)) (define dir_right 1) (define dir_down 2) (define dir_left 4) (define dir_up 8) ;When erasing a terminated cycle, the reverse ;trail is followed until dir_start_code is reached. (define dir_start_code 16) (define frame (instantiate frame% ("Tron") (width frameWidth) (height frameHeight) ) ) ;; Create a bitmap for an off screen buffer. (define buffer_bitmap (instantiate bitmap% (frameWidth frameHeight))) ;; Make the drawing area with a paint callback (define canvas (instantiate canvas% (frame) (paint-callback (lambda (canvas dc) (send dc draw-bitmap buffer_bitmap 0 0)) ) ) ) ; Create a drawing context for the screen and bitmap. (define screen_dc (send canvas get-dc)) (define buffer_dc (instantiate bitmap-dc% (buffer_bitmap))) (define lineThickness (- boxSize 1)) (define pen-white (instantiate pen% ("White" lineThickness 'solid))) (define pen-die (instantiate pen% ("Red" lineThickness 'solid))) (define pen-vector (vector (instantiate pen% ("Orchid" lineThickness 'solid)) (instantiate pen% ("Orchid" lineThickness 'solid)) (instantiate pen% ("Orchid" lineThickness 'solid)) (instantiate pen% ("DodgerBlue" lineThickness 'solid)) (instantiate pen% ("DodgerBlue" lineThickness 'solid)) (instantiate pen% ("DodgerBlue" lineThickness 'solid)) (instantiate pen% ("Salmon" lineThickness 'solid)) (instantiate pen% ("Salmon" lineThickness 'solid)) (instantiate pen% ("Salmon" lineThickness 'solid)) (instantiate pen% ("MediumSeaGreen" lineThickness 'solid)) (instantiate pen% ("MediumSeaGreen" lineThickness 'solid)) (instantiate pen% ("MediumSeaGreen" lineThickness 'solid)) ) ) (define no-brush (instantiate brush% ("WHITE" 'transparent))) (define initGrid (lambda (cycleVector) (define point 0) (define x 0) (define y 0) (do ((i 0 (+ i 1))) ((>= i cycle_max)) (set! point (vector-ref cycleVector i)) (set! x (vector-ref point 0)) (set! y (vector-ref point 1)) (matrix-set! grid x y dir_start_code) ;(writeln "start point: cycle=" i ", x=" x ", y=" y) ) ) ) (define teamAlive? (lambda (teamNumber) (> (bitwise-and livingBits (arithmetic-shift #o7 (* teamNumber 3)) ) 0) )) (define countLivingTeams (lambda () (define count 0) (do ((i 0 (+ i 1))) ((>= i teamCount)) (if (teamAlive? i) (set! count (+ count 1))) ) count )) (define getLivingTeam (lambda () (if (teamAlive? 0) 0 (if (teamAlive? 1) 1 (if (teamAlive? 2) 2 (if (teamAlive? 3) 3) ))))) (define runningMean (lambda (a b n) ; runningMean=a(n-1)/n + b/n (+ (/ (* a (- n 1.0)) n) (/ b n)) )) (define getTeam (lambda (cycleIdx) (inexact->exact (truncate (/ cycleIdx 3))) )) (define checkTeamReturnVector (lambda (teamReturnVector teamIdx) (define tmp 0) (define ok #t) (cond ((or (not (vector? teamReturnVector)) (not (= (vector-length teamReturnVector) 3)) ) (set! ok #f)) (else (do ((i 0 (+ i 1))) ((>= i 3)) (set! tmp (vector-ref teamReturnVector i)) (cond ((or (not (vector? tmp)) (not (= (vector-length tmp) 2)) (not (integer? (vector-ref tmp 0))) (not (exact? (vector-ref tmp 0))) (not (integer? (vector-ref tmp 1))) (not (exact? (vector-ref tmp 1))) ) (set! ok #f)) ) ) ) ) (if (not ok) (writeln "Team" teamIdx " returned bad value") ) ok ) ) (define terminateCycle (lambda (cycleVector idx) (define point 0) (define x1 0) (define y1 0) (define x2 0) (define y2 0) (define dir 0) (if (> (bitwise-and livingBits (expt 2 idx)) 0) (begin (set! livingBits (- livingBits (expt 2 idx))) (set! livingTeams (countLivingTeams)) (writeln "Tron::terminateCycle: idx=" idx ", average millsec=" (vector-ref averageTeamTime (getTeam idx)) ) (set! point (vector-ref cycleVector idx)) (set! x1 (vector-ref point 0)) (set! y1 (vector-ref point 1)) (set! x2 x1) (set! y2 y1) (send screen_dc set-pen pen-die) (send screen_dc draw-ellipse (- (* x1 boxSize) 10) (- (* y1 boxSize) 10) 21 21 ) ;(sleep 3) (play-sound "terminate.wav" #f) (do ((i 0 (+ i 1))) ((= dir dir_start_code)) ;(sleep 0) ;(writeln "x=" x1 ", y=" y1 ", dir=" dir) (set! dir (matrix-ref grid x1 y1)) (matrix-set! grid x1 y1 0) (cond ;To follow the trail backward, reverse the directions ((= dir dir_right) (set! x2 (- x1 1))) ((= dir dir_left) (set! x2 (+ x1 1))) ((= dir dir_up) (set! y2 (+ y1 1))) ((= dir dir_down) (set! y2 (- y1 1))) ((= dir dir_start_code) (send screen_dc draw-bitmap buffer_bitmap 0 0)) (else (writeln "Error in Tron::terminateCycle:") die ) ;else dir must equal dir_start_code ;and we are done. ) ;(writeln "x1=" x1 ", y1=" y1 ", x2=" x2 ", y2=" y2 ", dir=" dir) (DrawCycle x1 y1 x2 y2 -1) (set! x1 x2) (set! y1 y2) ) ) ) ) ) (define killTeamIfOverTime (lambda (teamIdx) ;;(writeln "boo" (vector-ref averageTeamTime teamIdx) maxMilliSec ) (if (> (vector-ref averageTeamTime teamIdx) maxMilliSec) (begin (writeln "Team" teamIdx " over average time limit") #f ) #t ) )) (define sortCyclesByAverageCPUTime (lambda () (define sortedCycleVector (make-vector 12 0)) (define sortedTeamIndex (vector 0 1 2 3)) (define sortedTeamTime (vector (vector-ref averageTeamTime 0) (vector-ref averageTeamTime 1) (vector-ref averageTeamTime 2) (vector-ref averageTeamTime 3) )) (define min 0) (define minIdx 0) (do ((i 0 (+ i 1))) ((>= i teamCount)) (set! min (vector-ref sortedTeamTime 0)) (set! minIdx 0) (do ((ii 1 (+ ii 1))) ((>= ii teamCount)) (if (< (vector-ref sortedTeamTime ii) min) (begin (set! min (vector-ref sortedTeamTime ii)) (set! minIdx ii) ) ) ) (vector-set! sortedTeamIndex i minIdx) ;Note: sortedTeamTime[minIdx] must be set to a ;number larger than any of the values in averageTeamTime. (vector-set! sortedTeamTime minIdx 99999999.0) ) (do ((i 0 (+ i 1))) ((>= i teamCount)) (set! minIdx (vector-ref sortedTeamIndex i)) (vector-set! sortedCycleVector (+ (* i 3) 0) (+ (* minIdx 3) 0)) (vector-set! sortedCycleVector (+ (* i 3) 1) (+ (* minIdx 3) 1)) (vector-set! sortedCycleVector (+ (* i 3) 2) (+ (* minIdx 3) 2)) ) sortedCycleVector ) ) (define checkIfMoveIsIllegal (lambda ( x1 y1 x2 y2) (cond ((< x2 0) (writeln "Illegal move: x2 < 0") #f) ((< y2 0) (writeln "Illegal move: y2 < 0") #f) ((>= x2 gridSize) (writeln "Illegal move: x2 >= gridSize") #f) ((>= y2 gridSize) (writeln "Illegal move: y2 >= gridSize") #f) ((> (matrix-ref grid x2 y2) 0) (writeln "Illegal move: grid space =" (matrix-ref grid x2 y2)) #f ) ((> (abs (- x1 x2)) 1) (writeln "Illegal move: abs(x1-x2)>1") #f) ((> (abs (- y1 y2)) 1) (writeln "Illegal move: abs(y1-y2)>1") #f) ((and (= x1 x2) (= y1 y2)) (writeln "Illegal move: same location.") #f) ((and (not (= x1 x2)) (not (= y1 y2))) (writeln "Illegal move: diagnal move.") #f) (else #t) ) ) ) (define point-set! (lambda (cycleVectorNew cycleIdx x y) (define point (vector-ref cycleVectorNew cycleIdx)) (vector-set! point 0 x) (vector-set! point 1 y) ) ) (define updateCycleLocations (lambda (cycleVector cycleVectorNew) (define point1 (vector 0 0)) (define point2 (vector 0 0)) (define x1 0) (define y1 0) (define x2 0) (define y2 0) (define dir 0) (define cycleIdx 0) (define sortedCycleVector (sortCyclesByAverageCPUTime)) ;(writeln "Update: cycleVector =" cycleVector) ;(writeln " : cycleVectorNew=" cycleVectorNew) (do ((i 0 (+ i 1))) ((>= i cycle_max)) (set! cycleIdx (vector-ref sortedCycleVector i)) (cond ((= (bitwise-and livingBits (expt 2 cycleIdx)) 0) (vector-set! cycleVectorNew cycleIdx (vector -1 -1)) ) (else (set! point1 (vector-ref cycleVector cycleIdx)) (set! point2 (vector-ref cycleVectorNew cycleIdx)) (set! x1 (vector-ref point1 0)) (set! y1 (vector-ref point1 1)) (set! x2 (vector-ref point2 0)) (set! y2 (vector-ref point2 1)) ;(writeln "Try: cycle=" cycleIdx ; " x1=" x1 ", y1=" y1 ", x2=" x2 ", y2=" y2 ;) (cond ((eq? (checkIfMoveIsIllegal x1 y1 x2 y2) #f) (point-set! cycleVectorNew cycleIdx -1 -1) (terminateCycle cycleVector cycleIdx) ) (else (cond ((> x2 x1) (set! dir dir_right)) ((< x2 x1) (set! dir dir_left)) ((> y2 y1) (set! dir dir_down)) ((< y2 y1) (set! dir dir_up)) ) (matrix-set! grid x2 y2 dir) ) ) ) ) ) ) ) (define DrawAllCycles (lambda (cycleVector1 cycleVector2) (define point1 0) (define point2 0) (do ((i 0 (+ i 1))) ((>= i cycle_max)) (if (> (bitwise-and livingBits (expt 2 i)) 0) (begin (set! point1 (vector-ref cycleVector1 i)) (set! point2 (vector-ref cycleVector2 i)) (DrawCycle (vector-ref point1 0) (vector-ref point1 1) (vector-ref point2 0) (vector-ref point2 1) i) ) ) ) )) (define DrawCycle (lambda (x1 y1 x2 y2 cycle) (define redrawTimes speed) (define cyclePen (cond ((< cycle 0) (set! redrawTimes (/ speed 5)) pen-white ;this value is returned into the define ) (else (vector-ref pen-vector cycle)) ) ) (set! x1 (+ (* x1 boxSize) 1)) (set! y1 (+ (* y1 boxSize) 1)) (set! x2 (+ (* x2 boxSize) 1)) (set! y2 (+ (* y2 boxSize) 1)) (do ((i 0 (+ i 1))) ((>= i speed)) (send screen_dc set-pen cyclePen) (send screen_dc draw-line x1 y1 x2 y2) ) (send buffer_dc set-pen cyclePen) (send buffer_dc draw-line x1 y1 x2 y2) )) (define copyCycleVectorByValue (lambda (sourceVector targetVector) (define x 0) (define y 0) (do ((i 0 (+ i 1))) ((>= i cycle_max)) (set! x (vector-ref (vector-ref sourceVector i) 0)) (set! y (vector-ref (vector-ref sourceVector i) 1)) (vector-set! (vector-ref targetVector i) 0 x) (vector-set! (vector-ref targetVector i) 1 y) ;(writeln "copy x y <" x ", " y ">") ) ) ) (define (MasterLoop) (define cycleVector (vector (vector 169 45) (vector 169 85) (vector 169 125) (vector 45 169) (vector 85 169) (vector 125 169) (vector 0 45) (vector 0 85) (vector 0 125) (vector 45 0) (vector 85 0) (vector 125 0) ) ) (define cycleVectorNew (vector (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) (vector 0 0) ) ) (define teamReturnVector 0) (define timeAfterCall 0) (define timeBeforeCall 0) (define cycleIdx 0) (define x 0) (define y 0) (send screen_dc set-brush no-brush) (send buffer_dc set-brush no-brush) (send screen_dc clear) (send buffer_dc clear) (initGrid cycleVector) (do ((i 0 (+ i 1))) ((<= livingTeams 1)) ;(sleep .02) ;(sleep 1) ;(sleep .06) ;(newline) ;(writeln "Main Loop: turn=" i ", livingTeams=" livingTeams) (do ((teamIdx 0 (+ teamIdx 1))) ((>= teamIdx teamCount)) (if (teamAlive? teamIdx) (begin (set! timeBeforeCall (- (current-process-milliseconds) (current-gc-milliseconds) ) ) ;Call Cycle Team Subroutine ;(newline) ;(writeln "Main Loop: " teamIdx ": cycleVector =" cycleVector) (copyCycleVectorByValue cycleVector tempCycleVector ) (set! teamReturnVector ((vector-ref teamCallVector teamIdx) teamIdx tempCycleVector) ) ;(writeln "Main Loop: " teamIdx ": cycleVector =" cycleVector) (set! timeAfterCall (- (current-process-milliseconds) (current-gc-milliseconds) ) ) (vector-set! averageTeamTime teamIdx (runningMean (vector-ref averageTeamTime teamIdx) (- timeAfterCall timeBeforeCall) (+ i 1.0) ) ) ;(writeln "averageTeamTime[" teamIdx "]=" (vector-ref averageTeamTime teamIdx)) (cond ((or (not (checkTeamReturnVector teamReturnVector teamIdx)) (not (killTeamIfOverTime teamIdx)) ) (point-set! teamReturnVector 0 -1 -1) (point-set! teamReturnVector 1 -1 -1) (point-set! teamReturnVector 2 -1 -1) ) ) ;Fill cycleVectorNew with the cycle locations ;returned by the teem subroutine. ;Note: this code is bad because it copies addresses ; returned by the cycle team. ;(do ((iii 0 (+ iii 1))) ((>= iii 3)) ; (vector-set! cycleVectorNew ; (+ (* teamIdx 3) iii) ; (vector-ref teamReturnVector iii) ; ) ;) (do ((iii 0 (+ iii 1))) ((>= iii 3)) (set! cycleIdx (+ (* teamIdx 3) iii)) (set! x (vector-ref (vector-ref teamReturnVector iii) 0)) (set! y (vector-ref (vector-ref teamReturnVector iii) 1)) (point-set! cycleVectorNew cycleIdx x y) ) ;(writeln "cycleVectorNew= " cycleVectorNew) )) ) ;Check that all of the moves in cycleVectorNew. ;Are legal. Also, terminate any cycles that make ;illegal moves. ;(writeln "cycleVector =" cycleVector) ;(writeln "cycleVectorNew=" cycleVectorNew) ;Replace cycleVector with the new locations. ;(do ((i 0 (+ i 1))) ((>= i cycle_max)) ; (vector-set! cycleVector i (vector-ref cycleVectorNew i)) ;) (updateCycleLocations cycleVector cycleVectorNew) (DrawAllCycles cycleVector cycleVectorNew) (copyCycleVectorByValue cycleVectorNew cycleVector) ) (if (= livingTeams 1) (writeln "***Winner*** team=" (getLivingTeam) ", average millsec=" (vector-ref averageTeamTime (getLivingTeam)) ) ) ) ;; Show the frame (send frame move 0 0) (send frame show #t) (MasterLoop) )) (Tron)