From 31193218c1d2774f55d3f66dac853daf25502b20 Mon Sep 17 00:00:00 2001 From: Live session user Date: Mon, 3 Feb 2014 00:00:06 +0000 Subject: [PATCH 01/17] adding hw2 --- hw2/compare.py | 15 +++++++++++++++ hw2/fermat.py | 21 +++++++++++++++++++++ hw2/grid.py | 15 +++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 hw2/compare.py create mode 100644 hw2/fermat.py create mode 100644 hw2/grid.py diff --git a/hw2/compare.py b/hw2/compare.py new file mode 100644 index 0000000..f8c6087 --- /dev/null +++ b/hw2/compare.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Feb 2 23:52:25 2014 + +@author: ubuntu +""" + +def comp(x,y): + if x>y: + return 1 + elif x2: + print "Holy smokes, Fermat was wrong!" + else: + print "No, that doesn't work" + +def fermatPrompt(): + a = int(raw_input("input a")) + b = int(raw_input("input b")) + c = int(raw_input("input c")) + n = int(raw_input("input n")) + fermatCheck(a,b,c,n) + +fermatPrompt() diff --git a/hw2/grid.py b/hw2/grid.py new file mode 100644 index 0000000..136a845 --- /dev/null +++ b/hw2/grid.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Feb 2 23:20:02 2014 + +@author: ubuntu +""" + +def makeGrid(): + print ("+"+(4*" -"+" +")*2 + 4*("\n|"+" |"*2)+"\n")*2 +"+"+(4*" -"+" +")*2 + + +def makeGrid4(): + print ("+"+(4*" -"+" +")*3 + 4*("\n|"+" |"*3)+"\n")*3 +"+"+(4*" -"+" +")*3 + +makeGrid4() \ No newline at end of file From a03f9ac9f0b7b98fc0542f454e8e05698ad58885 Mon Sep 17 00:00:00 2001 From: Live session user Date: Fri, 7 Feb 2014 09:51:39 -0500 Subject: [PATCH 02/17] Addind Gene_finder --- hw3/gene_finder.py | 111 +++++++++++++++++++++++++++++++++------------ 1 file changed, 83 insertions(+), 28 deletions(-) diff --git a/hw3/gene_finder.py b/hw3/gene_finder.py index 1a0245a..285f61a 100644 --- a/hw3/gene_finder.py +++ b/hw3/gene_finder.py @@ -2,9 +2,13 @@ """ Created on Sun Feb 2 11:24:42 2014 -@author: YOUR NAME HERE +@author: Josh Sapers and Paul Ruvolo +(from replacement code for code lost) """ +from numpy import argmax +from random import shuffle + # you may find it useful to import these variables (although you are not required to use them) from amino_acids import aa, codons @@ -25,13 +29,29 @@ def coding_strand_to_AA(dna): returns: a string containing the sequence of amino acids encoded by the the input DNA fragment """ - - # YOUR IMPLEMENTATION HERE + retval = "" + for i in range(0,len(dna),3): + for j in range(len(codons)): + if dna[i:i+3] in codons[j]: + retval += aa[j] + break + return retval def coding_strand_to_AA_unit_tests(): """ Unit tests for the coding_strand_to_AA function """ - - # YOUR IMPLEMENTATION HERE + print "input: ATGCGA, expected output: MR, actual output: " + coding_strand_to_AA("ATGCGA") + print "input: ATGCCCGCTTT, expected output: MPA, actual output: " + coding_strand_to_AA("ATGCCCGCTTT") + +def get_complementary_base(B): + """ Returns the complementary nucleotide to the specified nucleotide. """ + if B == 'A': + return 'T' + elif B == 'C': + return 'G' + elif B == 'G': + return 'C' + elif B == 'T': + return 'A' def get_reverse_complement(dna): """ Computes the reverse complementary sequence of DNA for the specfied DNA @@ -40,13 +60,15 @@ def get_reverse_complement(dna): dna: a DNA sequence represented as a string returns: the reverse complementary DNA sequence represented as a string """ - - # YOUR IMPLEMENTATION HERE + retval = "" + for i in reversed(dna): + retval += get_complementary_base(i) + return retval def get_reverse_complement_unit_tests(): """ Unit tests for the get_complement function """ - - # YOUR IMPLEMENTATION HERE + print "input: ATGCCCGCTTT, expected output: AAAGCGGGCAT, actual output: " + get_reverse_complement("ATGCCCGCTTT") + print "input: CCGCGTTCA, expected output: CCGCGTTCA, actual output: " + get_reverse_complement("CCGCGTTCA") def rest_of_ORF(dna): """ Takes a DNA sequence that is assumed to begin with a start codon and returns @@ -56,13 +78,17 @@ def rest_of_ORF(dna): dna: a DNA sequence returns: the open reading frame represented as a string """ - - # YOUR IMPLEMENTATION HERE + retval = "" + for i in range(0,len(dna),3): + if dna[i:i+3] in ['TAG', 'TAA', 'TGA']: + break + retval += dna[i:i+3] + return retval def rest_of_ORF_unit_tests(): """ Unit tests for the rest_of_ORF function """ - - # YOUR IMPLEMENTATION HERE + print "input: ATGTGAA, expected output: ATG, actual output: " + rest_of_ORF("ATGTGAA") + print "input: ATGAGATAGG, expected output: ATGAGA, actual output: " + rest_of_ORF("ATGAGATAGG") def find_all_ORFs_oneframe(dna): """ Finds all non-nested open reading frames in the given DNA sequence and returns @@ -74,9 +100,19 @@ def find_all_ORFs_oneframe(dna): dna: a DNA sequence returns: a list of non-nested ORFs """ - - # YOUR IMPLEMENTATION HERE - + retval = [] + i = 0 + while i < len(dna): + if dna[i:i+3] == 'ATG': + retval.append(rest_of_ORF(dna[i:])) + i += len(retval[-1]) + i += 3 + return retval + +def find_all_ORFs_oneframe_unit_tests(): + """ Unit tests for the find_all_ORFs_oneframe function """ + print "input: ATGCATGAATGTAGATAGATGTGCCC, expected output: ['ATGCATGAATGTAGA', 'ATGTGCCC'], actual output: " + str(find_all_ORFs_oneframe("ATGCATGAATGTAGATAGATGTGCCC")) + def find_all_ORFs(dna): """ Finds all non-nested open reading frames in the given DNA sequence in all 3 possible frames and returns them as a list. By non-nested we mean that if an @@ -86,13 +122,11 @@ def find_all_ORFs(dna): dna: a DNA sequence returns: a list of non-nested ORFs """ - - # YOUR IMPLEMENTATION HERE + return find_all_ORFs_oneframe(dna) + find_all_ORFs_oneframe(dna[1:]) + find_all_ORFs_oneframe(dna[2:]) def find_all_ORFs_unit_tests(): """ Unit tests for the find_all_ORFs function """ - - # YOUR IMPLEMENTATION HERE + print "input: ATGCATGAATGTAG, expected output: ['ATGCATGAATGTAG', 'ATGAATGTAG', 'ATG'], actual output: " + str(find_all_ORFs("ATGCATGAATGTAG")) def find_all_ORFs_both_strands(dna): """ Finds all non-nested open reading frames in the given DNA sequence on both @@ -101,19 +135,20 @@ def find_all_ORFs_both_strands(dna): dna: a DNA sequence returns: a list of non-nested ORFs """ - - # YOUR IMPLEMENTATION HERE + return find_all_ORFs(dna) + find_all_ORFs(get_reverse_complement(dna)) def find_all_ORFs_both_strands_unit_tests(): """ Unit tests for the find_all_ORFs_both_strands function """ - + print "input: ATGCGAATGTAGCATCAAA, expected output: ['ATGCGAATG', 'ATGCTACATTCGCAT'], actual output: " + str(find_all_ORFs_both_strands("ATGCGAATGTAGCATCAAA")) # YOUR IMPLEMENTATION HERE def longest_ORF(dna): """ Finds the longest ORF on both strands of the specified DNA and returns it as a string""" + ORFs = find_all_ORFs_both_strands(dna) + ind = argmax(map(len,ORFs)) + return ORFs[ind] - # YOUR IMPLEMENTATION HERE def longest_ORF_noncoding(dna, num_trials): """ Computes the maximum length of the longest ORF over num_trials shuffles @@ -122,8 +157,21 @@ def longest_ORF_noncoding(dna, num_trials): dna: a DNA sequence num_trials: the number of random shuffles returns: the maximum length longest ORF """ - - # YOUR IMPLEMENTATION HERE + #import random + for i in range(num_trials): + ORF = "" + dna_temp = [] + dna_string = "" + for char in dna: + dna_temp.append(char) + shuffle(dna_temp) + for item in dna_temp: + dna_string +=item + if longest_ORF(dna_string)>ORF: + longest_ORF(dna_string) + ORF = longest_ORF(dna_string) + return len(ORF) + def gene_finder(dna, threshold): """ Returns the amino acid sequences coded by all genes that have an ORF @@ -135,5 +183,12 @@ def gene_finder(dna, threshold): returns: a list of all amino acid sequences whose ORFs meet the minimum length specified. """ - - # YOUR IMPLEMENTATION HERE \ No newline at end of file + protiens = [] + protein = "" + ORFs = find_all_ORFs_both_strands(dna) + for item in ORFs: + if len(item)>threshold: + protiens+=coding_strand_to_AA(item) + for items in protiens: + protein += items + return protein \ No newline at end of file From ff3153a8e7b2f180e3479b94314907649e50801d Mon Sep 17 00:00:00 2001 From: Live session user Date: Mon, 17 Feb 2014 21:02:53 -0500 Subject: [PATCH 03/17] Adding hw4. --- hw4/random_art.py | 82 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/hw4/random_art.py b/hw4/random_art.py index 42075e4..b4e4a7f 100644 --- a/hw4/random_art.py +++ b/hw4/random_art.py @@ -7,17 +7,64 @@ # you do not have to use these particular modules, but they may help from random import randint +from math import * import Image - +current_depth = 1 def build_random_function(min_depth, max_depth): # your doc string goes here - + """Prints an array including function strings prod, sin_pi, cos_pi, x, y with their + repsective inputs in nested arrays. + inputs: + min_depth: the minimum depth that you want your function to reach + max_depth: the maximum depth that you want your function to reach + """ # your code goes here + global current_depth + if current_depth < min_depth: + current_depth += 1 + choices = ["prod","sin_pi","cos_pi"] + i = randint(0,len(choices)-1) + s = choices[i] + if s == "prod": + return [s,build_random_function(min_depth, max_depth),build_random_function(min_depth, max_depth)] + else: + return [s,build_random_function(min_depth, max_depth)] + + elif current_depth >= min_depth: + + if current_depth == max_depth: + current_depth += 1 + choices = ["x","y"] + i = randint(0,len(choices)-1) + s = choices[i] + else: + current_depth += 1 + choices = ["prod","sin_pi","cos_pi","x","y"] + i = randint(0,len(choices)-1) + s = choices[i] + + if s == "prod": + return [s,build_random_function(min_depth, max_depth),build_random_function(min_depth, max_depth)] + elif s=="sin_pi" or s=="cos_pi": + return [s,build_random_function(min_depth, max_depth)] + else: + return [s] + def evaluate_random_function(f, x, y): # your doc string goes here # your code goes here + if f[0] == 'prod': + return evaluate_random_function(f[1], x, y)*evaluate_random_function(f[2], x, y) + elif f[0] == 'sin_pi': + return sin(pi*evaluate_random_function(f[1], x, y)) + elif f[0] == 'cos_pi': + return cos(pi*evaluate_random_function(f[1], x, y)) + elif f[0] == 'y': + return y + elif f[0] == 'x': + return x def remap_interval(val, input_interval_start, input_interval_end, output_interval_start, output_interval_end): """ Maps the input value that is in the interval [input_interval_start, input_interval_end] @@ -27,4 +74,33 @@ def remap_interval(val, input_interval_start, input_interval_end, output_interva TODO: please fill out the rest of this docstring """ # your code goes here - \ No newline at end of file + ratio = (output_interval_end-output_interval_start)/(input_interval_end-input_interval_start) + offset = output_interval_start-input_interval_start*ratio + return val*ratio + offset + + +global current_depth +fR = build_random_function(2, 25) +current_depth = 1 +fB = build_random_function(2, 25) +current_depth = 1 +fG = build_random_function(2, 25) +print fR +print fG +print fB +im = Image.new("RGB",(350,350)) +pixels = im.load() +for i in range(0,350): + for j in range(0,350): + x = remap_interval(i, 0, 350, -1,1.) + y = remap_interval(j, 0, 350, -1,1.) + R = remap_interval(evaluate_random_function(fR, x, y),-1,1,0,256) + B =remap_interval(evaluate_random_function(fB, x, y),-1,1,0,256) + G = remap_interval(evaluate_random_function(fG, x, y),-1,1,0,256) + RBG = (R,G,B) + + pixels[i,j] = (int(R),int(G),int(B)) + +im.save("pic" + ".thumbnail", "JPEG") + + From 2caae28049b134583c4ade8e81a6fa9fd5f63a4f Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 3 Mar 2014 02:29:43 -0500 Subject: [PATCH 04/17] Adding a new creepy part.hw5 --- hw5/.~lock.tests.odt# | 1 + hw5/WikiRace.py | 86 ++++++++++++++++++++++++++++++++++++++++++ hw5/tests.odt | Bin 0 -> 25535 bytes 3 files changed, 87 insertions(+) create mode 100644 hw5/.~lock.tests.odt# create mode 100644 hw5/WikiRace.py create mode 100644 hw5/tests.odt diff --git a/hw5/.~lock.tests.odt# b/hw5/.~lock.tests.odt# new file mode 100644 index 0000000..3cde689 --- /dev/null +++ b/hw5/.~lock.tests.odt# @@ -0,0 +1 @@ +,josh,josh-Latitude-E6430,03.03.2014 02:04,file:///home/josh/.config/libreoffice/3; \ No newline at end of file diff --git a/hw5/WikiRace.py b/hw5/WikiRace.py new file mode 100644 index 0000000..d3762c9 --- /dev/null +++ b/hw5/WikiRace.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +""" +Spyder Editor + +This temporary script file is located here: +/home/josh/.spyder2/.temp.py +""" + +from bs4 import BeautifulSoup +import requests +import re +def getLinks(url): + """ + Scans through article in wikipedia and finds all hyperlinked + texts, then stores them inside a dictionary. + + Input: The article's URL + Output: A dicsatellitetionary of all links in the page. + """ + d={} + r = requests.get(url) + data = r.text + soup = BeautifulSoup(data) + for link in soup.find_all('a'): + l =link.get('href') + if l != None: + if l[0:6]=="/wiki/": + if not(":"in l or "Main_Page"in l): + d[l[6:]]="http://en.wikipedia.org"+l + return d +def compareLinks(start,prev,targetName,targetText): + """ + Recursively compares the current link's words to the goal's + words and selects the next article based similarity. + + Input: start (previous article) prev (list of all previous) + targetName (the goal) targetText (the goal's words) + Output: Name of preceding and next articles + """ + d = getLinks("http://en.wikipedia.org/wiki/"+start) + l= d.keys() + print "\n\n"+start+"\n\n\n" + + mostcommon=0 + for keys in d: + if keys.lower() == targetName.lower(): + return keys + if len(l)<100: + max=len(l) + else: + max = 100 + for i in range(0,max): + r = requests.get(d[l[i]]) + data = r.text + soup = BeautifulSoup(data) + text1 = soup.get_text() + words = re.findall("[\w]+",text1) + if targetName in words and not(l[i]in prev): + prev.append(l[i]) + return l[i]+","+ compareLinks(l[i],prev,targetName,targetText) + common = list(set(words) & set(targetText)) + if len(common)>mostcommon: + if not(l[i]in prev): + mostcommon = len(common) + nextkey = l[i] + prev.append(nextkey) + return nextkey+","+ compareLinks(nextkey,prev,targetName,targetText) + + +def Navigate(start,end): + """ + Main code, for starting the recursion. + + Input: start(beginning article) end(ending article (goal)) + Output: Prints path + """ + r1= requests.get("http://en.wikipedia.org/wiki/"+end) + data1 = r1.text + soup1 = BeautifulSoup(data1) + text1 = soup1.get_text() + words = re.findall("[\w]+",text1) + print compareLinks(start,[start],end,words) + +start = raw_input("Start") +end = raw_input("end") +Navigate(start,end) \ No newline at end of file diff --git a/hw5/tests.odt b/hw5/tests.odt new file mode 100644 index 0000000000000000000000000000000000000000..14dff1ee7c19dbe76d7f446eeac9c838c372fee3 GIT binary patch literal 25535 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 literal 0 HcmV?d00001 From 2e3451e8b80ed4c1c7b6be66afb8a76169713ce5 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 3 Mar 2014 03:03:04 -0500 Subject: [PATCH 05/17] Adding hw5 --- hw5/.~lock.tests.odt# | 1 - 1 file changed, 1 deletion(-) delete mode 100644 hw5/.~lock.tests.odt# diff --git a/hw5/.~lock.tests.odt# b/hw5/.~lock.tests.odt# deleted file mode 100644 index 3cde689..0000000 --- a/hw5/.~lock.tests.odt# +++ /dev/null @@ -1 +0,0 @@ -,josh,josh-Latitude-E6430,03.03.2014 02:04,file:///home/josh/.config/libreoffice/3; \ No newline at end of file From 3c0451788616070470ecb948f3a436ced98e94fc Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 3 Mar 2014 03:03:44 -0500 Subject: [PATCH 06/17] Adding hw5 --- hw5/WikiRace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw5/WikiRace.py b/hw5/WikiRace.py index d3762c9..ad8092d 100644 --- a/hw5/WikiRace.py +++ b/hw5/WikiRace.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ Spyder Editor - +By Josh Sapers and Subbhash Gubba This temporary script file is located here: /home/josh/.spyder2/.temp.py """ From ec2316aaf9b450ef1f9ea4649ca4d3c8c1c41e84 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 3 Mar 2014 03:11:48 -0500 Subject: [PATCH 07/17] Adding hw5 --- Reflection.pdf | Bin 0 -> 36692 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Reflection.pdf diff --git a/Reflection.pdf b/Reflection.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5f31e71b538267d497923b6e2cd911ee09ba4778 GIT binary patch literal 36692 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

