diff --git a/Ending_pics/grad_hat.png b/Ending_pics/grad_hat.png new file mode 100644 index 0000000..418063f Binary files /dev/null and b/Ending_pics/grad_hat.png differ diff --git a/Ideation/22690177_1814110521950453_239685912_o.jpg b/Ideation/22690177_1814110521950453_239685912_o.jpg new file mode 100644 index 0000000..421376c Binary files /dev/null and b/Ideation/22690177_1814110521950453_239685912_o.jpg differ diff --git a/Ideation/Course_Icons/BeeKeeping.png b/Ideation/Course_Icons/BeeKeeping.png new file mode 100644 index 0000000..33a6e40 Binary files /dev/null and b/Ideation/Course_Icons/BeeKeeping.png differ diff --git a/Ideation/Course_Icons/ENM.png b/Ideation/Course_Icons/ENM.png new file mode 100644 index 0000000..adc2ab4 Binary files /dev/null and b/Ideation/Course_Icons/ENM.png differ diff --git a/Ideation/Course_Icons/FOCS.png b/Ideation/Course_Icons/FOCS.png new file mode 100644 index 0000000..f9ee99b Binary files /dev/null and b/Ideation/Course_Icons/FOCS.png differ diff --git a/Ideation/Course_Icons/Fun Robo.png b/Ideation/Course_Icons/Fun Robo.png new file mode 100644 index 0000000..b3fd38f Binary files /dev/null and b/Ideation/Course_Icons/Fun Robo.png differ diff --git a/Ideation/Course_Icons/Mat Sci.png b/Ideation/Course_Icons/Mat Sci.png new file mode 100644 index 0000000..71090c5 Binary files /dev/null and b/Ideation/Course_Icons/Mat Sci.png differ diff --git a/Ideation/Course_Icons/Mecho Proto.png b/Ideation/Course_Icons/Mecho Proto.png new file mode 100644 index 0000000..baf52aa Binary files /dev/null and b/Ideation/Course_Icons/Mecho Proto.png differ diff --git a/Ideation/Level_Icons/BK1.png b/Ideation/Level_Icons/BK1.png new file mode 100644 index 0000000..a6e4a55 Binary files /dev/null and b/Ideation/Level_Icons/BK1.png differ diff --git a/Ideation/Level_Icons/BK2.png b/Ideation/Level_Icons/BK2.png new file mode 100644 index 0000000..8e7a36f Binary files /dev/null and b/Ideation/Level_Icons/BK2.png differ diff --git a/Ideation/Level_Icons/BK3.png b/Ideation/Level_Icons/BK3.png new file mode 100644 index 0000000..30addfa Binary files /dev/null and b/Ideation/Level_Icons/BK3.png differ diff --git a/Ideation/Level_Icons/ENM1.png b/Ideation/Level_Icons/ENM1.png new file mode 100644 index 0000000..61ca4e2 Binary files /dev/null and b/Ideation/Level_Icons/ENM1.png differ diff --git a/Ideation/Level_Icons/ENM2.png b/Ideation/Level_Icons/ENM2.png new file mode 100644 index 0000000..acd534d Binary files /dev/null and b/Ideation/Level_Icons/ENM2.png differ diff --git a/Ideation/Level_Icons/FOC1.png b/Ideation/Level_Icons/FOC1.png new file mode 100644 index 0000000..0fa64fc Binary files /dev/null and b/Ideation/Level_Icons/FOC1.png differ diff --git a/Ideation/Level_Icons/FOC2.png b/Ideation/Level_Icons/FOC2.png new file mode 100644 index 0000000..c194d76 Binary files /dev/null and b/Ideation/Level_Icons/FOC2.png differ diff --git a/Ideation/Level_Icons/FOC3.png b/Ideation/Level_Icons/FOC3.png new file mode 100644 index 0000000..f9d1f18 Binary files /dev/null and b/Ideation/Level_Icons/FOC3.png differ diff --git a/Ideation/Level_Icons/MP1.png b/Ideation/Level_Icons/MP1.png new file mode 100644 index 0000000..62da902 Binary files /dev/null and b/Ideation/Level_Icons/MP1.png differ diff --git a/Ideation/Level_Icons/MP2.png b/Ideation/Level_Icons/MP2.png new file mode 100644 index 0000000..e2ce672 Binary files /dev/null and b/Ideation/Level_Icons/MP2.png differ diff --git a/Ideation/Level_Icons/MP3.png b/Ideation/Level_Icons/MP3.png new file mode 100644 index 0000000..976d123 Binary files /dev/null and b/Ideation/Level_Icons/MP3.png differ diff --git a/Ideation/Level_Icons/MP4.png b/Ideation/Level_Icons/MP4.png new file mode 100644 index 0000000..868bcea Binary files /dev/null and b/Ideation/Level_Icons/MP4.png differ diff --git a/Ideation/Level_Icons/MP5.png b/Ideation/Level_Icons/MP5.png new file mode 100644 index 0000000..8095d3d Binary files /dev/null and b/Ideation/Level_Icons/MP5.png differ diff --git a/Ideation/Level_Icons/MS1.png b/Ideation/Level_Icons/MS1.png new file mode 100644 index 0000000..d822b2f Binary files /dev/null and b/Ideation/Level_Icons/MS1.png differ diff --git a/Ideation/Level_Icons/MS2.png b/Ideation/Level_Icons/MS2.png new file mode 100644 index 0000000..660ecb3 Binary files /dev/null and b/Ideation/Level_Icons/MS2.png differ diff --git a/Project Write-up and Reflection.ipynb b/Project Write-up and Reflection.ipynb new file mode 100644 index 0000000..7964768 --- /dev/null +++ b/Project Write-up and Reflection.ipynb @@ -0,0 +1,94 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Project Overview" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We created game that allows people to build their own Olin portforlio whose advances depend on a series of Olin courses chosen by the user. \n", + "This concept is inspired by the Grow Series games, specifically Grow Island (http://www.eyezmaze.com/grow/island/)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Results [~2-3 paragraphs + figures/examples]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Present what you accomplished. This will be different for each project, but screenshots are likely to be helpful" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementation [~2-3 paragraphs + UML diagram]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Describe your implementation at a system architecture level. Include a UML class diagram, and talk about the major components, algorithms, data structures and how they fit together. You should also discuss at least one design decision where you had to choose between multiple alternatives, and explain why you made the choice you did." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Reflection [~2 paragraphs]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Overall, working on this project was a great learning experience on how to build an interactive graphic with pygame and how code collaboratively. The project was divided into two parts: control algorithms and graphics. Each side of the project proved challenging and engaging to their owners. However, obvisouly, with three members in the team, the separation of the responsibilities was not as clear as it would have been with two member teams. The third member of our team often needed to complete sub-tasks for both algorithm and graphics, which presented challenges, such as Git merge errors and overload of code to examine. Our team has memebers from two different colleges, which resulted in different schedules and difficulty of meeting up in one setting. Despite these obstacles, our team still met more than four times in the span of two weeks, not including class time, and keep an active group chat to update each other on our progress.\n", + "\n", + "The most challanging part of the game development process was integration. Basically, both algorithms and and graphics had to meet each other halfway in a 'main' script to communicate to each other through passing of events and decisions. This time-consuming task forced all three members to teach each other the workings of their code. This process could have been optimized by creating a more in-depth model of our code prior to implementation. For the upcoming final project, some lessons we will all take with us is to emphasize initial code design, increase frequency of updates to team members, and clearly define individual tasks for each member." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/README.md b/README.md index 825cba1..deae710 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ -# InteractiveProgramming +# Interactive Programming -This is the base repo for the interactive programming project for Software Design at Olin College. +Software Design MP4 +---- +We created game that allows people to build their own Olin portfolio whose advances depend on a series of Olin courses chosen by the user. This concept is inspired by the Grow Series games, specifically Grow Island (http://www.eyezmaze.com/grow/island/). + +## Getting Started: +First, install required package: pip install pygame + +## Usage +To run the game, run main.py in the Source folder with python 3 + +## Links: +[Project Reflection](https://docs.google.com/document/d/17OtSFGBJM4z2rdNP-eROhAGwgEVZCMOTp_JZXipS9jc/edit?ts=59f699c3#heading=h.dhufdrd1c1qm) diff --git a/Source/Course_Icons/bees.png b/Source/Course_Icons/bees.png new file mode 100644 index 0000000..33a6e40 Binary files /dev/null and b/Source/Course_Icons/bees.png differ diff --git a/Source/Course_Icons/bees_clicked.png b/Source/Course_Icons/bees_clicked.png new file mode 100644 index 0000000..015b1fc Binary files /dev/null and b/Source/Course_Icons/bees_clicked.png differ diff --git a/Source/Course_Icons/elec.png b/Source/Course_Icons/elec.png new file mode 100644 index 0000000..adc2ab4 Binary files /dev/null and b/Source/Course_Icons/elec.png differ diff --git a/Source/Course_Icons/elec_clicked.png b/Source/Course_Icons/elec_clicked.png new file mode 100644 index 0000000..ae0bc9e Binary files /dev/null and b/Source/Course_Icons/elec_clicked.png differ diff --git a/Source/Course_Icons/focs.png b/Source/Course_Icons/focs.png new file mode 100644 index 0000000..f9ee99b Binary files /dev/null and b/Source/Course_Icons/focs.png differ diff --git a/Source/Course_Icons/focs_clicked.png b/Source/Course_Icons/focs_clicked.png new file mode 100644 index 0000000..f453500 Binary files /dev/null and b/Source/Course_Icons/focs_clicked.png differ diff --git a/Source/Course_Icons/mats.png b/Source/Course_Icons/mats.png new file mode 100644 index 0000000..71090c5 Binary files /dev/null and b/Source/Course_Icons/mats.png differ diff --git a/Source/Course_Icons/mats_clicked.png b/Source/Course_Icons/mats_clicked.png new file mode 100644 index 0000000..c0beda4 Binary files /dev/null and b/Source/Course_Icons/mats_clicked.png differ diff --git a/Source/Course_Icons/mech.png b/Source/Course_Icons/mech.png new file mode 100644 index 0000000..4358f4d Binary files /dev/null and b/Source/Course_Icons/mech.png differ diff --git a/Source/Course_Icons/mech_clicked.png b/Source/Course_Icons/mech_clicked.png new file mode 100644 index 0000000..19c77c4 Binary files /dev/null and b/Source/Course_Icons/mech_clicked.png differ diff --git a/Source/Course_Icons/robo.png b/Source/Course_Icons/robo.png new file mode 100644 index 0000000..b3fd38f Binary files /dev/null and b/Source/Course_Icons/robo.png differ diff --git a/Source/Course_Icons/robo_clicked.png b/Source/Course_Icons/robo_clicked.png new file mode 100644 index 0000000..3e37fed Binary files /dev/null and b/Source/Course_Icons/robo_clicked.png differ diff --git a/Source/Level_Icons/bees1.png b/Source/Level_Icons/bees1.png new file mode 100644 index 0000000..a6e4a55 Binary files /dev/null and b/Source/Level_Icons/bees1.png differ diff --git a/Source/Level_Icons/bees2.png b/Source/Level_Icons/bees2.png new file mode 100644 index 0000000..8e7a36f Binary files /dev/null and b/Source/Level_Icons/bees2.png differ diff --git a/Source/Level_Icons/bees3.png b/Source/Level_Icons/bees3.png new file mode 100644 index 0000000..30addfa Binary files /dev/null and b/Source/Level_Icons/bees3.png differ diff --git a/Source/Level_Icons/elec1.png b/Source/Level_Icons/elec1.png new file mode 100644 index 0000000..61ca4e2 Binary files /dev/null and b/Source/Level_Icons/elec1.png differ diff --git a/Source/Level_Icons/elec2.png b/Source/Level_Icons/elec2.png new file mode 100644 index 0000000..acd534d Binary files /dev/null and b/Source/Level_Icons/elec2.png differ diff --git a/Source/Level_Icons/focs1.png b/Source/Level_Icons/focs1.png new file mode 100644 index 0000000..0fa64fc Binary files /dev/null and b/Source/Level_Icons/focs1.png differ diff --git a/Source/Level_Icons/focs2.png b/Source/Level_Icons/focs2.png new file mode 100644 index 0000000..c194d76 Binary files /dev/null and b/Source/Level_Icons/focs2.png differ diff --git a/Source/Level_Icons/focs3.png b/Source/Level_Icons/focs3.png new file mode 100644 index 0000000..f9d1f18 Binary files /dev/null and b/Source/Level_Icons/focs3.png differ diff --git a/Source/Level_Icons/mats1.png b/Source/Level_Icons/mats1.png new file mode 100644 index 0000000..d822b2f Binary files /dev/null and b/Source/Level_Icons/mats1.png differ diff --git a/Source/Level_Icons/mats2.png b/Source/Level_Icons/mats2.png new file mode 100644 index 0000000..660ecb3 Binary files /dev/null and b/Source/Level_Icons/mats2.png differ diff --git a/Source/Level_Icons/mech1.png b/Source/Level_Icons/mech1.png new file mode 100644 index 0000000..62da902 Binary files /dev/null and b/Source/Level_Icons/mech1.png differ diff --git a/Source/Level_Icons/mech2.png b/Source/Level_Icons/mech2.png new file mode 100644 index 0000000..e2ce672 Binary files /dev/null and b/Source/Level_Icons/mech2.png differ diff --git a/Source/Level_Icons/mech3.png b/Source/Level_Icons/mech3.png new file mode 100644 index 0000000..976d123 Binary files /dev/null and b/Source/Level_Icons/mech3.png differ diff --git a/Source/Level_Icons/mech4.png b/Source/Level_Icons/mech4.png new file mode 100644 index 0000000..868bcea Binary files /dev/null and b/Source/Level_Icons/mech4.png differ diff --git a/Source/Level_Icons/mech5.png b/Source/Level_Icons/mech5.png new file mode 100644 index 0000000..8095d3d Binary files /dev/null and b/Source/Level_Icons/mech5.png differ diff --git a/Source/Level_Icons/robo1.png b/Source/Level_Icons/robo1.png new file mode 100644 index 0000000..14f0ce7 Binary files /dev/null and b/Source/Level_Icons/robo1.png differ diff --git a/Source/courses.csv b/Source/courses.csv new file mode 100644 index 0000000..c3735d4 --- /dev/null +++ b/Source/courses.csv @@ -0,0 +1,7 @@ +label,course,description,max,dependencies,xrange +mech,Mechanical Prototyping,Learn techniques for mechanical design... and how to not kill your teammates,5,3bees1 4focs3 4elec2 5mats1,841 +bees,Sustainable Beekeeping,Beekeeping. Good for the environment. Ben Linder. Good for the soul.,3,2focs1 3mats2,51 +focs,Fundamentals of Computer Science,Step one:FOCS. Step two:Offical Hacker d00d. Step 3:Rule the world.,3,3elec1,367 +elec,Electricity and Magnetism,Does anyone know how electricity and magnetism work?,2,0,209 +mats,Material Science,Material science. Explore materials. Self-explanatory...right?,2,0,683 +robo,Fundamentals of Robotics,Death by Dave but in a project-based-learning way.,1,2mech5 2bees3 2focs3 2elec2 2mats2,525 diff --git a/Source/courses.py b/Source/courses.py new file mode 100644 index 0000000..3c09b73 --- /dev/null +++ b/Source/courses.py @@ -0,0 +1,75 @@ +# Author: Isa Blancett +# Project: Interactive Programming +# Date: 10.30.2017 +# Description: Class for reading in a csv file containing course information and +# creating and instance for each course +# Acknowledgements: Script structure is modeled after Transcriptase's Game +# repository on Git + +import csv + +class Courses(object): + """ class for the different course options the user can choose from + + contains: + label - 4 letter id + course - full title + description - in-depth summary of course + max - total number of levels + reqs - dependencies, '%s%s%s' % (effected level, needed course, needed level) + lvl - current level + order - order picked by user + """ + + def setup(self, config): + + self.config = config + self.label = config['label'] + self.name = config['course'] + self.description = config['description'] + self.max = config['max'] + self.reqs = config['dependencies'] + self.range = config['xrange'] + self.lvl = 0 + self.order = 0 + + + +def create_course(config): + """ creates a single instance of a course given a config dictionary + + returns: single course instance + """ + + new_course = Courses() + new_course.setup(config) + return(new_course) + +def populate(): + """ sets up item objects by creating a config dictionary for each one + + Sample config dictionary (can be copied for each new item): + config = { + 'label':'LABEL' + 'course':'COURSE TITLE', + 'description':'DESCRIPTION', + 'max': NUMBER OF LEVELS, + 'dependencies': 'LVL' + 'NEEDEDCOURSE' + 'NEEDEDLEVEL', + 'xrange': 'MIN MAX' + } + + returns: dictionary of all course instances + """ + all_courses = {} + + f = open('Source/courses.csv', 'r') + reader = csv.DictReader(f) + + for row in reader: + if row != '0': + row['dependencies'] = row['dependencies'].split() + else: + row['dependencies'] = [] + new_course = (create_course(row)) + all_courses[new_course.label] = new_course + return all_courses diff --git a/Source/ending.py b/Source/ending.py new file mode 100644 index 0000000..4721a56 --- /dev/null +++ b/Source/ending.py @@ -0,0 +1,96 @@ +# Author: Siena Okuno +# Project: Interactive Programming +# Date: 10.30.2017 +# Description: Determines endings + +import pygame +import sys + +def screenScroll(screen, color): + '''Turns screen a color by filling in with rectangles.''' + for i in range(700): + pygame.draw.rect(screen, color, (0,i,1000,i+1)) + i+=1 + pygame.display.flip() + + +def ending(victory, levels, screen): + '''Creates basic, text-only ending''' + font50 = pygame.font.Font(None, 50) + font20 = pygame.font.Font(None, 20) + if victory == 0 or victory == 2: + screenScroll(screen, (0,0,0)) + screen.blit(font50.render("Looks like your portfolio", 1, (255,255,255)), (300, 250)) + screen.blit(font50.render("could use some improvement", 1, (255,255,255)), (280, 350)) + Done = False + while not Done: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + Done = True + for i in range(len(levels)): + screen.blit(font20.render(levels[i], 1, (200,200,200)), (100, 450+i*25)) + pygame.display.flip() + if victory == 1: + screenScroll(screen, (255,255,255)) + Done = False + while not Done: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + Done = True + screen.blit(font50.render("Good job!", 1, (0,0,0)), (450, 250)) + screen.blit(font50.render("You're the ultimate Oliner!'", 1, (0,0,0)), (300, 350)) + screen.blit(font20.render('All course levels maxed. :)', 1, (0,0,0)), (450, 500)) + pygame.display.flip() + pygame.event.pump() + +#not implemented yet +def graduation(): + '''Shows graphics for graduating. Used in all endings''' + screenScroll(screen, (255,255,255)) + font100 = pygame.font.Font(None, 100) + screen.blit(font100.render("Congratulations,", 1, (0,0,0)), (200, 175)) + screen.blit(font100.render("Olin Grad!", 1, (0,0,0)), (325, 325)) + grad_hat = pygame.transform.scale(pygame.image.load('Ending_pics/grad_hat.png'), (250, 200)) + screen.blit(grad_hat,(350,400)) + pygame.display.flip() + pygame.time.delay(2000) + screenScroll(screen, (255,255,255)) + font50 = pygame.font.Font(None, 50) + screen.blit(font100.render("You got your degree...", 1, (0,0,0)), (150, 300)) + pygame.display.flip() + pygame.time.delay(2000) + screenScroll(screen, (0,0,0)) + screen.blit(font100.render("But how will you fair", 1, (255,255,255)), (150, 300)) + screen.blit(font100.render("in the real world?", 1, (255,255,255)), (170, 400)) + pygame.display.flip() + pygame.time.delay(2000) + + +def badEnding(): + '''Shows graphics for bad ending. Called when average is below ___. + You tried? Desk jobs are all the rage these days.''' + + + +def middleEnding(): + '''Shows graphics for middle ending. Called when average is above ___ but levels are not maxed. + You are a leading engineer at your own startup''' + + + +def goodEnding(): + '''Shows graphics for good ending. Called when levels are all maxed. + You are the next Steve Jobs.''' + + +def determine(victory, levels): + '''Determines ending. + Victory is value 0, 1, or 2. 0 is bad, 2 is perfect. + Levels is a list of strings. Print out with for loop''' + graduation() + if victory == 0: + badEnding() + if victory == 2: + middleEnding() + if victory == 1: + goodEnding diff --git a/Source/environment.py b/Source/environment.py new file mode 100644 index 0000000..b6d5636 --- /dev/null +++ b/Source/environment.py @@ -0,0 +1,137 @@ +# Author: Siena Okuno +# Project: Interactive Programming +# Date: 10.30.2017 +# Description: Creates GUI for player and posts events when a button is clicked + +import pygame +import os +import sys + +def initialize(descriptions): + """ Initializes graphic screen. + """ + pygame.init() + screen = pygame.display.set_mode((1000, 700)) + pygame.font.init() + font = pygame.font.Font(None,26) + pygame.mouse.set_pos([500,350]) + pygame.mouse.set_visible(True) + text = setUpE(screen, font, descriptions) + return [screen, text] + +def setUpE(screen, font, descriptions): + '''This code is to load the basic backscreen for the program. + setUpE is NOT to be run whenever the user clicks something, just at beginning.''' + #loading/scaling images (loads as S___ for start, scaled as F___ for final) + Sbee_Icon = pygame.image.load('Source/Course_Icons/bees.png') + Fbee_Icon = pygame.transform.scale(Sbee_Icon, (108, 100)) + SENM_Icon = pygame.image.load('Source/Course_Icons/elec.png') + FENM_Icon = pygame.transform.scale(SENM_Icon, (108, 100)) + SFOCS_Icon = pygame.image.load('Source/Course_Icons/focs.png') + FFOCS_Icon = pygame.transform.scale(SFOCS_Icon, (108, 100)) + SFunRobo_Icon = pygame.image.load('Source/Course_Icons/robo.png') + FFunRobo_Icon = pygame.transform.scale(SFunRobo_Icon, (108, 100)) + SMatSci_Icon = pygame.image.load('Source/Course_Icons/mats.png') + FMatSci_Icon = pygame.transform.scale(SMatSci_Icon, (108, 100)) + SMechProto_Icon = pygame.image.load('Source/Course_Icons/mech.png') + FMechProto_Icon = pygame.transform.scale(SMechProto_Icon, (108, 100)) + #basic background + pygame.draw.rect(screen, (255, 255, 255), (0,10,1000,440)) + #icon buttons + pygame.draw.rect(screen, (255, 255, 255), (51,550,108,100)) + pygame.draw.rect(screen, (255, 255, 255), (209,550,108,100)) + pygame.draw.rect(screen, (255, 255, 255), (367,550,108,100)) + pygame.draw.rect(screen, (255, 255, 255), (525,550,108,100)) + pygame.draw.rect(screen, (255, 255, 255), (683,550,108,100)) + pygame.draw.rect(screen, (255, 255, 255), (841,550,108,100)) + #icon display + screen.blit(Fbee_Icon,(51,550)) + screen.blit(FENM_Icon,(209,550)) + screen.blit(FFOCS_Icon,(367,550)) + screen.blit(FFunRobo_Icon,(525,550)) + screen.blit(FMatSci_Icon,(683,550)) + screen.blit(FMechProto_Icon,(841,550)) + #render text + text = [] + text.append(font.render("Sustainable Beekeeping: %s" % descriptions[1], 1, (255,255,255))) + text.append(font.render("Electricity and Magnetism: %s" % descriptions[3], 1, (255,255,255))) + text.append(font.render("Fundamentals of Computer Science: %s" % descriptions[2], 1, (255,255,255))) + text.append(font.render("Fundamentals of Robotics: %s" % descriptions[5], 1, (255,255,255))) + text.append(font.render("Material Science: %s" % descriptions[4], 1, (255,255,255))) + text.append(font.render("Mechanical Prototyping: %s" % descriptions[0], 1, (255,255,255))) + #Reload display / return font + pygame.display.flip() + return text + +def mouseClicks(order, BUTTON, screen): + '''This function looks for the click of a mouse and queues an event based on where the mouse is''' + (x,y) = pygame.mouse.get_pos() + clicked_path = 'Source/Course_Icons/%s_clicked.png' + if y >= 550 and y<= 655 and any(pygame.mouse.get_pressed()): + if x >= 51 and x<= 159 and 'bees' not in order: + button1 = pygame.event.Event(BUTTON, pressed='bees') + pygame.event.post(button1) + updateImg(screen, clicked_path % 'bees', (51,550)) + elif x >= 209 and x <= 317 and 'elec' not in order: + button2 = pygame.event.Event(BUTTON, pressed='elec') + pygame.event.post(button2) + updateImg(screen, clicked_path % 'elec', (209,550)) + elif x >= 367 and x <= 475 and 'focs' not in order: + button3 = pygame.event.Event(BUTTON, pressed='focs') + pygame.event.post(button3) + updateImg(screen, clicked_path % 'focs', (367,550)) + elif x >= 525 and x <= 633 and 'robo' not in order: + button4 = pygame.event.Event(BUTTON, pressed='robo') + pygame.event.post(button4) + updateImg(screen, clicked_path % 'robo', (525,550)) + elif x >= 683 and x <= 791 and 'mats' not in order: + button5 = pygame.event.Event(BUTTON, pressed='mats') + pygame.event.post(button5) + updateImg(screen, clicked_path % 'mats', (683,550)) + elif x >= 841 and x <= 950 and 'mech' not in order: + button6 = pygame.event.Event(BUTTON, pressed='mech') + pygame.event.post(button6) + updateImg(screen, clicked_path % 'mech', (841,550)) + +def mouseOver(text, screen): + '''This function looks for the position of the mouse and will display text above the buttons if the mouse is hovering over the buttons''' + #icon descriptions + beeDesc = text[0] + ENMDesc = text[1] + FOCSDesc = text[2] + FunRoboDesc = text[3] + MatSciDesc = text[4] + MechProtoDesc = text[5] + #if statements + (x,y) = pygame.mouse.get_pos() + if y >= 550 and y<= 655: + if x >= 51 and x<= 159: + screen.blit(beeDesc, (100, 490)) + elif x >= 209 and x <= 317: + screen.blit(ENMDesc, (100, 490)) + elif x >= 367 and x <= 475: + screen.blit(FOCSDesc, (100, 490)) + elif x >= 525 and x <= 633: + screen.blit(FunRoboDesc, (100, 490)) + elif x >= 683 and x <= 791: + screen.blit(MatSciDesc, (100, 490)) + elif x >= 841 and x <= 950: + screen.blit(MechProtoDesc, (100, 490)) + else: + pygame.draw.rect(screen, (0,0,0), (0,480,1000,50)) + else: + pygame.draw.rect(screen, (0,0,0), (0,480,1000,50)) + +def updateImg(screen, img, location): + loaded = pygame.transform.scale(pygame.image.load(img), (108, 100)) + screen.blit(loaded, location) + pygame.display.flip() + +def update_portfolio(courses, screen): + labels = list(courses) + pygame.draw.rect(screen, (255,255,255), (0,10,1000,440)) + for label in labels: + if courses[label].lvl: + img = 'Source/Level_Icons/%s%s.png' % (label, courses[label].lvl) + xmin = int(courses[label].range) + updateImg(screen, img, (xmin, 150)) diff --git a/Source/gameplay.py b/Source/gameplay.py new file mode 100644 index 0000000..a9c4776 --- /dev/null +++ b/Source/gameplay.py @@ -0,0 +1,124 @@ +# Author: Isa Blancett +# Project: Interactive Programming +# Date: 10.30.2017 +# Description: Class for current gameplay status, including course levels and +# round number +# Acknowledgements: Script structure is modeled after Transcriptase's Game +# repository on Git + +from sys import exit +import courses +import doctest +import pygame + +class Gameplay(object): +#Parses player commands and manipulates a map object + + def __init__ (self, courses): + self.courses = courses # dictionary of course instances + self.labels = list(courses) # list of four letter labels for each course + self.order = [] # list of labels in order of the player's choosing + self.round = 0 # round number of the current game + + def add_order(self, selection): + """ adds the order to a course's class instance if picked + + returns: boolean (have all courses been picked?) + + Examples: + >>> test_game = Gameplay(courses.populate(), 0) + >>> test_game.add_order('mech') + >>> print(test_game.courses['mech'].order) + 1 + """ + # increase round + self.round = self.round + 1 + + # add order and level up newest choice + label = selection.pressed + self.courses[label].order = self.round + self.courses[label].lvl = 1 + self.order.append(label) + + # return whether all courses have been picked + return len(self.order) == len(list(self.courses)) + + def level_up(self): + """ level up any courses that meet all requirements starting with the + user's previous choice + + returns: All courses + + Examples: + >>> test_game = Gameplay(courses.populate(), 0) + >>> test_game.add_order('mech') + >>> test_game.add_order('elec') + >>> test_game.level_up() + >>> print(test_game.courses['mech'].lvl) + 2 + """ + # No leveling up until 2 courses have been picked + if len(self.order) > 1: + # Start leveling with second most recent course selection + for label in reversed(self.order[:-1]): + # Check for maxed out and for dependencies + if int(self.courses[label].lvl) < int(self.courses[label].max) and self.check_reqs(label): + self.courses[label].lvl = self.courses[label].lvl + 1 + return self.courses + + def check_reqs(self, label): + """ given a course label, checks whether all dependencies are met + + returns: boolean + + Examples: + >>> test_game = Gameplay(courses.populate(), 0) + >>> test_game.courses['mech'].lvl = 4 + >>> test_game.courses['focs'].lvl = 3 + >>> test_game.courses['elec'].lvl = 2 + >>> test_game.check_reqs('mech') + True + >>> test_game = Gameplay(courses.populate(), 0) + >>> test_game.courses['mech'].lvl = 4 + >>> test_game.courses['focs'].lvl = 3 + >>> test_game.check_reqs('mech') + False + """ + reqs_met = [] + lvl = self.courses[label].lvl + + # Loop through reqs of given class + for req in self.courses[label].reqs: + # Parse req string for dependent level, needed course, and needed course level + deplvl = int(req[0]) + neededcourse = req[1:5] + neededlevel = int(req[-1]) + if deplvl == lvl: + # Append list with True if req has been met + reqs_met.append(neededlevel <= self.courses[neededcourse].lvl) + # Return true if all reqs are met or no reqs are needed + return all(reqs_met) or not len(reqs_met) + + def evaluate_portfolio(self): + """ decides whether the user has picked the right order + + returns: None + + Examples: + >>> test_game = Gameplay(courses.populate(), 0) + >>> test_game.evaluate_portfolio() + "Your portfolio could use a little more work. Try again?" + """ + # Get list of current levels and max levels + lvls = [int(self.courses[label].lvl) for label in list(self.courses)] + maxlvls = [int(self.courses[label].max) for label in list(self.courses)] + # 1 = perfect game, 2 = acceptable game, 0 = bad game (no job 4 u!!) + if lvls == maxlvls: + return 1 + elif (sum(lvls)) >= (sum(maxlvls)*3/4): + return 2 + else: + return 0 + +# Example docstring test +# doctest.run_docstring_examples(Gameplay.evaluate_portfolio, globals(), verbose=True) diff --git a/Source/main.py b/Source/main.py new file mode 100644 index 0000000..2dd8f4a --- /dev/null +++ b/Source/main.py @@ -0,0 +1,41 @@ +# Author: Leo Liu, Siena Okuno, & Isa Blancett +# Project: Interactive Programming +# Date: 10.30.2017 +# Description: Game setup, loop through game graphics and control, & ending call + +import courses +from gameplay import Gameplay +import sys +import pygame +from ending import ending +from environment import * + +# INITIALIZE GAME +BUTTON = pygame.USEREVENT + 1 +init_courses = courses.populate() +text_screen = initialize([init_courses[label].description for label in list(init_courses)]) +screen = text_screen[0] +text = text_screen[1] +control = Gameplay(init_courses) + +# LOOP THROUGH GRAPHICS AND CONTROLS, CHECKING FOR PASSING OF EVENTS +done = False +while not done: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + sys.exit(1) + if event.type == BUTTON: + done = control.add_order(event) + courses = control.level_up() + update_portfolio(courses, screen) + mouseOver(text, screen) + mouseClicks(control.order, BUTTON, screen) + pygame.display.flip() + pygame.event.pump() + +# EVALUATE ENDING AND SEND TO VICTORY SCREEN +victory = control.evaluate_portfolio() +if victory == 1: + ending(victory, ["%s: %s" % (control.courses[course].name, 'MAX') for course in control.courses], screen) +else: + ending(victory, ["%s: %s" % (control.courses[course].name, control.courses[course].lvl) for course in control.courses], screen)