Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make the zombies in the program chase after other beings and eat them?

import random
from numpy import sqrt 


class Being():
    def __init__(self, limits, name):
        self.row = random.randint(0, limits[0])
        self.col = random.randint(0, limits[1])
        self.name = name
        self.infected = False
        self.dead = False
        self.zombie = False

    def getRow(self):
        return self.row

    def getCol(self):
        return self.col

    def getName(self):
        return self.name

    def lure(self, limits, beings):
    
        self.row += random.randint(-1, 1)
        self.col += random.randint(-1, 1)

        if self.row > limits[0]:
            self.row = limits[0]
        if self.row < 0:
            self.row = 0
        if self.col > limits[1]:
            self.col = limits[1]
        if self.col < 0:
            self.col = 0

        for i in range(len(beings)):
            for j in range(len(beings)):
                if i != j:
                    if beings[i].row == beings[j].row and beings[i].col == beings[j].col:
                        k = [-1, 1]
                        beings[i].row += random.choice(k)
                        beings[i].col += random.choice(k)
                            

        for i in range(len(beings)):
            if not beings[i].infected and not beings[i].dead:
                for j in range(len(beings)):
                    if beings[j].infected:
                        if i != j:
                            if beings[j].row + 1 == beings[i].row and beings[j].col + 1 == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)
                            if beings[j].row - 1 == beings[i].row and beings[j].col - 1 == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)
                            if beings[j].row + 1 == beings[i].row and beings[j].col - 1 == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)
                            if beings[j].row - 1 == beings[i].row and beings[j].col + 1 == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)
                            if beings[j].row== beings[i].row and beings[j].col + 1 == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)     
                            if beings[j].row== beings[i].row and beings[j].col - 1 == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)     
                            if beings[j].row - 1 == beings[i].row and beings[j].col == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)     
                            if beings[j].row + 1 == beings[i].row and beings[j].col == beings[i].col:
                                if random.randint(1,4)==1:
                                    beings[i].infected = True
                                    print(beings[j].name, "infected", beings[i].name)     

    def eat(self,beings):
        being_position = []
        for i in range(len(beings)):
            if not beings[i].zombie:
                being_position.append((self.col,self.row))
        distances = []
        for i in range(len(being_position)):
            distances.append(sqrt((being_position[i][0]-self.col)**2+(being_position[i][1]-self.row)**2))
        m = distances.index(min(distances))
        if self.row < being_position[m][1]:
            self.row += 1
        elif self.row > being_position[m][1]:
            self.row -= 1
        if self.col < being_position[m][0]:
            self.col += 1
        elif self.col > being_position[m][0]:
            self.col -= 1

        
     
import matplotlib.pyplot as plt
import numpy as np
import random

MAXROWS = 10
MAXCOLS = 10


def flipCoords(row, col, limits):
    xpos = col
    ypos = row
    return (xpos, ypos)


def plot_being_scatter(beings):
    xlist = []
    ylist = []
    slist = []
    clist = []
    for k in range(len(beings)):
        if not beings[k].infected and not beings[k].dead:
            ylist.append(beings[k].row)
            xlist.append(beings[k].col)
            slist.append(50)
            plt.scatter(xlist, ylist, s=slist, c="blue")


def plot_infected_scatter(beings):
    xlist = []
    ylist = []
    slist = []
    clist = []
    for k in range(len(beings)):
        if beings[k].infected:
            ylist.append(beings[k].row)
            xlist.append(beings[k].col)
            slist.append(50)
            plt.scatter(xlist, ylist, s=slist, c="red")
            
def plot_dead_scatter(beings):
    xlist = []
    ylist = []
    slist = []
    clist = []
    for k in range(len(beings)):
        if beings[k].dead:
            ylist.append(beings[k].row)
            xlist.append(beings[k].col)
            slist.append(50)
            plt.scatter(xlist, ylist, s=slist, c="k")
            
def plot_zombie_scatter(beings):
    xlist = []
    ylist = []
    slist = []
    clist = []
    for k in range(len(beings)):
        if beings[k].zombie:
            ylist.append(beings[k].row)
            xlist.append(beings[k].col)
            slist.append(50)
            plt.scatter(xlist, ylist, s=slist, c="c")