y#(zU-A6Ac!&!E;e=G+LBJ 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 EPXW202mk;8 literal 0 HcmV?d00001 From 56c03ae9b5ffa194050801fa581e4c2741140972 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 3 Mar 2014 03:13:34 -0500 Subject: [PATCH 08/17] Adding hw5 --- Reflection.pdf => hw5/Reflection.pdf | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename Reflection.pdf => hw5/Reflection.pdf (100%) diff --git a/Reflection.pdf b/hw5/Reflection.pdf similarity index 100% rename from Reflection.pdf rename to hw5/Reflection.pdf From 90b5d25814fc277eda48f1645f96ae7b8c967d7d Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Sun, 9 Mar 2014 01:46:28 -0500 Subject: [PATCH 09/17] hw6 added --- hw6/LightCycle.py | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 hw6/LightCycle.py diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py new file mode 100644 index 0000000..d52ce0e --- /dev/null +++ b/hw6/LightCycle.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Mar 8 23:11:28 2014 + +@author: dmichael +""" + +import pygame +from pygame.locals import * +import random +import math +import time + +class LightCycleModel: + def __init__(self): + self.cycle1 = Cycle(50,240,10,(250,0,0),.50) + self.cycle2 = Cycle(590,240,10,(0,0,250),-1.0) + self.trail1=[] + self.trail2=[] + + def update(self): + self.cycle1.update() + self.cycle2.update() + +class Cycle: + def __init__(self,x,y,thick,color,vx): + self.x = x + self.y = y + self.width = thick + self.height = thick + self.color = color + self.vx = vx + self.vy = 0.0 + + def update(self): + self.x += self.vx +class Trail: + def __init__(self,color,hieght,width,x,y): + self.color=color + self.hieght=hieght + self.width=width + self.x=x + self.y=y +class PyGameWindowView: + """ A view of brick breaker rendered in a Pygame window """ + def __init__(self,model,screen): + self.model = model + self.screen = screen + + def draw(self): + self.screen.fill(pygame.Color(0,0,0)) + pygame.draw.rect(self.screen, pygame.Color(self.model.cycle1.color[0],self.model.cycle1.color[1],self.model.cycle1.color[2]),pygame.Rect(self.model.cycle1.x,self.model.cycle1.y,self.model.cycle1.width,self.model.cycle1.height)) + #pygame.draw.rect(self.screen, pygame.Color(self.model.cycle2.color[0],self.model.cycle2.color[1],self.model.cycle2.color[2]),pygame.Rect(self.model.cycle2.x,self.model.cycle2.y,self.model.cycle2.width,self.model.cycle2.height)) + pygame.display.update() + +class Controller: + def __init__(self,model): + self.model = model + + def handle_keyboard_event(self,event): + if event.type != KEYDOWN: + return + if event.key == pygame.K_LEFT and self.model.cycle1.vx == 0: + self.model.cycle1.vx += -.50 + self.model.cycle1.vy = 0.0 + if event.key == pygame.K_RIGHT and self.model.cycle1.vx == 0: + self.model.cycle1.vx += .50 + self.model.cycle1.vy = 0.0 + if event.key == pygame.K_UP and self.model.cycle1.vy == 0: + self.model.cycle1.vx = 0.0 + self.model.cycle1.vy += .50 + if event.key == pygame.K_DOWN and self.model.cycle1.vy == 0: + self.model.cycle1.vx = 0.0 + self.model.cycle1.vy += -.50 + else: + self.model.cycle1.vx = self.model.cycle1.vx + self.model.cycle1.vy = self.model.cycle1.vy +# if event.key == pygame.K_A and self.model.cycle2.vx == 0: +# self.model.cycle2.vx = -1.0 +# self.model.cycle2.vy = 0.0 +# if event.key == pygame.K_D and self.model.cycle2.vx == 0: +# self.model.cycle2.vx = 1.0 +# self.model.cycle2.vy = 0.0 +# if event.key == pygame.K_W and self.model.cycle2.vy == 0: +# self.model.cycle2.vx = 0.0 +# self.model.cycle2.vy = 1.0 +# if event.key == pygame.K_S and self.model.cycle2.vy == 0: +# self.model.cycle2.vx = 0.0 +# self.model.cycle2.vy = -1.0 + +if __name__ == '__main__': + pygame.init() + + size = (640,480) + screen = pygame.display.set_mode(size) + + model = LightCycleModel() + view = PyGameWindowView(model,screen) + controller = Controller(model) + + + running = True + + while running: + for event in pygame.event.get(): + if event.type == QUIT: + running = False + if event.type == KEYDOWN: + controller.handle_keyboard_event(event) + model.update() + view.draw() + time.sleep(.001) + + pygame.quit() From 62380752934067a098f712057084bb005f18d934 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Sun, 9 Mar 2014 01:57:08 -0500 Subject: [PATCH 10/17] hw6 added --- hw6/Tron.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hw6/game.py | 34 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 hw6/Tron.py create mode 100644 hw6/game.py diff --git a/hw6/Tron.py b/hw6/Tron.py new file mode 100644 index 0000000..2b8411f --- /dev/null +++ b/hw6/Tron.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 27 19:34:24 2014 + +@author: pruvolo +""" + +import pygame +from pygame.locals import * +import random +import math +import time + +class TronModel: + """ Encodes the game state of Brick Breaker """ + def __init__(self): + self.number_of_lives = 3 + self.bricks = [] + for i in range(640/110): + for j in range(240/30): + new_brick = Brick(10+110*i,10+30*j,100,20,(random.randint(0,255),random.randint(0,255),random.randint(0,255))) + self.bricks.append(new_brick) + self.paddle = Paddle(200,450,100,20) + + def update(self): + self.paddle.update() + +class Road: + """ Encodes the state of a brick in Brick Breaker """ + def __init__(self,x,y,color): + self.x = x + self.y = y + self.width = 20 + self.height = 20 + self.color = color + +class car: + """ Encode the state of the paddle in Brick Breaker """ + def __init__(self,x,y,vx,vy,color): + self.x = x + self.y = y + self.width = 20 + self.height = 20 + self.color = color + self.vx = vx + self.vy = vy + + def update(self): + self.x += self.vx + +class PyGameBrickBreakerView: + """ renders the BrickBreakerModel to a pygame window """ + def __init__(self,model,screen): + self.model = model + self.screen = screen + + def draw(self): + self.screen.fill(pygame.Color(0,0,0)) + for brick in self.model.bricks: + pygame.draw.rect(self.screen, pygame.Color(brick.color[0], brick.color[1], brick.color[2]), pygame.Rect(brick.x, brick.y, brick.width, brick.height)) + pygame.draw.rect(self.screen, pygame.Color(self.model.paddle.color[0], self.model.paddle.color[1], self.model.paddle.color[2]), pygame.Rect(self.model.paddle.x, self.model.paddle.y, self.model.paddle.width, self.model.paddle.height)) + pygame.display.update() + +class PyGameKeyboardController: + """ Manipulate game state based on keyboard input """ + def __init__(self, model): + self.model = model + + def handle_pygame_event(self, event): + if event.type != KEYDOWN: + return + if event.key == pygame.K_LEFT: + self.model.paddle.vx += -1.0 + if event.key == pygame.K_RIGHT: + self.model.paddle.vx += 1.0 + +if __name__ == '__main__': + pygame.init() + + size = (640,480) + screen = pygame.display.set_mode(size) + + model = BrickBreakerModel() + view = PyGameBrickBreakerView(model,screen) + controller = PyGameKeyboardController(model) + running = True + while running: + for event in pygame.event.get(): + if event.type == QUIT: + running = False + controller.handle_pygame_event(event) + model.update() + view.draw() + time.sleep(.001) + + pygame.quit() \ No newline at end of file diff --git a/hw6/game.py b/hw6/game.py new file mode 100644 index 0000000..4b8a107 --- /dev/null +++ b/hw6/game.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Mar 3 15:07:40 2014 + +@author: josh +""" + +# Import a library of functions called 'pygame' +import pygame +# Initialize the game engine +pygame.init() +#Loop until the user clicks the close button. +done = False +# Used to manage how fast the screen updates +clock = pygame.time.Clock() +# -------- Main Program Loop ----------- +while not done: +# ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT + for event in pygame.event.get(): # User did something + if event.type == pygame.QUIT: # If user clicked close + done = True # Flag that we are done so we exit this loop + elif event.type == pygame.QUIT: + print("User asked to quit.") + elif event.type == pygame.KEYDOWN: + print("User pressed a key.") + elif event.type == pygame.KEYUP: + print("User let go of a key.") +# ALL EVENT PROCESSING SHOULD GO ABOVE THIS COMMENT +# ALL GAME LOGIC SHOULD GO BELOW THIS COMMENT +# ALL GAME LOGIC SHOULD GO ABOVE THIS COMMENT +# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT +# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT +# Limit to 20 frames per second +clock.tick(20) \ No newline at end of file From 14db3dcfb47b851f51b474cf894370ad6b433d30 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Sun, 9 Mar 2014 04:58:48 -0400 Subject: [PATCH 11/17] hw6 added --- hw6/LightCycle.py | 60 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py index d52ce0e..1785183 100644 --- a/hw6/LightCycle.py +++ b/hw6/LightCycle.py @@ -14,13 +14,31 @@ class LightCycleModel: def __init__(self): self.cycle1 = Cycle(50,240,10,(250,0,0),.50) - self.cycle2 = Cycle(590,240,10,(0,0,250),-1.0) + self.cycle2 = Cycle(590,240,10,(0,0,250),-.50) self.trail1=[] self.trail2=[] def update(self): self.cycle1.update() self.cycle2.update() + if self.cycle1.vx>0: + self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,self.cycle1.vx,self.cycle1.x,self.cycle1.y)) + if self.cycle1.vx<0: + self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,self.cycle1.vx,self.cycle1.x+self.cycle1.width,self.cycle1.y)) + if self.cycle1.vy>0: + self.trail1.append(Trail(self.cycle1.color,self.cycle1.vy,self.cycle1.width,self.cycle1.x,self.cycle1.y)) + if self.cycle1.vy<0: + self.trail1.append(Trail(self.cycle1.color,self.cycle1.vy,self.cycle1.width,self.cycle1.x,self.cycle1.y+self.cycle1.height)) + + if self.cycle2.vx>0: + self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,self.cycle2.vx,self.cycle2.x,self.cycle2.y)) + if self.cycle2.vx<0: + self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,self.cycle2.vx,self.cycle2.x+self.cycle2.width,self.cycle2.y)) + if self.cycle2.vy>0: + self.trail2.append(Trail(self.cycle2.color,self.cycle2.vy,self.cycle2.width,self.cycle2.x,self.cycle2.y)) + if self.cycle2.vy<0: + self.trail2.append(Trail(self.cycle2.color,self.cycle2.vy,self.cycle2.width,self.cycle2.x,self.cycle2.y+self.cycle2.height)) + class Cycle: def __init__(self,x,y,thick,color,vx): @@ -34,10 +52,11 @@ def __init__(self,x,y,thick,color,vx): def update(self): self.x += self.vx + self.y += self.vy class Trail: - def __init__(self,color,hieght,width,x,y): + def __init__(self,color,height,width,x,y): self.color=color - self.hieght=hieght + self.height=height self.width=width self.x=x self.y=y @@ -50,7 +69,12 @@ def __init__(self,model,screen): def draw(self): self.screen.fill(pygame.Color(0,0,0)) pygame.draw.rect(self.screen, pygame.Color(self.model.cycle1.color[0],self.model.cycle1.color[1],self.model.cycle1.color[2]),pygame.Rect(self.model.cycle1.x,self.model.cycle1.y,self.model.cycle1.width,self.model.cycle1.height)) - #pygame.draw.rect(self.screen, pygame.Color(self.model.cycle2.color[0],self.model.cycle2.color[1],self.model.cycle2.color[2]),pygame.Rect(self.model.cycle2.x,self.model.cycle2.y,self.model.cycle2.width,self.model.cycle2.height)) + pygame.draw.rect(self.screen, pygame.Color(self.model.cycle2.color[0],self.model.cycle2.color[1],self.model.cycle2.color[2]),pygame.Rect(self.model.cycle2.x,self.model.cycle2.y,self.model.cycle2.width,self.model.cycle2.height)) + for path1 in self.model.trail1: + pygame.draw.rect(self.screen, pygame.Color(path1.color[0],path1.color[1],path1.color[2]),pygame.Rect(path1.x,path1.y,path1.width,path1.height)) + for path2 in self.model.trail2: + pygame.draw.rect(self.screen, pygame.Color(path2.color[0],path2.color[1],path2.color[2]),pygame.Rect(path2.x,path2.y,path2.width,path2.height)) + pygame.display.update() class Controller: @@ -68,25 +92,25 @@ def handle_keyboard_event(self,event): self.model.cycle1.vy = 0.0 if event.key == pygame.K_UP and self.model.cycle1.vy == 0: self.model.cycle1.vx = 0.0 - self.model.cycle1.vy += .50 + self.model.cycle1.vy = -.50 if event.key == pygame.K_DOWN and self.model.cycle1.vy == 0: self.model.cycle1.vx = 0.0 - self.model.cycle1.vy += -.50 + self.model.cycle1.vy = .50 else: self.model.cycle1.vx = self.model.cycle1.vx self.model.cycle1.vy = self.model.cycle1.vy -# if event.key == pygame.K_A and self.model.cycle2.vx == 0: -# self.model.cycle2.vx = -1.0 -# self.model.cycle2.vy = 0.0 -# if event.key == pygame.K_D and self.model.cycle2.vx == 0: -# self.model.cycle2.vx = 1.0 -# self.model.cycle2.vy = 0.0 -# if event.key == pygame.K_W and self.model.cycle2.vy == 0: -# self.model.cycle2.vx = 0.0 -# self.model.cycle2.vy = 1.0 -# if event.key == pygame.K_S and self.model.cycle2.vy == 0: -# self.model.cycle2.vx = 0.0 -# self.model.cycle2.vy = -1.0 + if event.key == pygame.K_a and self.model.cycle2.vx == 0: + self.model.cycle2.vx = -.50 + self.model.cycle2.vy = 0.0 + if event.key == pygame.K_d and self.model.cycle2.vx == 0: + self.model.cycle2.vx = .50 + self.model.cycle2.vy = 0.0 + if event.key == pygame.K_w and self.model.cycle2.vy == 0: + self.model.cycle2.vx = 0.0 + self.model.cycle2.vy = -.50 + if event.key == pygame.K_s and self.model.cycle2.vy == 0: + self.model.cycle2.vx = 0.0 + self.model.cycle2.vy = .50 if __name__ == '__main__': pygame.init() From 8698b6940b511ab9d2f89f41b2f52981bf26ff47 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Sun, 9 Mar 2014 15:10:54 -0400 Subject: [PATCH 12/17] hw6 added --- hw6/LightCycle.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py index 1785183..182730c 100644 --- a/hw6/LightCycle.py +++ b/hw6/LightCycle.py @@ -13,8 +13,8 @@ class LightCycleModel: def __init__(self): - self.cycle1 = Cycle(50,240,10,(250,0,0),.50) - self.cycle2 = Cycle(590,240,10,(0,0,250),-.50) + self.cycle1 = Cycle(50,240,10,(250,0,0),.750) + self.cycle2 = Cycle(590,240,10,(0,0,250),-.750) self.trail1=[] self.trail2=[] @@ -39,6 +39,17 @@ def update(self): if self.cycle2.vy<0: self.trail2.append(Trail(self.cycle2.color,self.cycle2.vy,self.cycle2.width,self.cycle2.x,self.cycle2.y+self.cycle2.height)) + for path1 in self.trail1[:-30]: + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): + return False + if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): + return False + for path2 in self.trail2[:-30]: + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + return False + if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + return False + return True class Cycle: def __init__(self,x,y,thick,color,vx): @@ -53,6 +64,8 @@ def __init__(self,x,y,thick,color,vx): def update(self): self.x += self.vx self.y += self.vy + + class Trail: def __init__(self,color,height,width,x,y): self.color=color @@ -85,32 +98,32 @@ def handle_keyboard_event(self,event): if event.type != KEYDOWN: return if event.key == pygame.K_LEFT and self.model.cycle1.vx == 0: - self.model.cycle1.vx += -.50 + self.model.cycle1.vx += -.750 self.model.cycle1.vy = 0.0 if event.key == pygame.K_RIGHT and self.model.cycle1.vx == 0: - self.model.cycle1.vx += .50 + self.model.cycle1.vx += .750 self.model.cycle1.vy = 0.0 if event.key == pygame.K_UP and self.model.cycle1.vy == 0: self.model.cycle1.vx = 0.0 - self.model.cycle1.vy = -.50 + self.model.cycle1.vy = -.750 if event.key == pygame.K_DOWN and self.model.cycle1.vy == 0: self.model.cycle1.vx = 0.0 - self.model.cycle1.vy = .50 + self.model.cycle1.vy = .750 else: self.model.cycle1.vx = self.model.cycle1.vx self.model.cycle1.vy = self.model.cycle1.vy if event.key == pygame.K_a and self.model.cycle2.vx == 0: - self.model.cycle2.vx = -.50 + self.model.cycle2.vx = -.750 self.model.cycle2.vy = 0.0 if event.key == pygame.K_d and self.model.cycle2.vx == 0: - self.model.cycle2.vx = .50 + self.model.cycle2.vx = .750 self.model.cycle2.vy = 0.0 if event.key == pygame.K_w and self.model.cycle2.vy == 0: self.model.cycle2.vx = 0.0 - self.model.cycle2.vy = -.50 + self.model.cycle2.vy = -.750 if event.key == pygame.K_s and self.model.cycle2.vy == 0: self.model.cycle2.vx = 0.0 - self.model.cycle2.vy = .50 + self.model.cycle2.vy = .750 if __name__ == '__main__': pygame.init() @@ -131,7 +144,7 @@ def handle_keyboard_event(self,event): running = False if event.type == KEYDOWN: controller.handle_keyboard_event(event) - model.update() + running=model.update() view.draw() time.sleep(.001) From 464b8e31173c54d9a7006331711c5ffc3055f8c2 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 10 Mar 2014 12:36:09 -0400 Subject: [PATCH 13/17] adding lightcycle2 --- hw6/LightCycle.py | 75 ++++++++++++-------- hw6/LightCycle2.py | 166 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 30 deletions(-) create mode 100644 hw6/LightCycle2.py diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py index 182730c..2ba5d75 100644 --- a/hw6/LightCycle.py +++ b/hw6/LightCycle.py @@ -13,42 +13,50 @@ class LightCycleModel: def __init__(self): - self.cycle1 = Cycle(50,240,10,(250,0,0),.750) - self.cycle2 = Cycle(590,240,10,(0,0,250),-.750) + self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) + self.cycle1 = Cycle(800,500,10,(0,0,250),-1.0) self.trail1=[] self.trail2=[] - + self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,0,self.cycle1.x,self.cycle1.y)) + self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,0,self.cycle2.x,self.cycle2.y)) def update(self): self.cycle1.update() self.cycle2.update() if self.cycle1.vx>0: - self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,self.cycle1.vx,self.cycle1.x,self.cycle1.y)) + self.trail1[-1].width+=self.cycle1.vx if self.cycle1.vx<0: - self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,self.cycle1.vx,self.cycle1.x+self.cycle1.width,self.cycle1.y)) + self.trail1[-1].width+=self.cycle1.vx if self.cycle1.vy>0: - self.trail1.append(Trail(self.cycle1.color,self.cycle1.vy,self.cycle1.width,self.cycle1.x,self.cycle1.y)) + self.trail1[-1].height+=self.cycle1.vy if self.cycle1.vy<0: - self.trail1.append(Trail(self.cycle1.color,self.cycle1.vy,self.cycle1.width,self.cycle1.x,self.cycle1.y+self.cycle1.height)) + self.trail1[-1].height+=self.cycle1.vy if self.cycle2.vx>0: - self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,self.cycle2.vx,self.cycle2.x,self.cycle2.y)) + self.trail2[-1].width+=self.cycle2.vx if self.cycle2.vx<0: - self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,self.cycle2.vx,self.cycle2.x+self.cycle2.width,self.cycle2.y)) + self.trail2[-1].width+=self.cycle2.vx if self.cycle2.vy>0: - self.trail2.append(Trail(self.cycle2.color,self.cycle2.vy,self.cycle2.width,self.cycle2.x,self.cycle2.y)) + self.trail2[-1].height+=self.cycle2.vy if self.cycle2.vy<0: - self.trail2.append(Trail(self.cycle2.color,self.cycle2.vy,self.cycle2.width,self.cycle2.x,self.cycle2.y+self.cycle2.height)) + self.trail2[-1].height+=self.cycle2.vy - for path1 in self.trail1[:-30]: + for path1 in self.trail1[:-1]: + print path1.x, path1.y if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): return False - if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): + for path1 in self.trail1[:]: + if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): return False - for path2 in self.trail2[:-30]: - if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + for path2 in self.trail2[:]: + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): return False + for path2 in self.trail2[:-1]: if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): return False + if not(self.windowRect.contains(pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height))): + return False + #if not(self.windowRect.contains(pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height))): + # return False return True class Cycle: @@ -75,10 +83,10 @@ def __init__(self,color,height,width,x,y): self.y=y class PyGameWindowView: """ A view of brick breaker rendered in a Pygame window """ - def __init__(self,model,screen): + def __init__(self,model,screen,size): self.model = model + self.model.windowRect=pygame.Rect(0,0,size[0],size[1]) self.screen = screen - def draw(self): self.screen.fill(pygame.Color(0,0,0)) pygame.draw.rect(self.screen, pygame.Color(self.model.cycle1.color[0],self.model.cycle1.color[1],self.model.cycle1.color[2]),pygame.Rect(self.model.cycle1.x,self.model.cycle1.y,self.model.cycle1.width,self.model.cycle1.height)) @@ -86,8 +94,7 @@ def draw(self): for path1 in self.model.trail1: pygame.draw.rect(self.screen, pygame.Color(path1.color[0],path1.color[1],path1.color[2]),pygame.Rect(path1.x,path1.y,path1.width,path1.height)) for path2 in self.model.trail2: - pygame.draw.rect(self.screen, pygame.Color(path2.color[0],path2.color[1],path2.color[2]),pygame.Rect(path2.x,path2.y,path2.width,path2.height)) - + pygame.draw.rect(self.screen, pygame.Color(path2.color[0],path2.color[1],path2.color[2]),pygame.Rect(path2.x,path2.y,path2.width,path2.height)) pygame.display.update() class Controller: @@ -98,41 +105,49 @@ def handle_keyboard_event(self,event): if event.type != KEYDOWN: return if event.key == pygame.K_LEFT and self.model.cycle1.vx == 0: - self.model.cycle1.vx += -.750 + self.model.cycle1.vx = -1.0 self.model.cycle1.vy = 0.0 + self.model.trail1.append(Trail(self.model.cycle1.color,self.model.cycle1.height,0,self.model.cycle1.x+self.model.cycle1.width,self.model.cycle1.y)) if event.key == pygame.K_RIGHT and self.model.cycle1.vx == 0: - self.model.cycle1.vx += .750 + self.model.cycle1.vx = 1.0 self.model.cycle1.vy = 0.0 + self.model.trail1.append(Trail(self.model.cycle1.color,self.model.cycle1.height,0,self.model.cycle1.x,self.model.cycle1.y)) if event.key == pygame.K_UP and self.model.cycle1.vy == 0: self.model.cycle1.vx = 0.0 - self.model.cycle1.vy = -.750 + self.model.cycle1.vy = -1.0 + self.model.trail1.append(Trail(self.model.cycle1.color,0,self.model.cycle1.width,self.model.cycle1.x,self.model.cycle1.y+self.model.cycle1.height)) if event.key == pygame.K_DOWN and self.model.cycle1.vy == 0: self.model.cycle1.vx = 0.0 - self.model.cycle1.vy = .750 + self.model.cycle1.vy = .9999 + self.model.trail1.append(Trail(self.model.cycle1.color,0,self.model.cycle1.width,self.model.cycle1.x,self.model.cycle1.y)) else: self.model.cycle1.vx = self.model.cycle1.vx self.model.cycle1.vy = self.model.cycle1.vy + if event.key == pygame.K_a and self.model.cycle2.vx == 0: - self.model.cycle2.vx = -.750 + self.model.cycle2.vx = -1.0 self.model.cycle2.vy = 0.0 + self.model.trail2.append(Trail(self.model.cycle2.color,self.model.cycle2.height,0,self.model.cycle2.x+self.model.cycle2.width,self.model.cycle2.y)) if event.key == pygame.K_d and self.model.cycle2.vx == 0: - self.model.cycle2.vx = .750 + self.model.cycle2.vx = 1.0 self.model.cycle2.vy = 0.0 + self.model.trail2.append(Trail(self.model.cycle2.color,self.model.cycle2.height,0,self.model.cycle2.x,self.model.cycle2.y)) if event.key == pygame.K_w and self.model.cycle2.vy == 0: self.model.cycle2.vx = 0.0 - self.model.cycle2.vy = -.750 + self.model.cycle2.vy = -1.0 + self.model.trail2.append(Trail(self.model.cycle2.color,0,self.model.cycle2.width,self.model.cycle2.x,self.model.cycle2.y+self.model.cycle2.height)) if event.key == pygame.K_s and self.model.cycle2.vy == 0: self.model.cycle2.vx = 0.0 - self.model.cycle2.vy = .750 - + self.model.cycle2.vy = .9999 + self.model.trail2.append(Trail(self.model.cycle2.color,0,self.model.cycle2.width,self.model.cycle2.x,self.model.cycle2.y)) if __name__ == '__main__': pygame.init() - size = (640,480) + size = (1000,1000) screen = pygame.display.set_mode(size) model = LightCycleModel() - view = PyGameWindowView(model,screen) + view = PyGameWindowView(model,screen,size) controller = Controller(model) diff --git a/hw6/LightCycle2.py b/hw6/LightCycle2.py new file mode 100644 index 0000000..2ba5d75 --- /dev/null +++ b/hw6/LightCycle2.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Mar 8 23:11:28 2014 + +@author: dmichael +""" + +import pygame +from pygame.locals import * +import random +import math +import time + +class LightCycleModel: + def __init__(self): + self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) + self.cycle1 = Cycle(800,500,10,(0,0,250),-1.0) + self.trail1=[] + self.trail2=[] + self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,0,self.cycle1.x,self.cycle1.y)) + self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,0,self.cycle2.x,self.cycle2.y)) + def update(self): + self.cycle1.update() + self.cycle2.update() + if self.cycle1.vx>0: + self.trail1[-1].width+=self.cycle1.vx + if self.cycle1.vx<0: + self.trail1[-1].width+=self.cycle1.vx + if self.cycle1.vy>0: + self.trail1[-1].height+=self.cycle1.vy + if self.cycle1.vy<0: + self.trail1[-1].height+=self.cycle1.vy + + if self.cycle2.vx>0: + self.trail2[-1].width+=self.cycle2.vx + if self.cycle2.vx<0: + self.trail2[-1].width+=self.cycle2.vx + if self.cycle2.vy>0: + self.trail2[-1].height+=self.cycle2.vy + if self.cycle2.vy<0: + self.trail2[-1].height+=self.cycle2.vy + + for path1 in self.trail1[:-1]: + print path1.x, path1.y + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): + return False + for path1 in self.trail1[:]: + if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): + return False + for path2 in self.trail2[:]: + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + return False + for path2 in self.trail2[:-1]: + if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + return False + if not(self.windowRect.contains(pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height))): + return False + #if not(self.windowRect.contains(pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height))): + # return False + return True + +class Cycle: + def __init__(self,x,y,thick,color,vx): + self.x = x + self.y = y + self.width = thick + self.height = thick + self.color = color + self.vx = vx + self.vy = 0.0 + + def update(self): + self.x += self.vx + self.y += self.vy + + +class Trail: + def __init__(self,color,height,width,x,y): + self.color=color + self.height=height + self.width=width + self.x=x + self.y=y +class PyGameWindowView: + """ A view of brick breaker rendered in a Pygame window """ + def __init__(self,model,screen,size): + self.model = model + self.model.windowRect=pygame.Rect(0,0,size[0],size[1]) + self.screen = screen + def draw(self): + self.screen.fill(pygame.Color(0,0,0)) + pygame.draw.rect(self.screen, pygame.Color(self.model.cycle1.color[0],self.model.cycle1.color[1],self.model.cycle1.color[2]),pygame.Rect(self.model.cycle1.x,self.model.cycle1.y,self.model.cycle1.width,self.model.cycle1.height)) + pygame.draw.rect(self.screen, pygame.Color(self.model.cycle2.color[0],self.model.cycle2.color[1],self.model.cycle2.color[2]),pygame.Rect(self.model.cycle2.x,self.model.cycle2.y,self.model.cycle2.width,self.model.cycle2.height)) + for path1 in self.model.trail1: + pygame.draw.rect(self.screen, pygame.Color(path1.color[0],path1.color[1],path1.color[2]),pygame.Rect(path1.x,path1.y,path1.width,path1.height)) + for path2 in self.model.trail2: + pygame.draw.rect(self.screen, pygame.Color(path2.color[0],path2.color[1],path2.color[2]),pygame.Rect(path2.x,path2.y,path2.width,path2.height)) + pygame.display.update() + +class Controller: + def __init__(self,model): + self.model = model + + def handle_keyboard_event(self,event): + if event.type != KEYDOWN: + return + if event.key == pygame.K_LEFT and self.model.cycle1.vx == 0: + self.model.cycle1.vx = -1.0 + self.model.cycle1.vy = 0.0 + self.model.trail1.append(Trail(self.model.cycle1.color,self.model.cycle1.height,0,self.model.cycle1.x+self.model.cycle1.width,self.model.cycle1.y)) + if event.key == pygame.K_RIGHT and self.model.cycle1.vx == 0: + self.model.cycle1.vx = 1.0 + self.model.cycle1.vy = 0.0 + self.model.trail1.append(Trail(self.model.cycle1.color,self.model.cycle1.height,0,self.model.cycle1.x,self.model.cycle1.y)) + if event.key == pygame.K_UP and self.model.cycle1.vy == 0: + self.model.cycle1.vx = 0.0 + self.model.cycle1.vy = -1.0 + self.model.trail1.append(Trail(self.model.cycle1.color,0,self.model.cycle1.width,self.model.cycle1.x,self.model.cycle1.y+self.model.cycle1.height)) + if event.key == pygame.K_DOWN and self.model.cycle1.vy == 0: + self.model.cycle1.vx = 0.0 + self.model.cycle1.vy = .9999 + self.model.trail1.append(Trail(self.model.cycle1.color,0,self.model.cycle1.width,self.model.cycle1.x,self.model.cycle1.y)) + else: + self.model.cycle1.vx = self.model.cycle1.vx + self.model.cycle1.vy = self.model.cycle1.vy + + if event.key == pygame.K_a and self.model.cycle2.vx == 0: + self.model.cycle2.vx = -1.0 + self.model.cycle2.vy = 0.0 + self.model.trail2.append(Trail(self.model.cycle2.color,self.model.cycle2.height,0,self.model.cycle2.x+self.model.cycle2.width,self.model.cycle2.y)) + if event.key == pygame.K_d and self.model.cycle2.vx == 0: + self.model.cycle2.vx = 1.0 + self.model.cycle2.vy = 0.0 + self.model.trail2.append(Trail(self.model.cycle2.color,self.model.cycle2.height,0,self.model.cycle2.x,self.model.cycle2.y)) + if event.key == pygame.K_w and self.model.cycle2.vy == 0: + self.model.cycle2.vx = 0.0 + self.model.cycle2.vy = -1.0 + self.model.trail2.append(Trail(self.model.cycle2.color,0,self.model.cycle2.width,self.model.cycle2.x,self.model.cycle2.y+self.model.cycle2.height)) + if event.key == pygame.K_s and self.model.cycle2.vy == 0: + self.model.cycle2.vx = 0.0 + self.model.cycle2.vy = .9999 + self.model.trail2.append(Trail(self.model.cycle2.color,0,self.model.cycle2.width,self.model.cycle2.x,self.model.cycle2.y)) +if __name__ == '__main__': + pygame.init() + + size = (1000,1000) + screen = pygame.display.set_mode(size) + + model = LightCycleModel() + view = PyGameWindowView(model,screen,size) + controller = Controller(model) + + + running = True + + while running: + for event in pygame.event.get(): + if event.type == QUIT: + running = False + if event.type == KEYDOWN: + controller.handle_keyboard_event(event) + running=model.update() + view.draw() + time.sleep(.001) + + pygame.quit() From 23f328411dd6f274f05a5d3d5efbc225a12b5f6f Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 10 Mar 2014 12:48:40 -0400 Subject: [PATCH 14/17] adding lightcycle2 --- hw6/LightCycle2.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/hw6/LightCycle2.py b/hw6/LightCycle2.py index 2ba5d75..6aedeee 100644 --- a/hw6/LightCycle2.py +++ b/hw6/LightCycle2.py @@ -13,8 +13,8 @@ class LightCycleModel: def __init__(self): - self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) self.cycle1 = Cycle(800,500,10,(0,0,250),-1.0) + self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) self.trail1=[] self.trail2=[] self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,0,self.cycle1.x,self.cycle1.y)) @@ -25,21 +25,25 @@ def update(self): if self.cycle1.vx>0: self.trail1[-1].width+=self.cycle1.vx if self.cycle1.vx<0: - self.trail1[-1].width+=self.cycle1.vx + self.trail1[-1].width=self.trail1[-1].width-self.cycle1.vx + self.trail1[-1].x = self.cycle1.x+self.cycle1.width if self.cycle1.vy>0: self.trail1[-1].height+=self.cycle1.vy if self.cycle1.vy<0: - self.trail1[-1].height+=self.cycle1.vy + self.trail1[-1].height=self.trail1[-1].height-self.cycle1.vy + self.trail1[-1].y = self.cycle1.y+self.cycle1.height if self.cycle2.vx>0: self.trail2[-1].width+=self.cycle2.vx if self.cycle2.vx<0: - self.trail2[-1].width+=self.cycle2.vx + self.trail2[-1].width=self.trail2[-1].width-self.cycle2.vx + self.trail2[-1].x = self.cycle2.x+self.cycle2.width if self.cycle2.vy>0: self.trail2[-1].height+=self.cycle2.vy if self.cycle2.vy<0: - self.trail2[-1].height+=self.cycle2.vy - + self.trail2[-1].height=self.trail2[-1].height-self.cycle2.vy + self.trail2[-1].y = self.cycle2.y+self.cycle2.height + print "\n\n\n\n" for path1 in self.trail1[:-1]: print path1.x, path1.y if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): @@ -48,7 +52,7 @@ def update(self): if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): return False for path2 in self.trail2[:]: - if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): return False for path2 in self.trail2[:-1]: if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): From 76ace55b1056e231fcb8ee65db3551df44c748cf Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 10 Mar 2014 12:49:11 -0400 Subject: [PATCH 15/17] adding lightcycle --- hw6/LightCycle.py | 18 +++-- hw6/LightCycle2.py | 170 --------------------------------------------- 2 files changed, 11 insertions(+), 177 deletions(-) delete mode 100644 hw6/LightCycle2.py diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py index 2ba5d75..6aedeee 100644 --- a/hw6/LightCycle.py +++ b/hw6/LightCycle.py @@ -13,8 +13,8 @@ class LightCycleModel: def __init__(self): - self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) self.cycle1 = Cycle(800,500,10,(0,0,250),-1.0) + self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) self.trail1=[] self.trail2=[] self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,0,self.cycle1.x,self.cycle1.y)) @@ -25,21 +25,25 @@ def update(self): if self.cycle1.vx>0: self.trail1[-1].width+=self.cycle1.vx if self.cycle1.vx<0: - self.trail1[-1].width+=self.cycle1.vx + self.trail1[-1].width=self.trail1[-1].width-self.cycle1.vx + self.trail1[-1].x = self.cycle1.x+self.cycle1.width if self.cycle1.vy>0: self.trail1[-1].height+=self.cycle1.vy if self.cycle1.vy<0: - self.trail1[-1].height+=self.cycle1.vy + self.trail1[-1].height=self.trail1[-1].height-self.cycle1.vy + self.trail1[-1].y = self.cycle1.y+self.cycle1.height if self.cycle2.vx>0: self.trail2[-1].width+=self.cycle2.vx if self.cycle2.vx<0: - self.trail2[-1].width+=self.cycle2.vx + self.trail2[-1].width=self.trail2[-1].width-self.cycle2.vx + self.trail2[-1].x = self.cycle2.x+self.cycle2.width if self.cycle2.vy>0: self.trail2[-1].height+=self.cycle2.vy if self.cycle2.vy<0: - self.trail2[-1].height+=self.cycle2.vy - + self.trail2[-1].height=self.trail2[-1].height-self.cycle2.vy + self.trail2[-1].y = self.cycle2.y+self.cycle2.height + print "\n\n\n\n" for path1 in self.trail1[:-1]: print path1.x, path1.y if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): @@ -48,7 +52,7 @@ def update(self): if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): return False for path2 in self.trail2[:]: - if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): + if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): return False for path2 in self.trail2[:-1]: if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): diff --git a/hw6/LightCycle2.py b/hw6/LightCycle2.py deleted file mode 100644 index 6aedeee..0000000 --- a/hw6/LightCycle2.py +++ /dev/null @@ -1,170 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sat Mar 8 23:11:28 2014 - -@author: dmichael -""" - -import pygame -from pygame.locals import * -import random -import math -import time - -class LightCycleModel: - def __init__(self): - self.cycle1 = Cycle(800,500,10,(0,0,250),-1.0) - self.cycle2 = Cycle(200,500,10,(250,0,0),1.0) - self.trail1=[] - self.trail2=[] - self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,0,self.cycle1.x,self.cycle1.y)) - self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,0,self.cycle2.x,self.cycle2.y)) - def update(self): - self.cycle1.update() - self.cycle2.update() - if self.cycle1.vx>0: - self.trail1[-1].width+=self.cycle1.vx - if self.cycle1.vx<0: - self.trail1[-1].width=self.trail1[-1].width-self.cycle1.vx - self.trail1[-1].x = self.cycle1.x+self.cycle1.width - if self.cycle1.vy>0: - self.trail1[-1].height+=self.cycle1.vy - if self.cycle1.vy<0: - self.trail1[-1].height=self.trail1[-1].height-self.cycle1.vy - self.trail1[-1].y = self.cycle1.y+self.cycle1.height - - if self.cycle2.vx>0: - self.trail2[-1].width+=self.cycle2.vx - if self.cycle2.vx<0: - self.trail2[-1].width=self.trail2[-1].width-self.cycle2.vx - self.trail2[-1].x = self.cycle2.x+self.cycle2.width - if self.cycle2.vy>0: - self.trail2[-1].height+=self.cycle2.vy - if self.cycle2.vy<0: - self.trail2[-1].height=self.trail2[-1].height-self.cycle2.vy - self.trail2[-1].y = self.cycle2.y+self.cycle2.height - print "\n\n\n\n" - for path1 in self.trail1[:-1]: - print path1.x, path1.y - if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): - return False - for path1 in self.trail1[:]: - if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): - return False - for path2 in self.trail2[:]: - if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): - return False - for path2 in self.trail2[:-1]: - if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): - return False - if not(self.windowRect.contains(pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height))): - return False - #if not(self.windowRect.contains(pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height))): - # return False - return True - -class Cycle: - def __init__(self,x,y,thick,color,vx): - self.x = x - self.y = y - self.width = thick - self.height = thick - self.color = color - self.vx = vx - self.vy = 0.0 - - def update(self): - self.x += self.vx - self.y += self.vy - - -class Trail: - def __init__(self,color,height,width,x,y): - self.color=color - self.height=height - self.width=width - self.x=x - self.y=y -class PyGameWindowView: - """ A view of brick breaker rendered in a Pygame window """ - def __init__(self,model,screen,size): - self.model = model - self.model.windowRect=pygame.Rect(0,0,size[0],size[1]) - self.screen = screen - def draw(self): - self.screen.fill(pygame.Color(0,0,0)) - pygame.draw.rect(self.screen, pygame.Color(self.model.cycle1.color[0],self.model.cycle1.color[1],self.model.cycle1.color[2]),pygame.Rect(self.model.cycle1.x,self.model.cycle1.y,self.model.cycle1.width,self.model.cycle1.height)) - pygame.draw.rect(self.screen, pygame.Color(self.model.cycle2.color[0],self.model.cycle2.color[1],self.model.cycle2.color[2]),pygame.Rect(self.model.cycle2.x,self.model.cycle2.y,self.model.cycle2.width,self.model.cycle2.height)) - for path1 in self.model.trail1: - pygame.draw.rect(self.screen, pygame.Color(path1.color[0],path1.color[1],path1.color[2]),pygame.Rect(path1.x,path1.y,path1.width,path1.height)) - for path2 in self.model.trail2: - pygame.draw.rect(self.screen, pygame.Color(path2.color[0],path2.color[1],path2.color[2]),pygame.Rect(path2.x,path2.y,path2.width,path2.height)) - pygame.display.update() - -class Controller: - def __init__(self,model): - self.model = model - - def handle_keyboard_event(self,event): - if event.type != KEYDOWN: - return - if event.key == pygame.K_LEFT and self.model.cycle1.vx == 0: - self.model.cycle1.vx = -1.0 - self.model.cycle1.vy = 0.0 - self.model.trail1.append(Trail(self.model.cycle1.color,self.model.cycle1.height,0,self.model.cycle1.x+self.model.cycle1.width,self.model.cycle1.y)) - if event.key == pygame.K_RIGHT and self.model.cycle1.vx == 0: - self.model.cycle1.vx = 1.0 - self.model.cycle1.vy = 0.0 - self.model.trail1.append(Trail(self.model.cycle1.color,self.model.cycle1.height,0,self.model.cycle1.x,self.model.cycle1.y)) - if event.key == pygame.K_UP and self.model.cycle1.vy == 0: - self.model.cycle1.vx = 0.0 - self.model.cycle1.vy = -1.0 - self.model.trail1.append(Trail(self.model.cycle1.color,0,self.model.cycle1.width,self.model.cycle1.x,self.model.cycle1.y+self.model.cycle1.height)) - if event.key == pygame.K_DOWN and self.model.cycle1.vy == 0: - self.model.cycle1.vx = 0.0 - self.model.cycle1.vy = .9999 - self.model.trail1.append(Trail(self.model.cycle1.color,0,self.model.cycle1.width,self.model.cycle1.x,self.model.cycle1.y)) - else: - self.model.cycle1.vx = self.model.cycle1.vx - self.model.cycle1.vy = self.model.cycle1.vy - - if event.key == pygame.K_a and self.model.cycle2.vx == 0: - self.model.cycle2.vx = -1.0 - self.model.cycle2.vy = 0.0 - self.model.trail2.append(Trail(self.model.cycle2.color,self.model.cycle2.height,0,self.model.cycle2.x+self.model.cycle2.width,self.model.cycle2.y)) - if event.key == pygame.K_d and self.model.cycle2.vx == 0: - self.model.cycle2.vx = 1.0 - self.model.cycle2.vy = 0.0 - self.model.trail2.append(Trail(self.model.cycle2.color,self.model.cycle2.height,0,self.model.cycle2.x,self.model.cycle2.y)) - if event.key == pygame.K_w and self.model.cycle2.vy == 0: - self.model.cycle2.vx = 0.0 - self.model.cycle2.vy = -1.0 - self.model.trail2.append(Trail(self.model.cycle2.color,0,self.model.cycle2.width,self.model.cycle2.x,self.model.cycle2.y+self.model.cycle2.height)) - if event.key == pygame.K_s and self.model.cycle2.vy == 0: - self.model.cycle2.vx = 0.0 - self.model.cycle2.vy = .9999 - self.model.trail2.append(Trail(self.model.cycle2.color,0,self.model.cycle2.width,self.model.cycle2.x,self.model.cycle2.y)) -if __name__ == '__main__': - pygame.init() - - size = (1000,1000) - screen = pygame.display.set_mode(size) - - model = LightCycleModel() - view = PyGameWindowView(model,screen,size) - controller = Controller(model) - - - running = True - - while running: - for event in pygame.event.get(): - if event.type == QUIT: - running = False - if event.type == KEYDOWN: - controller.handle_keyboard_event(event) - running=model.update() - view.draw() - time.sleep(.001) - - pygame.quit() From 03a2a0a2ecfba15fe406dc244d124084778fdb9e Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 10 Mar 2014 12:49:29 -0400 Subject: [PATCH 16/17] adding lightcycle --- hw6/LightCycle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py index 6aedeee..1f4a2f3 100644 --- a/hw6/LightCycle.py +++ b/hw6/LightCycle.py @@ -59,8 +59,8 @@ def update(self): return False if not(self.windowRect.contains(pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height))): return False - #if not(self.windowRect.contains(pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height))): - # return False + if not(self.windowRect.contains(pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height))): + return False return True class Cycle: From 2680a7c1869c054ffc9655a9173775c913b4dfe0 Mon Sep 17 00:00:00 2001 From: Josh Sapers Date: Mon, 10 Mar 2014 13:03:51 -0400 Subject: [PATCH 17/17] adding lightcycle --- hw6/LightCycle.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/hw6/LightCycle.py b/hw6/LightCycle.py index 1f4a2f3..10e82f1 100644 --- a/hw6/LightCycle.py +++ b/hw6/LightCycle.py @@ -20,8 +20,11 @@ def __init__(self): self.trail1.append(Trail(self.cycle1.color,self.cycle1.height,0,self.cycle1.x,self.cycle1.y)) self.trail2.append(Trail(self.cycle2.color,self.cycle2.height,0,self.cycle2.x,self.cycle2.y)) def update(self): - self.cycle1.update() + """updates the cycles and the current paths for each lightcycle""" + self.cycle1.update() self.cycle2.update() + + #enlongating the path for cycle 1 if self.cycle1.vx>0: self.trail1[-1].width+=self.cycle1.vx if self.cycle1.vx<0: @@ -32,7 +35,8 @@ def update(self): if self.cycle1.vy<0: self.trail1[-1].height=self.trail1[-1].height-self.cycle1.vy self.trail1[-1].y = self.cycle1.y+self.cycle1.height - + + #enlongating the path for cycle 2 if self.cycle2.vx>0: self.trail2[-1].width+=self.cycle2.vx if self.cycle2.vx<0: @@ -43,10 +47,11 @@ def update(self): if self.cycle2.vy<0: self.trail2[-1].height=self.trail2[-1].height-self.cycle2.vy self.trail2[-1].y = self.cycle2.y+self.cycle2.height - print "\n\n\n\n" + for path1 in self.trail1[:-1]: - print path1.x, path1.y + #Checking for collisions with paths if pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): + #ends game if it collides return False for path1 in self.trail1[:]: if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path1.x,path1.y,path1.width,path1.height)): @@ -57,6 +62,7 @@ def update(self): for path2 in self.trail2[:-1]: if pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height).colliderect(pygame.Rect(path2.x,path2.y,path2.width,path2.height)): return False + #ends game if the cycle hit the edge of screen if not(self.windowRect.contains(pygame.Rect(self.cycle1.x,self.cycle1.y,self.cycle1.width,self.cycle1.height))): return False if not(self.windowRect.contains(pygame.Rect(self.cycle2.x,self.cycle2.y,self.cycle2.width,self.cycle2.height))): @@ -74,6 +80,7 @@ def __init__(self,x,y,thick,color,vx): self.vy = 0.0 def update(self): + """Changes the location based off of the two velocities""" self.x += self.vx self.y += self.vy @@ -86,12 +93,13 @@ def __init__(self,color,height,width,x,y): self.x=x self.y=y class PyGameWindowView: - """ A view of brick breaker rendered in a Pygame window """ + """ A view of LightCycles rendered in a Pygame window """ def __init__(self,model,screen,size): self.model = model self.model.windowRect=pygame.Rect(0,0,size[0],size[1]) self.screen = screen def draw(self): + """draws the two cycles and all of the paths they made""" self.screen.fill(pygame.Color(0,0,0)) pygame.draw.rect(self.screen, pygame.Color(self.model.cycle1.color[0],self.model.cycle1.color[1],self.model.cycle1.color[2]),pygame.Rect(self.model.cycle1.x,self.model.cycle1.y,self.model.cycle1.width,self.model.cycle1.height)) pygame.draw.rect(self.screen, pygame.Color(self.model.cycle2.color[0],self.model.cycle2.color[1],self.model.cycle2.color[2]),pygame.Rect(self.model.cycle2.x,self.model.cycle2.y,self.model.cycle2.width,self.model.cycle2.height)) @@ -106,6 +114,8 @@ def __init__(self,model): self.model = model def handle_keyboard_event(self,event): + """checks for wasd or arrow key inputs and changes the direction accordingly. Also adds + a new path when the cycle changes direction""" if event.type != KEYDOWN: return if event.key == pygame.K_LEFT and self.model.cycle1.vx == 0: