Print Details From Snake Code











up vote
-1
down vote

favorite












I have found the following code online that implements a game of snake. I have edited it so that it continually prints the Manhattan distance between the snake's head and the food to the terminal. This is really important as I want to train the snake using machine learning.



Code below:



import math
import random
import pygame
import tkinter as tk
from tkinter import messagebox
import time
import sys

class cube(object):
rows = 20
w = 500
def __init__(self,start,dirnx=1,dirny=0,color=(255,0,0)):
self.pos = start
self.dirnx = 1
self.dirny = 0
self.color = color


def move(self, dirnx, dirny):
self.dirnx = dirnx
self.dirny = dirny
self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)

def draw(self, surface, eyes=False):
dis = self.w // self.rows
i = self.pos[0]
j = self.pos[1]

pygame.draw.rect(surface, self.color, (i*dis+1,j*dis+1, dis-2, dis-2))
if eyes:
centre = dis//2
radius = 3
circleMiddle = (i*dis+centre-radius,j*dis+8)
circleMiddle2 = (i*dis + dis -radius*2, j*dis+8)
pygame.draw.circle(surface, (0,0,0), circleMiddle, radius)
pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius)




class snake(object):
body =
turns = {}
def __init__(self, color, pos):
self.color = color
self.head = cube(pos)
self.body.append(self.head)
self.dirnx = 0
self.dirny = 1

