-
Notifications
You must be signed in to change notification settings - Fork 2
/
snakeself.py
157 lines (139 loc) · 4.85 KB
/
snakeself.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from pygame import display, time, draw, QUIT, init, KEYDOWN, K_a, K_s, K_d, K_w
from random import randint
import pygame
from numpy import sqrt
init()
done = False
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
cols = 25
rows = 25
width = 600
height = 600
wr = width/cols
hr = height/rows
direction = 1
screen = display.set_mode([width, height])
display.set_caption("snake_self")
clock = time.Clock()
def getpath(food1, snake1):
food1.camefrom = []
for s in snake1:
s.camefrom = []
openset = [snake1[-1]]
closedset = []
dir_array1 = []
while 1:
current1 = min(openset, key=lambda x: x.f)
openset = [openset[i] for i in range(len(openset)) if not openset[i] == current1]
closedset.append(current1)
for neighbor in current1.neighbors:
if neighbor not in closedset and not neighbor.obstrucle and neighbor not in snake1:
tempg = neighbor.g + 1
if neighbor in openset:
if tempg < neighbor.g:
neighbor.g = tempg
else:
neighbor.g = tempg
openset.append(neighbor)
neighbor.h = sqrt((neighbor.x - food1.x) ** 2 + (neighbor.y - food1.y) ** 2)
neighbor.f = neighbor.g + neighbor.h
neighbor.camefrom = current1
if current1 == food1:
break
while current1.camefrom:
if current1.x == current1.camefrom.x and current1.y < current1.camefrom.y:
dir_array1.append(2)
elif current1.x == current1.camefrom.x and current1.y > current1.camefrom.y:
dir_array1.append(0)
elif current1.x < current1.camefrom.x and current1.y == current1.camefrom.y:
dir_array1.append(3)
elif current1.x > current1.camefrom.x and current1.y == current1.camefrom.y:
dir_array1.append(1)
current1 = current1.camefrom
#print(dir_array1)
for i in range(rows):
for j in range(cols):
grid[i][j].camefrom = []
grid[i][j].f = 0
grid[i][j].h = 0
grid[i][j].g = 0
return dir_array1
class Spot:
def __init__(self, x, y):
self.x = x
self.y = y
self.f = 0
self.g = 0
self.h = 0
self.neighbors = []
self.camefrom = []
self.obstrucle = False
if randint(1, 101) < 3:
self.obstrucle = True
def show(self, color):
draw.rect(screen, color, [self.x*hr+2, self.y*wr+2, hr-4, wr-4])
def add_neighbors(self):
if self.x > 0:
self.neighbors.append(grid[self.x - 1][self.y])
if self.y > 0:
self.neighbors.append(grid[self.x][self.y - 1])
if self.x < rows - 1:
self.neighbors.append(grid[self.x + 1][self.y])
if self.y < cols - 1:
self.neighbors.append(grid[self.x][self.y + 1])
grid = [[Spot(i, j) for j in range(cols)] for i in range(rows)]
for i in range(rows):
for j in range(cols):
grid[i][j].add_neighbors()
snake = [grid[round(rows/2)][round(cols/2)]]
food = grid[randint(0, rows-1)][randint(0, cols-1)]
current = snake[-1]
dir_array = getpath(food, snake)
food_array = [food]
while not done:
clock.tick(12)
screen.fill(BLACK)
direction = dir_array.pop(-1)
if direction == 0: # down
snake.append(grid[current.x][current.y + 1])
elif direction == 1: # right
snake.append(grid[current.x + 1][current.y])
elif direction == 2: # up
snake.append(grid[current.x][current.y - 1])
elif direction == 3: # left
snake.append(grid[current.x - 1][current.y])
current = snake[-1]
if current.x == food.x and current.y == food.y:
while 1:
food = grid[randint(0, rows - 1)][randint(0, cols - 1)]
if not (food.obstrucle or food in snake):
break
food_array.append(food)
dir_array = getpath(food, snake)
else:
snake.pop(0)
for spot in snake:
spot.show(WHITE)
for i in range(rows):
for j in range(cols):
if grid[i][j].obstrucle:
grid[i][j].show(RED)
food.show(GREEN)
snake[-1].show(BLUE)
display.flip()
for event in pygame.event.get():
if event.type == QUIT:
done = True
elif event.type == KEYDOWN:
if event.key == K_w and not direction == 0:
direction = 2
elif event.key == K_a and not direction == 1:
direction = 3
elif event.key == K_s and not direction == 2:
direction = 0
elif event.key == K_d and not direction == 3:
direction = 1