Python Forum
AI Techniques applied to a Game
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
AI Techniques applied to a Game
#1
Hello Everyone,

I want to understand how an AI technique is applied on a game in Python. can any body help me understand how the following code BFS is contributing or applying to the snake AI? your help will be much appreciated.


APP CODE
import pygame
import random
from bfs import bfs
from models import Apple, Snake

pygame.init()

# colors
white = (0, 0, 0)
black = (255, 255, 255)
red = (255, 0, 0)
green = (0, 155, 0)

# window size
display_width = 150
display_height = 150

# all the pygame settings
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("Snake Game")
clock = pygame.time.Clock()
icon = pygame.image.load("food.png")
pygame.display.set_icon(icon)
img = pygame.image.load('snake.png')
img2 = pygame.image.load('food.png')
pygame.display.flip()



block_size = 10
# frame per second will control the game speed
FPS = 20

def one_game():
    pygame.event.pump()
    game_over = False

    # snake will start in the middle of the game window
    lead_x = 70
    lead_y = 70

    # snake default direction is right
    snake = Snake(gameDisplay, display_width, display_height, img, lead_x, lead_y)
    apple = Apple(gameDisplay, display_width, display_height, block_size, img2, snake.snake_list) 

    while not game_over:
                 

        # based on the direction, we can work out the x, y changes to update the snake
        x, y = apple.get_apple_pos()
        snake.update_snake_list(x, y)

        # check if snake dies
        if snake.is_alive() is False:
            game_over = True

        gameDisplay.fill(white)
        
        # if snake eats the apple, make a random new apple
        if snake.eaten is True:
            apple.update_apple_pos(snake.snake_list)

        apple.display()
        snake.eaten = False
        snake.display()
        snake.display_score()
        pygame.display.update()



        # this part is using the snake position and apple
        # position to use the BFS method to get the path
        a_x, a_y = apple.get_apple_pos()
        s_x, s_y = snake.get_snake_head()
        visited = snake.snake_list.copy()
        visited.remove([s_x, s_y])
        result = bfs(display_width, display_height, block_size, visited, [a_x, a_y], [s_x, s_y])

        # since the path starts from snake position, the second element will
        # be next move
        next_cell = result[1]
        
        # update the snake position based on the next move position
        x_diff = next_cell[0] - s_x
        y_diff = next_cell[1] - s_y
        if x_diff > 0:
            snake.direction = "right"
        elif x_diff < 0:
            snake.direction = "left"
        elif y_diff > 0:
            snake.direction = "down"
        elif y_diff < 0:
            snake.direction = "up"

        clock.tick(FPS)

if __name__ == "__main__":
    one_game()
Model Code
import random

# this is the apple object of the snake game
class Apple:
    
    def __init__(self, gameDisplay, display_width, display_height, block_size, img, snake_list, apple_thickness = 10):
        self.gameDisplay = gameDisplay
        self.display_width = display_width
        self.display_height = display_height
        self.block_size = block_size
        self.apple = img
        self.apple_thickness = apple_thickness
        
        self.rand_apple_x = random.randint(0, self.display_width/self.block_size - 1) * 10 
        self.rand_apple_y = random.randint(0, self.display_height/self.block_size - 1) * 10 

        while [self.rand_apple_x, self.rand_apple_y] in snake_list:
            self.rand_apple_x = random.randint(0, self.display_width/self.block_size - 1) * 10 
            self.rand_apple_y = random.randint(0, self.display_height/self.block_size - 1) * 10

    # method to get the new apple
    def update_apple_pos(self, snake_list):
        self.rand_apple_x = random.randint(0, self.display_width/self.block_size - 1) * 10 
        self.rand_apple_y = random.randint(0, self.display_height/self.block_size - 1) * 10 

        while [self.rand_apple_x, self.rand_apple_y] in snake_list:
            self.rand_apple_x = random.randint(0, self.display_width/self.block_size - 1) * 10 
            self.rand_apple_y = random.randint(0, self.display_height/self.block_size - 1) * 10

    # get the apple 
    def get_apple_pos(self):
        return self.rand_apple_x, self.rand_apple_y

    # display the apple to the pygame board
    def display(self):        
        self.gameDisplay.blit(self.apple, [self.rand_apple_x, self.rand_apple_y, self.apple_thickness,
                                 self.apple_thickness])


