from cmu_graphics.cmu_graphics import AppWrapper, app, runApp from cmu_graphics import * from types import SimpleNamespace from random import randint, choice from time import sleep from sys import exit def onAppStart(app_inst: AppWrapper): app_inst.difficulty = 1 pairs = 5 * app_inst.difficulty app_inst.dots = [] for i in range(10 * app_inst.difficulty): app_inst.dots.append(makeDot(app_inst, i % pairs)) app_inst.counter = 0 app_inst.showing = [] app_inst.end_game = False app_inst.hint = False app_inst.hints = 0 app_inst.warning = 0 def checkOverlap(dot1, dots): for dot2 in dots: if (dot1.cx - dot2.cx) ** 2 + (dot1.cy - dot2.cy) ** 2 <= ( dot1.r + dot2.r ) ** 2: return True return False def makeDot(app_inst: AppWrapper, num: int): dot = SimpleNamespace() dot.num = num dot.r = randint(10, 30) dot.cx = 0 dot.cy = 0 while dot.cx == 0 or dot.cy == 0 or checkOverlap(dot, app_inst.dots): dot.cx = randint(20, app_inst.width - 20) dot.cy = randint(20, app_inst.height - 20) dot.color = choice(["aqua", "lime", "yellow"]) return dot def drawDot(dot: SimpleNamespace): drawCircle(dot.cx, dot.cy, dot.r, fill=dot.color) def collision(pointer, dot2): if (pointer.cx - dot2.cx) ** 2 + (pointer.cy - dot2.cy) ** 2 <= dot2.r**2: return True return False def onMousePress(app_inst: AppWrapper, mouseX, mouseY): pointer = SimpleNamespace() pointer.cx = mouseX pointer.cy = mouseY for dot in app_inst.dots: if collision(pointer, dot): app_inst.showing.append(dot) def onStep(app_inst: AppWrapper): if app_inst.warning != 0: sleep(2) app_inst.warning = 0 if app_inst.hint: sleep(2) app_inst.hint = False if len(app_inst.showing) == 2: if app_inst.showing[0].num == app_inst.showing[1].num: app_inst.dots.remove(app_inst.showing[0]) app_inst.dots.remove(app_inst.showing[1]) sleep(0.5) app_inst.counter += 1 app_inst.showing = [] if len(app_inst.dots) == 0: app_inst.end_game = True def onKeyPress(app_inst: AppWrapper, key): if key == "r": app_inst.dots = [] for i in range(10): app_inst.dots.append(makeDot(app_inst, i)) app_inst.showing = [] app_inst.counter = 0 app_inst.end_game = False elif key == "q": exit() elif key == "h": app_inst.hint = True app_inst.hints += 1 elif key.isdigit(): if int(key) < 1 or int(key) > 4: app_inst.warning = int(key) app_inst.difficulty = max(1, min(int(key), 4)) pairs = 5 * app_inst.difficulty app_inst.dots = [] for i in range(10 * app_inst.difficulty): app_inst.dots.append(makeDot(app_inst, i % pairs)) app_inst.counter = 0 app_inst.showing = [] app_inst.end_game = False def redrawAll(app_inst: AppWrapper): if app_inst.warning: drawLabel( f"Invalid difficulty: {app_inst.warning}", app_inst.width // 2, app_inst.height // 2 - 50, size=20, ) drawLabel( "difficulty must be between 1 and 4", app_inst.width // 2, app_inst.height // 2 - 25, size=20, ) drawLabel( f"picking difficulty {app_inst.difficulty}", app_inst.width // 2, app_inst.height // 2, size=20, ) return for dot in app_inst.dots: drawDot(dot) if dot in app_inst.showing: drawLabel(str(dot.num), dot.cx, dot.cy, size=24) elif app_inst.hint: drawLabel(str(dot.num), dot.cx, dot.cy, size=24) if app_inst.end_game: drawLabel("You win!", app_inst.width // 2, app_inst.height // 2 - 50, size=36) drawLabel( f"Final score: {app_inst.counter}", app_inst.width // 2, app_inst.height // 2, size=24, ) drawLabel( f"Hints used: {app_inst.hints}", app_inst.width // 2, app_inst.height // 2 + 25, size=24, ) drawLabel( "Press 'r' to restart", app_inst.width // 2, app_inst.height // 2 + 75, size=24, ) drawLabel( "Press 'q' to quit", app_inst.width // 2, app_inst.height // 2 + 100, size=24, ) else: drawLabel(f"{app_inst.counter}", 20, 20, size=24, fill="blue") drawLabel(f"{app_inst.hints}", app_inst.width - 20, 20, size=24, fill="red") runApp()