def main():
    beingNames = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18",
                  "19", "20"]
    limits = [MAXROWS, MAXCOLS]
    numBeings = 20
    beingList = []

    for i in range(numBeings):
        beingList.append(Being(limits, beingNames[i]))

    beingList[0].infected = True

    print("### Timestep ", 0, "###")
    plot_being_scatter(beingList)
    plot_infected_scatter(beingList)
    print(beingList[0].col, beingList[0].row)
    print(beingList[0].name, "is infected at row", beingList[0].row, "column", beingList[0].col)
    plt.title("Beacon Simulation")
    plt.xlabel("Columns")
    plt.ylabel("Rows")
    for i in range(numBeings):
        plt.annotate(beingList[i].name, flipCoords(beingList[i].getRow(), beingList[i].getCol(), limits))
    plt.xlim(-1, MAXCOLS)
    plt.ylim(-1, MAXROWS)
    plt.pause(1)
    plt.clf()

    for t in range(10):
        print("### Timestep ", t, "###")

        for i in range(numBeings):
            if not beingList[i].dead and not beingList[i].zombie:
                beingList[i].lure(limits, beingList)
            
        for i in range(numBeings):
            if beingList[i].infected:
                if random.randint(1,10)==1:
                    beingList[i].dead = True
                    beingList[i].infected = False
                    print(beingList[i].name, "died")
                if random.randint(1,10)==1:
                    beingList[i].zombie = True
                    beingList[i].infected = False
                    print(beingList[i].name, "died")

        for i in range(numBeings):
            if beingList[i].zombie:
                beingList[i].eat(beingList)
                    
        a = 20
        b = 0
        c = 0
        for i in range(20):
            if beingList[i].infected:
                b += 1
            if beingList[i].dead:
                c += 1
        print("Infected = ", b)
        print("Dead = ", c)
        print("Uninfected = ", a - b - c)
        plot_being_scatter(beingList)
        plot_infected_scatter(beingList)
        plot_dead_scatter(beingList)
        plot_zombie_scatter(beingList)
        plt.title("Beacon Simulation")
        plt.xlabel("Columns")
        plt.ylabel("Rows")
        for i in range(numBeings):
            plt.annotate(beingList[i].name, flipCoords(beingList[i].getRow(), beingList[i].getCol(), limits))
        plt.xlim(-1, MAXCOLS)
        plt.ylim(-1, MAXROWS)
        plt.pause(1)
        plt.clf()


if __name__ == "__main__":
    main()

This is a simulation where there are beings moving around an area. It starts off with 1 infected being. It has a 0.1 chance of spreading it to the beings around it by 1 unit. With each timestep the infected beings have a 0.1 chance of dying or becoming a zombie. If it dies it stays on the same location. If it becomes a zombie it goes chasing after all the other beings inclueing the dead ones but not the other zombies. How may I be able to achieve it. I would really appreciate if someone is able to help me out. Thank you

enter image description here

like image 959
Sajana Gunathilake Avatar asked Dec 11 '25 04:12

Sajana Gunathilake


1 Answers

So you have the positions of the zombies (xpos, ypos), and you have timesteps. What I would do if create some functions to help you.

First:

def distance_from_person_to_person(person_1, person_2):
    ...
    ...
    return x #(where this is the number)

Second you're going to loop over the people

def closest_person_to_zombie(zombie):
   ...
   # you get the gist, this returns you the coordinates of the closest person, using the previous function

Then you can finally create the vector in which direction the zombie should move (just the gradient is needed actually between the zombie and the person), and then each timestep, you adjust the zombie's position to that:)

For example if a zombie was position (6, 12), and the person was (20, 50), then you'd need to move the zombie 14 in x and 38 in y. You want to make it such that you find a scaling that it's a unit in that direction

let's call scaling s.

then by pythagoras, we want (14s)**2 + (38s)**2 = 1

so s=1/(14**2+38**2)**0.5 s=0.0246932399 Then you can move the zombie (14s, 38s) in the next timestep:)

Hope this helps

like image 169
Aron Atilla Hegedus Avatar answered Dec 13 '25 18:12

Aron Atilla Hegedus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!