From: Peter Gerwinski Date: Wed, 16 May 2018 18:39:12 +0000 (+0200) Subject: adopted eternal-flag mode and AI by balthasar_s X-Git-Url: http://bicyclesonthemoon.info/git-projects/?a=commitdiff_plain;h=b9a3dabdb4e13cce76aeed4b8c0fd258d68fa339;p=ott%2Fmolpy-up adopted eternal-flag mode and AI by balthasar_s --- diff --git a/README b/README index c4c6600..4c4faa4 100644 --- a/README +++ b/README @@ -40,12 +40,14 @@ In the game, the following keys can be used: Some additional key bindings for debugging and/or cheating: - Use with <+> or <-> to crank up/down the score. - - Use with to enable "eternal" mode. No more falling down. ;-) + - Use with to enable / disable "eternal" mode. No more falling down. ;-) + - Use with for flag-eternal mode. Lose a flag instead of falling down. - Use with to get / get rid of a flag. - Use with to get / get rid of a beanie. + - Use with enable / disable artificial intelligence playing for you. Thanks to NoMouse and taixzo for the installation instructions! -Thanks to balthasar_s for testing and debugging! +Thanks to balthasar_s for testing, debugging, and improving the game! Thanks to everyone who reported mustard and kept me up with the Present! Enjoy! diff --git a/assets/lucky.xcf.gz b/assets/lucky.xcf.gz new file mode 100644 index 0000000..4568546 Binary files /dev/null and b/assets/lucky.xcf.gz differ diff --git a/molpyup.py b/molpyup.py index 0c23e80..481a27b 100644 --- a/molpyup.py +++ b/molpyup.py @@ -7,7 +7,7 @@ # Copyright (C) 2018 by Peter Gerwinski , # OTTified in about 120 minutes. # -# edited to add arrow - balthasar_s +# edited to add arrow, AI, and a flag save mode - balthasar_s # # This program is Free Software: you can redistribute it and/or modify it # under the terms of the GNU General Public License (GNU GPL), version 3, @@ -40,6 +40,7 @@ from pygame.locals import * import sys import datetime import random +import math class MolpyUp: @@ -78,6 +79,7 @@ class MolpyUp: scoreEpilogue = 3094 def __init__(self): + self.relativeX=0 self.sx = 553 self.sy = 395 self.extrax = self.sx // 16 @@ -87,6 +89,9 @@ class MolpyUp: self.clock = pygame.time.Clock() self.xmovementmax = 10 self.eternal = False + self.eternalFlag = False + self.ai = False + self.aiDebag = False self.imgPlatformSand = [ pygame.image.load("assets/platformSand1.png").convert_alpha(), pygame.image.load("assets/platformSand2.png").convert_alpha(), pygame.image.load("assets/platformSand3.png").convert_alpha(), @@ -171,9 +176,11 @@ class MolpyUp: self.hadLucky = False self.hadTheEnd = False self.raftcastleHasFlag = False - self.platforms = [[self.playerx, self.playery + self.sy // 6, self.platformTypeSand, 0, 0]] + self.platforms = [[self.playerx, self.playery + self.sy // 6, self.platformTypeSand, 0, 0, -1, False, self.imgPlatformSand[0].get_width()]] self.generateInitialPlatforms() self.items = [] + self.aiNextPlatformOk = False + self.aiNextPlatform=[self.playerx,self.playery] if self.filename: self.restoreGame (self.filename) @@ -202,6 +209,7 @@ class MolpyUp: file.write("hadTheEnd: " + str(self.hadTheEnd) + "\n") file.write("raftcastleHasFlag: " + str(self.raftcastleHasFlag) + "\n") file.write("eternal: " + str(self.eternal) + "\n") + file.write("eternalFlag: " + str(self.eternalFlag) + "\n") file.write("platforms: " + str(self.platforms) + "\n") file.write("items: " + str(self.items) + "\n") @@ -241,8 +249,112 @@ class MolpyUp: return True except FileNotFoundError: return False - + + def findNextPlatform(self): + # bestDistance=float("Inf") + # for p in self.platforms: + # if not self.jump: + # distance = abs(p[0]-self.playerx) * 0.5 - p[1] + # else: + # distance = abs(p[0]-self.playerx) * 0.5 + abs(p[1]-self.playery) + # if p[1]>self.playery: + # distance += 900 + # if p[2] > self.platformTypeNormal and p[2] <= self.platformTypeFloating: + # distance += 290 + # if p[2] == self.platformTypeBreaking: + # distance = float("Inf") + # p[6]=distance + # if distance 0: + maxY = actualY - (self.jump * (self.jump+1) // 2) + framesUp = self.jump + else: + maxY = actualY + framesUp = 0 + + for p in self.platforms: + platformX = p[0] + p[7] //2 + platformY = p[1] + platformScore = 0 + + if (platformY < maxY) or (p[2] == self.platformTypeBreaking): + platformScore = float("-Inf") + p[6]=platformScore + continue + + distY = actualY - platformY + distDown = platformY - maxY + distX = abs(platformX-actualX) + + if self.gravity > 0: + framesDown = int(math.floor(math.sqrt(self.gravity * self.gravity + 2 * distDown) - self.gravity)) + else: + framesDown = int(math.floor(math.sqrt(2*distDown))) + + speedX=9; + + if p[2] > self.platformTypeNormal and p[2] <= self.platformTypeFloating: + if (p[4] and platformX>actualX) or (not p[4] and platformX2*self.xmovementmax and self.xmovement < 0: + platformScore -= (self.xmovementmax-self.xmovement)*(self.xmovementmax-self.xmovement)//4 + elif actualX-platformX>2*self.xmovementmax and self.xmovement > 0: + platformScore -= (-self.xmovementmax-self.xmovement)*(-self.xmovementmax-self.xmovement)//4 + + if platformScore < 0: + platformScore = float("-Inf") + platformScore *=4 + + if distY>16: + platformScore += distY + distX//2 + else: + platformScore += 2*distY - 200 + distX + + if p[2] > self.platformTypeNormal and p[2] <= self.platformTypeFloating: + platformScore -= 50 #100 + elif p[2] == self.platformTypeLucky: + platformScore -= 150 + + if p[5] == self.itemTypeSnake: + platformScore -= 150 + elif p[5] == self.itemTypeFlag and not self.playerCarriesFlag: + platformScore += 70 + elif p[5] == self.itemTypeSandcastle and self.playerCarriesFlag: + platformScore += 70 + elif p[5] == self.itemTypeBeanie and not self.playerWearsBeanie: + platformScore += 50 + + p[6] = platformScore + + if platformScore > bestPlatformScore: + bestPlatformScore = platformScore + self.aiNextPlatform = p + self.aiNextPlatformOk = True + + + + + def updatePlayer(self): + if ((not self.jump) and (self.playery > self.aiNextPlatform[1])) or (self.aiNextPlatform[1] - self.cameray > self.sy): + self.aiNextPlatformOk = False + + if not self.aiNextPlatformOk and self.ai: + self.findNextPlatform() + if not self.jump: self.playery += self.gravity self.gravity += 1 @@ -250,6 +362,7 @@ class MolpyUp: self.playery -= self.jump self.jump -= 1 key = pygame.key.get_pressed() + if key[K_RIGHT]: if self.xmovement < self.xmovementmax: self.xmovement += 1 @@ -271,14 +384,42 @@ class MolpyUp: self.speed -= 1 self.screen.blit(self.font.render("Speed: " + str(self.speed), -1, (0, 0, 0)), (self.sx // 32, self.sy - self.sy // 12)) else: - if self.xmovement > 0: - self.xmovement -= 1 - elif self.xmovement < 0: - self.xmovement += 1 + if self.ai: + actualX=self.playerx+self.imgPlayerRightUp.get_width()//2 + platformX = self.aiNextPlatform[0] + self.aiNextPlatform[7] //2 + if self.aiNextPlatform[2] > self.platformTypeNormal and self.aiNextPlatform[2] <= self.platformTypeFloating: + if self.aiNextPlatform[4] == True: + self.relativeX = self.xmovement - self.extrax // 10 + else: + self.relativeX = self.xmovement + self.extrax // 10 + else: + self.relativeX = self.xmovement + + if actualXplatformX -2.5*self.relativeX: + if self.xmovement > -self.xmovementmax: + self.xmovement -= 1 + self.direction = 1 + else: + if self.xmovement > 0: + self.xmovement -= 1 + elif self.xmovement < 0: + self.xmovement += 1 + else: + if self.xmovement > 0: + self.xmovement -= 1 + elif self.xmovement < 0: + self.xmovement += 1 + if self.playerx > self.sx + self.extrax: self.playerx = -self.extrax + self.aiNextPlatformOk = False elif self.playerx < -self.extrax: self.playerx = self.sx + self.extrax + self.aiNextPlatformOk = False self.playerx += self.xmovement if self.playery - self.cameray <= self.sy // 3: self.cameray -= self.sy // 60 @@ -317,6 +458,8 @@ class MolpyUp: self.screen.blit(self.imgPlayerLeftUp, (self.playerx, self.playery - self.cameray)) if self.playerCarriesFlag: self.screen.blit(self.imgFlagRightDown, (self.playerx + 11, self.playery - 10 - self.cameray)) + + def choosePlatformType(self): if self.score >= self.scoreTheEnd: @@ -348,31 +491,35 @@ class MolpyUp: return self.platformTypeBreaking def generateNewPlatform(self): + platform = False + platform2 = False platformType = self.choosePlatformType() if platformType == self.platformTypeTheEnd: if not self.hadTheEnd: - self.platforms.append([self.sx // 2 - self.imgPlatformTheEnd.get_width() // 2, self.platforms[-1][1] - self.sy // 4, self.platformTypeTheEnd, False, False]) - self.platforms.append([self.sx // 2 - self.imgPlatformWonTheGame.get_width() // 2, self.platforms[-1][1] - self.sy * 2 // 3, self.platformTypeWonTheGame, False, False]) + platform2=[self.sx // 2 - self.imgPlatformTheEnd.get_width() // 2, self.platforms[-1][1] - self.sy // 4, self.platformTypeTheEnd, False, False, -1, False, self.imgPlatformTheEnd.get_width()] + platform=[self.sx // 2 - self.imgPlatformWonTheGame.get_width() // 2, platform2[1] - self.sy * 2 // 3, self.platformTypeWonTheGame, False, False, -1, False, self.imgPlatformWonTheGame.get_width()] self.hadTheEnd = True elif platformType == self.platformTypeWater or platformType == self.platformTypeRaftcastle: - self.platforms.append([random.randint(0, self.sx * 7 // 8), self.platforms[-1][1] - self.sy // 8, platformType, False, False]) + platform=[random.randint(0, self.sx * 7 // 8), self.platforms[-1][1] - self.sy // 8, platformType, False, False, -1, False, self.imgPlatformSand[0].get_width()] elif platformType == self.platformTypeLucky: - self.platforms.append([0, self.platforms[-1][1] - self.sy // 12, platformType, False, False]) + platform=[0, self.platforms[-1][1] - self.sy // 12, platformType, False, False, -1, False, self.imgPlatformSand[0].get_width()] else: - self.platforms.append([random.randint(0, self.sx * 7 // 8), self.platforms[-1][1] - self.sy // 12, platformType, False, False]) + platform=[random.randint(0, self.sx * 7 // 8), self.platforms[-1][1] - self.sy // 12, platformType, False, False, -1, False, self.imgPlatformSand[0].get_width()] if platformType <= self.platformTypeNormal: if platformType == self.platformTypeSand: - self.platforms[-1][-1] = random.randint(0, len(self.imgPlatformSand) - 1) + platform[4] = random.randint(0, len(self.imgPlatformSand) - 1) elif platformType == self.platformTypeGrass: - self.platforms[-1][-1] = random.randint(0, len(self.imgPlatformGrass) - 1) + platform[4] = random.randint(0, len(self.imgPlatformGrass) - 1) else: - self.platforms[-1][-1] = random.randint(0, len(self.imgPlatformWater) - 1) - x = self.platforms[-1][0] - y = self.platforms[-1][1] + platform[4] = random.randint(0, len(self.imgPlatformWater) - 1) + x = platform[0] + y = platform[1] if platformType == self.platformTypeGrass and self.score > self.scoreSnake and not self.hadSnake: + platform[5]=self.itemTypeSnake self.items.append([x - 10, y + 9, self.itemTypeSnake, False]) self.hadSnake = True elif platformType == self.platformTypeGrass and self.score > self.scorePrickly and not self.hadPrickly: + platform[5]=self.itemTypePrickly self.items.append([x + self.imgPlatformSand[0].get_width() // 3, y + 8, self.itemTypePrickly, False]) self.hadPrickly = True elif self.score > 0: @@ -381,23 +528,36 @@ class MolpyUp: xx = x + random.randint(0, self.imgPlatformSand[0].get_width() - 40) itemType = random.randint(0,999) if itemType < 50: + platform[5]=self.itemTypeBeanie self.items.append([xx, y + 7, self.itemTypeBeanie, False]) elif itemType < 150 and platformType == self.platformTypeSand: + platform[5]=self.itemTypeSandcastle self.items.append([xx, y + 7, self.itemTypeSandcastle, False]) elif itemType < 350 and platformType == self.platformTypeSand: + platform[5]=self.itemTypeFlag self.items.append([xx, y + 7, self.itemTypeFlag, False]) elif itemType < 950 and platformType == self.platformTypeSand: + platform[5]=self.itemTypePlantSand self.items.append([xx, y + 8, self.itemTypePlantSand, itemType % len(self.imgPlantSand)]) elif itemType < 100 and platformType == self.platformTypeGrass: + platform[5]=self.itemTypeFlag self.items.append([xx, y + 6, self.itemTypeFlag, False]) elif itemType < 700 and platformType == self.platformTypeGrass: + platform[5]=self.itemTypePlantGrass self.items.append([xx, y + 10, self.itemTypePlantGrass, itemType % len(self.imgPlantGrass)]) elif itemType < 850 and platformType == self.platformTypeGrass and self.score > self.scorePrickly: + platform[5]=self.itemTypePrickly self.items.append([xx, y + 8, self.itemTypePrickly, False]) elif itemType < 950 and platformType == self.platformTypeGrass and self.score > self.scoreSnake: + platform[5]=self.itemTypeSnake self.items.append([x - 10, y + 9, self.itemTypeSnake, False]) else: + platform[5]=self.itemTypeAccelerator self.items.append([xx - 5, y + 10, self.itemTypeAccelerator, False]) + if platform2 != False: + self.platforms.append(platform2) + if platform != False: + self.platforms.append(platform) def updatePlatforms(self): while self.platforms[0][1] - self.cameray > self.sy + self.sy // 12: @@ -421,25 +581,27 @@ class MolpyUp: player = pygame.Rect(self.playerx + 15, self.playery, self.imgPlayerRightUp.get_width() - 30, self.imgPlayerRightUp.get_height()) if rect.colliderect(player) and self.gravity and self.playery < (p[1] - self.cameray): if p[2] == self.platformTypeBreaking: - p[-1] = True + p[4] = True else: self.jump = self.sy // 20 + self.aiNextPlatformOk = False self.gravity = 0 - if p[2] == self.platformTypeLucky and not (self.playerWearsBeanie and self.playerCarriesFlag) and p[-2] <= 0: + if p[2] == self.platformTypeLucky and not (self.playerWearsBeanie and self.playerCarriesFlag) and p[3] <= 0: + self.aiNextPlatformOk = False self.xmovement = self.sx // 20 self.direction = 0 self.cameray -= self.sy // 12 - p[-2] = -1 - elif (p[2] == self.platformTypeAfterLucky or p[2] == self.platformTypeCastle or p[2] == self.platformTypeLucky) and self.playerCarriesFlag and not p[-2]: + p[3] = -1 + elif (p[2] == self.platformTypeAfterLucky or p[2] == self.platformTypeCastle or p[2] == self.platformTypeLucky) and self.playerCarriesFlag and not p[3]: self.playerCarriesFlag = False - p[-2] = True + p[3] = True self.sandcastles += 1 elif p[2] == self.platformTypeRaftcastle and self.playerCarriesFlag and not self.raftcastleHasFlag: self.playerCarriesFlag = False self.raftcastleHasFlag = True self.sandcastles += 1 if p[2] > self.platformTypeNormal and p[2] <= self.platformTypeFloating: - if p[-1]: + if p[4]: if p[2] == self.platformTypeAfterLucky: img = self.imgPlatformAfterLucky elif p[2] == self.platformTypeCastle: @@ -447,35 +609,38 @@ class MolpyUp: else: img = self.imgPlatformGrapevine p[0] += self.extrax // 10 - if p[0] + img.get_width() > self.sx + self.extrax: - p[-1] = False + if p[0] + img.get_width() > self.sx:# + self.extrax: + p[4] = False else: p[0] -= self.extrax // 10 if p[0] <= 0: - p[-1] = True + p[4] = True + + + def drawPlatforms(self): for p in self.platforms: if p[2] == self.platformTypeSand: - self.screen.blit(self.imgPlatformSand[p[-1]], (p[0], p[1] - self.cameray)) + self.screen.blit(self.imgPlatformSand[p[4]], (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeGrass: - self.screen.blit(self.imgPlatformGrass[p[-1]], (p[0], p[1] - self.cameray)) + self.screen.blit(self.imgPlatformGrass[p[4]], (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeWater: - self.screen.blit(self.imgPlatformWater[p[-1]], (p[0], p[1] - self.cameray)) + self.screen.blit(self.imgPlatformWater[p[4]], (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeGrapevine: self.screen.blit(self.imgPlatformGrapevine, (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeAfterLucky: - if p[-2]: + if p[3]: self.screen.blit(self.imgFlagRight, (p[0] + 47, p[1] - 12 - self.cameray)) self.screen.blit(self.imgPlatformAfterLucky, (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeCastle: - if p[-2]: + if p[3]: self.screen.blit(self.imgFlagRight, (p[0] + self.imgPlatformCastle.get_width() - 16, p[1] - 4 - self.cameray)) self.screen.blit(self.imgPlatformCastle, (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeLucky: - if p[-2]: + if p[3]: self.screen.blit(self.imgPlatformLuckyAttacking, (p[0], p[1] - self.imgPlatformLuckyAttacking.get_height() + self.imgPlatformLuckySleeping.get_height() - self.cameray)) - if p[-2] > 0: + if p[3] > 0: self.screen.blit(self.imgFlagRight, (p[0] + self.imgPlatformLuckyAttacking.get_width() - 8, p[1] - 11 - self.cameray)) else: self.screen.blit(self.imgPlatformLuckySleeping, (p[0], p[1] - self.cameray)) @@ -484,7 +649,7 @@ class MolpyUp: self.screen.blit(self.imgFlagRight, (p[0] + 50, p[1] - 13 - self.cameray)) self.screen.blit(self.imgPlatformRaftcastle, (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeBreaking: - if not p[-1]: + if not p[4]: self.screen.blit(self.imgPlatformBreaking, (p[0], p[1] - self.cameray)) else: self.screen.blit(self.imgPlatformBroken, (p[0], p[1] - self.cameray)) @@ -492,6 +657,13 @@ class MolpyUp: self.screen.blit(self.imgPlatformTheEnd, (p[0], p[1] - self.cameray)) elif p[2] == self.platformTypeWonTheGame: self.screen.blit(self.imgPlatformWonTheGame, (p[0], p[1] - self.cameray)) + # print (str(p)) + if self.aiDebag: + self.screen.blit(self.font.render(str(p[2])+" "+str(p[5])+" "+str(p[6]), -1, (0, 0x57, 0xaf)), (p[0], p[1] - self.cameray + 16)) + if self.aiDebag: + self.screen.blit(self.imgMolpArrow, (self.aiNextPlatform[0] + (self.imgPlatformSand[0].get_width()-self.imgMolpArrow.get_width())//2, self.aiNextPlatform[1] - self.cameray + 16)) + + def drawAndUpdateItems(self): while self.items and self.items[0][1] - self.cameray > self.sy + self.sy // 12: @@ -537,6 +709,7 @@ class MolpyUp: if not item[-1]: if pygame.Rect(item[0], item[1] - imgItem.get_height(), imgItem.get_width(), imgItem.get_height()).colliderect(pygame.Rect(self.playerx, self.playery, self.imgPlayerRightUp.get_width(), self.imgPlayerRightUp.get_height())): if item[2] == self.itemTypeAccelerator: + self.aiNextPlatformOk = False self.jump = self.sy // 12 self.cameray -= self.sy // 12 item[-1] = True @@ -544,6 +717,7 @@ class MolpyUp: self.playerWearsBeanie = True item[-1] = True elif item[2] == self.itemTypeSnake: + self.aiNextPlatformOk = False if self.playerx + self.imgPlayerRightUp.get_width() // 2 < item[0] + self.imgPlatformGrass[0].get_width() // 2: self.xmovement = -self.sx // 30 self.direction = 0 @@ -616,9 +790,21 @@ class MolpyUp: key = pygame.key.get_pressed() if key[K_ESCAPE]: sys.exit() + elif key[K_i]: + if pygame.key.get_mods() & KMOD_CTRL: + self.ai = not self.ai + self.aiNextPlatformOk = False + elif key[K_d]: + if pygame.key.get_mods() & KMOD_CTRL: + self.aiDebag = not self.aiDebag elif key[K_e]: if pygame.key.get_mods() & KMOD_CTRL: self.eternal = not self.eternal + self.eternalFlag = False + elif key[K_f]: + if pygame.key.get_mods() & KMOD_CTRL: + self.eternalFlag = not self.eternalFlag + self.eternal = False elif key[K_f]: if pygame.key.get_mods() & KMOD_CTRL: self.playerCarriesFlag = not self.playerCarriesFlag @@ -640,13 +826,21 @@ class MolpyUp: self.screen.blit(self.font.render(str(self.score), -1, (0, 0, 0)), (self.sx // 32, self.sy // 24)) for i in range(0, self.sandcastles): self.screen.blit(self.imgFlagRight, (self.sx // 32 + 10 * i, self.sy // 8)) + + if self.playery - self.cameray > self.sy * 7 // 6: if self.eternal: self.jump = self.gravity self.gravity = 0 + self.aiNextPlatformOk = False + elif self.eternalFlag and self.sandcastles > 0: + self.sandcastles -= 1 + self.jump = self.gravity + self.gravity = 0 + self.aiNextPlatformOk = False else: self.showScore() self.reset() pygame.display.flip() -MolpyUp().run() +MolpyUp().run() \ No newline at end of file