{"id":76209,"date":"2022-12-09T19:18:10","date_gmt":"2022-12-10T00:18:10","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/?p=76209"},"modified":"2022-12-09T19:18:10","modified_gmt":"2022-12-10T00:18:10","slug":"final-project","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/2022\/12\/09\/final-project\/","title":{"rendered":"Final Project"},"content":{"rendered":"<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<html><body><div><a class=\"p5_sketch_link\" href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-content\/uploads\/2022\/12\/sketch-2.js\" data-width=\"480\" data-height=\"480\">sketch<\/a><iframe src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-content\/plugins\/p5-embedder\/p5_iframe.html\" class=\"p5_exampleFrame\" width=\"480\" height=\"480\"><\/iframe><pre class=\"language-javascript\"><code class=\"p5_editor language-javascript\">\/* Evan Stuhfire\n * estuhlfi@andrew.cmu.edu section B\n * Project-14: Municiple Water Management Game\n*\/\n\n\/\/ map repair state variables\nvar rsGreen = 0;\nvar rsYellow = 1;\nvar rsOrange = 2;\nvar rsRed = 3;\n\n\/\/ variable to track dam cracks\nvar dYellow = false;\nvar dOrange = false;\nvar dRed = false;\n\n\/\/ map facility icons to text\nvar fDam = \"Dam\";\nvar fFiltration = \"Filter\";\nvar fPumping = \"Pump\";\nvar fHydro = \"Hydro\\nPower\";\n\n\/\/ Array to hold facility icons\nvar iconArray = [];\n\n\/\/ Array to hold house objects\nvar houseArray = [];\nvar numHouses = 5;\n\/\/ arrays to store house coordinates\nvar houseX = [35, 80, 140, 210, 190];\nvar houseY = [315, 335, 310, 285, 330];\n\n\/\/ global worker object\nvar workerObj;\n\n\/\/ player stats, number of fixes\nvar statsObj;\n\/\/ control for directions page\nvar gameStart = true;\n\nfunction drawIcon() {\n    fill(this.repairColor);\n    \/\/ Draw both the tray and the facility icons\n    drawIconHelper(this.trayx, this.trayy, \n        this.traySize, this.facilityIcon, 13);\n    drawIconHelper(this.facilityx, this.facilityy,\n        this.facilitySize, this.facilityIcon, 10);\n}\n\nfunction drawIconHelper(x, y, size, label, txs) {\n    push();\n    translate(x, y);\n    ellipse(0, 0, size);\n\n    strokeWeight(1);\n    fill(10);\n    textAlign(CENTER);\n    textSize(txs);\n    text(label, 0, -3);\n    pop();\n}\n\nfunction drawWorker() {\n    fill(255);\n    \/\/ draw circle to contain the worker\n    ellipse(this.wx, this.wy, this.size);\n\n    \/\/ draw stickman worker\n    drawStickFigure(this.wx, this.wy, this.headSize);\n    textAlign(CENTER);\n    textSize(12);\n    fill(255);\n    strokeWeight(1);\n    text(\"1. Click the worker\", this.wx, this.wy + 50);\n}\n\nfunction drawStickFigure(x, y, h) {\n    fill(255);\n    strokeWeight(1.5);\n    \/\/ body\n    line(x, y - 15, x, y + 20);\n    \/\/ legs\n    line(x, y + 20, x - 10, y + 30);\n    line(x, y + 20, x + 10, y + 30);\n    \/\/ arms\n    line(x, y + 10, x -10, y + 15);\n    line(x, y + 10, x + 10, y + 15);\n\n    \/\/ head\n    circle(x, y - 15, h);\n\n    \/\/ hat\n    fill(255, 255, 0);\n    arc(x, y - 20, 30, 33, PI, 2 * PI, OPEN);\n    arc(x, y -25, 30, 15, 0, PI, CHORD);\n\n    \/\/ eyes\n    line(x - 5, y - 15, x - 5, y - 12);\n    line(x + 5, y - 15, x + 5, y - 12);\n    \/\/ mouth\n    line(x - 5, y - 5, x + 5, y - 5);\n}\n\nfunction drawHouse() {\n    \/\/ draw a house \n    \/\/ brick red\n    fill(153, 0, 0);\n    rect(this.hx, this.hy, this.hw, this.hh);\n\n    \/\/ draw roof\n    fill(50); \/\/ grey for roof\n    triangle(this.hx, this.hy, this.hx + this.hw\/2, this.hy - 15, \n        this.hx + this.hw, this.hy);\n\n    \/\/ draw windows\n    if(this.power == true) {\n        fill(255, 255, 153); \/\/ yellow for lit windows \n    } else {\n        fill(5); \/\/ black for unlit windows, no power\n    }\n   \n    rect(this.hx + 5, this.hy + 5, 10, 12);\n    rect(this.hx + 25, this.hy + 5, 10, 12);\n\n    \/\/ draw door\n    fill(153, 102, 51); \/\/ brown for door\n    rect(this.hx + 15, this.hy + 15, 10, 15);\n}\n\nfunction houseState() {\n    \/\/ change power to house based on probability of \n    \/\/ an outage, chances increae with higher repair state\n    var chanceOfOutage = 0;\n    var highState = 0;\n\n    \/\/ find highest repair state of hydro power\n    for(i = 0; i &lt; iconArray.length; i++) {\n        var currentIcon = iconArray[i];\n        if(currentIcon.facilityIcon.slice(0, 1) == \"H\" &\n         currentIcon.repairState > highState) {\n            highState = currentIcon.repairState;\n        }\n    }\n\n    if(highState &gt;= rsOrange & this.power == false){\n        return;\n    }\n\n    \/\/ green repair state all houses have power\n    switch (highState) {\n    case rsGreen:\n        chanceOfOutage = 0;\n        break;\n    case rsYellow:\n        \/\/ yellow repair state, probability of outage = low\n        chanceOfOutage = .005;\n        break;\n    case rsOrange:\n        \/\/ orange repair state, probability of outage = medium\n        chanceOfOutage = .01;\n        break;\n    case rsRed:\n        \/\/ red repair state, probability of outage = high\n        chanceOfOutage = .5\n        break;\n    }\n    if(random(0, 1) &lt; chanceOfOutage) {\n        this.power = false; \/\/ outage\n    } else {\n        this.power = true; \/\/ no outage\n    }\n}\n\nfunction changeState() {\n    if(gameStart == true) {\n        return;\n    }\n\n    repairFacility(this);\n\n    \/\/ generate a problem based on likelyhood\n    if(random(0, 1) &lt; this.problemLikely) {\n        this.ageOfState++;\n        \/\/ increase likelihood of problems over time\n        this.problemLikely += .002;\n    }\n\n\n    if(this.ageOfState &gt; 15 & this.repairState == rsYellow) {\n        \/\/ set state and color to orange\n        \/\/ reset ageOfState and increase likelyhood of problem\n\n        this.repairState = rsOrange; \n        this.repairColor = color(255, 102, 0);\n        this.ageOfState = 0; \n        this.problemLikely = .015;        \n    } else if(this.ageOfState &gt; 10 & this.repairState == rsOrange) {\n        \/\/ set state and color to red\n        \/\/ reset ageOfState and increase likelyhood of problem\n\n        this.repairState = rsRed;\n        this.repairColor = color(204, 0, 0);\n        this.ageOfState = 0;\n        this.problemLikely = .02; \n\n        if(this.facilityIcon.slice(0, 1) == \"D\" ||\n            this.facilityIcon.slice(0, 1) == \"P\") {\n            statsObj.floods++;\n        } else if(this.facilityIcon.slice(0, 1) ==\"F\"){\n            statsObj.filterFail++;\n        } else {\n            statsObj.powerLoss++;\n        }\n    } else if(this.ageOfState &gt; 5 & this.repairState == rsGreen) {\n        \/\/ set state and color to yellow\n        \/\/ reset ageOfState and increase likelyhood of problem\n\n        this.repairState = rsYellow;\n        this.repairColor = color(255, 255, 0);\n        this.ageOfState = 0;\n        this.problemLikely = .01;\n    } \n\n    \/\/ Check for failing services\n    if(this.facilityIcon.slice(0, 1) == \"D\") {\n        damFailure(this);\n    } else if(this.facilityIcon.slice(0, 1) == \"P\" &\n        this.repairState == rsRed) {\n        pumpFailure(this);\n    } else if(this.facilityIcon.slice(0,1) == \"F\" &\n        this.repairState == rsRed) {\n        filterFailure(this);\n    }\n}\n\nfunction makeIconObj(tx, ty, fx, fy, fac) {\n    \/\/ object def for game icons\n    var icon = {trayx: tx,\n                trayy: ty,\n                facilityx: fx,\n                facilityy: fy,\n                traySize: 50,\n                facilitySize: 35,\n                facilityIcon: fac, \n                repairState: rsGreen,\n                repairColor: color(0, 200, 0), \n                ageOfState: 0,\n                problemLikely: .05,\n                trayClick: false,\n                facillityClick: false,\n                drawFunction: drawIcon,\n                stateFunction: changeState\n                }\n    return icon;\n}\n\nfunction makeWorker(x, y) {\n    \/\/ object def for worker\n    var icon = {wx: x,\n                wy: y,\n                size: 80,\n                headSize: 30,\n                clicked: false,\n                drawFunction: drawWorker\n                }\n    return icon;\n}\n\nfunction makeHouse(x, y) {\n    \/\/ object def for houses\n    var house = {hx: x,\n                hy: y,\n                hw: 40, \/\/ house width\n                hh: 30, \/\/ house height\n                power: true,\n                drawFunction: drawHouse,\n                stateFunction: houseState}\n\n    return house;\n}\n\nfunction makeStats() {\n    \/\/ object definition for game stats\n    var stats = {maxRepairs: 10,\n                maxAge: 60,\n                repairs: 0,\n                floods: 0,\n                filterFail: 0,\n                powerLoss: 0}\n\n    return stats;\n}\n\nfunction createIcons() {\n    \/\/ create icons for equipment tray\n    iconArray.push(makeIconObj(200, 430, 295, 140, fDam));\n    iconArray.push(makeIconObj(270, 430, 60, 217, fFiltration));\n    iconArray.push(makeIconObj(340, 430, 397, 300, fPumping));\n    iconArray.push(makeIconObj(410, 430, 305, 235, fHydro));\n\n    \/\/ create worker icon\n    workerObj = makeWorker(70, 425);\n\n    \/\/ create game stats object\n    statsObj = makeStats();\n}   \n\nfunction createHouses() {\n    \/\/ make numHouses number of houses\n    for(i = 0; i &lt; numHouses; i++) {\n        houseArray[i] = makeHouse(houseX[i], houseY[i]);\n    }    \n}\n\nfunction setup() {\n    createCanvas(480, 480);\n    createIcons();\n    createHouses();\n}\n\nfunction draw() {\n    background(204, 239, 255);\n    drawScene();\n\n    \/\/ draw houses\n    for(j = 0; j &lt; houseArray.length; j++) {\n        var currentHouse = houseArray[j];\n        currentHouse.stateFunction();\n        currentHouse.drawFunction();\n    }\n\n\n    \/\/ draw game icons\n    var cIcon = 10;\n    for(i = 0; i &lt; iconArray.length; i++) {\n        var currentIcon = iconArray[i];\n\n        currentIcon.stateFunction();\n        currentIcon.drawFunction();\n\n        \/\/ if the tray icon was clicked show on mouse\n        if(currentIcon.trayClick == true) {\n            fill(currentIcon.repairColor);\n\n            \/\/ transform to make small icon at mouse pointer\n            push();\n            scale(.5);\n            translate(mouseX, mouseY);\n            drawIconHelper(mouseX - 70, mouseY + 30, \n                currentIcon.traySize,\n                currentIcon.facilityIcon);\n            pop();\n        }\n    }\n\n    \/\/ draw worker icon\n    workerObj.drawFunction();\n\n    \/\/ if the worker and\/or icon has been clicked,\n    \/\/ draw worker\/icon at mouse pointer\n    if(workerObj.clicked == true) {\n        push();\n        \/\/ transformation to make small worker at mouse pointer\n        scale(.5);\n        translate(mouseX, mouseY);\n        drawStickFigure(mouseX - 20, mouseY + 40, workerObj.headSize);\n        pop();\n    }\n\n    drawScore();\n\n    \/\/ at the start of game show instructions\n    if(gameStart == true) {\n        instructions();\n    }\n\n    \/\/ Display game stats\n    \/\/ if at least maxRepairs \n    if(statsObj.repairs &gt;= statsObj.maxRepairs || \n            iconArray[0].ageOfState &gt;= 100) {\n        gameStats();\n        noLoop(); \n    }\n}\n\n\nfunction mouseClicked() {\n    \/\/ start game\n    if(gameStart == true) {\n        gameStart = false;\n        return;\n    }\n\n    \/\/ check if worker was clicked\n    var d = dist(mouseX, mouseY, workerObj.wx, workerObj.wy);\n    if(d &lt; workerObj.size\/2) {\n        if(workerObj.clicked == false) {\n            workerObj.clicked = true;\n        } else {\n            workerObj.clicked = false;\n        }\n        return;\n    }\n\n    \/\/ check if worker has been clicked\n    if(workerObj.clicked == true) {\n        \/\/ check if tool was clicked in equipement tray\n        for(var i = 0; i &lt; iconArray.length; i++) {\n            var icon = iconArray[i];\n            var d = dist(mouseX, mouseY, icon.trayx, icon.trayy);\n            if(d &lt; icon.traySize\/2) {\n                setTrayIcon(i);\n                return;\n            }\n\n            \/\/ check if facility was clicked\n            if(icon.trayClick == true) {\n                var d = dist(mouseX, mouseY, icon.facilityx, icon.facilityy);\n                if(d &lt; icon.facilitySize\/2) {\n                    icon.facilityClick = true;\n                }\n            }\n        }\n    }\n}\n\nfunction gameStats() {\n    \/\/ draw final game stats from statsObj\n    push();\n\n    fill(255, 255, 255, 235);\n    rectMode(CENTER);\n    rect(width\/2, height\/2, 400, 400);\n    fill(5);\n    textSize(24);\n    strokeWeight(1);\n    textAlign(CENTER);\n    text(\"You made \"+statsObj.repairs+\" repairs\", width\/2, 75);\n\n    textSize(16);\n    text(\"The town flooded \"+statsObj.floods+\" time(s)\", \n            width\/2, 115);\n    text(\"The town filtration failed \"+statsObj.filterFail+\" time(s)\", \n            width\/2, 145);\n    text(\"The town lost all power \"+statsObj.powerLoss+\" time(s)\", \n            width\/2, 175);\n\n    textSize(24);\n    text(\"Refresh to Play Again\", width\/2, 380);\n\n    pop();\n}\n\nfunction instructions() {\n    \/\/ Create instruction front page\n    fill(255, 255, 255, 235);\n    push();\n    rectMode(CENTER);\n    rect(width\/2, height\/2, 400, 400);\n    fill(5);\n    textSize(24);\n    strokeWeight(1);\n    textAlign(CENTER);\n    text(\"Municipal Water Management Game\", width\/2, 75);\n \n    \/\/ create a click to start message\n    text(\"Click Anywhere to Start\", width\/2, 420);\n\n    textAlign(LEFT);\n    textSize(14);\n\n    var x = 55;\n    var y = 110;\n    \/\/ Display instructions\n    text(\"Welcome! You are managing the repairs for a town's water\",\n        x, y);\n    text(\"supply. If the dam or pump fail the town will flood. If the\",\n        x, y + 20);\n    text(\"filtration system fails the water will be dirty. If the hydro\",\n        x, y + 40);\n    text(\"electric plant falters the lights in the houses will flicker and\",\n        x, y + 60);\n    text(\"go out. Circle icon colors change as urgency increases.\",\n        x, y + 80);\n\n    textAlign(CENTER);\n    textSize(20);\n    text(\"To Play: Make Repairs\", width\/2, y + 120);\n\n    textAlign(LEFT);\n    textSize(14);\n    text(\"1. Click the worker. The icon will appear at the mouse pointer.\",\n        x, y + 150);\n    text(\"2. Click a yellow, orange, or red icon from the icon tray.\",\n        x, y + 180);\n    text(\"3. Click the matching facility in need of repair.\",\n        x, y + 210);\n    pop();\n}\n\nfunction setTrayIcon(index) {\n    \/\/ when setting icon clicked = true, set the others = false\n    for(i = 0; i &lt; iconArray.length; i++) {\n        if(i == index) {\n            iconArray[i].trayClick = true;\n        }else {\n            iconArray[i].trayClick = false;\n        }\n    }\n}\n\nfunction drawScore() {\n    fill(5);\n    strokeWeight(1);\n    textAlign(LEFT);\n    text(\"Repairs made: \" + statsObj.repairs, 3, 15);\n}\n\nfunction repairFacility(cur) {\n    \/\/ reset icons, player repairs the service\n    if(cur.facilityClick == true) {\n        if(cur.repairState == rsGreen) {\n            \/\/ there was nothing to repair\n            return;\n        }\n\n        \/\/ increment number of fixes for player score\n        statsObj.repairs++;\n\n        cur.trayClick = false;\n        cur.facilityClick = false;\n        workerObj.clicked = false;\n\n        \/\/ update for repaird facilities repaired\n        if(cur.facilityIcon.slice(0, 1) == \"D\") {\n            damFail = false;\n        } else if(cur.facilityIcon.slice(0, 1) == \"P\") {\n            pumpFail = false;\n        } else if (cur.facilityIcon.slice(0, 1) == \"F\") {\n            filterFail = false;\n        } \n\n         \/\/ user clicked to repair\n        \/\/ reset state to green\n        cur.repairState = rsGreen;\n        cur.repairColor = color(0, 200, 0);\n        \/\/ reset age of facility to 0\n        cur.ageOfState = 0;\n        \/\/ reset probability of problem\n        cur.problemLikely = .007;\n        return;\n    }\n}\n\n\/\/ variables to track failure\nvar damFail = false;\nvar pumpFail = false;\nvar filterFail = false;\n\nfunction filterFailure(filter) {\n    if(filter.repairState == rsRed) {\n        filterFail = true;\n    }\n}\n\nfunction pumpFailure(pump) {\n    if(pump.repairState == rsRed) {\n        pumpFail = true;\n    }\n}\n\nfunction damFailure(dam) {\n    if(dam.repairState == rsGreen & dYellow == true){\n        \/\/ reset cracks\n        dYellow = false;\n        dOrange = false;\n        dRed = false;\n    }\n\n    if(dam.repairState == rsRed) {\n        dRed = true;\n        damFail = true;\n    } else if(dam.repairState == rsOrange) {\n        dOrange = true;\n    } else if(dam.repairState == rsYellow) {\n        dYellow = true;\n    }\n}\n\nfunction drawScene() {\n    \/\/ draw horizon line\n    fill(0, 102, 0);\n    rect(0, height\/3, width, height);\n\n    drawStaticElements();\n    drawCracks();\n    drawFlood();\n    drawFilterFail();\n}\n\n\nfunction drawStaticElements() {\n    \/\/ draw static elements for the game background\n    \/\/ function are in static.js\n    drawMountains();\n    drawWater(r, g, b);  \n    drawDam();\n    drawFiltration();\n    drawPumpStation();\n    drawHydro();\n\n    drawIconTray();\n}\n\nvar r = 0;\nvar g = 0;\nvar b = 204;\nvar ft = 0; \/\/ filter transparency\n\nfunction drawFilterFail() {\n    \/\/ turn water brown to show it is polluted\n    \/\/ when the filter fails\n    if(filterFail == true) {\n        r = 134;\n        g = 89;\n        b = 45;\n        ft = min(t + 1, 255);\n    } else {\n        r = 0;\n        g = 0;\n        b = 204;\n        ft = 0; \/\/ filter transparency\n    }\n}\n\nvar t = 0; \/\/ variable to control transparency\nfunction drawFlood() {\n\n    \/\/ flood the town when the dam fails\n    if(damFail == true || pumpFail == true) { \n        t = min(t + 3, 255);       \n    }\n    else if (damFail == false & pumpFail == false) {\n        \/\/ dam is repaired decrease transparency\n        \/\/ to make grass green again\n        t = max(t - 3, 0);\n    }\n    fill(r, g, b, t);\n    rect(0, height\/3, width, height);\n    drawStaticElements();\n    drawCracks();\n}\n\nfunction drawCracks() {\n    \/\/ draw crack in dam\n    if(dYellow == true) {\n    \/\/ draw small cracks\n        noFill();\n        strokeWeight(1);\n\n        beginShape();\n        vertex(355, 170);\n        vertex(365, 162);\n        vertex(370, 140);\n       \n        endShape();\n    }\n\n    if(dOrange == true) {\n    \/\/ draw more cracks\n        noFill();\n\n        beginShape();\n        vertex(350, 170);\n        vertex(342, 180);\n        vertex(333, 164);\n        vertex(325, 168);\n       \n        endShape();\n        strokeWeight(2);\n\n        beginShape();\n        vertex(355, 170);\n        vertex(380, 180);\n        vertex(392, 164);\n       \n        endShape();\n    }\n\n        if(dRed == true) {\n        \/\/ draw many cracks\n        noFill();\n\n        beginShape();\n        vertex(350, 170);\n        vertex(347, 175);\n        vertex(355, 182);\n        vertex(358, 190);\n        vertex(383, 192);\n        vertex(400, 194);\n        vertex(425, 205);\n       \n        endShape();\n        strokeWeight(3);\n\n        beginShape();\n        vertex(345, 170);\n        vertex(340, 160);\n        vertex(325, 155);\n        vertex(315, 152);\n       \n        endShape();\n    }\n\n    strokeWeight(1);\n}\n\n\/\/ Functions to draw static game elements\n\nfunction drawIconTray() {\n    fill(230);\n    textAlign(LEFT);\n    textSize(12);\n    strokeWeight(1);\n    text(\"Icon Tray\", 165, 395);\n    text(\"2. Click icon from tray          3. Click matching facility\", \n        165, 475);\n    rect(165, 400, 285, 60);\n}\n\nfunction drawHydro() {\n    \/\/ draw hydro electric power\n    fill(179, 179, 204); \n    beginShape(); \n    vertex(255, 220); \n    vertex(365, 237);\n    vertex(365, 254); \n    vertex(255, 237); \n    endShape(CLOSE); \n\n    \/\/ draw top\n    beginShape();\n    vertex(255, 220);\n    vertex(320, 200);\n    vertex(388, 208);\n    vertex(365, 237);\n    endShape(CLOSE);;\n\n    \/\/ draw side\n    beginShape();\n    vertex(365, 237);\n    vertex(388, 208);\n    vertex(388, 215);\n    vertex(365, 254);\n    endShape();\n}\n\nfunction drawPumpStation() {\n    \/\/ draw pumpStation\n    fill(179, 179, 204);\n    rect(width * .75, 275, 75, 50);\n\n    \/\/ pump station top\n    beginShape();\n    vertex(width *.75, 275);\n    vertex(width *.75 + 15, 265);\n    vertex(width * .75 + 90, 265);\n    vertex(width * .75 + 75, 275);\n    endShape(CLOSE);\n\n    \/\/ pump station side\n    beginShape();\n    vertex(width * .75 + 90, 265);\n    vertex(width * .75 + 90, 310);\n    vertex(width * .75 + 75, 325);\n    vertex(width * .75 + 75, 275);\n    endShape(CLOSE);\n\n    \/\/ Draw pipe\n    beginShape();\n    vertex(width * .75, 285);\n    vertex(width * .75 - 30, 285);\n    vertex(width * .75 - 30, 325);\n    vertex(width * .75 - 15, 325);\n    vertex(width * .75 - 15, 300);\n    vertex(width * .75, 300);\n    endShape(CLOSE);\n}\n\nfunction drawFiltration() {\n    \/\/ draw filtration faciity\n    fill(179, 179, 204);\n    rect(width\/14, height\/2.5, 50, 50);\n\n    \/\/ Draw top\n    beginShape();\n    vertex(width\/14, height\/2.5);\n    vertex(width\/14 + 20, height\/2.5 - 10);\n    vertex(width\/14 + 70, height\/2.5 - 10);\n    vertex(width\/14 + 50, height\/2.5);\n    endShape(CLOSE);\n\n    \/\/ Draw side\n    beginShape();\n    vertex(width\/14 + 70, height\/2.5 - 10);\n    vertex(width\/14 + 70, height\/2.5 + 40);\n    vertex(width\/14 + 50, height\/2.5 + 50);\n    vertex(width\/14 + 50, height\/2.5);\n    endShape(CLOSE);\n\n    \/\/ Draw pipe 1\n    ellipse(100, 202, 10, 10);\n    beginShape();\n    vertex(98, 198);\n    vertex(130, 200);\n    vertex(130, 240);\n    vertex(125, 240);\n    vertex(125, 205);\n    vertex(98, 205);\n    endShape(CLOSE);\n\n    \/\/ Draw pipe 2\n    ellipse(95, 222, 10, 10);\n    beginShape();\n    vertex(93, 218);\n    vertex(113, 218);\n    vertex(113, 245);\n    vertex(107, 245);\n    vertex(107, 225);\n    vertex(93, 225);\n    endShape(CLOSE);\n}\n\nfunction drawWater(r, g, b) {\n    \/\/ draw water as a multipoint curve vertex shape\n    fill(r, g, b);\n    beginShape();\n\n    curveVertex(425, 100);\n    curveVertex(280, 120);\n    curveVertex(320, 200);\n    curveVertex(250, 240);\n    curveVertex(0, 260);\n    curveVertex(0, 300);\n    curveVertex(270, 280);\n    curveVertex(470, 150);\n\n    endShape(CLOSE);\n}\n\nfunction drawDam() {\n    var x = width * .55;\n    var y = height\/3;\n\n    fill(179, 179, 204);\n\n    \/\/ draw face of dam\n    beginShape();\n    vertex(x, y + 50);\n    vertex(x + 60, y + 45);\n    vertex(x + 90, y + 50);\n    vertex(x + 120, y + 55);\n    vertex(x + 150, y + 70);\n    vertex(x + 185, y + 90);\n    vertex(x + 185, y -20);\n    vertex(x, y - 50);\n    endShape(CLOSE);\n\n    \/\/ draw top ledge\n    beginShape();\n    vertex(x, y - 50);\n    vertex(x + 30, y - 55);\n    vertex(x + 215, y - 25);\n    vertex(x + 185, y - 20)\n    endShape();\n\n    \/\/ draw right side\n    beginShape();\n    vertex(x + 185 , y - 20);\n    vertex(x + 215, y - 25);\n    vertex(x + 215, y + 85);\n    vertex(x + 185, y + 90)\n    endShape();\n}\n\nfunction drawMountains() {\n    \/\/ set origin to 0, horizon line\n    push();\n    translate(0, height\/3);\n\n    \/\/ draw curves for background mountains\n    fill(71, 71, 107);\n    beginShape();\n    vertex();\n    vertex(-20, 20);\n    vertex(0, -125);\n    vertex(45, -80);\n    vertex(120, -155);\n    vertex(200, -85);\n    vertex(250, -135);\n    vertex(290, -90);\n    vertex(360, -140);\n    vertex(440, -40);\n    vertex(500, -120);\n    vertex(510, 0);\n    endShape(CLOSE);\n\n    \/\/ draw curves for mid range mountains\n    fill(153, 153, 150);\n    beginShape();\n    vertex(-30, 30);\n    vertex(30, -65);\n    vertex(75, -30);\n    vertex(120, -90);\n    vertex(165, -35);\n    vertex(210, -65);\n    vertex(255, -25);\n    vertex(310, -80);\n    vertex(395, 25);\n    endShape(CLOSE);\n\n    \/\/ draw curves for near mountains\n    fill(0, 153, 51);\n    beginShape();\n    curveVertex(-30, 60);\n    curveVertex(0, -5);\n    curveVertex(50, -15);\n    curveVertex(95, -5);\n    curveVertex(135, -20);\n    curveVertex(175, -5);\n    curveVertex(220, -15);\n    curveVertex(275, 10);\n    curveVertex(300, 25)\n    endShape(CLOSE);\n\n    pop();\n}\n\n\n<\/code><\/pre><\/div><\/body><\/html>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":760,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[116,56],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts\/76209"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/users\/760"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/comments?post=76209"}],"version-history":[{"count":3,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts\/76209\/revisions"}],"predecessor-version":[{"id":76215,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts\/76209\/revisions\/76215"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/media?parent=76209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/categories?post=76209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/tags?post=76209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}