# this is the snake object of the snake game
class Snake:
    def __init__(self, gameDisplay, display_width, display_height, img, x, y, block_size =10):
        self.gameDisplay = gameDisplay
        self.display_width = display_width
        self.display_height = display_height
        self.head = img
        self.snake_length = 1
        self.snake_list = [[x, y]]
        self.block_size = block_size
        self.eaten = False
        self.direction = "right"

    # check if the snake is still alive
    def is_alive(self):
        if self.snake_list[-1][0] >= self.display_width or self.snake_list[-1][0] < 0 or self.snake_list[-1][1] >= self.display_height\
                or self.snake_list[-1][1] < 0:
            return False
        elif self.snake_list[-1] in self.snake_list[:-1]:
            return False
        else:
            return True

    # check if snake eats the apple
    def eat_apple(self, rand_apple_x, rand_apple_y):
        if self.snake_list[-1][0] == rand_apple_x and self.snake_list[-1][1] == rand_apple_y:
            return True
        else: 
            return False
    
    # display the score to the pygame board 
    def display_score(self):
        from app import black, pygame
        score = self.snake_length - 1
        text = pygame.font.SysFont("Comic Sans MS", 15).render("Score: " + str(score), True, black)
        self.gameDisplay.blit(text, [0, 0])

    # return the snake head position
    def get_snake_head(self):
        return self.snake_list[-1][0], self.snake_list[-1][1]

    # move the snake by one step based on the snake's direction
    def update_snake_list(self, rand_apple_x, rand_apple_y):
        if self.direction == "left":
            lead_x_change = -self.block_size
            lead_y_change = 0
        elif self.direction == "right":
            lead_x_change = self.block_size
            lead_y_change = 0
        elif self.direction == "up":
            lead_y_change = -self.block_size
            lead_x_change = 0
        elif self.direction == "down":
            lead_y_change = self.block_size
            lead_x_change = 0

        snake_head = []
        snake_head.append(self.snake_list[-1][0] + lead_x_change)
        snake_head.append(self.snake_list[-1][1] + lead_y_change)
        self.snake_list.append(snake_head)

        if self.eat_apple(rand_apple_x, rand_apple_y):
            self.snake_length += 1
            self.eaten = True

        if len(self.snake_list) > self.snake_length:
            del self.snake_list[0]

    # display the snake to the board
    def display(self):
        from app import pygame, green
        self.gameDisplay.blit(self.head, (self.snake_list[-1][0], self.snake_list[-1][1]))

        for XnY in self.snake_list[:-1]:
            pygame.draw.rect(self.gameDisplay, green,
                            [XnY[0], XnY[1], self.block_size, self.block_size])
BFS - AI Technique implementation can some one help me understand how this is being implemented on the game?
import queue

# size_x = 150
# size_y = 150
# visited = []
# target = [50, 10]
# start = [80, 70]

# based on the parent list to generate the path from start to the end
def getTrace(parent, start, end):
    path = [end]
    while path[-1] != start:
        path.append(parent[str(path[-1])])
    path.reverse()
    return path

# the BFS method to get the path from start to target
# since the BFS is one of the basic search method
# will not add detail comments to this fucntion
def bfs(size_x, size_y, block_size, visited, target, start):

    options = queue.Queue(maxsize = 0)
    options.put(start)

    parent = {}
    while options.empty() is False:
        visit = options.get()        
     
        if visit == target:
            break
        elif visit in visited:
            pass
        else:
            new_options = []
            new_options.append([visit[0] + block_size, visit[1]])
            new_options.append([visit[0] - block_size, visit[1]])
            new_options.append([visit[0], visit[1] + block_size])
            new_options.append([visit[0], visit[1] - block_size])

            visited.append(visit)
            
            for i in new_options:
                if i[0] < 0 or i[1] < 0 or i[0] >= size_x or i[1] >= size_y or i in visited:
                    pass
                else:
                    parent[str(i)] = visit
                    options.put(i)
    
    final_path = getTrace(parent, start, target)
    return final_path
Larz60+ write Jun-11-2022, 02:30 AM:
Duplicate thread. This is against forum rules. We will see your thread regardless of which forum it's posted in.
Please read: Posts to NOT make at all
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python Assignment 3 - Applied Data Science - 2.3 eyavuz21 8 4,883 Jun-06-2020, 08:59 AM
Last Post: eyavuz21
  Applied Data Science with Python - homework 2.2 (Weather plotting) eyavuz21 4 3,326 Jun-03-2020, 07:09 PM
Last Post: eyavuz21

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020