def move(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()

keys = pygame.key.get_pressed()

for key in keys:
if keys[pygame.K_LEFT]:
self.dirnx = -1
self.dirny = 0
self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

elif keys[pygame.K_RIGHT]:
self.dirnx = 1
self.dirny = 0
self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

elif keys[pygame.K_UP]:
self.dirnx = 0
self.dirny = -1
self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

elif keys[pygame.K_DOWN]:
self.dirnx = 0
self.dirny = 1
self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

for i, c in enumerate(self.body):
p = c.pos[:]
if p in self.turns:
turn = self.turns[p]
c.move(turn[0],turn[1])
if i == len(self.body)-1:
self.turns.pop(p)
else:
if c.dirnx == -1 and c.pos[0] <= 0: c.pos = (c.rows-1, c.pos[1])
elif c.dirnx == 1 and c.pos[0] >= c.rows-1: c.pos = (0,c.pos[1])
elif c.dirny == 1 and c.pos[1] >= c.rows-1: c.pos = (c.pos[0], 0)
elif c.dirny == -1 and c.pos[1] <= 0: c.pos = (c.pos[0],c.rows-1)
else: c.move(c.dirnx,c.dirny)


def reset(self, pos):
self.head = cube(pos)
self.body =
self.body.append(self.head)
self.turns = {}
self.dirnx = 0
self.dirny = 1


def addCube(self):
tail = self.body[-1]
dx, dy = tail.dirnx, tail.dirny

if dx == 1 and dy == 0:
self.body.append(cube((tail.pos[0]-1,tail.pos[1])))
elif dx == -1 and dy == 0:
self.body.append(cube((tail.pos[0]+1,tail.pos[1])))
elif dx == 0 and dy == 1:
self.body.append(cube((tail.pos[0],tail.pos[1]-1)))
elif dx == 0 and dy == -1:
self.body.append(cube((tail.pos[0],tail.pos[1]+1)))

self.body[-1].dirnx = dx
self.body[-1].dirny = dy


def draw(self, surface):
for i, c in enumerate(self.body):
if i ==0:
c.draw(surface, True)
else:
c.draw(surface)



def drawGrid(w, rows, surface):
sizeBtwn = w // rows

x = 0
y = 0
for l in range(rows):
x = x + sizeBtwn
y = y + sizeBtwn

pygame.draw.line(surface, (255,255,255), (x,0),(x,w))
pygame.draw.line(surface, (255,255,255), (0,y),(w,y))


def redrawWindow(surface):
global rows, width, s, snack
surface.fill((0,0,0))
s.draw(surface)
snack.draw(surface)
drawGrid(width,rows, surface)
pygame.display.update()


def randomSnack(rows, item):

positions = item.body

while True:
x = random.randrange(rows)
y = random.randrange(rows)
if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
continue
else:
break

return (x,y)


def message_box(subject, content):
root = tk.Tk()
root.attributes("-topmost", True)
root.withdraw()
messagebox.showinfo(subject, content)
try:
root.destroy()
except:
pass


def game():
global width, rows, s, snack
width = 500
rows = 20
win = pygame.display.set_mode((width, width))
s = snake((255,0,0), (10,10))
snack = cube(randomSnack(rows, s), color=(0,255,0))
flag = True

clock = pygame.time.Clock()
start = time.time()




while True:


pygame.time.delay(50)
clock.tick(10)
s.move()
#print("Snack pos: {}".format(snack.pos))
#print("Snake pos: {}".format(s.body[0].pos))
print("Manhattan distance to snack: {}".format(abs(snack.pos[0] - s.body[0].pos[0]) + abs(snack.pos[1] - s.body[0].pos[1])))
if s.body[0].pos == snack.pos:
s.addCube()
snack = cube(randomSnack(rows, s), color=(0,255,0))



for x in range(len(s.body)):
if s.body[x].pos in list(map(lambda z:z.pos,s.body[x+1:])):
print("n Score: {}".format(len(s.body)))
print("Food collection rate: {} meals/sec".format(round((len(s.body))/(time.time()-start), 2)))
message_box("n You Lost!", "n Play again...n")
s.reset((10,10))
break


redrawWindow(win)


pass


The problem I am having is that I want to be able to run many "episodes" of training and store data from each of them. I have a separate script which should hopefully run repeated games until the snake has died a specified number of times (at the moment everything is human controlled - no machine learning yet!).



I am having difficulty implementing this. Here is my other script (snake_game is the name of the first script btw):



from snake_game import game
import random
import logging #cannot print as these will be interpreted as commands
import math
import numpy as np
import time

episodes = 2

# Create lookup tables and initialise everything to zero
#q_lookup_table = np.zeros((20,20))
#print(q_lookup_table)

# Loop over the required number of episodes
for e in range(episodes):
g = game()
print("Manhattand distance: {}".format(g.manhattan_distance()))

print("Done")


My intention is that when I execute this second script, I should then be able to play two games by myself. After I have died twice, the system should shut down. Instead what happens is that the game plays for two frames and then quits which is really annoying.



I have found a workaround which is to give the game function in the first script an episodes parameter. Then I just have a counter that increments for each new game and when we have equality the system exits. Whilst this works, it is not ideal as it puts control of the number of episodes in the game script and I really need to be able to control that with my machine learning script e.g. I will want to log data episode by episode and if this is left in the first script, all the code for that will need to be packaged in there as well.



Any suggestions on how to do this?



Secondly, I will also need (at a later stage) to be able to pull the snake's direction of travel from previous square to current square (this will need to be eliminated from available next moves) and I'm not clear how I can go about doing this?



Thanks and sorry if this is quite basic - I'm still finding my feet with Python.









share







New contributor




user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    -1
    down vote

    favorite












    I have found the following code online that implements a game of snake. I have edited it so that it continually prints the Manhattan distance between the snake's head and the food to the terminal. This is really important as I want to train the snake using machine learning.



    Code below:



    import math
    import random
    import pygame
    import tkinter as tk
    from tkinter import messagebox
    import time
    import sys

    class cube(object):
    rows = 20
    w = 500
    def __init__(self,start,dirnx=1,dirny=0,color=(255,0,0)):
    self.pos = start
    self.dirnx = 1
    self.dirny = 0
    self.color = color


    def move(self, dirnx, dirny):
    self.dirnx = dirnx
    self.dirny = dirny
    self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)

    def draw(self, surface, eyes=False):
    dis = self.w // self.rows
    i = self.pos[0]
    j = self.pos[1]

    pygame.draw.rect(surface, self.color, (i*dis+1,j*dis+1, dis-2, dis-2))
    if eyes:
    centre = dis//2
    radius = 3
    circleMiddle = (i*dis+centre-radius,j*dis+8)
    circleMiddle2 = (i*dis + dis -radius*2, j*dis+8)
    pygame.draw.circle(surface, (0,0,0), circleMiddle, radius)
    pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius)




    class snake(object):
    body =
    turns = {}
    def __init__(self, color, pos):
    self.color = color
    self.head = cube(pos)
    self.body.append(self.head)
    self.dirnx = 0
    self.dirny = 1

    def move(self):
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    pygame.quit()

    keys = pygame.key.get_pressed()

    for key in keys:
    if keys[pygame.K_LEFT]:
    self.dirnx = -1
    self.dirny = 0
    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

    elif keys[pygame.K_RIGHT]:
    self.dirnx = 1
    self.dirny = 0
    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

    elif keys[pygame.K_UP]:
    self.dirnx = 0
    self.dirny = -1
    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

    elif keys[pygame.K_DOWN]:
    self.dirnx = 0
    self.dirny = 1
    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

    for i, c in enumerate(self.body):
    p = c.pos[:]
    if p in self.turns:
    turn = self.turns[p]
    c.move(turn[0],turn[1])
    if i == len(self.body)-1:
    self.turns.pop(p)
    else:
    if c.dirnx == -1 and c.pos[0] <= 0: c.pos = (c.rows-1, c.pos[1])
    elif c.dirnx == 1 and c.pos[0] >= c.rows-1: c.pos = (0,c.pos[1])
    elif c.dirny == 1 and c.pos[1] >= c.rows-1: c.pos = (c.pos[0], 0)
    elif c.dirny == -1 and c.pos[1] <= 0: c.pos = (c.pos[0],c.rows-1)
    else: c.move(c.dirnx,c.dirny)


    def reset(self, pos):
    self.head = cube(pos)
    self.body =
    self.body.append(self.head)
    self.turns = {}
    self.dirnx = 0
    self.dirny = 1


    def addCube(self):
    tail = self.body[-1]
    dx, dy = tail.dirnx, tail.dirny

    if dx == 1 and dy == 0:
    self.body.append(cube((tail.pos[0]-1,tail.pos[1])))
    elif dx == -1 and dy == 0:
    self.body.append(cube((tail.pos[0]+1,tail.pos[1])))
    elif dx == 0 and dy == 1:
    self.body.append(cube((tail.pos[0],tail.pos[1]-1)))
    elif dx == 0 and dy == -1:
    self.body.append(cube((tail.pos[0],tail.pos[1]+1)))

    self.body[-1].dirnx = dx
    self.body[-1].dirny = dy


    def draw(self, surface):
    for i, c in enumerate(self.body):
    if i ==0:
    c.draw(surface, True)
    else:
    c.draw(surface)



    def drawGrid(w, rows, surface):
    sizeBtwn = w // rows

    x = 0
    y = 0
    for l in range(rows):
    x = x + sizeBtwn
    y = y + sizeBtwn

    pygame.draw.line(surface, (255,255,255), (x,0),(x,w))
    pygame.draw.line(surface, (255,255,255), (0,y),(w,y))


    def redrawWindow(surface):
    global rows, width, s, snack
    surface.fill((0,0,0))
    s.draw(surface)
    snack.draw(surface)
    drawGrid(width,rows, surface)
    pygame.display.update()


    def randomSnack(rows, item):

    positions = item.body

    while True:
    x = random.randrange(rows)
    y = random.randrange(rows)
    if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
    continue
    else:
    break

    return (x,y)


    def message_box(subject, content):
    root = tk.Tk()
    root.attributes("-topmost", True)
    root.withdraw()
    messagebox.showinfo(subject, content)
    try:
    root.destroy()
    except:
    pass


    def game():
    global width, rows, s, snack
    width = 500
    rows = 20
    win = pygame.display.set_mode((width, width))
    s = snake((255,0,0), (10,10))
    snack = cube(randomSnack(rows, s), color=(0,255,0))
    flag = True

    clock = pygame.time.Clock()
    start = time.time()




    while True:


    pygame.time.delay(50)
    clock.tick(10)
    s.move()
    #print("Snack pos: {}".format(snack.pos))
    #print("Snake pos: {}".format(s.body[0].pos))
    print("Manhattan distance to snack: {}".format(abs(snack.pos[0] - s.body[0].pos[0]) + abs(snack.pos[1] - s.body[0].pos[1])))
    if s.body[0].pos == snack.pos:
    s.addCube()
    snack = cube(randomSnack(rows, s), color=(0,255,0))



    for x in range(len(s.body)):
    if s.body[x].pos in list(map(lambda z:z.pos,s.body[x+1:])):
    print("n Score: {}".format(len(s.body)))
    print("Food collection rate: {} meals/sec".format(round((len(s.body))/(time.time()-start), 2)))
    message_box("n You Lost!", "n Play again...n")
    s.reset((10,10))
    break


    redrawWindow(win)


    pass


    The problem I am having is that I want to be able to run many "episodes" of training and store data from each of them. I have a separate script which should hopefully run repeated games until the snake has died a specified number of times (at the moment everything is human controlled - no machine learning yet!).



    I am having difficulty implementing this. Here is my other script (snake_game is the name of the first script btw):



    from snake_game import game
    import random
    import logging #cannot print as these will be interpreted as commands
    import math
    import numpy as np
    import time

    episodes = 2

    # Create lookup tables and initialise everything to zero
    #q_lookup_table = np.zeros((20,20))
    #print(q_lookup_table)

    # Loop over the required number of episodes
    for e in range(episodes):
    g = game()
    print("Manhattand distance: {}".format(g.manhattan_distance()))

    print("Done")


    My intention is that when I execute this second script, I should then be able to play two games by myself. After I have died twice, the system should shut down. Instead what happens is that the game plays for two frames and then quits which is really annoying.



    I have found a workaround which is to give the game function in the first script an episodes parameter. Then I just have a counter that increments for each new game and when we have equality the system exits. Whilst this works, it is not ideal as it puts control of the number of episodes in the game script and I really need to be able to control that with my machine learning script e.g. I will want to log data episode by episode and if this is left in the first script, all the code for that will need to be packaged in there as well.



    Any suggestions on how to do this?



    Secondly, I will also need (at a later stage) to be able to pull the snake's direction of travel from previous square to current square (this will need to be eliminated from available next moves) and I'm not clear how I can go about doing this?



    Thanks and sorry if this is quite basic - I'm still finding my feet with Python.









    share







    New contributor




    user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      -1
      down vote

      favorite









      up vote
      -1
      down vote

      favorite











      I have found the following code online that implements a game of snake. I have edited it so that it continually prints the Manhattan distance between the snake's head and the food to the terminal. This is really important as I want to train the snake using machine learning.



      Code below:



      import math
      import random
      import pygame
      import tkinter as tk
      from tkinter import messagebox
      import time
      import sys

      class cube(object):
      rows = 20
      w = 500
      def __init__(self,start,dirnx=1,dirny=0,color=(255,0,0)):
      self.pos = start
      self.dirnx = 1
      self.dirny = 0
      self.color = color


      def move(self, dirnx, dirny):
      self.dirnx = dirnx
      self.dirny = dirny
      self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)

      def draw(self, surface, eyes=False):
      dis = self.w // self.rows
      i = self.pos[0]
      j = self.pos[1]

      pygame.draw.rect(surface, self.color, (i*dis+1,j*dis+1, dis-2, dis-2))
      if eyes:
      centre = dis//2
      radius = 3
      circleMiddle = (i*dis+centre-radius,j*dis+8)
      circleMiddle2 = (i*dis + dis -radius*2, j*dis+8)
      pygame.draw.circle(surface, (0,0,0), circleMiddle, radius)
      pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius)




      class snake(object):
      body =
      turns = {}
      def __init__(self, color, pos):
      self.color = color
      self.head = cube(pos)
      self.body.append(self.head)
      self.dirnx = 0
      self.dirny = 1

      def move(self):
      for event in pygame.event.get():
      if event.type == pygame.QUIT:
      pygame.quit()

      keys = pygame.key.get_pressed()

      for key in keys:
      if keys[pygame.K_LEFT]:
      self.dirnx = -1
      self.dirny = 0
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      elif keys[pygame.K_RIGHT]:
      self.dirnx = 1
      self.dirny = 0
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      elif keys[pygame.K_UP]:
      self.dirnx = 0
      self.dirny = -1
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      elif keys[pygame.K_DOWN]:
      self.dirnx = 0
      self.dirny = 1
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      for i, c in enumerate(self.body):
      p = c.pos[:]
      if p in self.turns:
      turn = self.turns[p]
      c.move(turn[0],turn[1])
      if i == len(self.body)-1:
      self.turns.pop(p)
      else:
      if c.dirnx == -1 and c.pos[0] <= 0: c.pos = (c.rows-1, c.pos[1])
      elif c.dirnx == 1 and c.pos[0] >= c.rows-1: c.pos = (0,c.pos[1])
      elif c.dirny == 1 and c.pos[1] >= c.rows-1: c.pos = (c.pos[0], 0)
      elif c.dirny == -1 and c.pos[1] <= 0: c.pos = (c.pos[0],c.rows-1)
      else: c.move(c.dirnx,c.dirny)


      def reset(self, pos):
      self.head = cube(pos)
      self.body =
      self.body.append(self.head)
      self.turns = {}
      self.dirnx = 0
      self.dirny = 1


      def addCube(self):
      tail = self.body[-1]
      dx, dy = tail.dirnx, tail.dirny

      if dx == 1 and dy == 0:
      self.body.append(cube((tail.pos[0]-1,tail.pos[1])))
      elif dx == -1 and dy == 0:
      self.body.append(cube((tail.pos[0]+1,tail.pos[1])))
      elif dx == 0 and dy == 1:
      self.body.append(cube((tail.pos[0],tail.pos[1]-1)))
      elif dx == 0 and dy == -1:
      self.body.append(cube((tail.pos[0],tail.pos[1]+1)))

      self.body[-1].dirnx = dx
      self.body[-1].dirny = dy


      def draw(self, surface):
      for i, c in enumerate(self.body):
      if i ==0:
      c.draw(surface, True)
      else:
      c.draw(surface)



      def drawGrid(w, rows, surface):
      sizeBtwn = w // rows

      x = 0
      y = 0
      for l in range(rows):
      x = x + sizeBtwn
      y = y + sizeBtwn

      pygame.draw.line(surface, (255,255,255), (x,0),(x,w))
      pygame.draw.line(surface, (255,255,255), (0,y),(w,y))


      def redrawWindow(surface):
      global rows, width, s, snack
      surface.fill((0,0,0))
      s.draw(surface)
      snack.draw(surface)
      drawGrid(width,rows, surface)
      pygame.display.update()


      def randomSnack(rows, item):

      positions = item.body

      while True:
      x = random.randrange(rows)
      y = random.randrange(rows)
      if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
      continue
      else:
      break

      return (x,y)


      def message_box(subject, content):
      root = tk.Tk()
      root.attributes("-topmost", True)
      root.withdraw()
      messagebox.showinfo(subject, content)
      try:
      root.destroy()
      except:
      pass


      def game():
      global width, rows, s, snack
      width = 500
      rows = 20
      win = pygame.display.set_mode((width, width))
      s = snake((255,0,0), (10,10))
      snack = cube(randomSnack(rows, s), color=(0,255,0))
      flag = True

      clock = pygame.time.Clock()
      start = time.time()




      while True:


      pygame.time.delay(50)
      clock.tick(10)
      s.move()
      #print("Snack pos: {}".format(snack.pos))
      #print("Snake pos: {}".format(s.body[0].pos))
      print("Manhattan distance to snack: {}".format(abs(snack.pos[0] - s.body[0].pos[0]) + abs(snack.pos[1] - s.body[0].pos[1])))
      if s.body[0].pos == snack.pos:
      s.addCube()
      snack = cube(randomSnack(rows, s), color=(0,255,0))



      for x in range(len(s.body)):
      if s.body[x].pos in list(map(lambda z:z.pos,s.body[x+1:])):
      print("n Score: {}".format(len(s.body)))
      print("Food collection rate: {} meals/sec".format(round((len(s.body))/(time.time()-start), 2)))
      message_box("n You Lost!", "n Play again...n")
      s.reset((10,10))
      break


      redrawWindow(win)


      pass


      The problem I am having is that I want to be able to run many "episodes" of training and store data from each of them. I have a separate script which should hopefully run repeated games until the snake has died a specified number of times (at the moment everything is human controlled - no machine learning yet!).



      I am having difficulty implementing this. Here is my other script (snake_game is the name of the first script btw):



      from snake_game import game
      import random
      import logging #cannot print as these will be interpreted as commands
      import math
      import numpy as np
      import time

      episodes = 2

      # Create lookup tables and initialise everything to zero
      #q_lookup_table = np.zeros((20,20))
      #print(q_lookup_table)

      # Loop over the required number of episodes
      for e in range(episodes):
      g = game()
      print("Manhattand distance: {}".format(g.manhattan_distance()))

      print("Done")


      My intention is that when I execute this second script, I should then be able to play two games by myself. After I have died twice, the system should shut down. Instead what happens is that the game plays for two frames and then quits which is really annoying.



      I have found a workaround which is to give the game function in the first script an episodes parameter. Then I just have a counter that increments for each new game and when we have equality the system exits. Whilst this works, it is not ideal as it puts control of the number of episodes in the game script and I really need to be able to control that with my machine learning script e.g. I will want to log data episode by episode and if this is left in the first script, all the code for that will need to be packaged in there as well.



      Any suggestions on how to do this?



      Secondly, I will also need (at a later stage) to be able to pull the snake's direction of travel from previous square to current square (this will need to be eliminated from available next moves) and I'm not clear how I can go about doing this?



      Thanks and sorry if this is quite basic - I'm still finding my feet with Python.









      share







      New contributor




      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I have found the following code online that implements a game of snake. I have edited it so that it continually prints the Manhattan distance between the snake's head and the food to the terminal. This is really important as I want to train the snake using machine learning.



      Code below:



      import math
      import random
      import pygame
      import tkinter as tk
      from tkinter import messagebox
      import time
      import sys

      class cube(object):
      rows = 20
      w = 500
      def __init__(self,start,dirnx=1,dirny=0,color=(255,0,0)):
      self.pos = start
      self.dirnx = 1
      self.dirny = 0
      self.color = color


      def move(self, dirnx, dirny):
      self.dirnx = dirnx
      self.dirny = dirny
      self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)

      def draw(self, surface, eyes=False):
      dis = self.w // self.rows
      i = self.pos[0]
      j = self.pos[1]

      pygame.draw.rect(surface, self.color, (i*dis+1,j*dis+1, dis-2, dis-2))
      if eyes:
      centre = dis//2
      radius = 3
      circleMiddle = (i*dis+centre-radius,j*dis+8)
      circleMiddle2 = (i*dis + dis -radius*2, j*dis+8)
      pygame.draw.circle(surface, (0,0,0), circleMiddle, radius)
      pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius)




      class snake(object):
      body =
      turns = {}
      def __init__(self, color, pos):
      self.color = color
      self.head = cube(pos)
      self.body.append(self.head)
      self.dirnx = 0
      self.dirny = 1

      def move(self):
      for event in pygame.event.get():
      if event.type == pygame.QUIT:
      pygame.quit()

      keys = pygame.key.get_pressed()

      for key in keys:
      if keys[pygame.K_LEFT]:
      self.dirnx = -1
      self.dirny = 0
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      elif keys[pygame.K_RIGHT]:
      self.dirnx = 1
      self.dirny = 0
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      elif keys[pygame.K_UP]:
      self.dirnx = 0
      self.dirny = -1
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      elif keys[pygame.K_DOWN]:
      self.dirnx = 0
      self.dirny = 1
      self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

      for i, c in enumerate(self.body):
      p = c.pos[:]
      if p in self.turns:
      turn = self.turns[p]
      c.move(turn[0],turn[1])
      if i == len(self.body)-1:
      self.turns.pop(p)
      else:
      if c.dirnx == -1 and c.pos[0] <= 0: c.pos = (c.rows-1, c.pos[1])
      elif c.dirnx == 1 and c.pos[0] >= c.rows-1: c.pos = (0,c.pos[1])
      elif c.dirny == 1 and c.pos[1] >= c.rows-1: c.pos = (c.pos[0], 0)
      elif c.dirny == -1 and c.pos[1] <= 0: c.pos = (c.pos[0],c.rows-1)
      else: c.move(c.dirnx,c.dirny)


      def reset(self, pos):
      self.head = cube(pos)
      self.body =
      self.body.append(self.head)
      self.turns = {}
      self.dirnx = 0
      self.dirny = 1


      def addCube(self):
      tail = self.body[-1]
      dx, dy = tail.dirnx, tail.dirny

      if dx == 1 and dy == 0:
      self.body.append(cube((tail.pos[0]-1,tail.pos[1])))
      elif dx == -1 and dy == 0:
      self.body.append(cube((tail.pos[0]+1,tail.pos[1])))
      elif dx == 0 and dy == 1:
      self.body.append(cube((tail.pos[0],tail.pos[1]-1)))
      elif dx == 0 and dy == -1:
      self.body.append(cube((tail.pos[0],tail.pos[1]+1)))

      self.body[-1].dirnx = dx
      self.body[-1].dirny = dy


      def draw(self, surface):
      for i, c in enumerate(self.body):
      if i ==0:
      c.draw(surface, True)
      else:
      c.draw(surface)



      def drawGrid(w, rows, surface):
      sizeBtwn = w // rows

      x = 0
      y = 0
      for l in range(rows):
      x = x + sizeBtwn
      y = y + sizeBtwn

      pygame.draw.line(surface, (255,255,255), (x,0),(x,w))
      pygame.draw.line(surface, (255,255,255), (0,y),(w,y))


      def redrawWindow(surface):
      global rows, width, s, snack
      surface.fill((0,0,0))
      s.draw(surface)
      snack.draw(surface)
      drawGrid(width,rows, surface)
      pygame.display.update()


      def randomSnack(rows, item):

      positions = item.body

      while True:
      x = random.randrange(rows)
      y = random.randrange(rows)
      if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
      continue
      else:
      break

      return (x,y)


      def message_box(subject, content):
      root = tk.Tk()
      root.attributes("-topmost", True)
      root.withdraw()
      messagebox.showinfo(subject, content)
      try:
      root.destroy()
      except:
      pass


      def game():
      global width, rows, s, snack
      width = 500
      rows = 20
      win = pygame.display.set_mode((width, width))
      s = snake((255,0,0), (10,10))
      snack = cube(randomSnack(rows, s), color=(0,255,0))
      flag = True

      clock = pygame.time.Clock()
      start = time.time()




      while True:


      pygame.time.delay(50)
      clock.tick(10)
      s.move()
      #print("Snack pos: {}".format(snack.pos))
      #print("Snake pos: {}".format(s.body[0].pos))
      print("Manhattan distance to snack: {}".format(abs(snack.pos[0] - s.body[0].pos[0]) + abs(snack.pos[1] - s.body[0].pos[1])))
      if s.body[0].pos == snack.pos:
      s.addCube()
      snack = cube(randomSnack(rows, s), color=(0,255,0))



      for x in range(len(s.body)):
      if s.body[x].pos in list(map(lambda z:z.pos,s.body[x+1:])):
      print("n Score: {}".format(len(s.body)))
      print("Food collection rate: {} meals/sec".format(round((len(s.body))/(time.time()-start), 2)))
      message_box("n You Lost!", "n Play again...n")
      s.reset((10,10))
      break


      redrawWindow(win)


      pass


      The problem I am having is that I want to be able to run many "episodes" of training and store data from each of them. I have a separate script which should hopefully run repeated games until the snake has died a specified number of times (at the moment everything is human controlled - no machine learning yet!).



      I am having difficulty implementing this. Here is my other script (snake_game is the name of the first script btw):



      from snake_game import game
      import random
      import logging #cannot print as these will be interpreted as commands
      import math
      import numpy as np
      import time

      episodes = 2

      # Create lookup tables and initialise everything to zero
      #q_lookup_table = np.zeros((20,20))
      #print(q_lookup_table)

      # Loop over the required number of episodes
      for e in range(episodes):
      g = game()
      print("Manhattand distance: {}".format(g.manhattan_distance()))

      print("Done")


      My intention is that when I execute this second script, I should then be able to play two games by myself. After I have died twice, the system should shut down. Instead what happens is that the game plays for two frames and then quits which is really annoying.



      I have found a workaround which is to give the game function in the first script an episodes parameter. Then I just have a counter that increments for each new game and when we have equality the system exits. Whilst this works, it is not ideal as it puts control of the number of episodes in the game script and I really need to be able to control that with my machine learning script e.g. I will want to log data episode by episode and if this is left in the first script, all the code for that will need to be packaged in there as well.



      Any suggestions on how to do this?



      Secondly, I will also need (at a later stage) to be able to pull the snake's direction of travel from previous square to current square (this will need to be eliminated from available next moves) and I'm not clear how I can go about doing this?



      Thanks and sorry if this is quite basic - I'm still finding my feet with Python.







      object-oriented pygame





      share







      New contributor




      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share







      New contributor




      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share



      share






      New contributor




      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 6 mins ago









      user11128

      991




      991




      New contributor




      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      user11128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



























          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          user11128 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209760%2fprint-details-from-snake-code%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          user11128 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          user11128 is a new contributor. Be nice, and check out our Code of Conduct.













          user11128 is a new contributor. Be nice, and check out our Code of Conduct.












          user11128 is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209760%2fprint-details-from-snake-code%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Quarter-circle Tiles

          build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

          Mont Emei