From 5773c6e1bb9086238b7f89b8625ae35b9818c06d Mon Sep 17 00:00:00 2001 From: Tomek Sidoruk Date: Tue, 4 May 2021 16:43:01 +0200 Subject: [PATCH 1/9] added prompt to asking user of target coorfinates --- .idea/.gitignore | 3 + .idea/Projekt_Sztuczna_Inteligencja.iml | 10 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + main.py | 172 +++++++++++++++--- searching_algorithms/bfs.py | 6 +- 8 files changed, 185 insertions(+), 30 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/Projekt_Sztuczna_Inteligencja.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/Projekt_Sztuczna_Inteligencja.iml b/.idea/Projekt_Sztuczna_Inteligencja.iml new file mode 100644 index 0000000..7e9e487 --- /dev/null +++ b/.idea/Projekt_Sztuczna_Inteligencja.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e037e18 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fb92429 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main.py b/main.py index 9f46b88..dbb3abd 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,10 @@ # libraries +import sys import pygame import time from pyglet.gl import * # for blocky textures - +import random # other files of this project import project_constants as const import minefield as mf @@ -27,42 +28,157 @@ def main(): minefield = mf.Minefield(const.MAP_RANDOM_10x10) # get sequence of actions found by BFS algorithm - action_sequence = bfs.graphsearch( - initial_state=bfs.State( - row=minefield.agent.position[0], - column=minefield.agent.position[1], - direction=const.Direction.UP), - minefield=minefield) - running = True - while running: - # FPS control - clock.tick(const.V_FPS) + running = False - # graphics (from display_assets) - blit_graphics(minefield) + # basic font for user typed + base_font = pygame.font.Font(None, 32) + user_text1 = '' + user_text2 = '' + # create rectangle + input_rect1 = pygame.Rect(200, 200, 140, 32) + input_rect2 = pygame.Rect(200, 250, 140, 32) - # make the next move from sequence of actions - if any(action_sequence): + randomb = pygame.Rect(200, 300, 140, 32) + ok = pygame.Rect(200, 350, 140, 32) + x = pygame.Rect(180, 200, 140, 32) + y = pygame.Rect(180, 250, 140, 32) + okt = pygame.Rect(240, 305, 140, 32) + randtext = pygame.Rect(220, 355, 140, 32) + # color_active stores color(lightskyblue3) which + # gets active when input box is clicked by user + color_active = pygame.Color('lightskyblue3') - action = action_sequence.pop(0) - - if action == const.Action.ROTATE_LEFT: - minefield.agent.rotate_left() - elif action == const.Action.ROTATE_RIGHT: - minefield.agent.rotate_right() - elif action == const.Action.GO: - minefield.agent.go() - - time.sleep(const.ACTION_INTERVAL) - - else: + # color_passive store color(chartreuse4) which is + # color of input box. + color_passive = pygame.Color('chartreuse4') + color1 = color_passive + color2 = color_passive + while True: + active1 = False + active2 = False + while running== False: for event in pygame.event.get(): + # if user types QUIT then the screen will close if event.type == pygame.QUIT: - running = False + pygame.quit() + sys.exit() + + if event.type == pygame.MOUSEBUTTONDOWN: + if input_rect1.collidepoint(event.pos): + active1 = True + else: + active1 = False + if input_rect2.collidepoint(event.pos): + active2 = True + else: + active2 = False + if randomb.collidepoint(event.pos): + running = True + if ok.collidepoint(event.pos): + user_text1 = str(random.randint(0, 9)) + user_text2 =str(random.randint(0, 9)) + + if event.type == pygame.KEYDOWN: + if active2 == True: + if event.key == pygame.K_BACKSPACE: + user_text2 = user_text2[:-1] + else: + user_text2 += event.unicode + + if active1 == True: + if event.key == pygame.K_BACKSPACE: + user_text1 = user_text1[:-1] + else: + user_text1 += event.unicode + + + # it will set background color of screen + const.SCREEN.fill((255, 255, 255)) + + if active1: + color1 = color_active + else: + color1 = color_passive + + if active2: + color2 = color_active + else: + color2 = color_passive + + # draw rectangle and argument passed which should + # be on screen + pygame.draw.rect(const.SCREEN, color1, input_rect1) + pygame.draw.rect(const.SCREEN, color2, input_rect2) + pygame.draw.rect(const.SCREEN, color_passive, ok) + pygame.draw.rect(const.SCREEN, color_passive, randomb) + text_surface1 = base_font.render(user_text1, True, (255, 255, 255)) + text_surface2 = base_font.render(user_text2, True, (255, 255, 255)) + xd = base_font.render("x", True, (0, 0, 0)) + yd = base_font.render("y", True, (0, 0, 0)) + okd = base_font.render("ok", True, (0, 0, 0)) + randd = base_font.render("random", True, (0, 0, 0)) + # render at position stated in arguments + const.SCREEN.blit(xd, (x.x, x.y)) + const.SCREEN.blit(yd, (y.x, y.y)) + const.SCREEN.blit(okd, (okt.x, okt.y)) + const.SCREEN.blit(randd, (randtext.x, randtext.y)) + const.SCREEN.blit(text_surface1, (input_rect1.x + 5, input_rect1.y + 5)) + const.SCREEN.blit(text_surface2, (input_rect2.x + 5, input_rect2.y + 5)) + # set width of textfield so that text cannot get + # outside of user's text input + input_rect1.w = max(100, text_surface1.get_width() + 10) + input_rect2.w = max(100, text_surface2.get_width() + 10) + + # display.flip() will update only a portion of the + # screen to updated, not full area + pygame.display.flip() + + # clock.tick(60) means that for every second at most + # 60 frames should be passed. + clock.tick(60) + toy=int(user_text1) + tox = int(user_text2) + action_sequence = bfs.graphsearch( + initial_state=bfs.State( + row=minefield.agent.position[0], + column=minefield.agent.position[1], + direction=minefield.agent.direction), + minefield=minefield, tox=tox, toy = toy) + while running: + + # FPS control + clock.tick(const.V_FPS) + + # graphics (from display_assets) + blit_graphics(minefield) + + # make the next move from sequence of actions + if any(action_sequence): + + action = action_sequence.pop(0) + + if action == const.Action.ROTATE_LEFT: + minefield.agent.rotate_left() + elif action == const.Action.ROTATE_RIGHT: + minefield.agent.rotate_right() + elif action == const.Action.GO: + minefield.agent.go() + + time.sleep(const.ACTION_INTERVAL/5) + + else: + running = False + time.sleep(const.ACTION_INTERVAL/5) + #'for event in pygame.event.get(): + # if event.type == pygame.QUIT: + # running = False + + + if __name__ == "__main__": diff --git a/searching_algorithms/bfs.py b/searching_algorithms/bfs.py index c93dca0..04ab8a8 100644 --- a/searching_algorithms/bfs.py +++ b/searching_algorithms/bfs.py @@ -47,13 +47,15 @@ def get_successors(state: State, minefield: Minefield): return successors -def graphsearch(initial_state: State, minefield: Minefield, fringe: List[Node] = None, explored: List[Node] = None): +def graphsearch(initial_state: State, minefield: Minefield, fringe: List[Node] = None, explored: List[Node] = None, tox: int = None,toy: int = None): # fringe and explored initialization + global GOAL if fringe is None: fringe = list() if explored is None: explored = list() - + if tox is not None and toy is not None: + GOAL = (tox, toy) explored_states = set() fringe_states = set() From 7d7281db06db7d30c45ebe620bb2267b6e6be7fc Mon Sep 17 00:00:00 2001 From: Tomek Sidoruk Date: Tue, 4 May 2021 16:46:38 +0200 Subject: [PATCH 2/9] remove unwanted shortingof sllep --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index dbb3abd..c644a23 100644 --- a/main.py +++ b/main.py @@ -168,11 +168,11 @@ def main(): elif action == const.Action.GO: minefield.agent.go() - time.sleep(const.ACTION_INTERVAL/5) + time.sleep(const.ACTION_INTERVAL) else: running = False - time.sleep(const.ACTION_INTERVAL/5) + time.sleep(const.ACTION_INTERVAL) #'for event in pygame.event.get(): # if event.type == pygame.QUIT: # running = False From 8c7426ef9b478d07ac1d4c690e01810da9d14a17 Mon Sep 17 00:00:00 2001 From: Jakub Radowicz Date: Tue, 4 May 2021 18:22:00 +0200 Subject: [PATCH 3/9] deleted unnecessary files. updated .gitignore file to ignore the files in the future --- .gitignore | 5 ++++- .idea/.gitignore | 3 --- .idea/Projekt_Sztuczna_Inteligencja.iml | 10 ---------- .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 4 ---- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 7 files changed, 4 insertions(+), 38 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/Projekt_Sztuczna_Inteligencja.iml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index b81f96b..1fb64dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# .idea files +.idea* + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -138,4 +141,4 @@ dmypy.json cython_debug/ # local sandbox -sandbox/ \ No newline at end of file +sandbox/ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/Projekt_Sztuczna_Inteligencja.iml b/.idea/Projekt_Sztuczna_Inteligencja.iml deleted file mode 100644 index 7e9e487..0000000 --- a/.idea/Projekt_Sztuczna_Inteligencja.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index e037e18..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index fb92429..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 0d2955f90a559b6d0ca1927d092248e44ceb14a5 Mon Sep 17 00:00:00 2001 From: Tomek Sidoruk Date: Tue, 4 May 2021 21:40:18 +0200 Subject: [PATCH 4/9] refacetor --- main.py | 123 +++++++++----------------------------------------------- 1 file changed, 20 insertions(+), 103 deletions(-) diff --git a/main.py b/main.py index c644a23..9ea5ced 100644 --- a/main.py +++ b/main.py @@ -10,8 +10,9 @@ import project_constants as const import minefield as mf import searching_algorithms.bfs as bfs from display_assets import blit_graphics - - +from ui.input_box import * +from ui.button import * +from ui.text_box import * def main(): pygame.init() @@ -33,115 +34,31 @@ def main(): running = False # basic font for user typed - base_font = pygame.font.Font(None, 32) - user_text1 = '' - user_text2 = '' - # create rectangle - input_rect1 = pygame.Rect(200, 200, 140, 32) - input_rect2 = pygame.Rect(200, 250, 140, 32) - - randomb = pygame.Rect(200, 300, 140, 32) - ok = pygame.Rect(200, 350, 140, 32) - x = pygame.Rect(180, 200, 140, 32) - y = pygame.Rect(180, 250, 140, 32) - okt = pygame.Rect(240, 305, 140, 32) - randtext = pygame.Rect(220, 355, 140, 32) - # color_active stores color(lightskyblue3) which - # gets active when input box is clicked by user - color_active = pygame.Color('lightskyblue3') - - # color_passive store color(chartreuse4) which is - # color of input box. - color_passive = pygame.Color('chartreuse4') - color1 = color_passive - color2 = color_passive + input1=InputBox(position=(200,200),dimensions=(140,32),label="x") + input2 = InputBox(position=(200, 250), dimensions=(140, 32),label="y") + randombutton = Button(position=(200,350),dimensions=(140,32),text="random") + okbutton = Button(position=(200,300),dimensions=(140,32),text="ok") while True: - active1 = False - active2 = False while running== False: - for event in pygame.event.get(): - - # if user types QUIT then the screen will close - if event.type == pygame.QUIT: - pygame.quit() - sys.exit() - - if event.type == pygame.MOUSEBUTTONDOWN: - if input_rect1.collidepoint(event.pos): - active1 = True - else: - active1 = False - if input_rect2.collidepoint(event.pos): - active2 = True - else: - active2 = False - if randomb.collidepoint(event.pos): - running = True - if ok.collidepoint(event.pos): - user_text1 = str(random.randint(0, 9)) - user_text2 =str(random.randint(0, 9)) - - if event.type == pygame.KEYDOWN: - if active2 == True: - if event.key == pygame.K_BACKSPACE: - user_text2 = user_text2[:-1] - else: - user_text2 += event.unicode - - if active1 == True: - if event.key == pygame.K_BACKSPACE: - user_text1 = user_text1[:-1] - else: - user_text1 += event.unicode - - - # it will set background color of screen const.SCREEN.fill((255, 255, 255)) + events= pygame.event.get() + input1.run(const.SCREEN,pygame.mouse.get_pos(),events) + input2.run(const.SCREEN, pygame.mouse.get_pos(), events) - if active1: - color1 = color_active - else: - color1 = color_passive + okbutton.draw(const.SCREEN, pygame.mouse.get_pos()) + randombutton.draw(const.SCREEN, pygame.mouse.get_pos()) - if active2: - color2 = color_active - else: - color2 = color_passive - - # draw rectangle and argument passed which should - # be on screen - pygame.draw.rect(const.SCREEN, color1, input_rect1) - pygame.draw.rect(const.SCREEN, color2, input_rect2) - pygame.draw.rect(const.SCREEN, color_passive, ok) - pygame.draw.rect(const.SCREEN, color_passive, randomb) - text_surface1 = base_font.render(user_text1, True, (255, 255, 255)) - text_surface2 = base_font.render(user_text2, True, (255, 255, 255)) - xd = base_font.render("x", True, (0, 0, 0)) - yd = base_font.render("y", True, (0, 0, 0)) - okd = base_font.render("ok", True, (0, 0, 0)) - randd = base_font.render("random", True, (0, 0, 0)) - # render at position stated in arguments - const.SCREEN.blit(xd, (x.x, x.y)) - const.SCREEN.blit(yd, (y.x, y.y)) - const.SCREEN.blit(okd, (okt.x, okt.y)) - const.SCREEN.blit(randd, (randtext.x, randtext.y)) - const.SCREEN.blit(text_surface1, (input_rect1.x + 5, input_rect1.y + 5)) - const.SCREEN.blit(text_surface2, (input_rect2.x + 5, input_rect2.y + 5)) - # set width of textfield so that text cannot get - # outside of user's text input - input_rect1.w = max(100, text_surface1.get_width() + 10) - input_rect2.w = max(100, text_surface2.get_width() + 10) - - # display.flip() will update only a portion of the - # screen to updated, not full area + if okbutton.is_clicked(pygame.mouse.get_pos(),events): + running = True + if randombutton.is_clicked(pygame.mouse.get_pos(), events): + input1.set_texts(user_input=str(random.randint(0, 9))) + input2.set_texts(user_input=str(random.randint(0, 9))) pygame.display.flip() - # clock.tick(60) means that for every second at most - # 60 frames should be passed. - clock.tick(60) - toy=int(user_text1) - tox = int(user_text2) + clock.tick(const.V_FPS) + toy=int(input1.get_input()) + tox = int(input2.get_input()) action_sequence = bfs.graphsearch( initial_state=bfs.State( row=minefield.agent.position[0], From d8f1101bc67c206f7d6af7e5daee9a06324bd049 Mon Sep 17 00:00:00 2001 From: JakubR Date: Wed, 5 May 2021 13:48:48 +0200 Subject: [PATCH 5/9] minor changes in main; code refactoring --- main.py | 78 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/main.py b/main.py index 9ea5ced..5153d31 100644 --- a/main.py +++ b/main.py @@ -10,11 +10,12 @@ import project_constants as const import minefield as mf import searching_algorithms.bfs as bfs from display_assets import blit_graphics -from ui.input_box import * -from ui.button import * -from ui.text_box import * -def main(): +from ui.input_box import * +from ui.button import * +from ui.text_box import * + +def main(): pygame.init() pygame.display.set_caption(const.V_NAME_OF_WINDOW) @@ -28,44 +29,66 @@ def main(): # create an instance of Minefield, pass necessary data minefield = mf.Minefield(const.MAP_RANDOM_10x10) - # get sequence of actions found by BFS algorithm + # setting flags for program + running = True + in_menu = True - - running = False + # counting coordinates for ui components + ib_width, ib_height = 65, 48 + bt_width, bt_height = 140, 32 + ib_y = 230 + ib1_x = const.SCREEN.get_width() / 2 - ib_width - 5 + ib2_x = const.SCREEN.get_width() / 2 + 5 + bt_x = const.SCREEN.get_width() / 2 - bt_width / 2 + bt1_y = ib_y + ib_height + 10 + bt2_y = bt1_y + bt_height + 10 # basic font for user typed - input1=InputBox(position=(200,200),dimensions=(140,32),label="x") - input2 = InputBox(position=(200, 250), dimensions=(140, 32),label="y") - randombutton = Button(position=(200,350),dimensions=(140,32),text="random") - okbutton = Button(position=(200,300),dimensions=(140,32),text="ok") - while True: + input1 = InputBox(position=(ib1_x, ib_y), dimensions=(ib_width, ib_height), label="x", input_centered=True) + input2 = InputBox(position=(ib2_x, ib_y), dimensions=(ib_width, ib_height), label="y", input_centered=True) + random_button = Button(position=(bt_x, bt1_y), dimensions=(bt_width, bt_height), text="random") + ok_button = Button(position=(bt_x, bt2_y), dimensions=(bt_width, bt_height), text="ok") - while running== False: + # initializing goal position + to_x, to_y = 0, 0 + + while running: + + while running and in_menu: const.SCREEN.fill((255, 255, 255)) - events= pygame.event.get() - input1.run(const.SCREEN,pygame.mouse.get_pos(),events) + events = pygame.event.get() + + for event in events: + if event.type == pygame.QUIT: + running = False + + input1.run(const.SCREEN, pygame.mouse.get_pos(), events) input2.run(const.SCREEN, pygame.mouse.get_pos(), events) - okbutton.draw(const.SCREEN, pygame.mouse.get_pos()) - randombutton.draw(const.SCREEN, pygame.mouse.get_pos()) + ok_button.draw(const.SCREEN, pygame.mouse.get_pos()) + random_button.draw(const.SCREEN, pygame.mouse.get_pos()) - if okbutton.is_clicked(pygame.mouse.get_pos(),events): - running = True - if randombutton.is_clicked(pygame.mouse.get_pos(), events): + if ok_button.is_clicked(pygame.mouse.get_pos(), events): + in_menu = False + if random_button.is_clicked(pygame.mouse.get_pos(), events): input1.set_texts(user_input=str(random.randint(0, 9))) input2.set_texts(user_input=str(random.randint(0, 9))) pygame.display.flip() clock.tick(const.V_FPS) - toy=int(input1.get_input()) - tox = int(input2.get_input()) + + if running: + to_x = int(input1.get_input()) + to_y = int(input2.get_input()) + action_sequence = bfs.graphsearch( initial_state=bfs.State( row=minefield.agent.position[0], column=minefield.agent.position[1], direction=minefield.agent.direction), - minefield=minefield, tox=tox, toy = toy) - while running: + minefield=minefield, tox=to_x, toy=to_y) + + while running and not in_menu: # FPS control clock.tick(const.V_FPS) @@ -88,15 +111,12 @@ def main(): time.sleep(const.ACTION_INTERVAL) else: - running = False + in_menu = True time.sleep(const.ACTION_INTERVAL) - #'for event in pygame.event.get(): + # 'for event in pygame.event.get(): # if event.type == pygame.QUIT: # running = False - - - if __name__ == "__main__": main() From 46b6db6c00e518839b5259cc4983525c15b9b482 Mon Sep 17 00:00:00 2001 From: JakubR Date: Fri, 7 May 2021 13:54:42 +0200 Subject: [PATCH 6/9] made ui components inherit one from the other; added new ui components functionality; improved "menu" --- main.py | 27 ++-- ui/auxiliary_decorator.py | 6 + ui/button.py | 229 ++++++++++++++------------------- ui/input_box.py | 258 ++++++++++++++++++++++---------------- ui/text_box.py | 67 ++++++++-- 5 files changed, 327 insertions(+), 260 deletions(-) create mode 100644 ui/auxiliary_decorator.py diff --git a/main.py b/main.py index 5153d31..69b05fd 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,4 @@ # libraries -import sys - -import pygame import time from pyglet.gl import * # for blocky textures import random @@ -34,18 +31,30 @@ def main(): in_menu = True # counting coordinates for ui components - ib_width, ib_height = 65, 48 - bt_width, bt_height = 140, 32 - ib_y = 230 + ib_width, ib_height = 100, 65 + bt_width, bt_height = 210, 55 + ib_y = 200 ib1_x = const.SCREEN.get_width() / 2 - ib_width - 5 ib2_x = const.SCREEN.get_width() / 2 + 5 bt_x = const.SCREEN.get_width() / 2 - bt_width / 2 bt1_y = ib_y + ib_height + 10 bt2_y = bt1_y + bt_height + 10 - # basic font for user typed - input1 = InputBox(position=(ib1_x, ib_y), dimensions=(ib_width, ib_height), label="x", input_centered=True) - input2 = InputBox(position=(ib2_x, ib_y), dimensions=(ib_width, ib_height), label="y", input_centered=True) + # creating ui components used in menu + input1 = InputBox( + position=(ib1_x, ib_y), + dimensions=(ib_width, ib_height), + text="row", + input_centered=True, + clear_input_on_click=True + ) + input2 = InputBox( + position=(ib2_x, ib_y), + dimensions=(ib_width, ib_height), + text="column", + input_centered=True, + clear_input_on_click=True + ) random_button = Button(position=(bt_x, bt1_y), dimensions=(bt_width, bt_height), text="random") ok_button = Button(position=(bt_x, bt2_y), dimensions=(bt_width, bt_height), text="ok") diff --git a/ui/auxiliary_decorator.py b/ui/auxiliary_decorator.py new file mode 100644 index 0000000..8d7b97e --- /dev/null +++ b/ui/auxiliary_decorator.py @@ -0,0 +1,6 @@ + +def _return_itself(fun): + def wrapper(*args, **kwargs): + fun(*args, **kwargs) + + return wrapper diff --git a/ui/button.py b/ui/button.py index 8c2f375..054529d 100644 --- a/ui/button.py +++ b/ui/button.py @@ -1,8 +1,14 @@ import pygame -from math import floor + +# importing an auxiliary functions +from ui.auxiliary_decorator import _return_itself +from ui.text_box import get_fixed_rgb + +# importing parent class +from ui.text_box import TextBox -class Button: +class Button(TextBox): # constructor that can be used to set parameters of Button instance def __init__( self, @@ -17,90 +23,82 @@ class Button: is_active=True, fit_text=True, outline=True, + irregular_outline=False, + outline_additional_pixel=False, + outline_hover_inclusive=True, outline_thickness=None, outline_color=(50, 50, 50), box_transform_hover=1.16, box_transform_inactive=0.9, font_transform_hover=1.24, - font_transform_inactive=0.85 + font_transform_inactive=0.85, + outline_transform_hover=1, + outline_transform_inactive=0.9 ): - # extracting and setting values - smaller_dimension = min(dimensions) - width, height = dimensions - - # counting default outline thickness - default_outline_thickness = (smaller_dimension + (width + height) / 4) / 50 + # calling base class constructor + super().__init__( + position=position, + dimensions=dimensions, + text=text, + box_color=box_color, + font=font, + font_color=font_color, + font_size=font_size, + is_visible=is_visible, + fit_text=fit_text, + outline=outline, + irregular_outline=irregular_outline, + outline_additional_pixel=outline_additional_pixel, + outline_hover_inclusive=outline_hover_inclusive, + outline_thickness=outline_thickness, + outline_color=outline_color + ) # setting attributes - self.position = position - self.dimensions = dimensions - self.text = text - self.box_color = _get_proper_rgb(box_color) - self.font_color = _get_proper_rgb(font_color) - self.font_size = _return_value_or_default(font_size, floor(smaller_dimension / 2)) - self.font = pygame.font.SysFont(font, self.font_size) - self.is_visible = is_visible self.is_active = is_active - self.fit_text = fit_text - self.outline = outline - self.outline_thickness = _return_value_or_default(outline_thickness, default_outline_thickness) - self.outline_color = _get_proper_rgb(outline_color) self.box_transform_hover = box_transform_hover self.box_transform_inactive = box_transform_inactive self.font_transform_hover = font_transform_hover self.font_transform_inactive = font_transform_inactive - - # rendering text to get it's width and height - rendered_text = self.font.render(text, True, (0, 0, 0)) - - # if text is out of bounds and fit_text=True - resizing text to fit the box - if self.fit_text and rendered_text.get_width() > self.dimensions[0]: - self.font_size = floor(self.font_size / (rendered_text.get_width() / width + 0.1)) - self.font = pygame.font.SysFont(font, self.font_size) + self.outline_transform_hover = outline_transform_hover + self.outline_transform_inactive = outline_transform_inactive # counting colors on: hover, inactive - self.box_hover_color = _get_proper_rgb(tuple(_transform(self.box_color, self.box_transform_hover))) - self.box_inactive_color = _get_proper_rgb(tuple(_transform(self.box_color, self.box_transform_inactive))) - self.font_hover_color = _get_proper_rgb(tuple(_transform(self.font_color, self.font_transform_hover))) - self.font_inactive_color = _get_proper_rgb(tuple(_transform(self.font_color, self.font_transform_inactive))) + self.box_hover_color = get_fixed_rgb(_transform_rgb(self.box_color, self.box_transform_hover)) + self.box_inactive_color = get_fixed_rgb(_transform_rgb(self.box_color, self.box_transform_inactive)) + self.font_hover_color = get_fixed_rgb(_transform_rgb(self.font_color, self.font_transform_hover)) + self.font_inactive_color = get_fixed_rgb(_transform_rgb(self.font_color, self.font_transform_inactive)) + self.outline_hover_color = get_fixed_rgb(_transform_rgb(self.outline_color, self.outline_transform_hover)) + self.outline_inactive_color = get_fixed_rgb(_transform_rgb(self.outline_color, self.outline_transform_inactive)) # draws the Button instance - def draw(self, window, mouse_position): - # if is_visible=True - drawing Button - if self.is_visible: - # extracting and setting values from attributes - box_x, box_y = self.position - width, height = self.dimensions + @_return_itself + def draw(self, window, mouse_position, *args, **kwargs): + # saving attribute values + box_color_attribute_value = self.box_color + text_color_attribute_value = self.font_color + outline_attribute_value = self.outline_color - # if outline=True - drawing an outline - if self.outline: - padding = self.outline_thickness - outline_coordinates = (box_x - padding, box_y - padding, width + 2 * padding, height + 2 * padding) - pygame.draw.rect(window, self.outline_color, outline_coordinates) + # temporarily changing box and font color if necessary + # is active and mouse is over + if self.is_active and self.is_over(mouse_position): + self.box_color = self.box_hover_color + self.font_color = self.font_hover_color + self.outline_color = self.outline_hover_color - # setting values accordingly to InputBox'es state - # is active and mouse is not over - if not self.is_over(mouse_position) and self.is_active: - pygame.draw.rect(window, self.box_color, (box_x, box_y, width, height)) - text_color = self.font_color + # is not active + else: + self.box_color = self.box_inactive_color + self.font_color = self.font_inactive_color + self.outline_color = self.outline_inactive_color - # is active and mouse is over - elif self.is_active: - pygame.draw.rect(window, self.box_hover_color, (box_x, box_y, width, height)) - text_color = self.font_hover_color + # calling the draw function of base class + super().draw(window) - # is not active - else: - pygame.draw.rect(window, self.box_inactive_color, (box_x, box_y, width, height)) - text_color = self.font_inactive_color - - # rendering text and counting its coordinates - rendered_text = self.font.render(self.text, True, text_color) - rendered_text_x = box_x + width / 2 - rendered_text.get_width() / 2 - rendered_text_y = box_y + height / 2 - rendered_text.get_height() / 2 - - # drawing the text on the coordinates - window.blit(rendered_text, (rendered_text_x, rendered_text_y)) + # resetting colors to original values + self.box_color = box_color_attribute_value + self.font_color = text_color_attribute_value + self.outline_color = outline_attribute_value # returns True if the Button is clicked, or False otherwise def is_clicked(self, mouse_position, events): @@ -114,49 +112,6 @@ class Button: return False - # checks if a position is over the InputBox and returns True or False - def is_over(self, position): - mouse_x, mouse_y = position - button_x, button_y = self.position - width, height = self.dimensions - - return button_x <= mouse_x <= (button_x + width) and button_y <= mouse_y <= (button_y + height) - - # returns text value - def get_text(self): - return self.text - - # sets chosen coordinates - def set_coordinates(self, position=None, dimensions=None, outline_thickness=None): - if position is not None: - self.position = position - - if dimensions is not None: - self.dimensions = dimensions - - if outline_thickness is not None: - self.outline_thickness = outline_thickness - - # sets text attribute - def set_text(self, text): - self.text = text - - # sets chosen font attributes - def set_font(self, font=None, font_size=None): - if font_size is not None: - self.font_size = font_size - - # rendering text to get it's width and height - rendered_text = self.font.render(self.text, True, (0, 0, 0)) - - # if text is out of bounds and fit_text=True - resizing text to fit the box - if self.fit_text and rendered_text.get_width() > self.dimensions[0]: - self.font_size = floor(self.font_size / (rendered_text.get_width() / self.dimensions[0] + 0.1)) - self.font = pygame.font.SysFont(font, self.font_size) - - if font is not None: - self.font = pygame.font.SysFont(font, self.font_size) - # sets chosen color attributes def set_colors( self, @@ -168,14 +123,7 @@ class Button: font_transform_hover=None, font_transform_inactive=None ): - if box_color is not None: - self.box_color = _get_proper_rgb(box_color) - - if font_color is not None: - self.font_color = _get_proper_rgb(font_color) - - if outline_color is not None: - self.outline_color = _get_proper_rgb(outline_color) + super().set_colors(box_color=box_color, font_color=font_color, outline_color=outline_color) if box_transform_hover is not None: self.box_transform_hover = box_transform_hover @@ -189,33 +137,44 @@ class Button: if font_transform_inactive is not None: self.font_transform_inactive = font_transform_inactive - self.box_hover_color = _get_proper_rgb(tuple(_transform(self.box_color, self.box_transform_hover))) - self.box_inactive_color = _get_proper_rgb(tuple(_transform(self.box_color, self.box_transform_inactive))) - self.font_hover_color = _get_proper_rgb(tuple(_transform(self.font_color, self.font_transform_hover))) - self.font_inactive_color = _get_proper_rgb(tuple(_transform(self.font_color, self.font_transform_inactive))) + self.box_hover_color = get_fixed_rgb(tuple(_transform_rgb(self.box_color, self.box_transform_hover))) + self.box_inactive_color = get_fixed_rgb(tuple(_transform_rgb(self.box_color, self.box_transform_inactive))) + self.font_hover_color = get_fixed_rgb(tuple(_transform_rgb(self.font_color, self.font_transform_hover))) + self.font_inactive_color = get_fixed_rgb(tuple(_transform_rgb(self.font_color, self.font_transform_inactive))) # sets chosen flags - def set_flags(self, is_visible=None, is_active=None, outline=None): - if is_visible is not None: - self.is_visible = is_visible + def set_flags( + self, + is_visible=None, + is_active=None, + outline=None, + irregular_outline=None, + outline_additional_pixel=None, + outline_hover_inclusive=None + ): + super().set_flags( + is_visible=is_visible, + outline=outline, + irregular_outline=irregular_outline, + outline_additional_pixel=outline_additional_pixel, + outline_hover_inclusive=outline_hover_inclusive + ) if is_active is not None: self.is_active = is_active - if outline is not None: - self.outline = outline +def _transform_rgb(iterable, transform_value): + if isinstance(transform_value, int) or isinstance(transform_value, float): + return tuple([x * transform_value for x in iterable]) -def _get_proper_rgb(x): - r, g, b = x - r, g, b = max(0, min(255, floor(r))), max(0, min(255, floor(g))), max(0, min(255, floor(b))) + elif isinstance(transform_value, tuple) or isinstance(transform_value, list): + if len(transform_value) == 3 and all([isinstance(x, int) or isinstance(x, float) for x in transform_value]): + rgb_list = [x for x in iterable] - return tuple((r, g, b)) + for i in range(3): + rgb_list[i] += transform_value[i] + return tuple(rgb_list) -def _transform(iterable, transform_value): - return [x * transform_value for x in iterable] - - -def _return_value_or_default(value, default): - return default if value is None else value + return [0, 0, 0] diff --git a/ui/input_box.py b/ui/input_box.py index 95f3f36..fe5e1b0 100644 --- a/ui/input_box.py +++ b/ui/input_box.py @@ -1,24 +1,33 @@ import pygame from math import floor +from ui.auxiliary_decorator import _return_itself -class InputBox: +from ui.button import Button +from ui.button import get_fixed_rgb +from ui.button import _transform_rgb +from ui.text_box import _return_value_or_default + + +class InputBox(Button): backspace_tick = 0 backspace_deleted_streak = 0 backspace_breakpoint = 6 deleting_speeds = [12, 4] + was_enter_hit = False # constructor that can be used to set parameters of InputBox instance def __init__( self, position, dimensions, + text="", input_box_position=None, input_box_dimensions=None, - label="", user_input="", box_color=(195, 195, 195), input_box_color=(225, 245, 245), + writing_highlight_color=(150, 255, 255), inner_box_color=(205, 205, 205), bottom_strip_color=(180, 180, 180), font=pygame.font.get_default_font(), @@ -28,13 +37,46 @@ class InputBox: is_active=True, input_centered=False, fit_text=True, + clear_input_on_click=False, outline=True, + irregular_outline=False, + outline_additional_pixel=False, + outline_hover_inclusive=True, outline_thickness=None, outline_color=(50, 50, 50), + box_transform_hover=1, + box_transform_inactive=1, + font_transform_hover=1, + font_transform_inactive=1, + outline_transform_hover=1, + outline_transform_inactive=0.9, input_box_transform_hover=1.07, input_box_transform_selected=2, input_box_transform_inactive=0.9 ): + super().__init__( + position=position, + dimensions=dimensions, + text=text, + box_color=box_color, + font_color=font_color, + is_visible=is_visible, + is_active=is_active, + fit_text=fit_text, + outline=outline, + irregular_outline=irregular_outline, + outline_additional_pixel=outline_additional_pixel, + outline_hover_inclusive=outline_hover_inclusive, + outline_thickness=outline_thickness, + outline_color=outline_color, + box_transform_hover=box_transform_hover, + box_transform_inactive=box_transform_inactive, + font_transform_hover=font_transform_hover, + font_transform_inactive=font_transform_inactive, + outline_transform_hover=outline_transform_hover, + outline_transform_inactive=outline_transform_inactive + ) + # extracting and setting values smaller_dimension = min(dimensions) box_x, box_y = position @@ -49,59 +91,59 @@ class InputBox: default_input_box_position = (box_x + width / 12, box_y + height / 2) default_input_box_dimensions = (width - width / 6, 3 * height / 10) - # counting default outline thickness - default_outline_thickness = (smaller_dimension + (width + height) / 4) / 50 - # setting attributes - self.position = position - self.dimensions = dimensions self.input_box_position = _return_value_or_default(input_box_position, default_input_box_position) self.input_box_dimensions = _return_value_or_default(input_box_dimensions, default_input_box_dimensions) - self.label = label self.user_input = user_input - self.box_color = _get_proper_rgb(box_color) - self.ib_color = _get_proper_rgb(input_box_color) - self.inner_box_color = _get_proper_rgb(inner_box_color) - self.bottom_strip_color = _get_proper_rgb(bottom_strip_color) - self.font_color = _get_proper_rgb(font_color) + self.ib_color = get_fixed_rgb(input_box_color) + self.typing_highlight_color = get_fixed_rgb(writing_highlight_color) + self.inner_box_color = get_fixed_rgb(inner_box_color) + self.bottom_strip_color = get_fixed_rgb(bottom_strip_color) + self.clear_input_on_click = clear_input_on_click self.font_size = _return_value_or_default(font_size, floor(smaller_dimension / 2.8)) self.font = pygame.font.SysFont(font, self.font_size) self.input_font_size = max(15, floor(self.input_box_dimensions[1] - 2)) self.input_font = pygame.font.SysFont(font, self.input_font_size) - self.is_visible = is_visible - self.is_active = is_active self.is_selected = False + self.is_active = is_active self.input_centered = input_centered - self.fit_text = fit_text - self.outline = outline - self.outline_thickness = _return_value_or_default(outline_thickness, default_outline_thickness) - self.outline_color = outline_color self.ib_transform_hover = input_box_transform_hover self.ib_transform_selected = input_box_transform_selected self.ib_transform_inactive = input_box_transform_inactive self.backspace_pressed_down = False - # rendering label to get it's width and height - rendered_label = self.font.render(label, True, (0, 0, 0)) + # rendering text to get it's width and height + rendered_text = self.font.render(text, True, (0, 0, 0)) # if text is out of bounds and fit_text=True - resizing text to fit the box - if self.fit_text and rendered_label.get_width() > self.input_box_dimensions[0]: - self.font_size = floor(self.font_size / (rendered_label.get_width() / width + 0.1)) + if self.fit_text and rendered_text.get_width() > self.input_box_dimensions[0]: + self.font_size = floor(self.font_size / (rendered_text.get_width() / width + 0.1)) self.font = pygame.font.SysFont(font, self.font_size) # counting colors on: hover, inactive, selected - self.ib_hover_color = _get_proper_rgb(tuple(_transform(self.ib_color, self.ib_transform_hover))) - self.ib_inactive_color = _get_proper_rgb(tuple(_transform(self.ib_color, self.ib_transform_inactive))) - self.ib_selected_color = _get_proper_rgb(tuple(_transform(self.ib_color, self.ib_transform_selected))) + self.ib_hover_color = get_fixed_rgb(tuple(_transform_rgb(self.ib_color, self.ib_transform_hover))) + self.ib_inactive_color = get_fixed_rgb(tuple(_transform_rgb(self.ib_color, self.ib_transform_inactive))) + self.ib_selected_color = get_fixed_rgb(tuple(_transform_rgb(self.ib_color, self.ib_transform_selected))) # draws, updates and selects on mouse click the InputBox instance def run(self, window, mouse_position, events): self.select_on_click(mouse_position, events) + self.clear_user_input_on_click(mouse_position, events) self.draw(window, mouse_position) self.update(events) + @_return_itself # draws an InputBox instance (doesn't run interactions [for everything use run(self, ...) method]) - def draw(self, window, mouse_position): + def draw(self, window, mouse_position, *args, **kwargs): + text_attribute_value = self.text + + self.text = "" + + super().draw(window, mouse_position, *args, **kwargs) + + # resetting original attribute values + self.text = text_attribute_value + # if is_visible=True drawing the InputBox if self.is_visible: # extracting and setting values from attributes @@ -110,12 +152,6 @@ class InputBox: input_box_x, input_box_y = self.input_box_position input_width, input_height = self.input_box_dimensions - # if outline=True - drawing an outline - if self.outline: - padding = self.outline_thickness - outline_coordinates = (box_x - padding, box_y - padding, width + 2 * padding, height + 2 * padding) - pygame.draw.rect(window, self.outline_color, outline_coordinates) - # setting "transparent" background color text_background_color = self.ib_color @@ -123,7 +159,7 @@ class InputBox: # is selected if self.is_selected: input_box_color = self.ib_selected_color - text_background_color = (150, 255, 255) + text_background_color = self.typing_highlight_color # is active and mouse is not over elif not self.is_over(mouse_position) and self.is_active: @@ -137,9 +173,6 @@ class InputBox: else: input_box_color = self.ib_inactive_color - # drawing outer box - pygame.draw.rect(window, self.box_color, (box_x, box_y, width, height)) - # drawing inner (upper) box pygame.draw.rect(window, self.inner_box_color, @@ -152,13 +185,13 @@ class InputBox: # drawing bottom strip pygame.draw.rect(window, self.bottom_strip_color, (box_x, box_y + 9 * height / 10, width, 1 * height / 10)) - # rendering label and counting its coordinates - rendered_label = self.font.render(self.label, True, self.font_color) - rendered_label_x = box_x + width / 2 - rendered_label.get_width() / 2 - rendered_label_y = box_y + height / 4 - rendered_label.get_height() / 2 + # rendering text and counting its coordinates + rendered_text = self.font.render(self.text, True, self.font_color) + rendered_text_x = box_x + width / 2 - rendered_text.get_width() / 2 + rendered_text_y = box_y + height / 4 - rendered_text.get_height() / 2 - # drawing the label on the coordinates - window.blit(rendered_label, (rendered_label_x, rendered_label_y)) + # drawing the text on the coordinates + window.blit(rendered_text, (rendered_text_x, rendered_text_y)) # rendering input rendered_input_text = self.input_font.render(self.user_input, True, self.font_color, text_background_color) @@ -177,6 +210,9 @@ class InputBox: # updates InputBox'es attributes if user types something in it def update(self, events): + # resetting attribute value + self.was_enter_hit = False + # if the InputBox is selected - updating the input text if self.is_selected: self._delete_characters_if_backspace_pressed() @@ -194,6 +230,7 @@ class InputBox: elif event.key == pygame.K_RETURN: self.is_selected = False + self.was_enter_hit = True # if text isn't too long - adding a character elif rendered_input.get_width() + 10 < self.input_box_dimensions[0]: @@ -210,28 +247,42 @@ class InputBox: # if is active set is_selected attribute accordingly if self.is_active: for event in events: - # if mouse is clicked set as selected if mouse is over, or set as not selected otherwise + if event.type == pygame.MOUSEBUTTONUP: self.set_is_selected(self.is_over(mouse_position)) - # checks if a position is over the InputBox and returns True or False - def is_over(self, position): - mouse_x, mouse_y = position - button_x, button_y = self.position - width, height = self.dimensions + # clears user's input on click + def clear_user_input_on_click(self, mouse_position, events): + if self.is_active and self.clear_input_on_click: + for event in events: - return button_x <= mouse_x <= (button_x + width) and button_y <= mouse_y <= (button_y + height) + if event.type == pygame.MOUSEBUTTONUP and self.is_over(mouse_position): + self.clear_input() - # returns InputBox'es label - def get_label(self): - return self.label + # returns True if user input is empty, or False otherwise + def is_input_empty(self): + return not any(self.user_input) + + # clears user's input + def clear_input(self): + self.user_input = "" + + # returns True if enter key is hit, or False otherwise + def is_enter_hit(self, events): + + if self.is_active and self.is_selected: + for event in events: + if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN: + return True + + return self.was_enter_hit # returns InputBox'es user's input def get_input(self): return self.user_input # sets chosen coordinates - def set_space( + def set_coordinates( self, position=None, dimensions=None, @@ -239,11 +290,7 @@ class InputBox: input_box_dimensions=None, outline_thickness=None ): - if position is not None: - self.position = position - - if dimensions is not None: - self.dimensions = dimensions + super().set_coordinates(position=position, dimensions=dimensions, outline_thickness=outline_thickness) if input_box_position is not None: self.input_box_position = input_box_position @@ -251,13 +298,9 @@ class InputBox: if input_box_dimensions is not None: self.input_box_dimensions = input_box_dimensions - if outline_thickness is not None: - self.outline_thickness = outline_thickness - # sets chosen text attributes - def set_texts(self, label=None, user_input=None): - if label is not None: - self.label = label + def set_texts(self, text=None, user_input=None): + super().set_text(text=text) if user_input is not None: self.user_input = user_input @@ -268,15 +311,14 @@ class InputBox: self.font_size = font_size # rendering text to get it's width and height - rendered_text = self.font.render(self.user_input, True, (0, 0, 0)) + rendered_text = self.font.render(self.text, True, (0, 0, 0)) # if text is out of bounds and fit_text=True - resizing text to fit the box - if self.fit_text and rendered_text.get_width() > self.dimensions[0]: + if self.fit_text and rendered_text.get_width() > self.input_box_dimensions[0]: self.font_size = floor(self.font_size / (rendered_text.get_width() / self.dimensions[0] + 0.1)) self.font = pygame.font.SysFont(font, self.font_size) - if font is not None: - self.font = pygame.font.SysFont(font, self.font_size) + super().set_font(font=font) # sets chosen color attributes def set_colors( @@ -284,30 +326,39 @@ class InputBox: box_color=None, input_box_color=None, inner_box_color=None, + writing_highlight_color=None, bottom_strip_color=None, font_color=None, outline_color=None, + box_transform_hover=None, + box_transform_inactive=None, + font_transform_hover=None, + font_transform_inactive=None, input_box_transform_hover=None, input_box_transform_selected=None, - input_box_transform_inactive=None + input_box_transform_inactive=None, ): - if box_color is not None: - self.box_color = _get_proper_rgb(box_color) + super().set_colors( + box_color=box_color, + font_color=font_color, + outline_color=outline_color, + box_transform_hover=box_transform_hover, + box_transform_inactive=box_transform_inactive, + font_transform_hover=font_transform_hover, + font_transform_inactive=font_transform_inactive + ) if input_box_color is not None: - self.ib_color = _get_proper_rgb(input_box_color) + self.ib_color = get_fixed_rgb(input_box_color) + + if writing_highlight_color is not None: + self.typing_highlight_color = writing_highlight_color if inner_box_color is not None: - self.inner_box_color = _get_proper_rgb(inner_box_color) + self.inner_box_color = get_fixed_rgb(inner_box_color) if bottom_strip_color is not None: - self.bottom_strip_color = _get_proper_rgb(bottom_strip_color) - - if font_color is not None: - self.font_color = _get_proper_rgb(font_color) - - if outline_color is not None: - self.outline_color = _get_proper_rgb(outline_color) + self.bottom_strip_color = get_fixed_rgb(bottom_strip_color) if input_box_transform_hover is not None: self.ib_transform_hover = input_box_transform_hover @@ -318,14 +369,29 @@ class InputBox: if input_box_transform_inactive is not None: self.ib_transform_inactive = input_box_transform_inactive - self.ib_hover_color = _get_proper_rgb(tuple(_transform(self.ib_color, self.ib_transform_hover))) - self.ib_inactive_color = _get_proper_rgb(tuple(_transform(self.ib_color, self.ib_transform_inactive))) - self.ib_selected_color = _get_proper_rgb(tuple(_transform(self.ib_color, self.ib_transform_selected))) + self.ib_hover_color = get_fixed_rgb(tuple(_transform_rgb(self.ib_color, self.ib_transform_hover))) + self.ib_inactive_color = get_fixed_rgb(tuple(_transform_rgb(self.ib_color, self.ib_transform_inactive))) + self.ib_selected_color = get_fixed_rgb(tuple(_transform_rgb(self.ib_color, self.ib_transform_selected))) # sets chosen flag attributes - def set_flags(self, is_visible=None, is_active=None, input_centered=None, fit_text=None, outline=None): - if is_visible is not None: - self.is_visible = is_visible + def set_flags( + self, + is_visible=None, + is_active=None, + input_centered=None, + fit_text=None, + outline=None, + irregular_outline=None, + outline_additional_pixel=None, + outline_hover_inclusive=None + ): + super().set_flags( + is_visible=is_visible, + outline=outline, + irregular_outline=None, + outline_additional_pixel=None, + outline_hover_inclusive=None + ) if is_active is not None: self.is_active = is_active @@ -336,9 +402,6 @@ class InputBox: if fit_text is not None: self.fit_text = fit_text - if outline is not None: - self.outline = outline - # sets is_selected with a given value def set_is_selected(self, is_selected): self.is_selected = is_selected @@ -360,18 +423,3 @@ class InputBox: elif self.backspace_pressed_down: self.backspace_tick += 1 - - -def _get_proper_rgb(x): - r, g, b = x - r, g, b = max(0, min(255, floor(r))), max(0, min(255, floor(g))), max(0, min(255, floor(b))) - - return tuple((r, g, b)) - - -def _transform(iterable, transform_value): - return [x * transform_value for x in iterable] - - -def _return_value_or_default(value, default): - return default if value is None else value diff --git a/ui/text_box.py b/ui/text_box.py index e8d71d5..47d4d4f 100644 --- a/ui/text_box.py +++ b/ui/text_box.py @@ -16,6 +16,9 @@ class TextBox: is_visible=True, fit_text=True, outline=True, + irregular_outline=False, + outline_additional_pixel=False, + outline_hover_inclusive=True, outline_thickness=None, outline_color=(50, 50, 50) ): @@ -24,21 +27,24 @@ class TextBox: width, height = dimensions # counting default outline thickness - default_outline_thickness = (smaller_dimension + (width + height) / 4) / 50 + default_outline_thickness = max(1, floor((2 * smaller_dimension + width + height) / 200)) # setting attributes self.position = position self.dimensions = dimensions self.text = text - self.box_color = _get_proper_rgb(box_color) - self.font_color = _get_proper_rgb(font_color) + self.box_color = get_fixed_rgb(box_color) + self.font_color = get_fixed_rgb(font_color) self.font_size = _return_value_or_default(font_size, floor(smaller_dimension / 2)) self.font = pygame.font.SysFont(font, self.font_size) self.is_visible = is_visible self.fit_text = fit_text self.outline = outline + self.irregular_outline = irregular_outline + self.outline_additional_pixel = outline_additional_pixel + self.outline_hover_inclusive = outline_hover_inclusive self.outline_thickness = _return_value_or_default(outline_thickness, default_outline_thickness) - self.outline_color = _get_proper_rgb(outline_color) + self.outline_color = get_fixed_rgb(outline_color) # rendering text to get it's width and height rendered_text = self.font.render(text, True, (0, 0, 0)) @@ -49,7 +55,7 @@ class TextBox: self.font = pygame.font.SysFont(font, self.font_size) # draws the TextBox - def draw(self, window): + def draw(self, window, *args, **kwargs): # if is_visible=True drawing the TextBox if self.is_visible: # extracting and setting values from attributes @@ -58,8 +64,9 @@ class TextBox: # if outline=True - drawing an outline if self.outline: - padding = self.outline_thickness + padding = self.outline_thickness - self.irregular_outline / 2 + self.outline_additional_pixel outline_coordinates = (box_x - padding, box_y - padding, width + 2 * padding, height + 2 * padding) + pygame.draw.rect(window, self.outline_color, outline_coordinates) # drawing the box @@ -73,6 +80,27 @@ class TextBox: # drawing the box on the coordinates window.blit(rendered_text, (rendered_text_x, rendered_text_y)) + # checks if a position is over the InputBox and returns True or False + def is_over(self, position): + mouse_x, mouse_y = position + + if not self.outline_hover_inclusive: + button_x, button_y = self.position + width, height = self.dimensions + + else: + padding = self.outline_thickness + button_x, button_y = self.position + width, height = self.dimensions + button_x, button_y = button_x - padding, button_y - padding + width, height = width + 2 * padding, height + 2 * padding + + return button_x <= mouse_x <= (button_x + width) and button_y <= mouse_y <= (button_y + height) + + # returns text value + def get_text(self): + return self.text + # sets chosen coordinates def set_coordinates(self, position=None, dimensions=None, outline_thickness=None): if position is not None: @@ -86,7 +114,8 @@ class TextBox: # sets the TextBox's text def set_text(self, text): - self.text = text + if text is not None: + self.text = text # sets chosen font attributes def set_font(self, font=None, font_size=None): @@ -107,25 +136,41 @@ class TextBox: # sets chosen color attributes def set_colors(self, box_color=None, font_color=None, outline_color=None): if box_color is not None: - self.box_color = _get_proper_rgb(box_color) + self.box_color = get_fixed_rgb(box_color) if font_color is not None: - self.font_color = _get_proper_rgb(font_color) + self.font_color = get_fixed_rgb(font_color) if outline_color is not None: self.outline_color = outline_color # sets chosen flags - def set_flags(self, is_visible=None, outline=None): + def set_flags( + self, + is_visible=None, + outline=None, + irregular_outline=None, + outline_additional_pixel=None, + outline_hover_inclusive=None + ): if is_visible is not None: self.is_visible = is_visible if outline is not None: self.outline = outline + if irregular_outline is not None: + self.irregular_outline = irregular_outline + + if outline_additional_pixel is not None: + self.outline_additional_pixel = outline_additional_pixel + + if outline_hover_inclusive is not None: + self.outline_hover_inclusive = outline_hover_inclusive + # returns values that are not out of range -def _get_proper_rgb(x): +def get_fixed_rgb(x): r, g, b = x r, g, b = max(0, min(255, floor(r))), max(0, min(255, floor(g))), max(0, min(255, floor(b))) From f82d6657ef531e4b4c2a816fcb2cf52eb83fe172 Mon Sep 17 00:00:00 2001 From: Jakub Danilewicz Date: Fri, 7 May 2021 19:02:09 +0200 Subject: [PATCH 7/9] =?UTF-8?q?Dodany=20Enum=20Terrain;=20Dodany=20koszt?= =?UTF-8?q?=20na=20Tile;=20U=C5=BCywana=20jest=20nowa=20mapa=20testowa=20(?= =?UTF-8?q?reskin=20secondmap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- display_assets.py | 2 +- project_constants.py | 8 +- resources/minefields/fourthmap.json | 500 ++++++++++++++++++++++++++++ tile.py | 20 +- 4 files changed, 526 insertions(+), 4 deletions(-) create mode 100644 resources/minefields/fourthmap.json diff --git a/display_assets.py b/display_assets.py index b3fb554..33a710f 100644 --- a/display_assets.py +++ b/display_assets.py @@ -15,7 +15,7 @@ tile_asset_options = { "RED": const.ASSET_TILE_RED, "WHITE": const.ASSET_TILE_WHITE, "YELLOW": const.ASSET_TILE_YELLOW -} + } mine_asset_options = { 'A': const.ASSET_MINE_A, diff --git a/project_constants.py b/project_constants.py index 6f63163..381ee18 100644 --- a/project_constants.py +++ b/project_constants.py @@ -70,6 +70,12 @@ class Coords(Enum): Y = 1 +class Terrain(Enum): + CONCRETE = 1 + GRASS = 2 + MUD = 4 + + # =============== # # === STRUCTS === # # =============== # @@ -118,7 +124,7 @@ STRUCT_MINE_ATTRIBUTE_TYPES = { # ==== MAPS ==== # # ============== # -MAP_RANDOM_10x10 = os.path.join("resources", "minefields", "secondmap.json") +MAP_RANDOM_10x10 = os.path.join("resources", "minefields", "fourthmap.json") # ============== # diff --git a/resources/minefields/fourthmap.json b/resources/minefields/fourthmap.json new file mode 100644 index 0000000..644d011 --- /dev/null +++ b/resources/minefields/fourthmap.json @@ -0,0 +1,500 @@ +{ + "0,0": { + "color": "BLUE", + "mine": null + }, + "0,1": { + "color": "BLUE", + "mine": null + }, + "0,2": { + "color": "GREEN", + "mine": null + }, + "0,3": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "0,4": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "0,5": { + "color": "BLUE", + "mine": null + }, + "0,6": { + "color": "ORANGE", + "mine": null + }, + "0,7": { + "color": "GREEN", + "mine": null + }, + "0,8": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "0,3" + } + }, + "0,9": { + "color": "ORANGE", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 20 + } + }, + "1,0": { + "color": "GREEN", + "mine": null + }, + "1,1": { + "color": "GREEN", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "1,2": { + "color": "GREEN", + "mine": null + }, + "1,3": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "1,4": { + "color": "ORANGE", + "mine": null + }, + "1,5": { + "color": "GREEN", + "mine": null + }, + "1,6": { + "color": "GREEN", + "mine": null + }, + "1,7": { + "color": "GREEN", + "mine": null + }, + "1,8": { + "color": "ORANGE", + "mine": null + }, + "1,9": { + "color": "ORANGE", + "mine": null + }, + "2,0": { + "color": "ORANGE", + "mine": null + }, + "2,1": { + "color": "BLUE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "2,2": { + "color": "ORANGE", + "mine": null + }, + "2,3": { + "color": "ORANGE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "2,4": { + "color": "GREEN", + "mine": null + }, + "2,5": { + "color": "ORANGE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "2,6": { + "color": "BLUE", + "mine": null + }, + "2,7": { + "color": "BLUE", + "mine": null + }, + "2,8": { + "color": "ORANGE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "2,9": { + "color": "BLUE", + "mine": null + }, + "3,0": { + "color": "BLUE", + "mine": null + }, + "3,1": { + "color": "ORANGE", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 19 + } + }, + "3,2": { + "color": "GREEN", + "mine": null + }, + "3,3": { + "color": "ORANGE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "1,3" + } + }, + "3,4": { + "color": "ORANGE", + "mine": null + }, + "3,5": { + "color": "BLUE", + "mine": null + }, + "3,6": { + "color": "ORANGE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "3,7": { + "color": "ORANGE", + "mine": null + }, + "3,8": { + "color": "GREEN", + "mine": null + }, + "3,9": { + "color": "GREEN", + "mine": null + }, + "4,0": { + "color": "BLUE", + "mine": null + }, + "4,1": { + "color": "ORANGE", + "mine": null + }, + "4,2": { + "color": "BLUE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "4,3": { + "color": "BLUE", + "mine": null + }, + "4,4": { + "color": "ORANGE", + "mine": null + }, + "4,5": { + "color": "ORANGE", + "mine": null + }, + "4,6": { + "color": "BLUE", + "mine": null + }, + "4,7": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "4,8": { + "color": "BLUE", + "mine": null + }, + "4,9": { + "color": "ORANGE", + "mine": null + }, + "5,0": { + "color": "BLUE", + "mine": null + }, + "5,1": { + "color": "ORANGE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "2,3" + } + }, + "5,2": { + "color": "ORANGE", + "mine": null + }, + "5,3": { + "color": "GREEN", + "mine": null + }, + "5,4": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "2,8" + } + }, + "5,5": { + "color": "BLUE", + "mine": null + }, + "5,6": { + "color": "ORANGE", + "mine": null + }, + "5,7": { + "color": "ORANGE", + "mine": null + }, + "5,8": { + "color": "GREEN", + "mine": null + }, + "5,9": { + "color": "ORANGE", + "mine": null + }, + "6,0": { + "color": "GREEN", + "mine": null + }, + "6,1": { + "color": "BLUE", + "mine": null + }, + "6,2": { + "color": "ORANGE", + "mine": null + }, + "6,3": { + "color": "BLUE", + "mine": null + }, + "6,4": { + "color": "BLUE", + "mine": null + }, + "6,5": { + "color": "GREEN", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "6,6": { + "color": "GREEN", + "mine": null + }, + "6,7": { + "color": "BLUE", + "mine": null + }, + "6,8": { + "color": "BLUE", + "mine": null + }, + "6,9": { + "color": "BLUE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "7,0": { + "color": "BLUE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "4,7" + } + }, + "7,1": { + "color": "BLUE", + "mine": null + }, + "7,2": { + "color": "GREEN", + "mine": null + }, + "7,3": { + "color": "ORANGE", + "mine": null + }, + "7,4": { + "color": "GREEN", + "mine": null + }, + "7,5": { + "color": "GREEN", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "7,6": { + "color": "BLUE", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 39 + } + }, + "7,7": { + "color": "ORANGE", + "mine": null + }, + "7,8": { + "color": "GREEN", + "mine": null + }, + "7,9": { + "color": "GREEN", + "mine": null + }, + "8,0": { + "color": "GREEN", + "mine": null + }, + "8,1": { + "color": "GREEN", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 24 + } + }, + "8,2": { + "color": "GREEN", + "mine": null + }, + "8,3": { + "color": "BLUE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "8,4": { + "color": "BLUE", + "mine": null + }, + "8,5": { + "color": "GREEN", + "mine": null + }, + "8,6": { + "color": "GREEN", + "mine": null + }, + "8,7": { + "color": "BLUE", + "mine": null + }, + "8,8": { + "color": "GREEN", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "3,6" + } + }, + "8,9": { + "color": "GREEN", + "mine": null + }, + "9,0": { + "color": "ORANGE", + "mine": null + }, + "9,1": { + "color": "GREEN", + "mine": null + }, + "9,2": { + "color": "BLUE", + "mine": null + }, + "9,3": { + "color": "BLUE", + "mine": null + }, + "9,4": { + "color": "BLUE", + "mine": null + }, + "9,5": { + "color": "GREEN", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "0,4" + } + }, + "9,6": { + "color": "BLUE", + "mine": null + }, + "9,7": { + "color": "ORANGE", + "mine": null + }, + "9,8": { + "color": "ORANGE", + "mine": null + }, + "9,9": { + "color": "ORANGE", + "mine": null + }, + "agent_starting_position": "0,0" + + } \ No newline at end of file diff --git a/tile.py b/tile.py index ee31c23..c28209f 100644 --- a/tile.py +++ b/tile.py @@ -1,7 +1,23 @@ +from project_constants import Terrain as t + +#Assume_cost function assumes colour as an argument (colour that is already given to a tile) and depending +#on what it is returns value of Terrein Enum +#It is used in Tile.cost (giving the value to the tile) + + +def assume_cost(color): + if (color == "BLUE"): + return t.CONCRETE + elif (color == "GREEN"): + return t.GRASS + elif (color == "ORANGE"): + return t.MUD + + class Tile: def __init__(self, position, color=None, mine=None): self.position = position self.color = color - + self.cost = assume_cost(color) # mine is an instance of Mine class - self.mine = mine + self.mine = mine \ No newline at end of file From 436a155b7ea9fd452987c6e8780dbc001bb34b6f Mon Sep 17 00:00:00 2001 From: Jakub Danilewicz Date: Fri, 7 May 2021 19:02:09 +0200 Subject: [PATCH 8/9] =?UTF-8?q?Dodany=20Enum=20Terrain;=20Dodany=20koszt?= =?UTF-8?q?=20na=20Tile;=20U=C5=BCywana=20jest=20nowa=20mapa=20testowa=20(?= =?UTF-8?q?reskin=20secondmap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- display_assets.py | 37 +- json_generator.py | 18 +- minefield.py | 4 +- project_constants.py | 12 +- resources/minefields/fourthmap.json | 500 ++++++++++++++++++++++++++++ tile.py | 26 +- 6 files changed, 548 insertions(+), 49 deletions(-) create mode 100644 resources/minefields/fourthmap.json diff --git a/display_assets.py b/display_assets.py index b3fb554..4417b32 100644 --- a/display_assets.py +++ b/display_assets.py @@ -8,20 +8,13 @@ import project_constants as const # ================================= # tile_asset_options = { - "BLUE": const.ASSET_TILE_BLUE, - "GREEN": const.ASSET_TILE_GREEN, - "ORANGE": const.ASSET_TILE_ORANGE, - "PURPLE": const.ASSET_TILE_PURPLE, - "RED": const.ASSET_TILE_RED, - "WHITE": const.ASSET_TILE_WHITE, - "YELLOW": const.ASSET_TILE_YELLOW + "MUD": const.ASSET_MUD, + "GRASS": const.ASSET_GRASS, + "CONCRETE": const.ASSET_CONCRETE } mine_asset_options = { - 'A': const.ASSET_MINE_A, - 'B': const.ASSET_MINE_B, - 'F': const.ASSET_MINE_F, - 'K': const.ASSET_MINE_K + "MINE": CONST.ASSET_MINE } @@ -30,21 +23,6 @@ mine_asset_options = { # ====================== # -def test_blits(): - display_concrete((2, 3)) - display_mud((5, 6)) - display_mud((5, 7)) - display_grass((2, 1)) - display_mine((2, 7)) - display_mine((5, 7)) - display_concrete((0, 0)) - display_chained_mine((1, 2), (2, 3)) - display_chained_mine((2, 3)) - display_chained_mine((4, 8), (11, 15)) - display_time_mine((1, 8), 12) - display_time_mine((2, 8), 34) - - def blit_graphics(minefield): # background grid (fills frame with white, blits grid) const.SCREEN.fill((255, 255, 255)) @@ -64,7 +42,7 @@ def blit_graphics(minefield): # draw a tile const.SCREEN.blit( - tile_asset_options.get(tile.color), + tile_asset_options.get(tile.terrain_type), tile_screen_coords ) @@ -75,10 +53,9 @@ def blit_graphics(minefield): # draw a mine on top if there is one if tile.mine is not None: # current icons don't represent actual types, thus every mine has the same icon (temporary solution) - const.SCREEN.blit(mine_asset_options['A'], tile_screen_coords) + const.SCREEN.blit(mine_asset_options["MINE"], tile_screen_coords) + - # all the tests in one place - test_blits() # sapper display_sapper( diff --git a/json_generator.py b/json_generator.py index 1a5ce14..8242664 100644 --- a/json_generator.py +++ b/json_generator.py @@ -39,7 +39,7 @@ class JsonGenerator: "direction": direction } - # overwrites grid field with a new grid with randomized colors and mines + # overwrites grid field with a new grid with randomized terrains and mines def generate_randomized_grid(self, dimensions, mine_appearance_chance=0.15, predecessor_chance_decrease=0.25): # clearing grid field self.clear_grid() @@ -53,13 +53,13 @@ class JsonGenerator: for j in range(num_of_columns): # picking random values for tiles - random_tile_color = random.choice(const.STRUCT_TILE_COLORS) + random_tile_terrain = random.choice(const.STRUCT_TILE_TERRAINS) # adding added tile's indexes to a pool tile_pool.append((i, j)) # creating random tile - self.add_tile((i, j), random_tile_color) + self.add_tile((i, j), random_tile_terrain) # deleting agent's starting tile from the pool deleted_row, deleted_column = self.agents_initial_position @@ -104,15 +104,15 @@ class JsonGenerator: current_tile = predecessor # adds a new tile or edits an existing one in the grid field - def add_tile(self, position, color): + def add_tile(self, position, terrain): # creating new tile without a mine self.grid[format_position_to_str(position)] = { - "color": color, + "terrain": terrain, "mine": None } # adds a new tile with a mine or edits an existing one in the grid field - def add_tile_with_a_mine(self, position, color, mine_type, attribute_values): + def add_tile_with_a_mine(self, position, terrain, mine_type, attribute_values): # setting mine data using attribute_values mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type] @@ -122,7 +122,7 @@ class JsonGenerator: # creating a new tile self.grid[format_position_to_str(position)] = { - "color": color + "terrain": terrain } # updating the tile with a mine field @@ -247,11 +247,11 @@ def create_a_tile(tile_dict, position): position = format_position_to_tuple(position) # getting tile's parameters - color = tile_dict["color"] + terrain = tile_dict["terrain"] mine = create_a_mine(position, tile_dict["mine"]) # creating and returning a tile with the parameters set above - return tl.Tile(position, color, mine) + return tl.Tile(position, terrain, mine) # returns a list of tuples containing chained mine's position and it's predecessors position diff --git a/minefield.py b/minefield.py index dea6f4b..129d9ad 100644 --- a/minefield.py +++ b/minefield.py @@ -24,7 +24,7 @@ class Minefield: ] for row in range(const.V_GRID_VER_TILES) ] - # iterate through tiles, set their colors and add mines + # iterate through tiles, set their terrains and add mines for row in range(const.V_GRID_VER_TILES): for column in range(const.V_GRID_HOR_TILES): @@ -36,7 +36,7 @@ class Minefield: mine = self._create_mine(tile_data["mine"], row, column) self.matrix[row][column].mine = mine - self.matrix[row][column].color = tile_data["color"].upper() + self.matrix[row][column].terrain_type = tile_data["terrain"].upper() # ================ # # === MOVEMENT === # diff --git a/project_constants.py b/project_constants.py index 6f63163..a081cfd 100644 --- a/project_constants.py +++ b/project_constants.py @@ -70,6 +70,12 @@ class Coords(Enum): Y = 1 +class Terrain(Enum): + CONCRETE = 1 + GRASS = 2 + MUD = 4 + + # =============== # # === STRUCTS === # # =============== # @@ -79,8 +85,8 @@ class Coords(Enum): # # USED BY JSON GENERATOR # used to generate random tile colors -STRUCT_TILE_COLORS = ["BLUE", "GREEN", "ORANGE", "PURPLE", "RED", "WHITE", "YELLOW"] - +#####################STRUCT_TILE_COLORS = ["BLUE", "GREEN", "ORANGE", "PURPLE", "RED", "WHITE", "YELLOW"] +STRUCT_TILE_TERRAINS = ["CONCRETE","GRASS","MUD"] # used to generate random mines and create not random mines STRUCT_MINE_TYPES = ["standard", "chained", "time"] @@ -118,7 +124,7 @@ STRUCT_MINE_ATTRIBUTE_TYPES = { # ==== MAPS ==== # # ============== # -MAP_RANDOM_10x10 = os.path.join("resources", "minefields", "secondmap.json") +MAP_RANDOM_10x10 = os.path.join("resources", "minefields", "fourthmap.json") # ============== # diff --git a/resources/minefields/fourthmap.json b/resources/minefields/fourthmap.json new file mode 100644 index 0000000..23da209 --- /dev/null +++ b/resources/minefields/fourthmap.json @@ -0,0 +1,500 @@ +{ + "0,0": { + "terrain": "CONCRETE", + "mine": null + }, + "0,1": { + "terrain": "CONCRETE", + "mine": null + }, + "0,2": { + "terrain": "GRASS", + "mine": null + }, + "0,3": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "0,4": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "0,5": { + "terrain": "CONCRETE", + "mine": null + }, + "0,6": { + "terrain": "MUD", + "mine": null + }, + "0,7": { + "terrain": "GRASS", + "mine": null + }, + "0,8": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "0,3" + } + }, + "0,9": { + "terrain": "GRASS", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 20 + } + }, + "1,0": { + "terrain": "GRASS", + "mine": null + }, + "1,1": { + "terrain": "GRASS", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "1,2": { + "terrain": "GRASS", + "mine": null + }, + "1,3": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "1,4": { + "terrain": "MUD", + "mine": null + }, + "1,5": { + "terrain": "GRASS", + "mine": null + }, + "1,6": { + "terrain": "GRASS", + "mine": null + }, + "1,7": { + "terrain": "GRASS", + "mine": null + }, + "1,8": { + "terrain": "MUD", + "mine": null + }, + "1,9": { + "terrain": "MUD", + "mine": null + }, + "2,0": { + "terrain": "MUD", + "mine": null + }, + "2,1": { + "terrain": "CONCRETE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "2,2": { + "terrain": "MUD", + "mine": null + }, + "2,3": { + "terrain": "MUD", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "2,4": { + "terrain": "GRASS", + "mine": null + }, + "2,5": { + "terrain": "MUD", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "2,6": { + "terrain": "CONCRETE", + "mine": null + }, + "2,7": { + "terrain": "CONCRETE", + "mine": null + }, + "2,8": { + "terrain": "MUD", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "2,9": { + "terrain": "CONCRETE", + "mine": null + }, + "3,0": { + "terrain": "CONCRETE", + "mine": null + }, + "3,1": { + "terrain": "MUD", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 19 + } + }, + "3,2": { + "terrain": "GRASS", + "mine": null + }, + "3,3": { + "terrain": "MUD", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "1,3" + } + }, + "3,4": { + "terrain": "MUD", + "mine": null + }, + "3,5": { + "terrain": "CONCRETE", + "mine": null + }, + "3,6": { + "terrain": "MUD", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "3,7": { + "terrain": "MUD", + "mine": null + }, + "3,8": { + "terrain": "GRASS", + "mine": null + }, + "3,9": { + "terrain": "GRASS", + "mine": null + }, + "4,0": { + "terrain": "CONCRETE", + "mine": null + }, + "4,1": { + "terrain": "MUD", + "mine": null + }, + "4,2": { + "terrain": "CONCRETE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "4,3": { + "terrain": "CONCRETE", + "mine": null + }, + "4,4": { + "terrain": "MUD", + "mine": null + }, + "4,5": { + "terrain": "MUD", + "mine": null + }, + "4,6": { + "terrain": "CONCRETE", + "mine": null + }, + "4,7": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": null + } + }, + "4,8": { + "terrain": "CONCRETE", + "mine": null + }, + "4,9": { + "terrain": "MUD", + "mine": null + }, + "5,0": { + "terrain": "CONCRETE", + "mine": null + }, + "5,1": { + "terrain": "MUD", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "2,3" + } + }, + "5,2": { + "terrain": "MUD", + "mine": null + }, + "5,3": { + "terrain": "GRASS", + "mine": null + }, + "5,4": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "2,8" + } + }, + "5,5": { + "terrain": "CONCRETE", + "mine": null + }, + "5,6": { + "terrain": "MUD", + "mine": null + }, + "5,7": { + "terrain": "MUD", + "mine": null + }, + "5,8": { + "terrain": "GRASS", + "mine": null + }, + "5,9": { + "terrain": "MUD", + "mine": null + }, + "6,0": { + "terrain": "GRASS", + "mine": null + }, + "6,1": { + "terrain": "CONCRETE", + "mine": null + }, + "6,2": { + "terrain": "MUD", + "mine": null + }, + "6,3": { + "terrain": "CONCRETE", + "mine": null + }, + "6,4": { + "terrain": "CONCRETE", + "mine": null + }, + "6,5": { + "terrain": "GRASS", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "6,6": { + "terrain": "GRASS", + "mine": null + }, + "6,7": { + "terrain": "CONCRETE", + "mine": null + }, + "6,8": { + "terrain": "CONCRETE", + "mine": null + }, + "6,9": { + "terrain": "CONCRETE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "7,0": { + "terrain": "CONCRETE", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "4,7" + } + }, + "7,1": { + "terrain": "CONCRETE", + "mine": null + }, + "7,2": { + "terrain": "GRASS", + "mine": null + }, + "7,3": { + "terrain": "MUD", + "mine": null + }, + "7,4": { + "terrain": "GRASS", + "mine": null + }, + "7,5": { + "terrain": "GRASS", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "7,6": { + "terrain": "CONCRETE", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 39 + } + }, + "7,7": { + "terrain": "MUD", + "mine": null + }, + "7,8": { + "terrain": "GRASS", + "mine": null + }, + "7,9": { + "terrain": "GRASS", + "mine": null + }, + "8,0": { + "terrain": "GRASS", + "mine": null + }, + "8,1": { + "terrain": "GRASS", + "mine": { + "asset": "F", + "mine_type": "time", + "timer": 24 + } + }, + "8,2": { + "terrain": "GRASS", + "mine": null + }, + "8,3": { + "terrain": "CONCRETE", + "mine": { + "asset": "A", + "mine_type": "standard" + } + }, + "8,4": { + "terrain": "CONCRETE", + "mine": null + }, + "8,5": { + "terrain": "GRASS", + "mine": null + }, + "8,6": { + "terrain": "GRASS", + "mine": null + }, + "8,7": { + "terrain": "CONCRETE", + "mine": null + }, + "8,8": { + "terrain": "GRASS", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "3,6" + } + }, + "8,9": { + "terrain": "GRASS", + "mine": null + }, + "9,0": { + "terrain": "MUD", + "mine": null + }, + "9,1": { + "terrain": "GRASS", + "mine": null + }, + "9,2": { + "terrain": "CONCRETE", + "mine": null + }, + "9,3": { + "terrain": "CONCRETE", + "mine": null + }, + "9,4": { + "terrain": "CONCRETE", + "mine": null + }, + "9,5": { + "terrain": "GRASS", + "mine": { + "asset": "B", + "mine_type": "chained", + "predecessor": "0,4" + } + }, + "9,6": { + "terrain": "CONCRETE", + "mine": null + }, + "9,7": { + "terrain": "MUD", + "mine": null + }, + "9,8": { + "terrain": "MUD", + "mine": null + }, + "9,9": { + "terrain": "MUD", + "mine": null + }, + "agent_starting_position": "0,0" + + } \ No newline at end of file diff --git a/tile.py b/tile.py index ee31c23..6ad68fd 100644 --- a/tile.py +++ b/tile.py @@ -1,7 +1,23 @@ -class Tile: - def __init__(self, position, color=None, mine=None): - self.position = position - self.color = color +from project_constants import Terrain as t +#Assume_cost function assumes colour as an argument (colour that is already given to a tile) and depending +#on what it is returns value of Terrein Enum +#It is used in Tile.cost (giving the value to the tile) + + +def assume_cost(terrain_type): + if (terrain_type == "CONCRETE"): + return t.CONCRETE + elif (terrain_type == "GRASS"): + return t.GRASS + elif (terrain_type == "MUD"): + return t.MUD + + +class Tile: + def __init__(self, position, terrain_type=None, mine=None): + self.position = position + self.terrain_type = terrain_type + self.cost = assume_cost(terrain_type) # mine is an instance of Mine class - self.mine = mine + self.mine = mine \ No newline at end of file From 8ffdacd60346243d95726a1520b52a5d25bc7e0c Mon Sep 17 00:00:00 2001 From: JakubR Date: Fri, 7 May 2021 22:26:58 +0200 Subject: [PATCH 9/9] coordinated project modules; fully implemented blitting using display_assets.py; updated maps; fixed some bugs --- agent.py | 10 +- display_assets.py | 22 ++- json_generator.py | 46 ++++--- main.py | 3 + minefield.py | 31 +++-- project_constants.py | 21 ++- resources/minefields/fourthmap.json | 32 +---- resources/minefields/thirdmap.json | 200 ++++++++++++++-------------- tile.py | 23 ++-- 9 files changed, 188 insertions(+), 200 deletions(-) diff --git a/agent.py b/agent.py index 2fbb46a..63183e8 100644 --- a/agent.py +++ b/agent.py @@ -1,21 +1,19 @@ -import pygame import project_constants as const -import json_generator as js import json # Class of our agent, initialization of it -# movement functions (those defiend by the 'go_' prefix are not meant to actually move our agent, they just return some values -# that are later used by another function called 'is_valid_move' (which is defined in Minefield)); +# movement functions (those defined by the 'go_' prefix are not meant to actually move our agent, they just return some +# values that are later used by another function called 'is_valid_move' (which is defined in Minefield)); class Agent: def __init__(self, json_path): with open(json_path) as json_data: data = json.load(json_data) - self.row, self.column = data['agent_starting_position'].split(",") + self.row, self.column = data["agents_initial_state"]["position"].split(",") self.position = [int(self.row), int(self.column)] # self.direction = const.Direction() - self.direction = const.Direction.UP + self.direction = const.Direction(data["agents_initial_state"]["direction"]) def rotate_left(self): self.direction = self.direction.previous() diff --git a/display_assets.py b/display_assets.py index 4417b32..2dc302e 100644 --- a/display_assets.py +++ b/display_assets.py @@ -2,6 +2,10 @@ import pygame import project_constants as const +from mine_models.standard_mine import StandardMine +from mine_models.chained_mine import ChainedMine +from mine_models.time_mine import TimeMine + # ================================= # # === SO THE OLD BLITTING WORKS === # @@ -14,7 +18,9 @@ tile_asset_options = { } mine_asset_options = { - "MINE": CONST.ASSET_MINE + "MINE": const.ASSET_MINE, + "CHAINS": const.ASSET_CHAINS, + "TIME_MINE": const.ASSET_TIME_MINE, } @@ -52,10 +58,16 @@ def blit_graphics(minefield): # draw a mine on top if there is one if tile.mine is not None: - # current icons don't represent actual types, thus every mine has the same icon (temporary solution) - const.SCREEN.blit(mine_asset_options["MINE"], tile_screen_coords) + if isinstance(tile.mine, StandardMine): + const.SCREEN.blit(mine_asset_options["MINE"], tile_screen_coords) + if isinstance(tile.mine, ChainedMine): + predecessor = tile.mine.predecessor + predecessor_position = predecessor.position if predecessor is not None else None + display_chained_mine(tile.position, predecessor_position) + elif isinstance(tile.mine, TimeMine): + display_time_mine(tile.position, "0" + str(tile.mine.timer)) # sapper display_sapper( @@ -241,9 +253,9 @@ def display_time_mine(coords, time): mine_coords = calculate_screen_position(coords) number_coords = mine_coords if which_digit == const.Digit.ONES: - number_coords = (mine_coords[0] + 36, mine_coords[1] + 22) - elif which_digit == const.Digit.TENS: number_coords = (mine_coords[0] + 44, mine_coords[1] + 22) + elif which_digit == const.Digit.TENS: + number_coords = (mine_coords[0] + 36, mine_coords[1] + 22) const.SCREEN.blit( number_asset, diff --git a/json_generator.py b/json_generator.py index 8242664..601cbbd 100644 --- a/json_generator.py +++ b/json_generator.py @@ -4,12 +4,12 @@ import random import project_constants as const # import tile class -import tile as tl +from tile import Tile # import mine models -import mine_models.standard_mine as sm -import mine_models.time_mine as tm -import mine_models.chained_mine as cm +from mine_models.standard_mine import StandardMine +from mine_models.time_mine import TimeMine +from mine_models.chained_mine import ChainedMine class JsonGenerator: @@ -18,7 +18,7 @@ class JsonGenerator: # constructor that can be used to set agent's initial state def __init__(self, agents_initial_position=(0, 0), agents_initial_direction=const.Direction.UP.value): # saving agent's initial state (position & direction) - self.agents_initial_position = agents_initial_position + self.agents_initial_position = format_position_to_tuple(agents_initial_position) self.agents_initial_direction = agents_initial_direction # saving data to the grid dictionary @@ -30,7 +30,7 @@ class JsonGenerator: # sets agent's initial state def set_agents_initial_state(self, position=(0, 0), direction=const.Direction.UP.value): # setting fields in the instance - self.agents_initial_position = position + self.agents_initial_position = format_position_to_tuple(position) self.agents_initial_direction = direction # setting new agent's initial state @@ -39,11 +39,14 @@ class JsonGenerator: "direction": direction } - # overwrites grid field with a new grid with randomized terrains and mines + # overwrites grid field with a new grid with randomized colors and mines def generate_randomized_grid(self, dimensions, mine_appearance_chance=0.15, predecessor_chance_decrease=0.25): # clearing grid field self.clear_grid() + # formatting dimensions to tuple + dimensions = format_position_to_tuple(dimensions) + # getting grid dimensions num_of_rows, num_of_columns = dimensions @@ -53,13 +56,13 @@ class JsonGenerator: for j in range(num_of_columns): # picking random values for tiles - random_tile_terrain = random.choice(const.STRUCT_TILE_TERRAINS) + random_tile_color = random.choice(const.STRUCT_TILE_TERRAINS) # adding added tile's indexes to a pool tile_pool.append((i, j)) # creating random tile - self.add_tile((i, j), random_tile_terrain) + self.add_tile((i, j), random_tile_color) # deleting agent's starting tile from the pool deleted_row, deleted_column = self.agents_initial_position @@ -104,15 +107,15 @@ class JsonGenerator: current_tile = predecessor # adds a new tile or edits an existing one in the grid field - def add_tile(self, position, terrain): + def add_tile(self, position, color): # creating new tile without a mine self.grid[format_position_to_str(position)] = { - "terrain": terrain, + "color": color, "mine": None } # adds a new tile with a mine or edits an existing one in the grid field - def add_tile_with_a_mine(self, position, terrain, mine_type, attribute_values): + def add_tile_with_a_mine(self, position, color, mine_type, attribute_values): # setting mine data using attribute_values mine_values = const.STRUCT_MINE_ATTRIBUTES[mine_type] @@ -122,14 +125,14 @@ class JsonGenerator: # creating a new tile self.grid[format_position_to_str(position)] = { - "terrain": terrain + "color": color } # updating the tile with a mine field self.grid[format_position_to_str(position)]["mine"] = {} for key in mine_values.keys(): - self.grid[format_position_to_str()]["mine"][key] = mine_values[key] + self.grid[format_position_to_str(position)]["mine"][key] = mine_values[key] # deletes a mine with a given position from the grid field def delete_a_tile(self, position): @@ -227,16 +230,16 @@ def create_a_mine(mine_dict, position): # if mine's type is "standard" - creating standard mine if mine_dict["mine_type"] == "standard": - mine = sm.StandardMine(position) + mine = StandardMine(position) # if mine's type is "time" - creating time mine elif mine_dict["mine_type"] == "time": timer_value = mine_dict["timer"] - mine = tm.TimeMine(position, timer_value) + mine = TimeMine(position, timer_value) # if mine's type is "chained" - creating chained mine (no successors assigned yet) elif mine_dict["mine_type"] == "chained": - mine = cm.ChainedMine(position) + mine = ChainedMine(position) return mine @@ -247,11 +250,11 @@ def create_a_tile(tile_dict, position): position = format_position_to_tuple(position) # getting tile's parameters - terrain = tile_dict["terrain"] - mine = create_a_mine(position, tile_dict["mine"]) + color = tile_dict["color"] + mine = create_a_mine(tile_dict["mine"], position) # creating and returning a tile with the parameters set above - return tl.Tile(position, terrain, mine) + return Tile(position, color, mine) # returns a list of tuples containing chained mine's position and it's predecessors position @@ -268,7 +271,8 @@ def get_chained_mine_and_its_predecessor_pairs(minefield_dictionary): # getting the chained mines and it's predecessors positions this_mines_position = tuple(int(i) for i in key.split(',')) - its_predecessors_position = tuple(int(i) for i in minefield_dictionary[key]["mine"]["predecessor"].split(',')) + its_predecessors_position = \ + tuple(int(i) for i in minefield_dictionary[key]["mine"]["predecessor"].split(',')) # adding the positions to the list as a tuple predecessors.append((this_mines_position, its_predecessors_position)) diff --git a/main.py b/main.py index 69b05fd..8e39924 100644 --- a/main.py +++ b/main.py @@ -10,11 +10,14 @@ from display_assets import blit_graphics from ui.input_box import * from ui.button import * from ui.text_box import * +import json_generator as jg def main(): pygame.init() pygame.display.set_caption(const.V_NAME_OF_WINDOW) + jes = jg.JsonGenerator() + print(jes.get_grid()) # for blocky textures glEnable(GL_TEXTURE_2D) diff --git a/minefield.py b/minefield.py index 129d9ad..2b1f072 100644 --- a/minefield.py +++ b/minefield.py @@ -1,10 +1,10 @@ -import json import agent as ag import project_constants as const import tile as tl from mine_models import standard_mine as sm from mine_models import time_mine as tm from mine_models import chained_mine as cm +import json_generator as jg class Minefield: @@ -14,29 +14,28 @@ class Minefield: self.agent = ag.Agent(const.MAP_RANDOM_10x10) # open JSON with minefield info - with open(json_path) as json_data: - data = json.load(json_data) + json_gen = jg.JsonGenerator() + json_gen.load_from_a_file(json_path) # create matrix of a desired size, fill it with default tile objects self.matrix = [ [ - tl.Tile((row, column)) for column in range(const.V_GRID_HOR_TILES) + tl.Tile( + (row, column), + terrain_type=json_gen.get_tile((row, column))["terrain"], + mine=jg.create_a_mine(json_gen.get_mine((row, column)), (row, column)) + ) for column in range(const.V_GRID_HOR_TILES) ] for row in range(const.V_GRID_VER_TILES) ] - # iterate through tiles, set their terrains and add mines - for row in range(const.V_GRID_VER_TILES): - for column in range(const.V_GRID_HOR_TILES): + # iterate through chained mines, set mine predecessors + for pair in jg.get_chained_mine_and_its_predecessor_pairs(json_gen.get_grid()): + successor_position, predecessor_position = pair + successor_row, successor_column = successor_position + predecessor_row, predecessor_column = predecessor_position - # load tile's data from json - tile_data = data[f"{row},{column}"] - - # if there is a mine, create & assign new Mine object (type recognition included) - if tile_data["mine"] is not None: - mine = self._create_mine(tile_data["mine"], row, column) - self.matrix[row][column].mine = mine - - self.matrix[row][column].terrain_type = tile_data["terrain"].upper() + predecessor = self.matrix[predecessor_row][predecessor_column] + self.matrix[successor_row][successor_column].mine.predecessor = predecessor # ================ # # === MOVEMENT === # diff --git a/project_constants.py b/project_constants.py index a081cfd..35ce325 100644 --- a/project_constants.py +++ b/project_constants.py @@ -17,11 +17,11 @@ V_NAME_OF_WINDOW = "MineFusion TM" DIR_ASSETS = os.path.join("resources", "assets") V_FPS = 60 -ACTION_INTERVAL = 1 # interval between two actions in seconds +ACTION_INTERVAL = 1 # interval between two actions in seconds V_TILE_SIZE = 60 -V_GRID_VER_TILES = 10 # vertical (number of rows) -V_GRID_HOR_TILES = 10 # horizontal (number of columns) +V_GRID_VER_TILES = 10 # vertical (number of rows) +V_GRID_HOR_TILES = 10 # horizontal (number of columns) V_SCREEN_PADDING = 10 V_NUMBER_PADDING = 50 V_TILE_AREA_HEIGHT = V_TILE_SIZE * V_GRID_VER_TILES @@ -30,7 +30,7 @@ V_TILE_AREA_WIDTH = V_TILE_SIZE * V_GRID_HOR_TILES SCREEN = pygame.display.set_mode( ( V_TILE_AREA_WIDTH + 2 * V_SCREEN_PADDING + V_NUMBER_PADDING, # screen width - V_TILE_AREA_HEIGHT + 2 * V_SCREEN_PADDING + V_NUMBER_PADDING # screen height + V_TILE_AREA_HEIGHT + 2 * V_SCREEN_PADDING + V_NUMBER_PADDING # screen height ) ) @@ -72,9 +72,9 @@ class Coords(Enum): class Terrain(Enum): CONCRETE = 1 - GRASS = 2 + GRASS = 2 MUD = 4 - + # =============== # # === STRUCTS === # @@ -85,8 +85,8 @@ class Terrain(Enum): # # USED BY JSON GENERATOR # used to generate random tile colors -#####################STRUCT_TILE_COLORS = ["BLUE", "GREEN", "ORANGE", "PURPLE", "RED", "WHITE", "YELLOW"] -STRUCT_TILE_TERRAINS = ["CONCRETE","GRASS","MUD"] +STRUCT_TILE_TERRAINS = ["CONCRETE", "GRASS", "MUD"] + # used to generate random mines and create not random mines STRUCT_MINE_TYPES = ["standard", "chained", "time"] @@ -119,14 +119,12 @@ STRUCT_MINE_ATTRIBUTE_TYPES = { "time": [int] } - # ============== # # ==== MAPS ==== # # ============== # MAP_RANDOM_10x10 = os.path.join("resources", "minefields", "fourthmap.json") - # ============== # # === ASSETS === # # ============== # @@ -176,7 +174,6 @@ ASSET_TIME_MINE = pygame.transform.scale( (V_TILE_SIZE, V_TILE_SIZE) ) - # ==================== # # === TIME NUMBERS === # # ==================== # @@ -231,7 +228,6 @@ ASSET_NUMBER_TIME_9 = pygame.transform.scale( (6, 16) ) - # ====================== # # === CHAINS NUMBERS === # # ====================== # @@ -316,7 +312,6 @@ ASSET_NUMBER_CHAINS_15 = pygame.transform.scale( (6, 12) ) - # ================== # # === OLD ASSETS === # # ================== # diff --git a/resources/minefields/fourthmap.json b/resources/minefields/fourthmap.json index 23da209..7ed7998 100644 --- a/resources/minefields/fourthmap.json +++ b/resources/minefields/fourthmap.json @@ -14,7 +14,6 @@ "0,3": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -22,7 +21,6 @@ "0,4": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -42,7 +40,6 @@ "0,8": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "0,3" } @@ -50,7 +47,6 @@ "0,9": { "terrain": "GRASS", "mine": { - "asset": "F", "mine_type": "time", "timer": 20 } @@ -62,7 +58,6 @@ "1,1": { "terrain": "GRASS", "mine": { - "asset": "A", "mine_type": "standard" } }, @@ -73,7 +68,6 @@ "1,3": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -109,7 +103,6 @@ "2,1": { "terrain": "CONCRETE", "mine": { - "asset": "A", "mine_type": "standard" } }, @@ -120,7 +113,6 @@ "2,3": { "terrain": "MUD", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -132,7 +124,6 @@ "2,5": { "terrain": "MUD", "mine": { - "asset": "A", "mine_type": "standard" } }, @@ -147,7 +138,6 @@ "2,8": { "terrain": "MUD", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -163,7 +153,6 @@ "3,1": { "terrain": "MUD", "mine": { - "asset": "F", "mine_type": "time", "timer": 19 } @@ -175,7 +164,6 @@ "3,3": { "terrain": "MUD", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "1,3" } @@ -191,7 +179,6 @@ "3,6": { "terrain": "MUD", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -219,7 +206,6 @@ "4,2": { "terrain": "CONCRETE", "mine": { - "asset": "A", "mine_type": "standard" } }, @@ -242,7 +228,6 @@ "4,7": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": null } @@ -262,7 +247,6 @@ "5,1": { "terrain": "MUD", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "2,3" } @@ -278,7 +262,6 @@ "5,4": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "2,8" } @@ -326,7 +309,6 @@ "6,5": { "terrain": "GRASS", "mine": { - "asset": "A", "mine_type": "standard" } }, @@ -345,14 +327,12 @@ "6,9": { "terrain": "CONCRETE", "mine": { - "asset": "A", "mine_type": "standard" } }, "7,0": { "terrain": "CONCRETE", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "4,7" } @@ -376,14 +356,12 @@ "7,5": { "terrain": "GRASS", "mine": { - "asset": "A", "mine_type": "standard" } }, "7,6": { "terrain": "CONCRETE", "mine": { - "asset": "F", "mine_type": "time", "timer": 39 } @@ -407,7 +385,6 @@ "8,1": { "terrain": "GRASS", "mine": { - "asset": "F", "mine_type": "time", "timer": 24 } @@ -419,7 +396,6 @@ "8,3": { "terrain": "CONCRETE", "mine": { - "asset": "A", "mine_type": "standard" } }, @@ -442,7 +418,6 @@ "8,8": { "terrain": "GRASS", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "3,6" } @@ -474,7 +449,6 @@ "9,5": { "terrain": "GRASS", "mine": { - "asset": "B", "mine_type": "chained", "predecessor": "0,4" } @@ -495,6 +469,8 @@ "terrain": "MUD", "mine": null }, - "agent_starting_position": "0,0" - + "agents_initial_state": { + "direction": 1, + "position": "0,0" + } } \ No newline at end of file diff --git a/resources/minefields/thirdmap.json b/resources/minefields/thirdmap.json index ff046e3..81ae29b 100644 --- a/resources/minefields/thirdmap.json +++ b/resources/minefields/thirdmap.json @@ -1,456 +1,456 @@ { "0,0": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "0,1": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "0,2": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "0,3": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "0,4": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "0,5": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "0,6": { - "color": "RED", + "terrain": "MUD", "mine": null }, "0,7": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "0,8": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "0,9": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": { "mine_type": "time", "timer": 28 } }, "1,0": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "1,1": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "1,2": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "1,3": { - "color": "WHITE", + "terrain": "GRASS", "mine": { "mine_type": "chained", "predecessor": "8,9" } }, "1,4": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "1,5": { - "color": "RED", + "terrain": "MUD", "mine": null }, "1,6": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "1,7": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "1,8": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "1,9": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "2,0": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "2,1": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": { "mine_type": "time", "timer": 27 } }, "2,2": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "2,3": { - "color": "RED", + "terrain": "MUD", "mine": null }, "2,4": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "2,5": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "2,6": { - "color": "BLUE", + "terrain": "GRASS", "mine": { "mine_type": "chained", "predecessor": "7,2" } }, "2,7": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "2,8": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "2,9": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "3,0": { - "color": "WHITE", + "terrain": "GRASS", "mine": { "mine_type": "time", "timer": 27 } }, "3,1": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "3,2": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "3,3": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "3,4": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": { "mine_type": "chained", "predecessor": "8,8" } }, "3,5": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "3,6": { - "color": "RED", + "terrain": "MUD", "mine": null }, "3,7": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "3,8": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "3,9": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "4,0": { - "color": "GREEN", + "terrain": "MUD", "mine": { "mine_type": "chained", "predecessor": null } }, "4,1": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": { "mine_type": "standard" } }, "4,2": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "4,3": { - "color": "RED", + "terrain": "MUD", "mine": null }, "4,4": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "4,5": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "4,6": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "4,7": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "4,8": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "4,9": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "5,0": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "5,1": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "5,2": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "5,3": { - "color": "YELLOW", + "terrain": "GRASS", "mine": { "mine_type": "time", "timer": 25 } }, "5,4": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "5,5": { - "color": "RED", + "terrain": "MUD", "mine": null }, "5,6": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "5,7": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "5,8": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "5,9": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "6,0": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": { "mine_type": "chained", "predecessor": "6,1" } }, "6,1": { - "color": "BLUE", + "terrain": "GRASS", "mine": { "mine_type": "chained", "predecessor": "3,4" } }, "6,2": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "6,3": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "6,4": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "6,5": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "6,6": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "6,7": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "6,8": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "6,9": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "7,0": { - "color": "YELLOW", + "terrain": "GRASS", "mine": { "mine_type": "time", "timer": 30 } }, "7,1": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "7,2": { - "color": "WHITE", + "terrain": "GRASS", "mine": { "mine_type": "chained", "predecessor": "7,3" } }, "7,3": { - "color": "GREEN", + "terrain": "MUD", "mine": { "mine_type": "chained", "predecessor": null } }, "7,4": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "7,5": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": { "mine_type": "standard" } }, "7,6": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "7,7": { - "color": "BLUE", + "terrain": "GRASS", "mine": null }, "7,8": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "7,9": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "8,0": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "8,1": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "8,2": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "8,3": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "8,4": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "8,5": { - "color": "YELLOW", + "terrain": "GRASS", "mine": null }, "8,6": { - "color": "WHITE", + "terrain": "GRASS", "mine": { "mine_type": "standard" } }, "8,7": { - "color": "GREEN", + "terrain": "MUD", "mine": null }, "8,8": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": { "mine_type": "chained", "predecessor": null } }, "8,9": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": { "mine_type": "chained", "predecessor": null } }, "9,0": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "9,1": { - "color": "BLUE", + "terrain": "GRASS", "mine": { "mine_type": "chained", "predecessor": "4,0" } }, "9,2": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "9,3": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "9,4": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "9,5": { - "color": "PURPLE", + "terrain": "CONCRETE", "mine": null }, "9,6": { - "color": "WHITE", + "terrain": "GRASS", "mine": null }, "9,7": { - "color": "RED", + "terrain": "MUD", "mine": null }, "9,8": { - "color": "ORANGE", + "terrain": "CONCRETE", "mine": null }, "9,9": { - "color": "RED", + "terrain": "MUD", "mine": null }, "agents_initial_state": { diff --git a/tile.py b/tile.py index 6ad68fd..e4fa23b 100644 --- a/tile.py +++ b/tile.py @@ -1,17 +1,18 @@ -from project_constants import Terrain as t +from project_constants import Terrain -#Assume_cost function assumes colour as an argument (colour that is already given to a tile) and depending -#on what it is returns value of Terrein Enum -#It is used in Tile.cost (giving the value to the tile) + +# Assume_cost function assumes colour as an argument (colour that is already given to a tile) and depending +# on what it is returns value of Terrein Enum +# It is used in Tile.cost (giving the value to the tile) def assume_cost(terrain_type): - if (terrain_type == "CONCRETE"): - return t.CONCRETE - elif (terrain_type == "GRASS"): - return t.GRASS - elif (terrain_type == "MUD"): - return t.MUD + if terrain_type == "CONCRETE": + return Terrain.CONCRETE + elif terrain_type == "GRASS": + return Terrain.GRASS + elif terrain_type == "MUD": + return Terrain.MUD class Tile: @@ -20,4 +21,4 @@ class Tile: self.terrain_type = terrain_type self.cost = assume_cost(terrain_type) # mine is an instance of Mine class - self.mine = mine \ No newline at end of file + self.mine = mine