From 0fa109ef35c3d432e1d7b9d21d366b30e0f068b4 Mon Sep 17 00:00:00 2001 From: Marcin Dobrowolski Date: Mon, 27 Apr 2020 21:56:17 +0200 Subject: [PATCH] 3rd part AStar implementation --- main.py | 30 +++- src/__pycache__/matrix.cpython-38.pyc | Bin 2021 -> 2021 bytes src/__pycache__/tile.cpython-38.pyc | Bin 869 -> 942 bytes src/__pycache__/waiter.cpython-38.pyc | Bin 3598 -> 4471 bytes src/tile.py | 2 +- src/waiter.py | 225 +++++++++++++++++++------- 6 files changed, 189 insertions(+), 68 deletions(-) diff --git a/main.py b/main.py index 89e16cc..35c974d 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ import sys +import secrets from src.graphics import * from src.waiter import * @@ -7,15 +8,17 @@ if __name__ == "__main__": # SETUP pygame.init() clock = pygame.time.Clock() - fps = 40 + fps = 2 graphics = Graphics() waiter = Waiter(graphics) # init functions graphics.drawBackground(waiter.matrix) graphics.update(waiter.X, waiter.Y) - print(waiter.findPath((1, 10))) + goal = None + path = [(0, 0)] + # print(waiter.findPath()) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -29,9 +32,26 @@ if __name__ == "__main__": sys.exit() break - graphics.clear(waiter.X, waiter.Y) + if event.key == pygame.K_r: + temp = False + while not temp: + x = secrets.randbelow(graphics.width) + y = secrets.randbelow(graphics.height) + + if waiter.matrix.matrix[x][y].walk_through == 1: + temp = True + + goal = (x, y) + path = waiter.findPath(goal) + + if path != []: + temp = path.pop(0) + print(temp) + waiter.travel(temp, graphics) + + #graphics.clear(waiter.X, waiter.Y) + #waiter.update(event, graphics) + #graphics.update(waiter.X, waiter.Y) - waiter.update(event, graphics) - graphics.update(waiter.X, waiter.Y) pygame.display.flip() clock.tick(fps) diff --git a/src/__pycache__/matrix.cpython-38.pyc b/src/__pycache__/matrix.cpython-38.pyc index d25964548a24e1c8386dbb212202cf61540f6d73..c6374d3827fb9aa0cf81197fdefc13a65ed78d89 100644 GIT binary patch delta 26 gcmaFL|CFCQl$V!_0SH(>FWbnyke%_?+Ha0AzIsp#T5? diff --git a/src/__pycache__/tile.cpython-38.pyc b/src/__pycache__/tile.cpython-38.pyc index 9e713a27cdc556699693f3809a36ce4a3033194a..d1bbc21e8899905face3e85759646643caa5e8bf 100644 GIT binary patch delta 293 zcmaFLwvL@Il$V!_0SNYpEst|xnaDSRalyp-3c+DD3|R~*%-KxEQD7DeoW%-fvB6pF za27{4Q&C0=XAMI9SGY~TX0G%y0hX4Qo diff --git a/src/__pycache__/waiter.cpython-38.pyc b/src/__pycache__/waiter.cpython-38.pyc index 3cbbe93b6fe1b72e3c17767f820c98e0d04bb26f..ddb113712aa9cd57e9727fe2662dd56aaf5fbfdf 100644 GIT binary patch literal 4471 zcma)AO^h5z6|SnT?&P*vjkW6!z=f?p;ON^t_kJ3ty8k{#@_K(5 zbqP896PR2;OI}46v4ATU2*s5ELq|DE;w!Dlz%2xMs;(M<*Hlxr@b%RK1TW^^8(}|< zbeDLRKN^#P7txZ}(4}m^2V&pJ*a3%WJYyYcde`(`TFW5)BZB)1RGoU-$XLb(63x9s zkfvggC)aghqra)caj)M^a{j}1EBD5?HpA^G_mZ)OKDl?ze*I3TANSKvC+BbG{O7rQ zLxW5^P%8Jfjhphi>g%YR_D8WMt#g^eX>F0qBpTk(9zcI!`f+^zv$6Ji66s`ZJJj8N ztVZwY(aq5?+3K%diju8#G+x`dmG(yQ+O@rO(%p;0&X40X8umA%xH||tFP(kq>{_C` zYd4M0UL4=jO|Y$_C5z}7U*w+oYoXseVO{%TX+oE@D}OY0(TtDpVnCi8u#7(m*E?*B z>(iMtfLB*&d^^TAir+CbA`=zOCD1r?G(RA(@4F>0d=349P-08y+Zni%l$V)c9YhE- z;LS{!2st)Fn)X23(=B{*_hw(EJ-t9uk)r{J-@X5lBob}6#ukH(dcTG%+)WgJ$llXb?PlV-QE z`1=MTfjgsMdxyo(8i)(Xc_j>F$v_-hudpv+Jy#xPA6MLZ#o9w|dj<3nyA zTmIly+Y4<6!YqbT$eaQY;=wqs%xH2ZOq>WMuxbV81X%A1T; zm`1BWCFjsF?(@c6^X6uR_0Sp!XxUnPZ=ndScuLX zB5($Vu&**eaUAG7bvD^lqPdwwQWBJuQkls+v_0f~M{i_u;HI8(J^}_bHN_A3)XQ8@ zdqkai8Eu45!K0RWQ$O<++p6o|W;Iaw1K-g2gZk9p$+8;qI|BDBXB8<7E9#jyK;B-( zk==3;oO@;t%@htM^e{RT{tn+_z&~GDQLKU;G%Dy<*`PsN+0fM~#TttrL2Gp{SFapu z@W@pw@K+__UiP&Th_;eI_RZL1Y!O;kx|8iRpOZ{04(+QX6Wv!NAElj_T-YY`?h%Q* zMhw3)g1o}9L_X4XPPgubi9w87bZvGWPq-ONTx z=+9^sARk~KH9NE)nq&>e&9p^H3K})-9$CRIFfhd1!0;uQp~$8Ku`pX*j$%O48gJkH&#N9wmLcYH?$SI*L>MB)A3j zBn@?H$-?)Npx%onx}T)|ZeCAI4(&yILCDQfI4qW|k5m-+1hAtKbhv_rL8ChyC6O}Y zW_O}V7Lnv~9HzazR)7M(+v^V%us}q5J8;cBXxil$2^sjrl@=e(a{die0UO}=3XDi@ zqhro8UvVUtq9GP}OCX~;KF1u{u7$QJq*&so`SXCBdML$mIdY!jOVxOJW{j1BvZLe; za3jthI0?S=Q1Io4o>&BSh4>fPs%$8Ao6DM%F{{$--?*gdG@$Vt!emP^b+8{~#xG$P zy!~fnNR$W2bbrcFn_>sL)MLJjxx@*V*m*9E0DCh-(fBeltMaDEsusU;i2nlk8sXy& zi>+3EVYwIFtb|WN?Hg`&!wpa+4L6G?ZViKPPM!M#7q+A7CJ)}W+)7=M8PAm39BK=w zUr9JtUr>Bd$$($ttMgjpeE;LCdSlgFSY_-iv4>ilHKmtGZypbzH_8ZLUa|BudjHi* zob@vJ|8a)DiNT?d!Q~vVHVUNk&n$=1(~r&`{k*^wN~X&l#As zu$||MyKArYi|OeXP8XdCt9}|v>TjZJ`}%wMM5R$I|2pbPPG1g6SjExA+o*+j4wS z)w`B@y1>bGWJu#yr?WE&hZbWVk)}M?q^3Sg9hs)-TAI=1ahlRg zN>kYA4VBP_h87Lq^Pl!N{C5qeOKus*Ti#a~uz-LB|5%C?s z{)?92k^u)z^LAa6R9iaG>&&jC3rW)}SkpgEj0%Q)hGnIC?!RiiaGsP(XaRi3TXOlA GZ1O*qsH-CY literal 3598 zcmai1&2QX96rZujUVC?whBj&wgsM;#!AezAReXpFRh61Tt3rrqtAYi%%Z{7%?q`l|F$cl8nWu7DXHP&!!;-l&R6#2VqrM`mGm#)j4I>kA z(7UZ{fPQ7_2!_W?^Ecu^#q%po)e8GE`btH2qh8z%=NE#wn?!^8rS+s8_2;i`Bx|jW ze$&6wPl8^!9Q0eArhoR#*)#L8YR%u(F*`k2S2c)r(c(#Tj8Ae~|JBiN9Lhs`dgMZj ztQ&nax6pKqzsH0k*zhRnJf%A~C(Xl}QIaJikR zL$s*hZT7l8P|@0QyCKwJ0`hwqU)N#RLC?Es!ibgVPCy$GJLnj{%#R~t8?_=%gl*Bz zjy{@?WAru>C*>WMAQQXB7FTDnGO-fy>lXY(E@E~{8pt-Q|E7kRfSi}eLO@Pv2vINP zx!a%85Q@t!owZgW(FWxAvBa+n{#}V%g^pc`Kj-`~zXDzK)#Bf)B?}BIZmEA%n%YveOzU;)El#Gh*Z%qE&&4+$Bo9Jxy*(F%}NC> zJ%cX2M5JO9bX~D!saI0bu@YOF4}bwpMe=Pvv{MVzwx)I@s0p{gzBoLrBu-lCxU}I9 zuqmte5^R{pTl?aFOzo7?;a}L`r1sEFUCFwx`a5-?!R@%D17mgQuKtlacyE|=zB6aB z+2E+AHgv%wSZg75{?coBCUJ4V5A8GIH+h!<-!7t1a3KyfE9hsDNOW~*x+*;ZI%3bE z)pm`!XLc=kF4qj=J=XA7`a%svJJvw{mHg4ZnCfKN_Gf%G)aQHcCkfB-muR1{Wrcy+Sb{~KDYNFL1O%ze`_o;}MxyHT_-2oa3=~bNYpN6%R zPWtq)p4QSjPLojgx5TP$h*h2TEv@;$<|h}=x<0|!1@{Or`FYe(?0pW^923A1*Mwe8 z>ig!z5YTi&Yk8#c6P>#D?Gbe9rth^Hc@N0O>UsT4RLf64SFhp%-EgZP4}$)OVVpeX zb0|Q~pf5M-)r-9-4&)rc)p5}6=yKtZt_pVFg3N9Xz%4Vg7xYn%MJmba%RzEIN}9ck zQJiGvAR4IGARu!FQ5;eYhf=Vq=;=5Hu;<1}Qzb;}x$R(0L1Ea+++-x7F{z&$Pb^2x zUO~MW$-r|6kk6vR1FzcBW|P%kt+l2|4Uwpq$O18FChe?Jz&)qc4to+Lo~38t(A*aZ z>^US<^HM!is&Sm#C@hyC>0Q9%pU^R5n$MVm3!`e}4_(!8@Yqe|z3Fh^u&$#`8iG&p zIsOJ9$Dasr7Blk|Ku-aBLPJNhsWE=~0K6mg^J>)jQGWD^ZA==DF~c2mT&0feUTjn{ zRNZ})*{Hg!zP}R5wI0puzQ4NG?By6;`RWoty-pE$i@M!d=ouA#ir!!45 diff --git a/src/tile.py b/src/tile.py index a4c0d88..a9a6eae 100644 --- a/src/tile.py +++ b/src/tile.py @@ -6,7 +6,7 @@ class Tile: if self.type == 'wall': self.watch_through = 0 self.walk_through = 0 - elif self.type == 'table' or self.type == 'bar' or self.type == 'chair': + elif self.type == 'table' or self.type == 'bar' or self.type == 'chair_front' or self.type == 'chair_back' or self.type == 'chair_left' or self.type == 'chair_right': self.watch_through = 1 self.walk_through = 0 else: diff --git a/src/waiter.py b/src/waiter.py index 9230a1d..213e8a9 100644 --- a/src/waiter.py +++ b/src/waiter.py @@ -22,39 +22,39 @@ class Waiter(pygame.sprite.Sprite): self.X += x self.Y += y - def update(self, event, graphics): - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_RIGHT: - if self.direction == 'N': - self.direction = 'W' - elif self.direction == 'S': - self.direction = 'E' - elif self.direction == 'E': - self.direction = 'N' - elif self.direction == 'W': - self.direction = 'S' - if event.key == pygame.K_LEFT: - if self.direction == 'N': - self.direction = 'E' - elif self.direction == 'S': - self.direction = 'W' - elif self.direction == 'E': - self.direction = 'S' - elif self.direction == 'W': - self.direction = 'N' - if event.key == pygame.K_UP: - if self.direction == 'N': - self.move(0, 1, graphics) - if self.direction == 'S': - self.move(0, -1, graphics) - if self.direction == 'E': - self.move(1, 0, graphics) - if self.direction == 'W': - self.move(-1, 0, graphics) - print(self.X, self.Y) + def update(self, instruction, graphics): + if instruction == 'L': + if self.direction == 'N': + self.direction = 'W' + elif self.direction == 'S': + self.direction = 'E' + elif self.direction == 'E': + self.direction = 'N' + elif self.direction == 'W': + self.direction = 'S' + if instruction == 'R': + if self.direction == 'N': + self.direction = 'E' + elif self.direction == 'S': + self.direction = 'W' + elif self.direction == 'E': + self.direction = 'S' + elif self.direction == 'W': + self.direction = 'N' + if instruction == 'F': + if self.direction == 'N': + self.move(0, -1, graphics) + if self.direction == 'S': + self.move(0, 1, graphics) + if self.direction == 'E': + self.move(1, 0, graphics) + if self.direction == 'W': + self.move(-1, 0, graphics) + #print(self.X, self.Y) # AStar def findPath(self, goal): + # Stworzenie startowego i koncowego wierzcholka startNode = self.matrix.matrix[self.X][self.Y] goalNode = self.matrix.matrix[goal[0]][goal[1]] @@ -67,17 +67,10 @@ class Waiter(pygame.sprite.Sprite): while len(openList) > 0: openList.sort(key=getTotalCost) + currentNode = openList.pop(0) closedList.append(currentNode) - print("\nOpenList") - for tile in openList: - print(tile.position, end=" ") - - print("\nClosed List") - for tile in closedList: - print(tile.position, end=' ') - # Tutaj odbywac sie bedzie budowanie sciezki gdy algorytm osiagnie cel if currentNode == goalNode: path = [] @@ -88,6 +81,7 @@ class Waiter(pygame.sprite.Sprite): return path[::-1] children = [] + if currentNode.position[0] >= 0: if currentNode.position[1] + 1 < len(self.matrix.matrix[0]): if self.matrix.matrix[currentNode.position[0]][currentNode.position[1] + 1].walk_through == 1: @@ -99,54 +93,161 @@ class Waiter(pygame.sprite.Sprite): self.matrix.matrix[currentNode.position[0]][currentNode.position[1] - 1]) if currentNode.position[0] + 1 < len(self.matrix.matrix): - if currentNode.position[1] + 1 < len(self.matrix.matrix[0]): - if self.matrix.matrix[currentNode.position[0] + 1][currentNode.position[1] + 1].walk_through == 1: - children.append( - self.matrix.matrix[currentNode.position[0] + 1][currentNode.position[1] + 1]) - if currentNode.position[1] - 1 >= 0: - if self.matrix.matrix[currentNode.position[0] + 1][currentNode.position[1] - 1].walk_through == 1: - children.append( - self.matrix.matrix[currentNode.position[0] + 1][currentNode.position[1] - 1]) if currentNode.position[1] >= 0: if self.matrix.matrix[currentNode.position[0] + 1][currentNode.position[1]].walk_through == 1: children.append( self.matrix.matrix[currentNode.position[0] + 1][currentNode.position[1]]) if currentNode.position[0] - 1 >= 0: - if currentNode.position[1] + 1 < len(self.matrix.matrix[0]): - if self.matrix.matrix[currentNode.position[0] - 1][currentNode.position[1] + 1].walk_through == 1: - children.append( - self.matrix.matrix[currentNode.position[0] - 1][currentNode.position[1] + 1]) - if currentNode.position[1] - 1 >= 0: - if self.matrix.matrix[currentNode.position[0] - 1][currentNode.position[1] - 1].walk_through == 1: - children.append( - self.matrix.matrix[currentNode.position[0] - 1][currentNode.position[1] - 1]) if currentNode.position[1] >= 0: if self.matrix.matrix[currentNode.position[0] - 1][currentNode.position[1]].walk_through == 1: children.append( self.matrix.matrix[currentNode.position[0] - 1][currentNode.position[1]]) + perm = 0 for child in children: - #child.parent = currentNode - for closedChild in closedList: if child == closedChild: - continue + perm = 1 + break + if perm == 1: + perm = 0 + continue + + child.parent = currentNode child.startCost = currentNode.startCost + 1 - child.heuristic = ((child.position[0] - goalNode.position[0]) ** 2) + ( - (child.position[1] - goalNode.position[1]) ** 2) + child.heuristic = abs( + goal[0] - child.position[0]) + abs(goal[1] - child.position[1]) child.totalCost = child.startCost + child.heuristic for openNode in openList: - - if child == openNode and child.startCost >= openNode.startCost: + if child == openNode and child.startCost > openNode.startCost: + perm = 1 continue - #child.parent = currentNode + if perm == 1: + perm = 0 + continue + openList.append(child) + def translatePath(self, path): + + currentPosition = (self.X, self.Y) + currentDirection = self.direction + output = '' + + for node in path: + + if currentDirection == 'N': + + if currentPosition[0] == node[0]: + + if currentPosition[1] + 1 == node[1]: + output += 'LLF' + currentDirection = 'S' + + if currentPosition[1] - 1 == node[1]: + output += 'F' + + elif currentPosition[1] == node[1]: + + if currentPosition[0] + 1 == node[0]: + output += 'RF' + currentDirection = 'E' + + if currentPosition[0] - 1 == node[0]: + output += 'LF' + currentDirection = 'W' + + elif currentDirection == 'E': + + if currentPosition[0] == node[0]: + + if currentPosition[1] + 1 == node[1]: + output += 'RF' + currentDirection = 'S' + + if currentPosition[1] - 1 == node[1]: + output += 'LF' + currentDirection = 'N' + + elif currentPosition[1] == node[1]: + + if currentPosition[0] + 1 == node[0]: + output += 'F' + + if currentPosition[0] - 1 == node[0]: + output += 'LLF' + currentDirection = 'W' + + elif currentDirection == 'S': + + if currentPosition[0] == node[0]: + + if currentPosition[1] + 1 == node[1]: + output += 'F' + + if currentPosition[1] - 1 == node[1]: + output += 'LLF' + currentDirection = 'N' + + elif currentPosition[1] == node[1]: + + if currentPosition[0] + 1 == node[0]: + output += 'LF' + currentDirection = 'E' + + if currentPosition[0] - 1 == node[0]: + output += 'RF' + currentDirection = 'W' + + elif currentDirection == 'W': + + if currentPosition[0] == node[0]: + + if currentPosition[1] + 1 == node[1]: + output += 'LF' + currentDirection = 'S' + + if currentPosition[1] - 1 == node[1]: + output += 'RF' + currentDirection = 'N' + + elif currentPosition[1] == node[1]: + + if currentPosition[0] + 1 == node[0]: + output += 'LLF' + currentDirection = 'E' + + if currentPosition[0] - 1 == node[0]: + output += 'F' + + currentPosition = node + + return output + + def travel(self, goal, graphics): + translatedPath = self.translatePath([goal]) + print('{} - {} - {}'.format(self.direction, goal, translatedPath)) + for character in translatedPath: + if character == 'F': + graphics.clear(self.X, self.Y) + self.update('F', graphics) + graphics.update(self.X, self.Y) + + if character == 'R': + #graphics.clear(self.X, self.Y) + self.update('R', graphics) + #graphics.update(self.X, self.Y) + + if character == 'L': + #graphics.clear(self.X, self.Y) + self.update('L', graphics) + #graphics.update(self.X, self.Y) + def getTotalCost(tile): return tile.totalCost