Home > Software engineering >  How to make an algorithm for this game?
How to make an algorithm for this game?

Time:05-21

I am trying to re-code a game which I played as a child on a very old PC. For that, I probably need the help of some riddle- or logic-enthusiasts. The principle is very simple:

On the right side of the window is a "car" (five rectangles resembling a car-like structure) which can be moved in three lines, the top line, the middle line and the bottom line. Other cars are coming from the left of the window in one of these three lines, and are moving towards the car on the right. The player has to move the car on the right, so that it doesn't collide with the cars coming from the left.

The cars coming from the left are saved in a list. If one car moves out of frame, another car is spawned. All cars are simulated with a for-loop iterating through the array of cars.

But I can't seem to figure out an algorithm to spawn the new cars in the right line. There are some restrictions to ensure, that the car has the possibility to get through.

This for example is not allowed: enter image description here

To prevent this, I used this condition:

if cars[-1].line != cars[-2].line:
            pssble=[carss[-1].line,cars[-2].line] 
            cars.append(Auto(pssble[random.randint(0,1)])

So, if the last two cars were NOT in the same line, the third one has to be in one of these rows, otherwise, something like the picture above will happen. But something else can happen. This: enter image description here

I could now continue to explain every possibility of anything, but I doubt it would help anybody. If it would, please tell me and I will describe more of them.

Although I found a possibility to make the cars not block the way, it indirectly forced all cars in two lines, so that the player didn't ever had to make any move. That's also not what I want.

So summed up, either the game is impossible because the cars get blocked, or it is boring, because you never have to do anything.

If anybody has an idea on how to solve this, or is into the kind of logic-riddle this question is, I would be happy for an awnser. I will put the whole code below.

Thanks in Advance

The Code:


#Setup
import pygame, sys, random, time
from pygame.locals import *
from pygame import mixer
import math
pygame.init()
pygame.font.init()
infobj=pygame.display.Info()
WINDOWWIDTH= 1000#infobj.current_w
WINDOWHEIGHT=400#infobj.current_h
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE=(255, 255, 255)
BROWN=(139, 69, 19)
RED=(255,0,0)
Grey=(179,179,179)
clock=0.06
MOVESPEED=8
carHeight=3 #As in current line of the car
autos=[]  #the list of cars
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)

auto=pygame.image.load("Auto.png")
auto=pygame.transform.scale(auto,(int(WINDOWWIDTH/5),int(WINDOWHEIGHT/3)))
playerrect=auto.get_rect()
playerrect.bottom=WINDOWHEIGHT/carHeight
playerrect.left=0
global windowSufarce
class Auto:
    def __init__(self, line):
        self.line=line
        self.auto=pygame.image.load("Auto.png")
        self.auto=pygame.transform.scale(auto,(int(WINDOWWIDTH/5),int(WINDOWHEIGHT/3)))
        self.autorect=auto.get_rect()
        self.autorect.bottom=(WINDOWHEIGHT/3)*self.line
        self.autorect.left=WINDOWWIDTH
    def sim(self):
        self.autorect.left=self.autorect.left-MOVESPEED
        windowSurface.blit(self.auto,self.autorect)
#makes two cars at the beginning
autos.append(Auto(random.randint(1,3)))
autos.append(Auto(random.randint(1,3)))
while True:
    windowSurface.fill(WHITE)
    playerrect.bottom=(WINDOWHEIGHT/3)*carHeight
    windowSurface.blit(auto, playerrect)
    if autos[-1].autorect.right<=WINDOWWIDTH-4 and autos[-1].autorect.right>=WINDOWWIDTH-10:
        if something: #THIS IS THE PROBLEM. This is where I need the conditions for the car. All my tries, even consisting of up to 6 if-statements failed.
            autos.append(Auto(LINE))
    for car in autos:
        try:
            car.sim()
        except:
            pass
        if playerrect.colliderect(car.autorect):
            print("Collision detected. Exiting")
            sys.exit()

    pygame.display.update()
    time.sleep(clock)

    #Keyboard stuff
    pressed=pygame.key.get_pressed()
    if (pressed[pygame.K_w] or pressed[pygame.K_UP]) and carHeight>1:
        carHeight=carHeight-1
    if (pressed[pygame.K_s] or pressed[pygame.K_DOWN]) and carHeight<3:
        carHeight=carHeight 1
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

CodePudding user response:

Thanks to the comments of The_spider and fana, I found a Solution. The condition I explained in my question stays. The class Auto has been modified, an additional parameter can be passed which flags the Car as visible or invisible. Every fourth car spawned is defined as being invisible, and a blank image is loaded, the collision detection is also deactivated for these cars.

Through this solution, the situation of the upper picture gets avoided by the mentioned condition, and the situation in the lower picture and all other possibilities of blocking the car gets avoided by the fact the every fourth car-sized space is empty, so the player has the ability to move around the other cars. To make the sure that there are no long areas of free way by coincidence, the probability of a car spawning in the players line is increased massively.

If anyone needs any further information or my code (for whatever reason, I don't know), feel free to come back at me.

Thanks for helping me out!

  • Related